FSharp.Azure.Quantum 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package FSharp.Azure.Quantum --version 1.1.0
                    
NuGet\Install-Package FSharp.Azure.Quantum -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FSharp.Azure.Quantum" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FSharp.Azure.Quantum" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="FSharp.Azure.Quantum" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FSharp.Azure.Quantum --version 1.1.0
                    
#r "nuget: FSharp.Azure.Quantum, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FSharp.Azure.Quantum@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FSharp.Azure.Quantum&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=FSharp.Azure.Quantum&version=1.1.0
                    
Install as a Cake Tool

FSharp.Azure.Quantum

Hybrid Quantum-Classical F# Library - Intelligently routes optimization problems between classical algorithms (fast, cheap) and quantum backends (scalable, powerful) based on problem size and structure.

NuGet License

✨ Status: Production Ready (v1.1.0)

Current Features (v1.1.0):

  • ✅ Production-ready classical optimization (TSP, Portfolio)
  • ✅ Quantum Advisor (recommendations for quantum advantage)
  • Azure Quantum backend integration (IonQ, Rigetti simulators)
  • HybridSolver with automatic quantum routing
  • QAOA parameter optimization (variational quantum-classical loop)
  • ✅ Job submission, polling, and result parsing
  • ✅ Local quantum simulation (≤10 qubits)

Production-Ready Azure Quantum Features:

  • ✅ IonQ simulator and QPU (ionq.simulator, ionq.qpu.aria-1)
  • ✅ Rigetti QVM and Aspen QPU (rigetti.sim.qvm, rigetti.qpu.aspen-m-3)
  • ✅ Azure authentication via Azure.Identity (CLI, Managed Identity)
  • ✅ Pre-flight circuit validation (catch errors before submission)
  • ✅ Cost limit enforcement and error handling
  • ✅ Multi-provider QAOA support (OpenQASM 2.0)
  • ✅ Automatic QAOA parameter optimization (Nelder-Mead simplex method)

Future Enhancements (v1.x):

  • 🎯 QuantumPortfolioSolver with QAOA parameter optimization
  • 🎯 Advanced result comparison and quantum advantage validation
  • 🎯 Support for IBM Quantum, Amazon Braket, Google Cirq

🚀 Quick Start

open FSharp.Azure.Quantum.Classical

// Solve a TSP problem with named cities
let cities = [
    ("Seattle", 47.6, -122.3)
    ("Portland", 45.5, -122.7)
    ("San Francisco", 37.8, -122.4)
]

match TSP.solveDirectly cities None with
| Ok tour -> 
    printfn "Best route: %A" tour.Cities
    printfn "Distance: %.2f miles" tour.TotalDistance
| Error msg -> printfn "Error: %s" msg

📦 Installation

NuGet Package: FSharp.Azure.Quantum

dotnet add package FSharp.Azure.Quantum --prerelease

✨ Features

🔀 HybridSolver - Automatic Quantum/Classical Routing

Automatically chooses the best solver (quantum or classical) based on problem characteristics:

// Let the solver decide automatically
match HybridSolver.solveTsp distances None None None with
| Ok solution ->
    printfn "Method used: %A" solution.Method  // Classical or Quantum
    printfn "Reasoning: %s" solution.Reasoning
    printfn "Solution: %A" solution.Result
| Error msg -> printfn "Error: %s" msg

🗺️ TSP (Traveling Salesman Problem)

Solve routing problems with named cities:

let cities = [("NYC", 40.7, -74.0); ("LA", 34.0, -118.2); ("Chicago", 41.9, -87.6)]

// Option 1: Direct solve (easiest)
let tour = TSP.solveDirectly cities None

// Option 2: Build problem first (for customization)
let problem = TSP.createProblem cities
let tour = TSP.solve problem (Some customConfig)

Features:

  • Named cities with coordinates
  • Automatic distance calculation
  • Simulated annealing with 2-opt
  • Configurable iterations and cooling

