Skip to content

Core API Reference

Unverified examples

This page predates the current release and parts of it describe planned or older API. Only 5 of 15 code snippets on this page run as-is today. For verified, runnable code see the Quick Start, the Showcase and the Backends guide.

The core API provides fundamental functionality for SuperQuantX, including backend management, configuration, and system information.

Package-Level Functions

Version Information

superquantx.get_version

get_version() -> str

Get SuperQuantX version.

Source code in src/superquantx/__init__.py
def get_version() -> str:
    """Get SuperQuantX version."""
    return __version__

superquantx.get_backend_info

get_backend_info() -> dict[str, str | None]

Return the installed version of each backend SDK, or None if absent.

Versions come from :mod:importlib.metadata, so a package that does not define __version__ (for example braket) is still reported.

Source code in src/superquantx/__init__.py
def get_backend_info() -> dict[str, str | None]:
    """Return the installed version of each backend SDK, or None if absent.

    Versions come from :mod:`importlib.metadata`, so a package that does not
    define ``__version__`` (for example ``braket``) is still reported.
    """
    from importlib.metadata import PackageNotFoundError, version

    info: dict[str, str | None] = {}
    for key, dists in _BACKEND_DISTRIBUTIONS.items():
        info[key] = None
        for dist in dists:
            try:
                info[key] = version(dist)
                break
            except PackageNotFoundError:
                continue
    return info

superquantx.print_system_info

print_system_info() -> None

Print system and backend information.

Source code in src/superquantx/__init__.py
def print_system_info() -> None:
    """Print system and backend information."""
    import platform
    import sys

    print(f"SuperQuantX version: {__version__}")
    print(f"Python version: {sys.version}")
    print(f"Platform: {platform.platform()}")
    print("\nBackend versions:")

    backend_info = get_backend_info()
    for backend, version in backend_info.items():
        status = version if version else "Not installed"
        print(f"  {backend}: {status}")

Backend Management

superquantx.get_backend

get_backend(backend: str | BaseBackend, **kwargs) -> BaseBackend

Get a quantum backend instance.

Parameters:

Name Type Description Default
backend str | BaseBackend

Backend name or instance

required
**kwargs

Backend configuration parameters

{}

Returns:

Type Description
BaseBackend

Backend instance

Raises:

Type Description
ValueError

If backend is not supported

ImportError

If backend dependencies are missing

Example

backend = get_backend('pennylane', device='default.qubit') backend = get_backend('qiskit', provider='IBMQ')

Source code in src/superquantx/backends/__init__.py
def get_backend(backend: str | BaseBackend, **kwargs) -> BaseBackend:
    """Get a quantum backend instance.

    Args:
        backend: Backend name or instance
        **kwargs: Backend configuration parameters

    Returns:
        Backend instance

    Raises:
        ValueError: If backend is not supported
        ImportError: If backend dependencies are missing

    Example:
        >>> backend = get_backend('pennylane', device='default.qubit')
        >>> backend = get_backend('qiskit', provider='IBMQ')

    """
    if isinstance(backend, BaseBackend):
        return backend

    if not isinstance(backend, str):
        raise ValueError(f"Backend must be string or BaseBackend instance, got {type(backend)}")

    # Resolve aliases
    backend_name = BACKEND_ALIASES.get(backend.lower(), backend.lower())

    # Auto-select backend if requested
    if backend_name == 'auto':
        backend_name = _auto_select_backend()

    # Get backend class
    if backend_name not in BACKEND_REGISTRY:
        available = list(BACKEND_REGISTRY.keys())
        raise ValueError(f"Backend '{backend_name}' not supported. Available: {available}")

    backend_class = BACKEND_REGISTRY[backend_name]

    try:
        logger.info(f"Initializing {backend_name} backend")
        return backend_class(**kwargs)
    except ImportError as e:
        logger.error(f"Failed to import {backend_name} backend: {e}")
        raise ImportError(f"Backend '{backend_name}' requires additional dependencies: {e}")
    except Exception as e:
        logger.error(f"Failed to initialize {backend_name} backend: {e}")
        raise

superquantx.list_available_backends

list_available_backends() -> dict[str, dict[str, Any]]

List all available backends and their status.

Returns:

Type Description
dict[str, dict[str, Any]]

Dictionary with backend information

Source code in src/superquantx/backends/__init__.py
def list_available_backends() -> dict[str, dict[str, Any]]:
    """List all available backends and their status.

    Returns:
        Dictionary with backend information

    """
    backend_info = {}

    for name, backend_class in BACKEND_REGISTRY.items():
        if name == 'auto' or backend_class is None:
            continue

        try:
            # Try to instantiate to check availability
            test_instance = backend_class()
            backend_info[name] = {
                'available': True,
                'class': backend_class.__name__,
                'description': getattr(backend_class, '__doc__', '').split('\n')[0] if backend_class.__doc__ else '',
                'capabilities': getattr(test_instance, 'capabilities', {}),
                'gate_model': getattr(test_instance, 'gate_model', True),
            }
        except ImportError:
            backend_info[name] = {
                'available': False,
                'class': backend_class.__name__,
                'reason': 'Missing dependencies',
            }
        except Exception as e:
            backend_info[name] = {
                'available': False,
                'class': backend_class.__name__,
                'reason': str(e),
            }

    return backend_info

superquantx.check_backend_compatibility

check_backend_compatibility(backend_name: str) -> dict[str, Any]

Check compatibility and requirements for a specific backend.

Parameters:

Name Type Description Default
backend_name str

Name of the backend to check

required

Returns:

Type Description
dict[str, Any]

Compatibility information

Source code in src/superquantx/backends/__init__.py
def check_backend_compatibility(backend_name: str) -> dict[str, Any]:
    """Check compatibility and requirements for a specific backend.

    Args:
        backend_name: Name of the backend to check

    Returns:
        Compatibility information

    """
    backend_name = BACKEND_ALIASES.get(backend_name.lower(), backend_name.lower())

    if backend_name not in BACKEND_REGISTRY:
        return {'compatible': False, 'reason': 'Backend not supported'}

    backend_class = BACKEND_REGISTRY[backend_name]

    try:
        # Try basic instantiation
        test_backend = backend_class()

        return {
            'compatible': True,
            'backend_class': backend_class.__name__,
            'requirements_met': True,
            'capabilities': getattr(test_backend, 'capabilities', {}),
            'version_info': getattr(test_backend, 'get_version_info', lambda: {})(),
        }

    except ImportError as e:
        return {
            'compatible': False,
            'reason': 'Missing dependencies',
            'missing_packages': str(e),
            'requirements_met': False,
        }
    except Exception as e:
        return {
            'compatible': False,
            'reason': str(e),
            'requirements_met': False,
        }

Configuration

superquantx.config

Global configuration for SuperQuantX.

This module provides configuration management for the SuperQuantX package, including backend settings, default parameters, and runtime options.

Classes

Config

Config()

Global configuration class for SuperQuantX.

Initialize configuration with defaults.

