ts-quantum
Version:
TypeScript library for quantum mechanics calculations and utilities
198 lines • 8.15 kB
JavaScript
;
/**
* Quantum state geometry - distances and metrics on quantum state manifolds
* Based on Provost & Vallee (1980) "Riemannian structure on manifolds of quantum states"
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BlochSphere = exports.TwoLevelSystem = exports.quantumFidelity = exports.quantumDistanceUnnormalized = exports.quantumDistance = void 0;
const stateVector_1 = require("../states/stateVector");
const math = __importStar(require("mathjs"));
/**
* Calculates the quantum distance between two normalized state vectors
* Formula: D²(ψ₁,ψ₂) = 2 - 2|⟨ψ₁|ψ₂⟩| (Provost-Vallee Eq. 2.14)
*
* This distance is gauge-invariant and represents the geometric distance
* on the projective Hilbert space of quantum states.
*
* @param state1 First quantum state (should be normalized)
* @param state2 Second quantum state (should be normalized)
* @returns Quantum distance between the states
*/
function quantumDistance(state1, state2) {
if (state1.dimension !== state2.dimension) {
throw new Error(`States must have same dimension: ${state1.dimension} vs ${state2.dimension}`);
}
// Calculate inner product ⟨ψ₁|ψ₂⟩
const innerProduct = state1.innerProduct(state2);
// Calculate |⟨ψ₁|ψ₂⟩|
const overlapMagnitude = math.abs(innerProduct);
// D²(ψ₁,ψ₂) = 2 - 2|⟨ψ₁|ψ₂⟩|
const distanceSquared = 2 - 2 * overlapMagnitude;
// Return distance (not distance squared)
return Math.sqrt(Math.max(0, distanceSquared)); // max ensures non-negative for numerical precision
}
exports.quantumDistance = quantumDistance;
/**
* Calculates quantum distance for states that may not be normalized
* Automatically normalizes before computing distance
*
* @param state1 First quantum state
* @param state2 Second quantum state
* @returns Quantum distance between normalized states
*/
function quantumDistanceUnnormalized(state1, state2) {
const norm1 = state1.norm();
const norm2 = state2.norm();
if (norm1 < 1e-10 || norm2 < 1e-10) {
throw new Error('Cannot compute distance for zero states');
}
const normalized1 = state1.normalize();
const normalized2 = state2.normalize();
return quantumDistance(normalized1, normalized2);
}
exports.quantumDistanceUnnormalized = quantumDistanceUnnormalized;
/**
* Calculates the quantum fidelity between two states
* Fidelity F = |⟨ψ₁|ψ₂⟩|²
* Related to distance by: D² = 2(1 - √F)
*
* @param state1 First quantum state (should be normalized)
* @param state2 Second quantum state (should be normalized)
* @returns Fidelity between states (0 to 1)
*/
function quantumFidelity(state1, state2) {
if (state1.dimension !== state2.dimension) {
throw new Error(`States must have same dimension: ${state1.dimension} vs ${state2.dimension}`);
}
const innerProduct = state1.innerProduct(state2);
const overlapMagnitude = math.abs(innerProduct);
return overlapMagnitude * overlapMagnitude;
}
exports.quantumFidelity = quantumFidelity;
/**
* Creates a simple two-level quantum system for testing
* |0⟩ and |1⟩ basis states
*/
class TwoLevelSystem {
/**
* Ground state |0⟩
*/
static ground() {
return stateVector_1.StateVector.computationalBasis(2, 0);
}
/**
* Excited state |1⟩
*/
static excited() {
return stateVector_1.StateVector.computationalBasis(2, 1);
}
/**
* Plus state |+⟩ = (|0⟩ + |1⟩)/√2
*/
static plus() {
const coeffs = [math.complex(1 / Math.sqrt(2), 0), math.complex(1 / Math.sqrt(2), 0)];
return new stateVector_1.StateVector(2, coeffs, '|+⟩');
}
/**
* Minus state |-⟩ = (|0⟩ - |1⟩)/√2
*/
static minus() {
const coeffs = [math.complex(1 / Math.sqrt(2), 0), math.complex(-1 / Math.sqrt(2), 0)];
return new stateVector_1.StateVector(2, coeffs, '|-⟩');
}
/**
* General qubit state cos(θ/2)|0⟩ + e^(iφ)sin(θ/2)|1⟩
* @param theta Polar angle (0 to π)
* @param phi Azimuthal angle (0 to 2π)
*/
static blochState(theta, phi) {
const cosHalfTheta = Math.cos(theta / 2);
const sinHalfTheta = Math.sin(theta / 2);
const eiPhi = math.complex(Math.cos(phi), Math.sin(phi));
const coeffs = [
math.complex(cosHalfTheta, 0),
math.multiply(eiPhi, sinHalfTheta)
];
return new stateVector_1.StateVector(2, coeffs, `|θ=${theta.toFixed(2)},φ=${phi.toFixed(2)}⟩`);
}
}
exports.TwoLevelSystem = TwoLevelSystem;
/**
* Bloch sphere geometry utilities
*/
class BlochSphere {
/**
* Calculates the quantum distance on the Bloch sphere
* This matches the Provost-Vallee quantum distance for qubit states
*
* The relationship is: D_quantum = √2 * sin(θ_bloch/2)
* where θ_bloch is the angle between Bloch vectors
*
* @param theta1 Polar angle of first state
* @param phi1 Azimuthal angle of first state
* @param theta2 Polar angle of second state
* @param phi2 Azimuthal angle of second state
* @returns Quantum distance between states
*/
static geodesicDistance(theta1, phi1, theta2, phi2) {
// Convert to Bloch vectors (Cartesian coordinates on unit sphere)
const x1 = Math.sin(theta1) * Math.cos(phi1);
const y1 = Math.sin(theta1) * Math.sin(phi1);
const z1 = Math.cos(theta1);
const x2 = Math.sin(theta2) * Math.cos(phi2);
const y2 = Math.sin(theta2) * Math.sin(phi2);
const z2 = Math.cos(theta2);
// Dot product of Bloch vectors
const dotProduct = x1 * x2 + y1 * y2 + z1 * z2;
// Angle between Bloch vectors
const clampedDot = Math.max(-1, Math.min(1, dotProduct));
const blochAngle = Math.acos(clampedDot);
// Convert to quantum distance: D = √2 * sin(θ_bloch/2)
return Math.sqrt(2) * Math.sin(blochAngle / 2);
}
/**
* Verifies that quantum distance matches Bloch sphere calculation
* @param theta1 Polar angle of first state
* @param phi1 Azimuthal angle of first state
* @param theta2 Polar angle of second state
* @param phi2 Azimuthal angle of second state
* @param tolerance Numerical tolerance for comparison
* @returns True if distances match within tolerance
*/
static verifyQuantumDistance(theta1, phi1, theta2, phi2, tolerance = 1e-10) {
const state1 = TwoLevelSystem.blochState(theta1, phi1);
const state2 = TwoLevelSystem.blochState(theta2, phi2);
console.log("State1: ", state1);
console.log("State2: ", state2);
const quantumDist = quantumDistance(state1, state2);
const blochDist = this.geodesicDistance(theta1, phi1, theta2, phi2);
console.log("Quantum Distance: ", quantumDist);
console.log("Bloch Distance: ", blochDist);
return Math.abs(quantumDist - blochDist) < tolerance;
}
}
exports.BlochSphere = BlochSphere;
//# sourceMappingURL=quantumDistance.js.map