💼 Portfolio Optimization

Optimize investment portfolios with risk/return constraints:

let assets = [
    ("AAPL", 0.12, 0.18, 150.0)  // symbol, return, risk, price
    ("MSFT", 0.10, 0.15, 300.0)
    ("GOOGL", 0.15, 0.20, 2800.0)
]

let allocation = Portfolio.solveDirectly assets 10000.0 None

match allocation with
| Ok result ->
    printfn "Total Value: $%.2f" result.TotalValue
    printfn "Expected Return: %.2f%%" (result.ExpectedReturn * 100.0)
    printfn "Risk: %.2f" result.Risk
| Error msg -> printfn "Error: %s" msg

Features:

  • Greedy return/risk ratio optimization
  • Budget constraints
  • Min/max holding limits
  • Efficient allocation

🤖 Quantum Advisor

Get recommendations on when to use quantum vs classical:

match QuantumAdvisor.getRecommendation distances with
| Ok recommendation ->
    printfn "Recommendation: %A" recommendation.RecommendationType
    printfn "Problem size: %d" recommendation.ProblemSize
    printfn "Reasoning: %s" recommendation.Reasoning
| Error msg -> printfn "Error: %s" msg

🧪 Classical Solvers

Direct access to classical optimization algorithms:

// TSP Solver
let tspSolution = TspSolver.solveWithDistances distances TspSolver.defaultConfig

// Portfolio Solver  
let portfolio = PortfolioSolver.solveGreedyByRatio assets constraints PortfolioSolver.defaultConfig

🔬 Quantum TSP Solver with QAOA Parameter Optimization

Solve TSP using quantum algorithms with automatic parameter tuning:

open FSharp.Azure.Quantum.Quantum.QuantumTspSolver
open FSharp.Azure.Quantum.Core.BackendAbstraction

// Create distance matrix
let distances = array2D [
    [ 0.0; 1.0; 2.0 ]
    [ 1.0; 0.0; 1.5 ]
    [ 2.0; 1.5; 0.0 ]
]

// Option 1: Use default configuration (optimization enabled)
let backend = createLocalBackend()
match solve backend distances defaultConfig with
| Ok solution ->
    printfn "Best tour: %A" solution.Tour
    printfn "Tour length: %.2f" solution.TourLength
    printfn "Optimized parameters: %A" solution.OptimizedParameters
    printfn "Optimization converged: %A" solution.OptimizationConverged
| Error msg -> printfn "Error: %s" msg

// Option 2: Custom configuration
let config = {
    OptimizationShots = 100       // Fast parameter search (low shots)
    FinalShots = 1000             // Accurate result (high shots)
    EnableOptimization = true     // Enable variational loop
    InitialParameters = (0.5, 0.5) // Starting guess for (gamma, beta)
}
let result = solve backend distances config

// Option 3: Disable optimization (backward compatibility)
let resultNoOpt = solveWithShots backend distances 1000

Features:

  • Variational quantum-classical loop - Classical optimizer finds best QAOA parameters
  • Nelder-Mead simplex method - Derivative-free optimization for noisy quantum circuits
  • Problem-specific tuning - Parameters adapt to each TSP instance
  • Configurable - Easy to disable for testing/demos
  • Convergence tracking - Iteration count and convergence status

How It Works:

  1. Classical optimizer proposes QAOA parameters (gamma, beta)
  2. Quantum backend executes QAOA circuit with those parameters
  3. Measure tour quality (cost)
  4. Optimizer updates parameters based on results
  5. Repeat until convergence
  6. Use optimized parameters for final high-accuracy execution

Benefits:

  • ✅ Better solutions - Optimized parameters → higher success probability
  • ✅ Research-grade - Matches published QAOA implementations
  • ✅ Existing infrastructure - Uses QaoaOptimizer module (Nelder-Mead)
  • ✅ Backward compatible - Old API still works via solveWithShots