Source code in src/superquantx/config.py
def __init__(self) -> None:
    """Initialize configuration with defaults."""
    self._config: dict[str, Any] = {
        # Backend configuration
        "backends": {
            "default": "auto",
            "auto_selection_strategy": "performance",  # "performance", "cost", "speed", "accuracy"
            "fallback_backend": "pennylane",
            "timeout": 300,  # seconds
            "max_retries": 3,
        },

        # Algorithm defaults
        "algorithms": {
            "default_shots": 1024,
            "optimization_level": 1,
            "seed": None,
            "max_iterations": 1000,
            "convergence_tolerance": 1e-6,
        },

        # Visualization settings
        "visualization": {
            "backend": "matplotlib",  # "matplotlib", "plotly", "both"
            "style": "default",
            "save_figures": False,
            "figure_format": "png",
            "dpi": 150,
        },

        # Benchmarking configuration
        "benchmarks": {
            "default_runs": 5,
            "include_classical": True,
            "save_results": True,
            "results_dir": "benchmark_results",
        },

        # Logging configuration
        "logging": {
            "level": "INFO",
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
            "file": None,  # Log file path, None for console only
        },

        # Cache settings
        "cache": {
            "enabled": True,
            "directory": ".superquantx_cache",
            "max_size_mb": 1000,
            "ttl_hours": 24,
        },

        # Platform-specific settings
        "platforms": {
            "ibm": {
                "token": None,
                "hub": "ibm-q",
                "group": "open",
                "project": "main",
            },
            "braket": {
                "s3_folder": None,
                "device_arn": None,
            },
            "azure": {
                "resource_id": None,
                "location": None,
            },
            "dwave": {
                "token": None,
                "solver": None,
            },
            "rigetti": {
                "api_key": None,
                "user_id": None,
            },
        },

        # Development settings
        "development": {
            "debug": False,
            "profile": False,
            "warnings": True,
        },
    }

    # Load configuration from files
    self._load_config_files()

    # Override with environment variables
    self._load_environment_variables()

Functions

get
get(key: str, default: Any = None) -> Any

Get configuration value using dot notation.

Source code in src/superquantx/config.py
def get(self, key: str, default: Any = None) -> Any:
    """Get configuration value using dot notation."""
    keys = key.split(".")
    current = self._config

    try:
        for k in keys:
            current = current[k]
        return current
    except (KeyError, TypeError):
        return default
set
set(key: str, value: Any) -> None

Set configuration value using dot notation.

Source code in src/superquantx/config.py
def set(self, key: str, value: Any) -> None:
    """Set configuration value using dot notation."""
    keys = key.split(".")
    current = self._config

    for k in keys[:-1]:
        if k not in current:
            current[k] = {}
        current = current[k]

    current[keys[-1]] = value
update
update(updates: dict[str, Any]) -> None

Update configuration with a dictionary of values.

Source code in src/superquantx/config.py
def update(self, updates: dict[str, Any]) -> None:
    """Update configuration with a dictionary of values."""
    self._merge_config(updates)
save
save(path: str | Path | None = None) -> None

Save current configuration to file.

Source code in src/superquantx/config.py
def save(self, path: str | Path | None = None) -> None:
    """Save current configuration to file."""
    if path is None:
        path = Path.home() / ".superquantx" / "config.yaml"
    else:
        path = Path(path)

    # Create directory if it doesn't exist
    path.parent.mkdir(parents=True, exist_ok=True)

    try:
        with open(path, "w") as f:
            yaml.dump(self._config, f, default_flow_style=False, indent=2)
        logger.info(f"Configuration saved to {path}")
    except Exception as e:
        logger.error(f"Failed to save configuration to {path}: {e}")
reset
reset() -> None

Reset configuration to defaults.

Source code in src/superquantx/config.py
def reset(self) -> None:
    """Reset configuration to defaults."""
    self.__init__()
to_dict
to_dict() -> dict[str, Any]

Get configuration as dictionary.

Source code in src/superquantx/config.py
def to_dict(self) -> dict[str, Any]:
    """Get configuration as dictionary."""
    return self._config.copy()
print_config
print_config() -> None

Print current configuration.

Source code in src/superquantx/config.py
def print_config(self) -> None:
    """Print current configuration."""
    import pprint
    pprint.pprint(self._config, indent=2)
validate
validate() -> bool

Validate current configuration.

Source code in src/superquantx/config.py
def validate(self) -> bool:
    """Validate current configuration."""
    # Add validation logic here
    return True

ConfigContext

ConfigContext(**kwargs)

Context manager for temporary configuration changes.

Source code in src/superquantx/config.py
def __init__(self, **kwargs):
    self.changes = kwargs
    self.original_values = {}

ValidationResult

ValidationResult(is_valid: bool, errors: list = None)

Result of configuration validation.

Source code in src/superquantx/config.py
def __init__(self, is_valid: bool, errors: list = None):
    self.is_valid = is_valid
    self.errors = errors or []

ConfigValidationError

Bases: Exception

Exception raised when configuration validation fails.

ExperimentContext

ExperimentContext(name: str)

Context manager for experiment tracking.

Source code in src/superquantx/config.py
def __init__(self, name: str):
    self.name = name
    self.parameters = {}
    self.metrics = {}
    self.artifacts = {}

Functions

log_parameter
log_parameter(key: str, value: Any) -> None

Log an experiment parameter.

Source code in src/superquantx/config.py
def log_parameter(self, key: str, value: Any) -> None:
    """Log an experiment parameter."""
    self.parameters[key] = value
log_metric
log_metric(key: str, value: Any) -> None

Log an experiment metric.

Source code in src/superquantx/config.py
def log_metric(self, key: str, value: Any) -> None:
    """Log an experiment metric."""
    self.metrics[key] = value
log_artifact
log_artifact(filename: str, data: Any) -> None

Log an experiment artifact.

Source code in src/superquantx/config.py
def log_artifact(self, filename: str, data: Any) -> None:
    """Log an experiment artifact."""
    self.artifacts[filename] = data

ProfileContext

ProfileContext(name: str)

Context manager for temporary profile activation.

Source code in src/superquantx/config.py
def __init__(self, name: str):
    self.name = name
    self.original_config = None

Functions

configure

configure(backend: str | None = None, shots: int | None = None, debug: bool | None = None, **kwargs) -> None

Configure SuperQuantX settings.

Parameters:

Name Type Description Default
backend str | None

Default backend to use

None
shots int | None

Default number of shots for quantum circuits

None
debug bool | None

Enable debug mode

None
**kwargs

Additional configuration parameters

{}
Source code in src/superquantx/config.py
def configure(
    backend: str | None = None,
    shots: int | None = None,
    debug: bool | None = None,
    **kwargs
) -> None:
    """Configure SuperQuantX settings.

    Args:
        backend: Default backend to use
        shots: Default number of shots for quantum circuits
        debug: Enable debug mode
        **kwargs: Additional configuration parameters

    """
    updates = {}

    if backend is not None:
        updates["backends.default"] = backend

    if shots is not None:
        updates["algorithms.default_shots"] = shots

    if debug is not None:
        updates["development.debug"] = debug

    # Handle additional keyword arguments
    for key, value in kwargs.items():
        updates[key] = value

    # Apply updates
    for key, value in updates.items():
        config.set(key, value)

    # Setup logging if level changed
    if "logging.level" in updates:
        setup_logging()

setup_logging

setup_logging() -> None

Configure the superquantx package logger from the current config.

Only the library's own logger is touched; the root logger and other libraries' loggers (Qiskit, PennyLane, ...) are left alone. This is not called on import: applications opt in via :func:configure_logging or :func:configure.

Source code in src/superquantx/config.py
def setup_logging() -> None:
    """Configure the ``superquantx`` package logger from the current config.

    Only the library's own logger is touched; the root logger and other
    libraries' loggers (Qiskit, PennyLane, ...) are left alone. This is not
    called on import: applications opt in via :func:`configure_logging` or
    :func:`configure`.
    """
    level = getattr(logging, str(config.get("logging.level", "WARNING")).upper())
    format_str = config.get("logging.format") or "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    log_file = config.get("logging.file")

    pkg_logger = logging.getLogger("superquantx")
    for handler in list(pkg_logger.handlers):
        if getattr(handler, "_superquantx_handler", False):
            pkg_logger.removeHandler(handler)

    handler: logging.Handler
    handler = logging.FileHandler(log_file, mode="a") if log_file else logging.StreamHandler()
    handler.setFormatter(logging.Formatter(format_str))
    handler._superquantx_handler = True  # type: ignore[attr-defined]
    pkg_logger.addHandler(handler)
    pkg_logger.setLevel(level)

