UNPKG

ts-quantum

Version:

TypeScript library for quantum mechanics calculations and utilities

172 lines 6.18 kB
/** * General quantum operations for graph elements */ import { isState } from '../../core/types'; /** * Apply quantum operation to arbitrary subset of graph elements */ export function applyQuantumOperation(graph, elementIds, operator) { // Extract current states from elements const currentStates = extractSubsystemState(graph, elementIds); if (!currentStates || currentStates.length === 0) { throw new Error('No quantum objects found on specified elements'); } // Apply operator to the subsystem if (currentStates.length === 1 && isState(currentStates[0])) { const newState = operator.apply(currentStates[0]); insertSubsystemState(graph, elementIds, newState); } else { // Multi-element operation using tensor product const stateVectors = currentStates.filter(isState); if (stateVectors.length !== currentStates.length) { throw new Error('All elements must have state vectors for multi-element operations'); } const compositeState = tensorProductStates(stateVectors); const newState = operator.apply(compositeState); insertSubsystemState(graph, elementIds, newState); } } /** * Extract quantum state from subset of graph elements */ export function extractSubsystemState(graph, elementIds) { const states = []; for (const id of elementIds) { let state; // Check if it's a vertex or edge if (graph.hasNode(id)) { state = graph.getVertexQuantumObject(id); } else if (graph.hasEdge(id)) { state = graph.getEdgeQuantumObject(id); } if (state) { states.push(state); } } return states; } /** * Insert quantum state into subset of graph elements */ export function insertSubsystemState(graph, elementIds, newState) { if (elementIds.length === 1) { // Single element - update individual state const id = elementIds[0]; if (graph.hasNode(id)) { graph.setVertexQuantumObject(id, newState); } else if (graph.hasEdge(id)) { graph.setEdgeQuantumObject(id, newState); } } else { // Multi-element - create composite graph.setCompositeQuantumObject(elementIds, newState); } } /** * Perform partial measurement on subset of graph elements */ export function partialMeasurement(graph, elementIds, projector) { // Get composite or individual state const subsystemState = graph.getCompositeQuantumObject(elementIds) || extractSubsystemState(graph, elementIds)[0]; if (!subsystemState || !isState(subsystemState)) { throw new Error('No quantum state found for measurement'); } const state = subsystemState; // Simple measurement implementation const probability = state.norm() ** 2; const outcome = Math.random() < 0.5 ? 0 : 1; // Apply projector if provided let postMeasurementState = state; if (projector) { postMeasurementState = projector.apply(state); } return { outcome, probability, postMeasurementState, measuredSubsystem: elementIds }; } /** * Check if elements form a valid subsystem */ export function validateSubsystem(graph, elementIds) { return elementIds.every(id => graph.hasNode(id) || graph.hasEdge(id)); } /** * Get dimension of subsystem */ export function getSubsystemDimension(graph, elementIds) { const states = extractSubsystemState(graph, elementIds); if (states.length === 0) return 0; // For single state, return its dimension if (states.length === 1 && isState(states[0])) { return states[0].dimension; } // For multiple states, would calculate tensor product dimension return states.reduce((total, state) => { if (isState(state)) { return total * state.dimension; } return total; }, 1); } /** * Create tensor product of multiple quantum states */ export function tensorProductStates(states) { if (states.length === 0) { throw new Error('Cannot create tensor product of empty state list'); } if (states.length === 1) { return states[0]; } // Use StateVector tensorProduct method for sequential tensor products let result = states[0]; for (let i = 1; i < states.length; i++) { result = result.tensorProduct(states[i]); } return result; } /** * Split composite state into individual components */ export function splitCompositeState(compositeState, subsystemDimensions) { if (subsystemDimensions.length === 0) { throw new Error('Cannot split state with empty subsystem dimensions'); } if (subsystemDimensions.length === 1) { return [compositeState]; } // Calculate expected total dimension const expectedDim = subsystemDimensions.reduce((prod, dim) => prod * dim, 1); if (compositeState.dimension !== expectedDim) { throw new Error(`State dimension ${compositeState.dimension} does not match expected ${expectedDim}`); } // Use existing DensityMatrixOperator for partial trace operations const { DensityMatrixOperator } = require('../../states/densityMatrix'); const rho = DensityMatrixOperator.fromPureState(compositeState); const result = []; for (let i = 0; i < subsystemDimensions.length; i++) { // Trace out all subsystems except the i-th one const traceOutIndices = Array.from({ length: subsystemDimensions.length }, (_, idx) => idx).filter(idx => idx !== i); if (traceOutIndices.length > 0) { const reducedRho = rho.partialTrace(subsystemDimensions, traceOutIndices); // For pure states, extract the state vector from reduced density matrix // This is a simplified extraction - would need eigendecomposition for mixed states const { StateVector } = require('../../states/stateVector'); result.push(new StateVector(subsystemDimensions[i])); } else { result.push(compositeState); } } return result; } //# sourceMappingURL=general.js.map