🔬 Local Quantum Simulation

Test quantum algorithms offline without Azure credentials:

open FSharp.Azure.Quantum.Core
open FSharp.Azure.Quantum.Core.QuantumBackend
open FSharp.Azure.Quantum.Core.QaoaCircuit

// Create a QAOA circuit (example: 3-qubit MaxCut)
let quboMatrix = array2D [[0.0; 0.5; 0.5]; [0.5; 0.0; 0.5]; [0.5; 0.5; 0.0]]
let circuit = {
    NumQubits = 3
    InitialStateGates = [| H(0); H(1); H(2) |]
    Layers = [|
        {
            CostGates = [| RZZ(0, 1, 0.5); RZZ(1, 2, 0.5); RZZ(0, 2, 0.5) |]
            MixerGates = [| RX(0, 1.0); RX(1, 1.0); RX(2, 1.0) |]
            Gamma = 0.25
            Beta = 0.5
        }
    |]
    ProblemHamiltonian = ProblemHamiltonian.fromQubo quboMatrix
    MixerHamiltonian = MixerHamiltonian.create 3
}

// Execute on local simulator
match Local.simulate circuit 1000 with
| Ok result ->
    printfn "Backend: %s" result.Backend
    printfn "Time: %.2f ms" result.ExecutionTimeMs
    result.Counts
    |> Map.toList
    |> List.sortByDescending snd
    |> List.take 3
    |> List.iter (fun (bitstring, count) ->
        printfn "  %s: %d shots" bitstring count)
| Error msg ->
    eprintfn "Error: %s" msg

Features:

  • State vector simulation (up to 10 qubits)
  • QAOA circuit execution with mixer and cost Hamiltonians
  • Measurement and shot sampling
  • Zero external dependencies

QAOA Multi-Provider Support:

QAOA circuits use OpenQASM 2.0 format, making them compatible with all major quantum providers:

open FSharp.Azure.Quantum.Core.QaoaCircuit

// Build QAOA circuit (provider-agnostic)
let quboMatrix = array2D [[1.0; -2.0]; [-2.0; 1.0]]
let problemHam = ProblemHamiltonian.fromQubo quboMatrix
let mixerHam = MixerHamiltonian.create 2
let circuit = QaoaCircuit.build problemHam mixerHam [|(0.5, 0.3)|]

// Export to OpenQASM 2.0 (universal format)
let qasm = QaoaCircuit.toOpenQasm circuit
printfn "%s" qasm
// Output:
// OPENQASM 2.0;
// include "qelib1.inc";
// qreg q[2];
// // Initial state preparation
// h q[0];
// h q[1];
// ...

Provider Compatibility:

  • IonQ - Native OpenQASM or JSON gate format
  • Rigetti - Translate OpenQASM → Quil (assembly language)
  • IBM Qiskit - Native OpenQASM 2.0 support
  • Amazon Braket - OpenQASM support
  • Google Cirq - OpenQASM import capability
  • Local Simulator - Direct QAOA execution (no translation needed)

Why QAOA is Provider-Agnostic:

  • Uses standard gate set (H, RX, RY, RZ, RZZ, CNOT)
  • OpenQASM 2.0 is the industry standard for circuit interchange
  • Algorithm logic is separate from backend submission code

☁️ Azure Quantum Integration (v0.5.0-beta)

Execute quantum circuits on Azure Quantum backends (IonQ, Rigetti):

open FSharp.Azure.Quantum.Core
open FSharp.Azure.Quantum.Core.Authentication
open FSharp.Azure.Quantum.Core.IonQBackend

// Step 1: Create authenticated HTTP client
let credential = CredentialProviders.createDefaultCredential()  // Uses Azure CLI, Managed Identity, etc.
let httpClient = Authentication.createAuthenticatedClient credential