get_platform_config

get_platform_config(platform: str) -> dict[str, Any]

Get configuration for a specific platform.

Parameters:

Name Type Description Default
platform str

Platform name (e.g., 'ibm', 'braket', 'azure')

required

Returns:

Type Description
dict[str, Any]

Platform configuration dictionary

Source code in src/superquantx/config.py
def get_platform_config(platform: str) -> dict[str, Any]:
    """Get configuration for a specific platform.

    Args:
        platform: Platform name (e.g., 'ibm', 'braket', 'azure')

    Returns:
        Platform configuration dictionary

    """
    return config.get(f"platforms.{platform}", {})

create_default_config

create_default_config(path: str = './superquantx.json', format: str = 'json') -> None

Generate default configuration file.

Parameters:

Name Type Description Default
path str

Path where to save the configuration file

'./superquantx.json'
format str

Format of the file ('json' or 'yaml')

'json'
Source code in src/superquantx/config.py
def create_default_config(path: str = "./superquantx.json", format: str = "json") -> None:
    """Generate default configuration file.

    Args:
        path: Path where to save the configuration file
        format: Format of the file ('json' or 'yaml')
    """
    default_config = {
        "default_backend": "simulator",
        "logging": {
            "level": "INFO",
            "file": "superquantx.log",
            "console": True
        },
        "simulation": {
            "max_qubits": 20,
            "default_shots": 1000,
            "seed": None
        },
        "backends": {
            "simulator": {
                "enabled": True,
                "device": "CPU"
            },
            "pennylane": {
                "enabled": True,
                "device": "default.qubit"
            },
            "qiskit": {
                "enabled": False,
                "provider": "local"
            }
        }
    }

    path_obj = Path(path)
    path_obj.parent.mkdir(parents=True, exist_ok=True)

    if format.lower() == "json":
        with open(path_obj, "w") as f:
            json.dump(default_config, f, indent=2)
    elif format.lower() in ["yaml", "yml"]:
        with open(path_obj, "w") as f:
            yaml.dump(default_config, f, default_flow_style=False, indent=2)
    else:
        raise ValueError(f"Unsupported format: {format}. Use 'json' or 'yaml'.")

configure_interactive

configure_interactive()

Interactive configuration wizard.

Returns:

Type Description

Configuration object that can be saved

Source code in src/superquantx/config.py
def configure_interactive():
    """Interactive configuration wizard.

    Returns:
        Configuration object that can be saved
    """
    print("SuperQuantX Interactive Configuration")
    print("====================================")

    # For now, return a basic config object
    # In a real implementation, this would ask interactive questions
    class InteractiveConfig:
        def __init__(self):
            self.config_data = {
                "default_backend": "simulator",
                "logging": {"level": "INFO"},
                "simulation": {"max_qubits": 20}
            }

        def save(self, path: str):
            path_obj = Path(path)
            path_obj.parent.mkdir(parents=True, exist_ok=True)
            with open(path_obj, "w") as f:
                json.dump(self.config_data, f, indent=2)

    return InteractiveConfig()

load_config

load_config(config_path=None) -> None

Load configuration from file(s).

Parameters:

Name Type Description Default
config_path

Path to config file or list of paths. If None, uses default locations.

None
Source code in src/superquantx/config.py
def load_config(config_path=None) -> None:
    """Load configuration from file(s).

    Args:
        config_path: Path to config file or list of paths. If None, uses default locations.
    """
    if config_path is None:
        # Reload from default locations
        config._load_config_files()
        return

    if isinstance(config_path, str):
        config_path = [config_path]

    for path in config_path:
        path_obj = Path(path)
        if path_obj.exists():
            try:
                with open(path_obj) as f:
                    if path_obj.suffix.lower() in [".yaml", ".yml"]:
                        file_config = yaml.safe_load(f)
                    else:
                        file_config = json.load(f)

                if file_config:
                    config._merge_config(file_config)
                    logger.info(f"Loaded configuration from {path_obj}")
            except Exception as e:
                logger.warning(f"Failed to load config from {path_obj}: {e}")

configure_logging

configure_logging(level='INFO', file=None, console=True, format=None, max_file_size='10MB', backup_count=3) -> None

Configure logging settings.

Parameters:

Name Type Description Default
level

Logging level

'INFO'
file

Log file path

None
console

Whether to log to console

True
format

Log format string

None
max_file_size

Maximum log file size before rotation

'10MB'
backup_count

Number of backup files to keep

3
Source code in src/superquantx/config.py
def configure_logging(level="INFO", file=None, console=True, format=None, max_file_size="10MB", backup_count=3) -> None:
    """Configure logging settings.

    Args:
        level: Logging level
        file: Log file path
        console: Whether to log to console
        format: Log format string
        max_file_size: Maximum log file size before rotation
        backup_count: Number of backup files to keep
    """
    config.set("logging.level", level)
    if file is not None:
        config.set("logging.file", file)
    config.set("logging.console", console)
    if format is not None:
        config.set("logging.format", format)
    config.set("logging.max_file_size", max_file_size)
    config.set("logging.backup_count", backup_count)

    # Re-setup logging with new settings
    setup_logging()

configure_simulation

configure_simulation(max_qubits=None, default_shots=None, memory_limit=None) -> None

Configure simulation settings.

Parameters:

Name Type Description Default
max_qubits

Maximum number of qubits to simulate

None
default_shots

Default number of shots

None
memory_limit

Memory limit for simulations

None
Source code in src/superquantx/config.py
def configure_simulation(max_qubits=None, default_shots=None, memory_limit=None) -> None:
    """Configure simulation settings.

    Args:
        max_qubits: Maximum number of qubits to simulate
        default_shots: Default number of shots
        memory_limit: Memory limit for simulations
    """
    if max_qubits is not None:
        config.set("algorithms.max_qubits", max_qubits)
    if default_shots is not None:
        config.set("algorithms.default_shots", default_shots)
    if memory_limit is not None:
        config.set("simulation.memory_limit", memory_limit)

config_context

config_context(**kwargs)

Create a configuration context manager.

Usage

with config_context(backend="qiskit", shots=10000): # Code here uses the specified configuration pass

Source code in src/superquantx/config.py
def config_context(**kwargs):
    """Create a configuration context manager.

    Usage:
        with config_context(backend="qiskit", shots=10000):
            # Code here uses the specified configuration
            pass
    """
    return ConfigContext(**kwargs)

get_default_backend

get_default_backend() -> str

Get the default backend name.

Source code in src/superquantx/config.py
def get_default_backend() -> str:
    """Get the default backend name."""
    return config.get("backends.default", "simulator")

get_config

get_config(key: str = None) -> Any

Get configuration value(s).

Parameters:

Name Type Description Default
key str

Configuration key (dot notation). If None, returns all config.

None

Returns:

Type Description
Any

Configuration value or full config dict

Source code in src/superquantx/config.py
def get_config(key: str = None) -> Any:
    """Get configuration value(s).

    Args:
        key: Configuration key (dot notation). If None, returns all config.

    Returns:
        Configuration value or full config dict
    """
    if key is None:
        return config.to_dict()
    return config.get(key)

get_config_search_paths

get_config_search_paths() -> list

Get list of configuration search paths.

Source code in src/superquantx/config.py
def get_config_search_paths() -> list:
    """Get list of configuration search paths."""
    return [
        str(Path.home() / ".superquantx" / "config.yaml"),
        str(Path.home() / ".superquantx" / "config.yml"),
        str(Path.home() / ".superquantx" / "config.json"),
        str(Path.cwd() / "superquantx_config.yaml"),
        str(Path.cwd() / "superquantx_config.yml"),
        str(Path.cwd() / "superquantx_config.json"),
    ]

get_active_config_path

get_active_config_path() -> str

