import { BigInteger } from "./index.js"; /** * @param { number } length */ function RNG(length) { let result = ""; for (let i = 0; i < length; i++) { result += Math.trunc((Math.random() * 10)).toString(); } return result.toLowerCase(); } /** * @param { BigInteger[] } vec1 * @param { BigInteger[] } vec2 */ function vecAdd(vec1, vec2) { const length = Math.min(vec1.length, vec2.length); /**@type { BigInteger[] } */ const out = []; for (let i = 0; i < length; i++) { out.push(vec1[i].copy().add(vec2[i])); } return out; } /** * @param { bigint[] } vec1 * @param { bigint[] } vec2 */ function vecAddNative(vec1, vec2) { const length = Math.min(vec1.length, vec2.length); /**@type { bigint[] } */ const out = []; for (let i = 0; i < length; i++) { out.push(vec1[i] + vec2[i]); } return out; } /** * @param { BigInteger[] } vec1 * @param { BigInteger[] } vec2 */ function dot(vec1, vec2) { const length = Math.min(vec1.length, vec2.length); const out = BigInteger.from("0"); for (let i = 0; i < length; i++) { out.add(vec1[i].copy().mul(vec2[i])); } return out; } /** * @param { bigint[] } vec1 * @param { bigint[] } vec2 */ function dotNative(vec1, vec2) { const length = Math.min(vec1.length, vec2.length); let out = 0n; for (let i = 0; i < length; i++) { out += vec1[i] * vec2[i]; } return out; } /** * @param { BigInteger[] } mx1 [m * n] * @param { BigInteger[] } mx2 [n * k] * @param { number } m * @param { number } n * @param { number } k * @returns { BigInteger[] } [m * k] */ function matmul(mx1, mx2, m, n, k) { const TMP = BigInteger.from("0"); /**@type { BigInteger[] } */ const out = [] for (let i0 = 0; i0 < m; i0++) { for (let i3 = 0; i3 < k; i3++) { let element = BigInteger.from("0"); for (let i2 = 0; i2 < n; i2++) { element.add(TMP.assign(mx1[i0 * n + i2]).mul(mx2[i2 * k + i3])); } out.push(element); } } return out; } /** * @param { bigint[] } mx1 [m * n] * @param { bigint[] } mx2 [n * k] * @param { number } m * @param { number } n * @param { number } k * @returns { bigint[] } [m * k] */ function matmulNative(mx1, mx2, m, n, k) { /**@type { bigint[] } */ const out = [] for (let i0 = 0; i0 < m; i0++) { for (let i3 = 0; i3 < k; i3++) { let element = 0n; for (let i2 = 0; i2 < n; i2++) { element += mx1[i0 * n + i2] * mx2[i2 * k + i3]; } out.push(element); } } return out; } // const r = matmulNative([2n, -3n, 1n, 5n, 4n, -2n], [-7n, 5n, 2n, -1n, 4n, 3n], 2, 3, 2); // const r = matmul([BigInteger.from("2"), BigInteger.from("-3"), BigInteger.from("1"), BigInteger.from("5"), BigInteger.from("4"), BigInteger.from("-2")], [BigInteger.from("-7"), BigInteger.from("5"), BigInteger.from("2"), BigInteger.from("-1"), BigInteger.from("4"), BigInteger.from("3")], 2, 3, 2) function test() { // console.time("tests"); /**@type { { n: number, name: string, time: number}[]} */ const results = []; for (let i = 100; i <= 2000; i+= 100) { const vec1Str = []; const vec2Str = []; for (let j = 0; j < 6; j++) { vec1Str.push(RNG(i)); vec2Str.push(RNG(i)); } const vec1 = vec1Str.map(str => BigInteger.from(str)); const vec2 = vec2Str.map(str => BigInteger.from(str)); const vec1n = vec1Str.map(str => BigInt(str)); const vec2n = vec2Str.map(str => BigInt(str)); let now = performance.now(); vecAdd(vec1, vec2); results.push({ n: i, name: "vecAdd", time: performance.now() - now}); now = performance.now(); vecAddNative(vec1n, vec2n); results.push({ n: i, name: "vecAddNative", time: performance.now() - now}); now = performance.now(); dot(vec1, vec2); results.push({ n: i, name: "dot", time: performance.now() - now}); now = performance.now(); dotNative(vec1n, vec2n); results.push({ n: i, name: "dotNative", time: performance.now() - now}); now = performance.now(); matmul(vec1, vec2, 2, 3, 2); results.push({ n: i, name: "matmul", time: performance.now() - now}); now = performance.now(); matmulNative(vec1n, vec2n, 2, 3, 2); results.push({ n: i, name: "matmulNative", time: performance.now() - now}); } console.table(results); } test();