// Step 2: Build workspace URL
let subscriptionId = "your-subscription-id"
let resourceGroup = "your-resource-group"
let workspaceName = "your-workspace-name"
let location = "eastus"
let workspaceUrl = 
    $"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Quantum/Workspaces/{workspaceName}"

// Step 3: Create IonQ circuit (Bell state example)
let circuit: IonQCircuit = {
    Qubits = 2
    Circuit = [
        SingleQubit("h", 0)      // Hadamard on qubit 0
        TwoQubit("cnot", 0, 1)   // CNOT with control=0, target=1
        Measure([|0; 1|])        // Measure both qubits
    ]
}

// Step 4: Submit and execute
async {
    let! result = IonQBackend.submitAndWaitForResultsAsync httpClient workspaceUrl circuit 100 "ionq.simulator"
    
    match result with
    | Ok histogram ->
        printfn "✅ Job completed!"
        histogram 
        |> Map.iter (fun bitstring count -> 
            printfn "  %s: %d shots" bitstring count)
    | Error err ->
        eprintfn "❌ Error: %A" err
} |> Async.RunSynchronously

Supported Backends:

  • ionq.simulator - IonQ cloud simulator
  • ionq.qpu.aria-1 - IonQ Aria-1 QPU (requires credits)
  • rigetti.sim.qvm - Rigetti QVM simulator
  • rigetti.qpu.aspen-m-3 - Rigetti Aspen-M-3 QPU (requires credits)

Authentication Methods:

  • DefaultAzureCredential() - Tries Azure CLI, Managed Identity, Environment Variables
  • AzureCliCredential() - Uses az login credentials
  • ManagedIdentityCredential() - For Azure VMs/App Services

Features:

  • Automatic token acquisition and refresh
  • Job submission, polling, and result retrieval
  • Error handling with retry logic
  • Cost tracking and estimation

🔍 Circuit Validation (Pre-Flight Checks)

Validate circuits against backend constraints before submission to catch errors early and avoid costly failed API calls:

open FSharp.Azure.Quantum.Core.CircuitValidator

// Example: Validate circuit for IonQ simulator
let circuit = {
    NumQubits = 5
    GateCount = 50
    UsedGates = Set.ofList ["H"; "CNOT"; "RX"]
    TwoQubitGates = [(0, 1); (1, 2)]
}

let constraints = BackendConstraints.ionqSimulator()
match validateCircuit constraints circuit with
| Ok () -> 
    printfn "✅ Circuit valid for IonQ simulator"
| Error errors ->
    printfn "❌ Validation failed:"
    errors |> List.iter (fun err -> 
        printfn "  - %s" (formatValidationError err))

Built-in Backend Constraints:

// Local simulator (1-10 qubits, all gates, no depth limit)
let local = BackendConstraints.localSimulator()

// IonQ simulator (29 qubits, all-to-all connectivity, 100 gate limit)
let ionqSim = BackendConstraints.ionqSimulator()

// IonQ hardware (11 qubits, all-to-all connectivity, 100 gate limit)
let ionqHw = BackendConstraints.ionqHardware()

// Rigetti Aspen-M-3 (79 qubits, limited connectivity, 50 gate limit)
let rigetti = BackendConstraints.rigettiAspenM3()

Auto-Detection from Target String:

// Automatically detect constraints from Azure Quantum target
match KnownTargets.getConstraints "ionq.simulator" with
| Some constraints -> 
    // Validate circuit...
    validateCircuit constraints myCircuit
| None -> 
    printfn "Unknown target - provide custom constraints"

Integrated Validation (IonQ):

// IonQ backend validates automatically before submission
async {
    let! result = IonQBackend.submitAndWaitForResultsWithValidationAsync
        httpClient
        workspaceUrl
        circuit
        1000  // shots
        "ionq.simulator"
        None  // Auto-detect constraints from target string
    
    match result with
    | Ok histogram -> printfn "Success!"
    | Error (InvalidCircuit errors) -> 
        printfn "Circuit validation failed before submission:"
        errors |> List.iter (printfn "  %s")
    | Error otherError -> 
        printfn "Execution error: %A" otherError
} |> Async.RunSynchronously