Get path of currently active configuration file.

Source code in src/superquantx/config.py
def get_active_config_path() -> str:
    """Get path of currently active configuration file."""
    # For simplicity, return the first existing path
    for path in get_config_search_paths():
        if Path(path).exists():
            return path
    return "Built-in defaults"

validate_config

validate_config() -> ValidationResult

Validate current configuration.

Returns:

Type Description
ValidationResult

ValidationResult with validation status and errors

Source code in src/superquantx/config.py
def validate_config() -> ValidationResult:
    """Validate current configuration.

    Returns:
        ValidationResult with validation status and errors
    """
    errors = []

    # Basic validation - check required keys exist
    required_keys = ["backends", "algorithms", "logging"]
    for key in required_keys:
        if config.get(key) is None:
            errors.append(f"Missing required section: {key}")

    # Validate backend configuration
    backends = config.get("backends", {})
    if not isinstance(backends, dict):
        errors.append("backends section must be a dictionary")

    # Validate logging level
    log_level = config.get("logging.level", "INFO")
    valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
    if log_level not in valid_levels:
        errors.append(f"Invalid logging level: {log_level}. Must be one of {valid_levels}")

    return ValidationResult(is_valid=len(errors) == 0, errors=errors)

validate_config_schema

validate_config_schema(config_path: str) -> None

Validate configuration file against schema.

Parameters:

Name Type Description Default
config_path str

Path to configuration file

required

Raises:

Type Description
ConfigValidationError

If validation fails

Source code in src/superquantx/config.py
def validate_config_schema(config_path: str) -> None:
    """Validate configuration file against schema.

    Args:
        config_path: Path to configuration file

    Raises:
        ConfigValidationError: If validation fails
    """
    path_obj = Path(config_path)
    if not path_obj.exists():
        raise ConfigValidationError(f"Configuration file not found: {config_path}")

    try:
        with open(path_obj) as f:
            if path_obj.suffix.lower() in [".yaml", ".yml"]:
                file_config = yaml.safe_load(f)
            else:
                file_config = json.load(f)
    except Exception as e:
        raise ConfigValidationError(f"Invalid configuration file format: {e}")

    if not isinstance(file_config, dict):
        raise ConfigValidationError("Configuration must be a dictionary")

configure_performance

configure_performance(parallel_backends=None, thread_count=None, memory_limit=None, gpu_enabled=None, optimization_level=None) -> None

Configure performance settings.

Parameters:

Name Type Description Default
parallel_backends

Number of backends to run in parallel

None
thread_count

Number of threads per backend

None
memory_limit

Memory limit for simulations

None
gpu_enabled

Enable GPU acceleration

None
optimization_level

Optimization level (0-3)

None
Source code in src/superquantx/config.py
def configure_performance(parallel_backends=None, thread_count=None, memory_limit=None, gpu_enabled=None, optimization_level=None) -> None:
    """Configure performance settings.

    Args:
        parallel_backends: Number of backends to run in parallel
        thread_count: Number of threads per backend
        memory_limit: Memory limit for simulations
        gpu_enabled: Enable GPU acceleration
        optimization_level: Optimization level (0-3)
    """
    if parallel_backends is not None:
        config.set("performance.parallel_backends", parallel_backends)
    if thread_count is not None:
        config.set("performance.thread_count", thread_count)
    if memory_limit is not None:
        config.set("performance.memory_limit", memory_limit)
    if gpu_enabled is not None:
        config.set("performance.gpu_enabled", gpu_enabled)
    if optimization_level is not None:
        config.set("simulation.optimization_level", optimization_level)

configure_experiments

configure_experiments(experiment_dir='./experiments', auto_save_results=True, save_circuits=True, save_metadata=True, version_control=True) -> None

Configure experiment tracking.

Parameters:

Name Type Description Default
experiment_dir

Directory to save experiments

'./experiments'
auto_save_results

Automatically save experiment results

True
save_circuits

Save quantum circuits

True
save_metadata

Save experiment metadata

True
version_control

Enable version control for experiments

True
Source code in src/superquantx/config.py
def configure_experiments(experiment_dir="./experiments", auto_save_results=True, save_circuits=True, save_metadata=True, version_control=True) -> None:
    """Configure experiment tracking.

    Args:
        experiment_dir: Directory to save experiments
        auto_save_results: Automatically save experiment results
        save_circuits: Save quantum circuits
        save_metadata: Save experiment metadata
        version_control: Enable version control for experiments
    """
    config.set("experiments.directory", experiment_dir)
    config.set("experiments.auto_save_results", auto_save_results)
    config.set("experiments.save_circuits", save_circuits)
    config.set("experiments.save_metadata", save_metadata)
    config.set("experiments.version_control", version_control)

experiment

experiment(name: str)

Create an experiment context.

Parameters:

Name Type Description Default
name str

Name of the experiment

required

Returns:

Type Description

ExperimentContext for tracking the experiment

Source code in src/superquantx/config.py
def experiment(name: str):
    """Create an experiment context.

    Args:
        name: Name of the experiment

    Returns:
        ExperimentContext for tracking the experiment
    """
    return ExperimentContext(name)

create_profile

create_profile(name: str, config_dict: dict) -> None

Create a configuration profile.

Parameters:

Name Type Description Default
name str

Profile name

required
config_dict dict

Configuration dictionary

required
Source code in src/superquantx/config.py
def create_profile(name: str, config_dict: dict) -> None:
    """Create a configuration profile.

    Args:
        name: Profile name
        config_dict: Configuration dictionary
    """
    _profiles[name] = config_dict.copy()

activate_profile

activate_profile(name: str) -> None

Activate a configuration profile.

Parameters:

Name Type Description Default
name str

Profile name

required
Source code in src/superquantx/config.py
def activate_profile(name: str) -> None:
    """Activate a configuration profile.

    Args:
        name: Profile name
    """
    if name not in _profiles:
        raise ValueError(f"Profile '{name}' not found")

    config._merge_config(_profiles[name])
    logger.info(f"Activated profile: {name}")

profile

profile(name: str)

Create a profile context manager.

Parameters:

Name Type Description Default
name str

Profile name

required

Returns:

Type Description

ProfileContext for temporary profile activation

Source code in src/superquantx/config.py
def profile(name: str):
    """Create a profile context manager.

    Args:
        name: Profile name

    Returns:
        ProfileContext for temporary profile activation
    """
    return ProfileContext(name)

superquantx.configure

configure(backend: str | None = None, shots: int | None = None, debug: bool | None = None, **kwargs) -> None

Configure SuperQuantX settings.

Parameters:

Name Type Description Default
backend str | None

Default backend to use

None
shots int | None

Default number of shots for quantum circuits

None
debug bool | None

Enable debug mode

None
**kwargs

Additional configuration parameters

{}
Source code in src/superquantx/config.py
def configure(
    backend: str | None = None,
    shots: int | None = None,
    debug: bool | None = None,
    **kwargs
) -> None:
    """Configure SuperQuantX settings.

    Args:
        backend: Default backend to use
        shots: Default number of shots for quantum circuits
        debug: Enable debug mode
        **kwargs: Additional configuration parameters

    """
    updates = {}

    if backend is not None:
        updates["backends.default"] = backend

    if shots is not None:
        updates["algorithms.default_shots"] = shots

    if debug is not None:
        updates["development.debug"] = debug

    # Handle additional keyword arguments
    for key, value in kwargs.items():
        updates[key] = value

    # Apply updates
    for key, value in updates.items():
        config.set(key, value)

    # Setup logging if level changed
    if "logging.level" in updates:
        setup_logging()

Backend Classes

Base Backend

superquantx.backends.BaseBackend

BaseBackend(device: str | None = None, shots: int = 1024, **kwargs)

Bases: ABC

Abstract base class for quantum computing backends.

