UNPKG

ts-quantum

Version:

TypeScript library for quantum mechanics calculations and utilities

282 lines 10.2 kB
"use strict"; /** * Quantum state vector implementation */ 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.StateVector = void 0; const types_1 = require("../core/types"); const math = __importStar(require("mathjs")); const validation_1 = require("../utils/validation"); class StateVector { constructor(dimension, amplitudes, basis, properties) { this.objectType = 'state'; // Discriminator property (0, validation_1.validatePosDim)(dimension); this.dimension = dimension; this.amplitudes = amplitudes || Array(dimension).fill(null) .map(() => math.complex(0, 0)); this.basis = basis; this.properties = properties; if (amplitudes) { (0, validation_1.validateAmps)(amplitudes, dimension); } } /** * Sets amplitude at specified index */ setState(index, value) { (0, validation_1.validateIdx)(index, this.dimension); this.amplitudes[index] = value; } /** * Gets amplitude at specified index */ getState(index) { (0, validation_1.validateIdx)(index, this.dimension); return this.amplitudes[index]; } /** * Calculates inner product ⟨ψ|φ⟩ with another state */ innerProduct(other) { if (this.dimension !== other.dimension) { throw new Error('States must have same dimension for inner product'); } let result = math.complex(0, 0); for (let i = 0; i < this.dimension; i++) { const conj = math.conj((0, types_1.toComplex)(this.amplitudes[i])); const prod = math.multiply(conj, (0, types_1.toComplex)(other.amplitudes[i])); result = math.add(result, prod); } return result; } /** * Calculates norm of state vector */ norm() { const innerProd = this.innerProduct(this); const abs = math.abs(innerProd); return Math.sqrt(abs); } /** * Returns normalized version of state vector */ normalize() { const currentNorm = this.norm(); if (currentNorm < 1e-10) { throw new Error('Cannot normalize zero state vector'); } const normalizedAmplitudes = this.amplitudes.map(amp => math.divide((0, types_1.toComplex)(amp), math.complex(currentNorm, 0))); return new StateVector(this.dimension, normalizedAmplitudes, this.basis, this.properties); } /** * Computes tensor product with another state vector */ tensorProduct(other) { const newDimension = this.dimension * other.dimension; const newAmplitudes = []; for (let i = 0; i < this.dimension; i++) { for (let j = 0; j < other.dimension; j++) { newAmplitudes.push(math.multiply(this.amplitudes[i], other.amplitudes[j])); } } // Generate new basis label if both states have basis labels let newBasis; if (this.basis && other.basis) { newBasis = `${this.basis}⊗${other.basis}`; } return new StateVector(newDimension, newAmplitudes, newBasis, this.properties); } /** * Returns true if state is zero vector */ isZero(tolerance = 1e-10) { return this.amplitudes.every(amp => math.abs(amp) < tolerance); } /** * Get a copy of the amplitudes array */ getAmplitudes() { return [...this.amplitudes]; } /** * Check if this state vector equals another within tolerance */ equals(other, tolerance = 1e-10) { if (this.dimension !== other.dimension) { return false; } return this.amplitudes.every((amp, i) => { const diff = math.subtract(amp, other.getState(i)); const absDiff = math.abs(diff); return absDiff < tolerance; }); } /** * Scale the state vector by a complex number * @param factor Complex scaling factor * @returns New scaled state vector */ scale(factor) { const scaledAmplitudes = this.amplitudes.map(amp => math.multiply((0, types_1.toComplex)(amp), (0, types_1.toComplex)(factor))); return new StateVector(this.dimension, scaledAmplitudes, this.basis, this.properties ? { ...this.properties } : undefined); } /** * Add another state vector to this one * @param other The state vector to add * @returns New state vector representing the sum */ add(other) { if (this.dimension !== other.dimension) { throw new Error(`Cannot add state vectors with different dimensions: ${this.dimension} vs ${other.dimension}`); } const sumAmplitudes = this.amplitudes.map((amp, i) => math.add((0, types_1.toComplex)(amp), (0, types_1.toComplex)(other.getState(i)))); // Generate new basis label if appropriate let newBasis; if (this.basis && other.basis) { newBasis = `(${this.basis}) + (${other.basis})`; } return new StateVector(this.dimension, sumAmplitudes, newBasis, this.properties ? { ...this.properties } : undefined); } /** * Returns array representation of state vector */ toArray() { return [...this.amplitudes]; } /** * Returns string representation of state vector */ toString() { const components = this.amplitudes .map((amp, i) => { if (math.abs(amp) < 1e-10) { return ''; } const sign = i === 0 ? '' : ' + '; return `${sign}${amp.toString()}|${i}⟩`; }) .filter(s => s !== '') .join(''); return components || '0'; } /** * Returns string representation in computational basis |n⟩ */ toComputationalString() { const components = this.amplitudes .map((amp, i) => { if (math.abs(amp) < 1e-10) { return ''; } const sign = i === 0 ? '' : ' + '; return `${sign}${amp.toString()}|${i}⟩`; }) .filter(s => s !== '') .join(''); return components || '0'; } /** * Returns string representation in angular momentum basis |j,m⟩ * @param j Total angular momentum quantum number */ toAngularString(j) { const dim = Math.floor(2 * j + 1); if (this.dimension !== dim) { throw new Error(`State dimension ${this.dimension} does not match 2j+1 = ${dim}`); } const components = this.amplitudes .map((amp, n) => { if (math.abs(amp) < 1e-10) { return ''; } const m = -j + n; // Convert index to m value const sign = n === 0 ? '' : ' + '; return `${sign}${amp.toString()}|${j},${m}⟩`; }) .filter(s => s !== '') .join(''); return components || '0'; } /** * Creates a computational basis state |i⟩ */ static computationalBasis(dimension, index) { (0, validation_1.validatePosDim)(dimension); (0, validation_1.validateIdx)(index, dimension); const amplitudes = Array(dimension).fill(null) .map((_, i) => i === index ? math.complex(1, 0) : math.complex(0, 0)); return new StateVector(dimension, amplitudes, `|${index}⟩`); } /** * Returns array of all computational basis states */ static computationalBasisStates(dimension) { (0, validation_1.validatePosDim)(dimension); return Array(dimension).fill(null) .map((_, i) => StateVector.computationalBasis(dimension, i)); } /** * Creates normalized superposition of basis states with given coefficients */ static superposition(coefficients) { const dimension = coefficients.length; (0, validation_1.validatePosDim)(dimension); return new StateVector(dimension, coefficients, 'superposition').normalize(); } /** * Creates an equally weighted superposition of all basis states */ static equalSuperposition(dimension) { (0, validation_1.validatePosDim)(dimension); const coefficient = math.complex(1 / Math.sqrt(dimension), 0); const coefficients = Array(dimension).fill(coefficient); return new StateVector(dimension, coefficients, '|+⟩'); } /** * Sets angular momentum metadata for this state */ setAngularMomentumMetadata(metadata) { if (!this.properties) { this.properties = {}; } this.properties.angularMomentumMetadata = metadata; } /** * Gets angular momentum metadata if present */ getAngularMomentumMetadata() { return this.properties?.angularMomentumMetadata || null; } /** * Checks if this state has angular momentum structure */ hasAngularMomentumStructure() { const metadata = this.getAngularMomentumMetadata(); return metadata?.type === 'angular_momentum'; } } exports.StateVector = StateVector; //# sourceMappingURL=stateVector.js.map