UNPKG

ts-quantum

Version:

TypeScript library for quantum mechanics calculations and utilities

219 lines 7.6 kB
"use strict"; /** * Math utilities for quantum operations */ 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.singularValueDecomposition = exports.multiplyMatrices = exports.matrixExponential = exports.legendrePolynomial = exports.triangleCoefficient = exports.doubleFactorial = exports.factorial = exports.logFactorial = void 0; const math = __importStar(require("mathjs")); // Cache for factorial computations const factorialCache = new Map(); const logFactorialCache = new Map(); const doubleFactorialCache = new Map(); /** * Computes log(n!) avoiding overflow using summation of logs * Uses caching for efficiency * * @param n Input number (must be non-negative integer) * @returns log(n!) */ function logFactorial(n) { if (n < 0) return -Infinity; if (Math.abs(Math.round(n) - n) > 1e-10) { throw new Error('Factorial only defined for integers'); } n = Math.round(n); // Ensure integer // Check cache const cached = logFactorialCache.get(n); if (cached !== undefined) return cached; // Compute using summation of logs let result = 0; for (let i = 2; i <= n; i++) { result += Math.log(i); } // Cache result logFactorialCache.set(n, result); return result; } exports.logFactorial = logFactorial; /** * Computes n! using cached log factorial * * @param n Input number (must be non-negative integer) * @returns n! */ function factorial(n) { if (n < 0) throw new Error('Factorial not defined for negative numbers'); if (n > 170) throw new Error('Factorial too large for direct computation'); // Check cache const cached = factorialCache.get(n); if (cached !== undefined) return cached; const result = Math.exp(logFactorial(n)); factorialCache.set(n, result); return result; } exports.factorial = factorial; /** * Computes double factorial n!! = n * (n-2) * (n-4) * ... * Uses caching for efficiency * * @param n Input number (must be non-negative integer) * @returns n!! */ function doubleFactorial(n) { if (n < 0) throw new Error('Double factorial not defined for negative numbers'); if (n > 300) throw new Error('Double factorial too large for direct computation'); // Check cache const cached = doubleFactorialCache.get(n); if (cached !== undefined) return cached; // Base cases if (n <= 1) return 1; const result = n * doubleFactorial(n - 2); doubleFactorialCache.set(n, result); return result; } exports.doubleFactorial = doubleFactorial; /** * Computes Legendre polynomial P_n(x) using recursion * * @param n Degree of polynomial (must be non-negative integer) * @param x Argument (-1 <= x <= 1) * @returns P_n(x) */ /** * Calculates triangle coefficient for three angular momenta * Delta(a,b,c) = sqrt((a+b-c)!(a-b+c)!(-a+b+c)!/(a+b+c+1)!) * * @param a First angular momentum * @param b Second angular momentum * @param c Third angular momentum * @returns Triangle coefficient */ function triangleCoefficient(a, b, c) { // Check triangle inequality if (c > a + b || c < Math.abs(a - b)) { return 0; } // Calculate using log factorials to avoid overflow const sum = logFactorial(Math.round(a + b - c)) + logFactorial(Math.round(a - b + c)) + logFactorial(Math.round(-a + b + c)) - logFactorial(Math.round(a + b + c + 1)); return Math.exp(sum / 2); // sqrt of exp(sum) } exports.triangleCoefficient = triangleCoefficient; /** * Computes Legendre polynomial P_n(x) using recursion * * @param n Degree of polynomial (must be non-negative integer) * @param x Argument (-1 <= x <= 1) * @returns P_n(x) */ function legendrePolynomial(n, x) { if (n < 0 || Math.abs(Math.round(n) - n) > 1e-10) { throw new Error('Degree must be non-negative integer'); } if (Math.abs(x) > 1) { throw new Error('Argument must be in [-1,1]'); } // Base cases if (n === 0) return 1; if (n === 1) return x; // Bonnet's recursion formula let p0 = 1; // P_0(x) let p1 = x; // P_1(x) let pn = 0; // P_n(x) for (let k = 2; k <= n; k++) { pn = ((2 * k - 1) * x * p1 - (k - 1) * p0) / k; p0 = p1; p1 = pn; } return pn; } exports.legendrePolynomial = legendrePolynomial; /** * Computes matrix exponential using Taylor series */ function matrixExponential(matrix, terms = 10) { const dim = matrix.length; // Initialize result to identity matrix const result = Array(dim).fill(null).map((_, i) => Array(dim).fill(null).map((_, j) => i === j ? math.complex(1, 0) : math.complex(0, 0))); // Initialize term to identity let term = Array(dim).fill(null).map((_, i) => Array(dim).fill(null).map((_, j) => i === j ? math.complex(1, 0) : math.complex(0, 0))); // Compute sum of terms for (let n = 1; n <= terms; n++) { // Multiply term by matrix and divide by n term = multiplyMatrices(term, matrix).map(row => row.map(element => math.complex(element.re / n, element.im / n))); // Add to result result.forEach((row, i) => row.forEach((_, j) => { result[i][j] = math.add(result[i][j], term[i][j]); })); } return result; } exports.matrixExponential = matrixExponential; /** * Multiplies two complex matrices */ function multiplyMatrices(a, b) { const dim = a.length; const result = Array(dim).fill(null).map(() => Array(dim).fill(null).map(() => math.complex(0, 0))); for (let i = 0; i < dim; i++) { for (let j = 0; j < dim; j++) { for (let k = 0; k < dim; k++) { const prod = math.multiply(a[i][k], b[k][j]); result[i][j] = math.add(result[i][j], prod); } } } return result; } exports.multiplyMatrices = multiplyMatrices; /** * Computes the singular value decomposition of a matrix * Note: This is a placeholder for a proper SVD implementation */ function singularValueDecomposition(matrix) { const dim = matrix.length; // Placeholder implementation return { U: Array(dim).fill(null).map((_, i) => Array(dim).fill(null).map((_, j) => i === j ? math.complex(1, 0) : math.complex(0, 0))), S: Array(dim).fill(1), V: Array(dim).fill(null).map((_, i) => Array(dim).fill(null).map((_, j) => i === j ? math.complex(1, 0) : math.complex(0, 0))) }; } exports.singularValueDecomposition = singularValueDecomposition; //# sourceMappingURL=math.js.map