This class defines the interface that all quantum backends must implement to provide quantum circuit execution, measurement, and algorithm-specific operations for SuperQuantX.

Parameters:

Name Type Description Default
device str | None

Device or simulator to use

None
shots int

Default number of measurement shots

1024
**kwargs

Backend-specific configuration

{}
Source code in src/superquantx/backends/base_backend.py
def __init__(self, device: str | None = None, shots: int = 1024, **kwargs):
    self.device = device
    self.shots = shots
    self.config = kwargs
    self.capabilities = {}

    self._initialize_backend()

Functions

create_circuit abstractmethod

create_circuit(n_qubits: int) -> Any

Create a quantum circuit with n qubits.

Source code in src/superquantx/backends/base_backend.py
@abstractmethod
def create_circuit(self, n_qubits: int) -> Any:
    """Create a quantum circuit with n qubits."""
    pass

add_gate abstractmethod

add_gate(circuit: Any, gate: str, qubits: int | list[int], params: list[float] | None = None) -> Any

Add a quantum gate to the circuit.

Source code in src/superquantx/backends/base_backend.py
@abstractmethod
def add_gate(self, circuit: Any, gate: str, qubits: int | list[int],
             params: list[float] | None = None) -> Any:
    """Add a quantum gate to the circuit."""
    pass

add_measurement abstractmethod

add_measurement(circuit: Any, qubits: list[int] | None = None) -> Any

Add measurement operations to the circuit.

Source code in src/superquantx/backends/base_backend.py
@abstractmethod
def add_measurement(self, circuit: Any, qubits: list[int] | None = None) -> Any:
    """Add measurement operations to the circuit."""
    pass

execute_circuit abstractmethod

execute_circuit(circuit: Any, shots: int | None = None) -> dict[str, Any]

Execute quantum circuit and return results.

Source code in src/superquantx/backends/base_backend.py
@abstractmethod
def execute_circuit(self, circuit: Any, shots: int | None = None) -> dict[str, Any]:
    """Execute quantum circuit and return results."""
    pass

get_statevector abstractmethod

get_statevector(circuit: Any) -> np.ndarray

Get the statevector from a quantum circuit.

Source code in src/superquantx/backends/base_backend.py
@abstractmethod
def get_statevector(self, circuit: Any) -> np.ndarray:
    """Get the statevector from a quantum circuit."""
    pass

counts_big_endian

counts_big_endian(counts: dict[str, int]) -> dict[str, int]

Return counts re-keyed so that character i is the value of qubit i.

Source code in src/superquantx/backends/base_backend.py
def counts_big_endian(self, counts: dict[str, int]) -> dict[str, int]:
    """Return counts re-keyed so that character i is the value of qubit i."""
    if self._bit_order('counts') == 'big':
        return {str(k).replace(' ', ''): int(v) for k, v in counts.items()}
    return {str(k).replace(' ', '')[::-1]: int(v) for k, v in counts.items()}

statevector_big_endian

statevector_big_endian(circuit: Any) -> np.ndarray

Statevector of circuit with qubit 0 as the most significant bit.

Source code in src/superquantx/backends/base_backend.py
def statevector_big_endian(self, circuit: Any) -> np.ndarray:
    """Statevector of ``circuit`` with qubit 0 as the most significant bit."""
    sv = np.asarray(self.get_statevector(circuit), dtype=complex).ravel()
    n = int(round(np.log2(len(sv))))
    if 2 ** n != len(sv):
        raise RuntimeError(f"Statevector length {len(sv)} is not a power of two")
    if self._bit_order('statevector') == 'little' and n > 1:
        sv = sv.reshape([2] * n).transpose(list(range(n))[::-1]).reshape(-1)
    return sv

create_feature_map

create_feature_map(n_features: int, feature_map: str = 'ZZFeatureMap', reps: int = 2) -> FeatureMapSpec

Return a feature-map specification used by :meth:compute_kernel_matrix.

Supported maps: ZZFeatureMap (Havlicek et al. 2019, linear entanglement), ZFeatureMap (the same without entanglement), PauliFeatureMap (RX/RY/RZ plus CNOT chain) and AngleEncoding (one RY per feature).

Source code in src/superquantx/backends/base_backend.py
def create_feature_map(self, n_features: int, feature_map: str = 'ZZFeatureMap',
                       reps: int = 2) -> 'FeatureMapSpec':
    """Return a feature-map specification used by :meth:`compute_kernel_matrix`.

    Supported maps: ``ZZFeatureMap`` (Havlicek et al. 2019, linear
    entanglement), ``ZFeatureMap`` (the same without entanglement),
    ``PauliFeatureMap`` (RX/RY/RZ plus CNOT chain) and
    ``AngleEncoding`` (one RY per feature).
    """
    if feature_map not in FEATURE_MAPS:
        raise ValueError(
            f"Unknown feature map '{feature_map}'. Supported: {sorted(FEATURE_MAPS)}"
        )
    return FeatureMapSpec(name=feature_map, n_features=n_features, reps=reps)

build_feature_map_circuit

build_feature_map_circuit(x: ndarray, spec: FeatureMapSpec) -> Any

Build the backend-native circuit that encodes x with spec.

Source code in src/superquantx/backends/base_backend.py
def build_feature_map_circuit(self, x: np.ndarray, spec: 'FeatureMapSpec') -> Any:
    """Build the backend-native circuit that encodes ``x`` with ``spec``."""
    n = spec.n_features
    x = np.asarray(x, dtype=float).ravel()
    if len(x) != n:
        raise ValueError(f"Feature map expects {n} features, got {len(x)}")
    circuit = self.create_circuit(n)
    for _ in range(spec.reps):
        if spec.name == 'ZZFeatureMap':
            for i in range(n):
                circuit = self.add_gate(circuit, 'H', i)
                circuit = self.add_gate(circuit, 'RZ', i, [2.0 * x[i]])
            for i in range(n - 1):
                phi = 2.0 * (np.pi - x[i]) * (np.pi - x[i + 1])
                circuit = self.add_gate(circuit, 'CNOT', [i, i + 1])
                circuit = self.add_gate(circuit, 'RZ', i + 1, [phi])
                circuit = self.add_gate(circuit, 'CNOT', [i, i + 1])
        elif spec.name == 'ZFeatureMap':
            for i in range(n):
                circuit = self.add_gate(circuit, 'H', i)
                circuit = self.add_gate(circuit, 'RZ', i, [2.0 * x[i]])
        elif spec.name == 'PauliFeatureMap':
            for i in range(n):
                circuit = self.add_gate(circuit, 'RX', i, [x[i]])
                circuit = self.add_gate(circuit, 'RY', i, [x[i]])
                circuit = self.add_gate(circuit, 'RZ', i, [x[i]])
            for i in range(n - 1):
                circuit = self.add_gate(circuit, 'CNOT', [i, i + 1])
        else:  # AngleEncoding
            for i in range(n):
                circuit = self.add_gate(circuit, 'RY', i, [x[i]])
    return circuit

compute_kernel_matrix

compute_kernel_matrix(X1: ndarray, X2: ndarray, feature_map: Any = None, shots: int | None = None) -> np.ndarray

Fidelity quantum kernel K[i, j] = ||^2.

Each data point is encoded with the feature map and simulated on this backend; the kernel is computed exactly from the resulting statevectors (shots is accepted for API compatibility and ignored). This is a real quantum-circuit kernel, but it is classically simulated, so it says nothing about quantum advantage.