Custom Backend Constraints:

// Define constraints for a new quantum provider
let ibmConstraints = BackendConstraints.create
    "IBM Quantum Eagle"      // Name
    127                      // Max qubits
    ["H"; "X"; "CX"; "RZ"]  // Supported gates
    (Some 1000)              // Max circuit depth
    false                    // Limited connectivity
    [(0,1); (1,2); (2,3)]   // Connected qubit pairs

// Use custom constraints
match validateCircuit ibmConstraints myCircuit with
| Ok () -> printfn "Valid for IBM Quantum!"
| Error errors -> printfn "Validation errors: %A" errors

Validation Checks:

  • Qubit count - Does circuit exceed backend qubit limit?
  • Gate set - Are all gates supported by the backend?
  • Circuit depth - Does circuit exceed recommended depth limit?
  • Connectivity - Do two-qubit gates respect topology constraints?

📊 Problem Analysis

Analyze problem complexity and characteristics:

match ProblemAnalysis.classifyProblem distances with
| Ok info ->
    printfn "Type: %A" info.ProblemType
    printfn "Size: %d" info.Size
    printfn "Complexity: %s" info.Complexity
| Error msg -> printfn "Error: %s" msg

💰 Cost Estimation

Estimate quantum execution costs before running:

let estimate = CostEstimation.estimateQuantumCost problemSize shots tier
printfn "Estimated cost: $%.2f %s" estimate.EstimatedCost estimate.Currency

📚 Documentation

🏗️ Architecture

Hybrid Design: Classical algorithms for small problems, quantum for large. Detailed architecture →

Three Layers:

  1. Hybrid Orchestration - HybridSolver routes to classical or quantum
  2. Solvers - Classical (CPU, no backend) vs Quantum (requires backend)
  3. Backends - IonQ, Rigetti, LocalSimulator

Key Difference:

  • TspSolver - Classical algorithm, NO backend parameter, CPU execution
  • QuantumTspSolver - Quantum algorithm, REQUIRES backend parameter
// Classical - fast, free
TspSolver.solve distances config

// Quantum with parameter optimization - scalable, research-grade
QuantumTspSolver.solve rigettiBackend distances defaultConfig

// Quantum without optimization (backward compatibility)
QuantumTspSolver.solveWithShots rigettiBackend distances 1000

// Hybrid - automatic routing
HybridSolver.solveTsp distances None None None

✅ Production Ready

Component Description
Classical Solvers TSP, Portfolio optimization with CPU algorithms
Quantum Solvers TSP (QAOA with parameter optimization), Quantum Chemistry (VQE)
HybridSolver Automatic routing based on problem size
Parameter Optimization Variational quantum-classical loop (Nelder-Mead)
Azure Quantum IonQ and Rigetti backend integration
Local Simulator Offline testing (≤10 qubits)
Problem Builders Graph, Subset, Scheduling, CSP
Error Mitigation ZNE, PEC, readout error correction

🧱 Problem Builders

Fluent APIs for encoding optimization problems:

Builder Domains
GraphOptimization TSP, Graph Coloring, MaxCut
SubsetSelection Knapsack, Portfolio, Set Cover
Scheduling Task Scheduling, Resource Allocation
ConstraintSatisfaction N-Queens, Sudoku
CircuitBuilder Low-level quantum circuits

All builders support both classical and quantum solvers.

🚧 Roadmap (v1.x)

  • QuantumPortfolioSolver - QAOA for portfolio optimization with parameter tuning
  • Additional Providers - IBM Quantum, Amazon Braket, Google Cirq
  • More Algorithms - MaxCut, Graph Coloring quantum solvers
  • Enhanced Error Mitigation - Additional ZNE, PEC strategies

🎯 When to Use Quantum

