ts-quantum
Version:
TypeScript library for quantum mechanics calculations and utilities
196 lines • 6.51 kB
JavaScript
/**
* Specialized quantum operator implementations for performance optimization
*/
import { StateVector } from '../states/stateVector';
import { validateMatchDims } from '../utils/validation';
import { MatrixOperator } from "./operator";
import * as math from 'mathjs';
/**
* Identity operator with no matrix storage - optimal performance
*/
export class IdentityOperator {
objectType = 'operator';
dimension;
type = 'identity';
constructor(dimension) {
if (dimension <= 0 || !Number.isInteger(dimension)) {
throw new Error('Dimension must be a positive integer');
}
this.dimension = dimension;
}
/**
* Apply identity operator - returns cloned state
*/
apply(state) {
validateMatchDims(state.dimension, this.dimension);
return new StateVector(state.dimension, [...state.amplitudes], state.basis);
}
/**
* Compose with another operator - returns other operator
*/
compose(other) {
validateMatchDims(other.dimension, this.dimension);
return other;
}
/**
* Adjoint of identity is identity
*/
adjoint() {
return new IdentityOperator(this.dimension);
}
/**
* Generate identity matrix on demand
*/
toMatrix() {
return Array(this.dimension).fill(null)
.map((_, i) => Array(this.dimension).fill(null)
.map((_, j) => i === j ? math.complex(1, 0) : math.complex(0, 0)));
}
tensorProduct(other) {
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).tensorProduct(other);
}
partialTrace(dims, traceOutIndices) {
// const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).partialTrace(dims, traceOutIndices);
}
scale(scalar) {
const diagonal = Array(this.dimension).fill(scalar);
return new DiagonalOperator(diagonal);
}
add(other) {
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).add(other);
}
eigenDecompose() {
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).eigenDecompose();
}
norm() {
return Math.sqrt(this.dimension);
}
isZero() {
return false;
}
}
/**
* Diagonal operator with compressed storage
*/
export class DiagonalOperator {
objectType = 'operator';
dimension;
type = 'diagonal';
diagonal;
constructor(diagonal) {
if (diagonal.length === 0) {
throw new Error('Diagonal cannot be empty');
}
this.dimension = diagonal.length;
this.diagonal = diagonal.map(val => math.clone(val));
}
/**
* Apply diagonal operator - element-wise multiplication
*/
apply(state) {
validateMatchDims(state.dimension, this.dimension);
const newAmplitudes = state.amplitudes.map((amp, i) => math.multiply(amp, this.diagonal[i]));
return new StateVector(this.dimension, newAmplitudes, state.basis);
}
/**
* Compose with another operator
*/
compose(other) {
validateMatchDims(other.dimension, this.dimension);
if (other.type === 'diagonal') {
const otherDiagonal = other.getDiagonal();
const resultDiagonal = this.diagonal.map((val, i) => math.multiply(val, otherDiagonal[i]));
return new DiagonalOperator(resultDiagonal);
}
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).compose(other);
}
/**
* Adjoint of diagonal operator
*/
adjoint() {
const conjugateDiagonal = this.diagonal.map(val => math.conj(val));
return new DiagonalOperator(conjugateDiagonal);
}
/**
* Generate full matrix on demand
*/
toMatrix() {
return Array(this.dimension).fill(null)
.map((_, i) => Array(this.dimension).fill(null)
.map((_, j) => i === j ? math.clone(this.diagonal[i]) : math.complex(0, 0)));
}
tensorProduct(other) {
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).tensorProduct(other);
}
partialTrace(dims, traceOutIndices) {
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).partialTrace(dims, traceOutIndices);
}
scale(scalar) {
const scaledDiagonal = this.diagonal.map(val => math.multiply(val, scalar));
return new DiagonalOperator(scaledDiagonal);
}
add(other) {
if (other.type === 'diagonal') {
const otherDiagonal = other.getDiagonal();
const sumDiagonal = this.diagonal.map((val, i) => math.add(val, otherDiagonal[i]));
return new DiagonalOperator(sumDiagonal);
}
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).add(other);
}
eigenDecompose() {
const { MatrixOperator } = require('./operator');
return new MatrixOperator(this.toMatrix()).eigenDecompose();
}
norm() {
return Math.sqrt(this.diagonal.reduce((sum, val) => {
const magnitude = Number(math.abs(val));
return sum + magnitude * magnitude;
}, 0));
}
isZero(tolerance = 1e-12) {
return this.diagonal.every(val => Math.abs(val.re) < tolerance && Math.abs(val.im) < tolerance);
}
/**
* Get diagonal elements
*/
getDiagonal() {
return this.diagonal.map(val => math.clone(val));
}
}
/**
* Factory function to create identity operator
*/
export function createIdentityOperator(dimension) {
return new IdentityOperator(dimension);
}
/**
* Factory function to create diagonal operator
*/
export function createDiagonalOperator(diagonal) {
return new DiagonalOperator(diagonal);
}
/**
* Check if matrix is diagonal
*/
export function isDiagonalMatrix(matrix, tolerance = 1e-12) {
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
if (i !== j) {
const element = matrix[i][j];
if (Math.abs(element.re) > tolerance || Math.abs(element.im) > tolerance) {
return false;
}
}
}
}
return true;
}
//# sourceMappingURL=specialized.js.map