Source code in src/superquantx/backends/base_backend.py
def compute_kernel_matrix(self, X1: np.ndarray, X2: np.ndarray,
                          feature_map: Any = None, shots: int | None = None) -> np.ndarray:
    """Fidelity quantum kernel K[i, j] = |<phi(x1_i)|phi(x2_j)>|^2.

    Each data point is encoded with the feature map and simulated on this
    backend; the kernel is computed exactly from the resulting statevectors
    (``shots`` is accepted for API compatibility and ignored). This is a
    real quantum-circuit kernel, but it is classically simulated, so it says
    nothing about quantum advantage.
    """
    X1 = np.atleast_2d(np.asarray(X1, dtype=float))
    X2 = np.atleast_2d(np.asarray(X2, dtype=float))
    if feature_map is None:
        spec = self.create_feature_map(X1.shape[1])
    elif isinstance(feature_map, str):
        spec = self.create_feature_map(X1.shape[1], feature_map)
    elif isinstance(feature_map, FeatureMapSpec):
        spec = feature_map
    else:
        raise TypeError(
            "feature_map must be a FeatureMapSpec, a feature map name, or None; "
            f"got {type(feature_map).__name__}"
        )

    def states(X: np.ndarray) -> np.ndarray:
        return np.array([
            self.statevector_big_endian(self.build_feature_map_circuit(x, spec))
            for x in X
        ])

    S1 = states(X1)
    S2 = S1 if X2 is X1 or (X2.shape == X1.shape and np.array_equal(X1, X2)) else states(X2)
    return np.abs(S1.conj() @ S2.T) ** 2

ansatz_param_count

ansatz_param_count(ansatz_type: str, n_qubits: int, reps: int = 1) -> int

Number of parameters used by :meth:create_ansatz.

Source code in src/superquantx/backends/base_backend.py
def ansatz_param_count(self, ansatz_type: str, n_qubits: int, reps: int = 1) -> int:
    """Number of parameters used by :meth:`create_ansatz`."""
    if ansatz_type == 'EfficientSU2':
        return 2 * n_qubits * (reps + 1)
    if ansatz_type in ('RealAmplitudes', 'TwoLocal'):
        return n_qubits * (reps + 1)
    raise ValueError(
        f"Ansatz '{ansatz_type}' is not implemented. Use 'RealAmplitudes', "
        "'EfficientSU2' or 'TwoLocal', or pass a callable ansatz."
    )

create_ansatz

create_ansatz(ansatz_type: str, n_qubits: int, params: ndarray, include_custom_gates: bool = False, reps: int | None = None) -> Any

Build a hardware-efficient ansatz with this backend's own gates.

RealAmplitudes/TwoLocal: reps layers of RY on every qubit followed by a linear CNOT chain, plus a final RY layer. EfficientSU2: the same structure with RY and RZ rotations.