The library automatically recommends quantum vs classical based on:

Use Classical When:

  • ✅ Problem size < 50 variables
  • ✅ Need immediate results (milliseconds)
  • ✅ Developing/testing locally
  • ✅ Cost is a concern

Consider Quantum When:

  • ⚡ Problem size > 100 variables
  • ⚡ Problem has special structure (QUBO-compatible)
  • ⚡ Can tolerate longer wait times (seconds)
  • ⚡ Budget available (~$10-100 per run)

Use HybridSolver to decide automatically!

🔧 Development

Prerequisites

  • .NET 10.0 SDK
  • F# 10.0

Build

dotnet build

Test

dotnet test

All 1,021 tests passing ✅ (including QAOA parameter optimization, local simulation, Azure Quantum backends, and validation tests)

Run Examples

cd examples
dotnet run

📊 Performance

Classical Solvers (Local Execution):

Problem Size Time Quality
TSP 10 cities ~20ms Optimal
TSP 50 cities ~500ms Within 5% of optimal
TSP 100 cities ~2s Within 10% of optimal
Portfolio 20 assets ~10ms Optimal
Portfolio 50 assets ~50ms Near-optimal

🤝 Contributing

Contributions welcome! This is an alpha release and we're actively improving.

Areas for Contribution

  • Additional problem domains (Scheduling, MaxCut, etc.)
  • Quantum backend integration
  • Performance optimizations
  • Documentation improvements
  • Bug fixes

Development Process

  • Follow TDD methodology (see docs-for-mulder/AI-DEVELOPMENT-GUIDE.md)
  • Write tests first (RED → GREEN → REFACTOR)
  • Update documentation
  • Submit PR to dev branch

📄 License

Unlicense - Public domain. Use freely for any purpose.

🙏 Acknowledgments

Built with:

  • F# 10.0
  • .NET 10.0
  • Azure Quantum platform

Developed using AI-assisted TDD methodology.

📞 Support


Status: Production Ready (v1.1.0) - QAOA with automatic parameter optimization, all core features complete, fully tested, quantum backends integrated.

Last Updated: 2025-11-28

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on FSharp.Azure.Quantum:

Package Downloads
FSharp.Azure.Quantum.Topological

Topological quantum computing plugin for FSharp.Azure.Quantum. Provides anyon theory (Ising/Fibonacci/SU(2)_k), braiding compilation, gate-to-braid conversion, Majorana hardware simulator, noise models, and topological file format (.tqp). Seamlessly integrates with main package algorithms (Grover, QFT, QAOA) via IQuantumBackend interface. Requires FSharp.Azure.Quantum v1.3.10+.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.10 94 2/22/2026
1.3.9 95 2/19/2026
1.3.7 109 2/17/2026
1.3.6 104 2/13/2026
1.3.5 109 2/10/2026
1.3.4 109 1/25/2026
1.3.3 202 12/20/2025
1.3.2 190 12/13/2025
1.3.1 447 12/11/2025
1.2.9 448 12/8/2025
1.2.7 319 12/7/2025
1.2.5 211 12/4/2025
1.2.4 688 12/3/2025
1.2.3 686 12/1/2025
1.2.1 143 11/29/2025
1.2.0 144 11/29/2025
1.1.0 113 11/28/2025
1.0.0 195 11/28/2025
0.5.0-beta 208 11/25/2025
0.1.0-alpha 199 11/24/2025

v1.1.0: QAOA Parameter Optimization Release
- Add automatic QAOA parameter optimization via variational quantum-classical loop
- Implement Nelder-Mead simplex optimizer for problem-specific parameter tuning
- Configurable optimization settings (shots, initial parameters, enable/disable)
- Convergence tracking and optimized parameter reporting
- Backward compatible API via solveWithShots function
- Clean up redundant backend documentation
- All 1,021 tests passing
- Production-ready for quantum TSP solving with research-grade algorithms