ts-quantum
Version:
TypeScript library for quantum mechanics calculations and utilities
129 lines • 5.63 kB
JavaScript
/**
* 2D Quantum Random Walk implementation
*/
import { StateVector } from '../../states/stateVector';
import { MatrixOperator } from '../../operators/operator';
import { CoinDirection } from './types';
import * as math from 'mathjs';
export class QuantumWalk2D {
state;
coinOperator;
width;
height;
constructor(lattice, startPosition) {
const metadata = lattice.getMetadata();
const width = metadata?.parameters?.width;
const height = metadata?.parameters?.height;
// Ensure width and height are valid numbers
if (typeof width !== 'number' || typeof height !== 'number' || width <= 0 || height <= 0) {
throw new Error('Invalid lattice dimensions: width and height must be positive numbers');
}
this.width = width;
this.height = height;
// Total dimension: 4 coin states × width × height positions
const totalDim = 4 * this.width * this.height;
// Initialize state at starting position with UP coin
const startIndex = this.getStateIndex(startPosition, CoinDirection.UP);
this.state = StateVector.computationalBasis(totalDim, startIndex);
// Create Hadamard coin operator (4×4 for 2D)
const h = 1 / Math.sqrt(2);
const coinMatrix = [
[math.complex(h, 0), math.complex(h, 0), math.complex(0, 0), math.complex(0, 0)],
[math.complex(h, 0), math.complex(-h, 0), math.complex(0, 0), math.complex(0, 0)],
[math.complex(0, 0), math.complex(0, 0), math.complex(h, 0), math.complex(h, 0)],
[math.complex(0, 0), math.complex(0, 0), math.complex(h, 0), math.complex(-h, 0)]
];
this.coinOperator = new MatrixOperator(coinMatrix);
}
/**
* Perform single evolution step: coin flip then conditional shift
*/
step() {
// Apply coin operator to each position
this.applyCoin();
// Apply shift operator based on coin states
this.applyShift();
}
/**
* Evolve for multiple steps
*/
evolve(steps) {
for (let i = 0; i < steps; i++) {
this.step();
}
return this.state;
}
/**
* Get probability distribution over positions
*/
getPositionDistribution() {
const distribution = new Map();
for (let x = 0; x < this.width; x++) {
for (let y = 0; y < this.height; y++) {
let probability = 0;
// Sum probabilities over all coin states at this position
for (let coin = 0; coin < 4; coin++) {
const index = this.getStateIndex({ x, y }, coin);
const amplitude = this.state.getState(index);
probability += Number(math.abs(math.multiply(amplitude, math.conj(amplitude))));
}
if (probability > 1e-10) {
distribution.set(`${x},${y}`, probability);
}
}
}
return distribution;
}
applyCoin() {
const newAmplitudes = Array(this.state.dimension).fill(math.complex(0, 0));
for (let x = 0; x < this.width; x++) {
for (let y = 0; y < this.height; y++) {
// Apply coin operator to the 4 coin states at position (x,y)
const coinStates = [];
for (let coin = 0; coin < 4; coin++) {
const index = this.getStateIndex({ x, y }, coin);
coinStates.push(this.state.getState(index));
}
// Matrix-vector multiplication for coin operation
const coinMatrix = this.coinOperator.toMatrix();
for (let i = 0; i < 4; i++) {
let sum = math.complex(0, 0);
for (let j = 0; j < 4; j++) {
sum = math.add(sum, math.multiply(coinMatrix[i][j], coinStates[j]));
}
const newIndex = this.getStateIndex({ x, y }, i);
newAmplitudes[newIndex] = sum;
}
}
}
this.state = new StateVector(this.state.dimension, newAmplitudes);
}
applyShift() {
const newAmplitudes = Array(this.state.dimension).fill(math.complex(0, 0));
for (let x = 0; x < this.width; x++) {
for (let y = 0; y < this.height; y++) {
for (let coin = 0; coin < 4; coin++) {
const currentIndex = this.getStateIndex({ x, y }, coin);
const amplitude = this.state.getState(currentIndex);
// Determine new position based on coin state
let newX = x, newY = y;
if (coin === CoinDirection.UP && y > 0)
newY = y - 1;
else if (coin === CoinDirection.DOWN && y < this.height - 1)
newY = y + 1;
else if (coin === CoinDirection.LEFT && x > 0)
newX = x - 1;
else if (coin === CoinDirection.RIGHT && x < this.width - 1)
newX = x + 1;
const newIndex = this.getStateIndex({ x: newX, y: newY }, coin);
newAmplitudes[newIndex] = math.add(newAmplitudes[newIndex], amplitude);
}
}
}
this.state = new StateVector(this.state.dimension, newAmplitudes);
}
getStateIndex(position, coin) {
return coin * this.width * this.height + position.y * this.width + position.x;
}
}
//# sourceMappingURL=QuantumWalk2D.js.map