Source code in src/superquantx/backends/base_backend.py
def create_ansatz(self, ansatz_type: str, n_qubits: int, params: np.ndarray,
                  include_custom_gates: bool = False, reps: int | None = None) -> Any:
    """Build a hardware-efficient ansatz with this backend's own gates.

    ``RealAmplitudes``/``TwoLocal``: ``reps`` layers of RY on every qubit
    followed by a linear CNOT chain, plus a final RY layer.
    ``EfficientSU2``: the same structure with RY and RZ rotations.
    """
    params = np.asarray(params, dtype=float).ravel()
    per_layer = 2 * n_qubits if ansatz_type == 'EfficientSU2' else n_qubits
    if reps is None:
        reps = max(len(params) // per_layer - 1, 0)
    expected = self.ansatz_param_count(ansatz_type, n_qubits, reps)
    if len(params) != expected:
        raise ValueError(
            f"{ansatz_type} with {n_qubits} qubits and reps={reps} needs "
            f"{expected} parameters, got {len(params)}"
        )

    circuit = self.create_circuit(n_qubits)
    idx = 0
    for layer in range(reps + 1):
        for q in range(n_qubits):
            circuit = self.add_gate(circuit, 'RY', q, [params[idx]])
            idx += 1
            if ansatz_type == 'EfficientSU2':
                circuit = self.add_gate(circuit, 'RZ', q, [params[idx]])
                idx += 1
        if layer < reps:
            for q in range(n_qubits - 1):
                circuit = self.add_gate(circuit, 'CNOT', [q, q + 1])
    return circuit

compute_expectation

compute_expectation(circuit: Any, hamiltonian: Any, shots: int | None = None) -> float

Exact expectation value from this backend's statevector.

hamiltonian may be a dense matrix (qubit 0 most significant), a superquantx.gates.Hamiltonian, a dict like {"ZI": -0.4}, a list of (coeff, "ZI") pairs, or a PennyLane / Qiskit operator. shots is accepted for API compatibility and ignored.

Source code in src/superquantx/backends/base_backend.py
def compute_expectation(self, circuit: Any, hamiltonian: Any,
                        shots: int | None = None) -> float:
    """Exact expectation value <psi|H|psi> from this backend's statevector.

    ``hamiltonian`` may be a dense matrix (qubit 0 most significant), a
    ``superquantx.gates.Hamiltonian``, a dict like ``{"ZI": -0.4}``, a list
    of ``(coeff, "ZI")`` pairs, or a PennyLane / Qiskit operator.
    ``shots`` is accepted for API compatibility and ignored.
    """
    sv = self.statevector_big_endian(circuit)
    n = int(round(np.log2(len(sv))))
    H = hamiltonian_to_matrix(hamiltonian, n)
    return float(np.real(np.vdot(sv, H @ sv)))

create_qaoa_circuit

create_qaoa_circuit(n_qubits: int, gammas: ndarray, betas: ndarray, problem_hamiltonian: Any, mixer_hamiltonian: Any, initial_state: Any, problem_instance: Any) -> Any

QAOA circuit for weighted MaxCut given an adjacency matrix.

Cost layer: exp(-i gamma w_ij Z_i Z_j / 2) per edge (CNOT, RZ, CNOT); mixer layer: RX(2 beta) on every qubit; initial state |+>^n.

Source code in src/superquantx/backends/base_backend.py
def create_qaoa_circuit(self, n_qubits: int, gammas: np.ndarray, betas: np.ndarray,
                        problem_hamiltonian: Any, mixer_hamiltonian: Any,
                        initial_state: Any, problem_instance: Any) -> Any:
    """QAOA circuit for weighted MaxCut given an adjacency matrix.

    Cost layer: exp(-i gamma w_ij Z_i Z_j / 2) per edge (CNOT, RZ, CNOT);
    mixer layer: RX(2 beta) on every qubit; initial state |+>^n.
    """
    W = _as_weight_matrix(problem_instance, n_qubits)
    circuit = self.create_circuit(n_qubits)
    for q in range(n_qubits):
        circuit = self.add_gate(circuit, 'H', q)
    for gamma, beta in zip(gammas, betas, strict=True):
        for i in range(n_qubits):
            for j in range(i + 1, n_qubits):
                if W[i, j] != 0:
                    circuit = self.add_gate(circuit, 'CNOT', [i, j])
                    circuit = self.add_gate(circuit, 'RZ', j, [float(gamma * W[i, j])])
                    circuit = self.add_gate(circuit, 'CNOT', [i, j])
        for q in range(n_qubits):
            circuit = self.add_gate(circuit, 'RX', q, [float(2 * beta)])
    return circuit

execute_qaoa

execute_qaoa(circuit: Any, problem_hamiltonian: Any, problem_instance: Any, shots: int | None = None) -> float

Expected MaxCut value of the QAOA state (exact, from the statevector).

Source code in src/superquantx/backends/base_backend.py
def execute_qaoa(self, circuit: Any, problem_hamiltonian: Any, problem_instance: Any,
                 shots: int | None = None) -> float:
    """Expected MaxCut value of the QAOA state (exact, from the statevector)."""
    probs = np.abs(self.statevector_big_endian(circuit)) ** 2
    n = int(round(np.log2(len(probs))))
    W = _as_weight_matrix(problem_instance, n)
    return float(probs @ maxcut_values(W))

sample_circuit

sample_circuit(circuit: Any, shots: int | None = None) -> np.ndarray

Sample bitstrings; row k column i is the measured value of qubit i.

Source code in src/superquantx/backends/base_backend.py
def sample_circuit(self, circuit: Any, shots: int | None = None) -> np.ndarray:
    """Sample bitstrings; row k column i is the measured value of qubit i."""
    circuit = self.add_measurement(circuit)
    result = self.execute_circuit(circuit, shots)
    if not result.get('counts'):
        raise RuntimeError(f"{self.__class__.__name__} returned no counts: {result}")
    counts = self.counts_big_endian(result['counts'])
    rows = []
    for bitstring, count in counts.items():
        rows.extend([[int(b) for b in bitstring]] * int(count))
    return np.array(rows, dtype=int)

encode_data_point

encode_data_point(data: ndarray, encoding: str, n_qubits: int) -> Any

Encode classical data into quantum state.

Source code in src/superquantx/backends/base_backend.py
def encode_data_point(self, data: np.ndarray, encoding: str, n_qubits: int) -> Any:
    """Encode classical data into quantum state."""
    circuit = self.create_circuit(n_qubits)

    if encoding == 'amplitude':
        return self._amplitude_encoding(circuit, data)
    elif encoding == 'angle':
        return self._angle_encoding(circuit, data)
    elif encoding == 'basis':
        return self._basis_encoding(circuit, data)
    else:
        logger.warning(f"Encoding '{encoding}' not implemented, using angle encoding")
        return self._angle_encoding(circuit, data)

compute_quantum_distance

compute_quantum_distance(x1: ndarray, x2: ndarray, metric: str, encoding: str, n_qubits: int, shots: int) -> float

Distance between two data points.

Only metric='fidelity' uses quantum states: it angle-encodes both points and returns sqrt(1 - ||^2) computed from statevectors. 'euclidean' and 'manhattan' are plain classical distances.

Source code in src/superquantx/backends/base_backend.py
def compute_quantum_distance(self, x1: np.ndarray, x2: np.ndarray, metric: str,
                            encoding: str, n_qubits: int, shots: int) -> float:
    """Distance between two data points.

    Only ``metric='fidelity'`` uses quantum states: it angle-encodes both
    points and returns sqrt(1 - |<x1|x2>|^2) computed from statevectors.
    ``'euclidean'`` and ``'manhattan'`` are plain classical distances.
    """
    if metric == 'fidelity':
        spec = FeatureMapSpec(name='AngleEncoding', n_features=len(x1), reps=1)
        s1 = self.statevector_big_endian(self.build_feature_map_circuit(x1, spec))
        s2 = self.statevector_big_endian(self.build_feature_map_circuit(x2, spec))
        return float(np.sqrt(max(0.0, 1.0 - abs(np.vdot(s1, s2)) ** 2)))
    if metric == 'euclidean':
        return np.linalg.norm(x1 - x2)
    elif metric == 'manhattan':
        return np.sum(np.abs(x1 - x2))
    else:
        return np.linalg.norm(x1 - x2)

execute_qnn

execute_qnn(input_data: ndarray, weights: ndarray, quantum_layers: list[dict], classical_layers: list[dict], encoding: str, measurement: str, shots: int) -> np.ndarray

Execute quantum neural network.

Source code in src/superquantx/backends/base_backend.py
def execute_qnn(self, input_data: np.ndarray, weights: np.ndarray,
               quantum_layers: list[dict], classical_layers: list[dict],
               encoding: str, measurement: str, shots: int) -> np.ndarray:
    """Execute quantum neural network."""
    # Each variational layer holds an RY and an RZ angle per qubit.
    n_qubits = len(weights) // (2 * len(quantum_layers)) if quantum_layers else input_data.shape[1]

    # Get expected output size from classical layers
    expected_output_size = None
    if classical_layers:
        for layer in classical_layers:
            if 'units' in layer:
                expected_output_size = layer['units']
                break


    outputs = []
    for sample in input_data:
        # Encode input data into a fresh circuit
        circuit = self.encode_data_point(sample, encoding, n_qubits)

        # Add variational layers
        param_idx = 0
        for layer in quantum_layers:
            layer_params = weights[param_idx:param_idx + n_qubits * 2]
            circuit = self._add_variational_layer(circuit, layer_params)
            param_idx += n_qubits * 2

        # Measure
        if measurement == 'expectation':
            # Compute expectation values
            result = self._compute_pauli_expectation(circuit, ['Z'] * n_qubits)
        else:
            # Sample and get probabilities
            result = self.execute_circuit(circuit, shots)
            result = self._result_to_probabilities(result)

        # Apply classical layers if present
        if classical_layers and expected_output_size:
            # Simple linear transformation to get desired output size
            if len(result) != expected_output_size:
                # Reshape/transform the quantum output to match expected size
                if len(result) > expected_output_size:
                    # Take first n elements or average
                    result = result[:expected_output_size]
                else:
                    # Pad with zeros or repeat
                    result = np.pad(result, (0, expected_output_size - len(result)), mode='constant')

        outputs.append(result)

    return np.array(outputs)

get_version_info

get_version_info() -> dict[str, Any]

Get backend version information.

Source code in src/superquantx/backends/base_backend.py
def get_version_info(self) -> dict[str, Any]:
    """Get backend version information."""
    return {
        'backend_name': self.__class__.__name__,
        'device': self.device,
        'capabilities': self.capabilities,
        'backend_version': '1.0.0',  # Default backend version
    }

get_device_info

get_device_info() -> dict[str, Any]

Get information about the quantum device.

Source code in src/superquantx/backends/base_backend.py
def get_device_info(self) -> dict[str, Any]:
    """Get information about the quantum device."""
    return {
        'device': self.device,
        'n_qubits': getattr(self, 'n_qubits', 'Unknown'),
        'topology': getattr(self, 'topology', 'Unknown'),
    }

Auto Backend

superquantx.AutoBackend

Auto backend selection (wrapper around get_backend).

Quick Start Examples

Basic Usage

import superquantx as sqx

# Get version information
print(f"SuperQuantX version: {sqx.get_version()}")

# Check available backends
backends = sqx.list_available_backends()
print(f"Available backends: {backends}")

# Get system information
sqx.print_system_info()

Backend Selection

import superquantx as sqx

# Automatic backend selection
backend = sqx.get_backend('auto')

# Specific backend with configuration
qiskit_backend = sqx.get_backend('qiskit', 
                                device='ibmq_qasm_simulator',
                                shots=1000)

# Check backend compatibility
is_compatible = sqx.check_backend_compatibility('qiskit')
print(f"Qiskit compatible: {is_compatible}")

Configuration Management

import superquantx as sqx

# View current configuration
print("Current config:", sqx.config)

# Update configuration
sqx.configure({
    'default_backend': 'simulator',
    'default_shots': 1024,
    'optimization_level': 2,
    'visualization': {
        'style': 'dark',
        'dpi': 300
    }
})

Available Backends

SuperQuantX supports multiple quantum computing backends:

Hardware Backends

  • IBM Quantum (qiskit): Access to IBM Quantum devices
  • Google Quantum AI (cirq): Integration with Google's quantum hardware
  • Amazon Braket (braket): AWS quantum computing service
  • Quantinuum (tket): H-Series trapped-ion quantum computers
  • D-Wave (ocean): Quantum annealing systems

Simulator Backends

  • Python Simulator (simulator): Pure Python quantum simulation
  • Local Simulators: High-performance local quantum simulators
  • Classical Emulation: Classical algorithms for quantum-inspired computations

Example Backend Usage

import superquantx as sqx

# Initialize different backends
backends = {}

# Simulator for development
backends['sim'] = sqx.get_backend('simulator', max_qubits=10)

# IBM Quantum for real hardware
backends['ibm'] = sqx.get_backend('qiskit', 
                                 device='ibmq_manila',
                                 token='your-ibm-token')

# Amazon Braket for cloud quantum computing
backends['aws'] = sqx.get_backend('braket',
                                 device_arn='arn:aws:braket:::device/quantum-simulator/amazon/sv1',
                                 s3_bucket='my-braket-bucket')

# D-Wave for optimization problems
backends['dwave'] = sqx.get_backend('ocean',
                                   device='advantage',
                                   token='your-dwave-token')

# Use backends
for name, backend in backends.items():
    if backend.is_available():
        info = backend.get_backend_info()
        print(f"{name}: {info['provider']} - {info['device']}")

Error Handling

SuperQuantX provides comprehensive error handling for backend operations:

import superquantx as sqx
from superquantx.exceptions import QuantumBackendError

try:
    # Attempt to initialize backend
    backend = sqx.get_backend('qiskit', device='fake_device')

except QuantumBackendError as e:
    print(f"Backend error: {e}")
    # Fallback to simulator
    backend = sqx.get_backend('simulator')

except ImportError as e:
    print(f"Missing dependency: {e}")
    print("Install with: pip install superquantx[qiskit]")

# Check backend availability
if backend.is_available():
    print("Backend ready for use")
else:
    print("Backend not available, check configuration")

Advanced Configuration

Environment Variables

SuperQuantX respects environment variables for configuration:

# Default backend selection
export SUPERQUANTX_BACKEND=qiskit

# IBM Quantum credentials
export QISKIT_IBMQ_TOKEN=your-token-here

# AWS credentials for Braket
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key

# D-Wave credentials
export DWAVE_API_TOKEN=your-dwave-token

# Quantinuum credentials
export QUANTINUUM_API_KEY=your-quantinuum-key

Configuration Files

Create ~/.superquantx/config.yaml for persistent configuration:

default_backend: simulator
default_shots: 1024
optimization_level: 2

backends:
  qiskit:
    token: your-ibm-token
    hub: ibm-q
    group: open
    project: main

  braket:
    s3_bucket: my-quantum-bucket
    s3_prefix: experiments

  ocean:
    token: your-dwave-token
    solver: Advantage_system4.1

logging:
  level: INFO
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"

visualization:
  backend: matplotlib
  style: seaborn
  figsize: [10, 6]
  dpi: 300

Programmatic Configuration

import superquantx as sqx

# Advanced configuration
config = {
    'default_backend': 'qiskit',
    'default_shots': 2048,
    'optimization': {
        'level': 3,
        'passes': ['cx_cancellation', 'commutative_cancellation'],
        'coupling_map': 'heavy_hex',
    },
    'error_mitigation': {
        'enabled': True,
        'method': 'zero_noise_extrapolation',
        'noise_factors': [1, 3, 5],
    },
    'caching': {
        'enabled': True,
        'backend': 'file',
        'ttl': 3600,  # 1 hour
    }
}

sqx.configure(config)

# Access nested configuration
print(f"Optimization level: {sqx.config.optimization.level}")
print(f"Error mitigation enabled: {sqx.config.error_mitigation.enabled}")

Package Information

Metadata

import superquantx as sqx

# Package metadata
print(f"Title: {sqx.__title__}")
print(f"Description: {sqx.__description__}")
print(f"Author: {sqx.__author__}")
print(f"License: {sqx.__license__}")
print(f"URL: {sqx.__url__}")

Version Compatibility

SuperQuantX maintains compatibility with major quantum computing frameworks:

Framework Supported Versions Backend Class
Qiskit 0.45+ QiskitBackend
PennyLane 0.32+ PennyLaneBackend
Cirq 1.0+ CirqBackend
Amazon Braket 1.50+ BraketBackend
TKET/Pytket 1.20+ TKETBackend
D-Wave Ocean 6.0+ OceanBackend

Checking Dependencies

import superquantx as sqx

# Get detailed backend information
backend_info = sqx.get_backend_info()

for backend_name, version in backend_info.items():
    if version:
        print(f"✓ {backend_name}: {version}")
    else:
        print(f"✗ {backend_name}: Not installed")

# Check specific backend availability
backends_to_check = ['qiskit', 'pennylane', 'cirq', 'braket']

for backend in backends_to_check:
    try:
        test_backend = sqx.get_backend(backend)
        print(f"✓ {backend}: Available")
    except Exception as e:
        print(f"✗ {backend}: {e}")

Module Structure

The core SuperQuantX package is organized as follows:

superquantx/
├── __init__.py          # Main package initialization
├── algorithms/          # Quantum algorithms and ML models  
├── backends/           # Quantum backend implementations
├── datasets/           # Quantum datasets and data utilities
├── utils/              # Utility functions and tools
├── cli/                # Command-line interface
├── config.py           # Configuration management
├── exceptions.py       # Custom exception classes
├── logging_config.py   # Logging configuration
└── version.py          # Version information

Integration Examples

With Jupyter Notebooks

# Cell 1: Setup
import superquantx as sqx
import numpy as np
import matplotlib.pyplot as plt

# Configure for notebook use
sqx.configure({
    'visualization': {
        'inline': True,
        'style': 'notebook'
    }
})

# Cell 2: System information  
sqx.print_system_info()

# Cell 3: Backend comparison
backends = ['simulator', 'qiskit']
for backend_name in backends:
    try:
        backend = sqx.get_backend(backend_name)
        print(f"{backend_name}: {backend.get_backend_info()}")
    except Exception as e:
        print(f"{backend_name}: Not available - {e}")

With External Libraries

import superquantx as sqx
import pandas as pd
import plotly.graph_objects as go

# Create backend comparison dashboard
def create_backend_dashboard():
    backend_data = []

    for backend_name in ['simulator', 'qiskit', 'cirq', 'braket']:
        try:
            backend = sqx.get_backend(backend_name)
            info = backend.get_backend_info()

            backend_data.append({
                'Backend': backend_name,
                'Provider': info.get('provider', 'Unknown'),
                'Available': backend.is_available(),
                'Max Qubits': info.get('capabilities', {}).get('max_qubits', 'N/A')
            })
        except:
            backend_data.append({
                'Backend': backend_name,
                'Provider': 'N/A',
                'Available': False,
                'Max Qubits': 'N/A'
            })

    df = pd.DataFrame(backend_data)

    # Create interactive table
    fig = go.Figure(data=[go.Table(
        header=dict(values=list(df.columns)),
        cells=dict(values=[df[col] for col in df.columns])
    )])

    fig.update_layout(title="SuperQuantX Backend Status")
    return fig

# Display dashboard
dashboard = create_backend_dashboard()
dashboard.show()

Best Practices

Backend Selection

  1. Use Auto Backend for Development:

    backend = sqx.get_backend('auto')  # Automatically selects best available
    

  2. Specify Backend for Production:

    backend = sqx.get_backend('qiskit', device='ibmq_manila')
    

  3. Check Availability Before Use:

    if backend.is_available():
        result = run_quantum_algorithm(backend)
    else:
        logger.warning("Backend not available, using fallback")
        backend = sqx.get_backend('simulator')
    

Configuration Management

  1. Use Environment Variables for Credentials:

    export QISKIT_IBMQ_TOKEN=your-token
    

  2. Separate Development and Production Configs:

    if os.getenv('ENVIRONMENT') == 'production':
        sqx.configure(production_config)
    else:
        sqx.configure(development_config)
    

  3. Validate Configuration:

    def validate_config():
        required_backends = ['qiskit', 'simulator']
        for backend in required_backends:
            if not sqx.check_backend_compatibility(backend):
                raise ValueError(f"Required backend {backend} not available")
    
    validate_config()
    


For more detailed information about specific modules, see the dedicated API reference sections: - Algorithms API - Backends API - Circuits API - Utilities API