// export function Weights(size) { // let set = new Set() // for(let i = 0; i < size; i++) { // set.add(i + 1) // } // return new Map([ // [ 1, set ] // ]) // } export function Weights(size) { let out = [] for(let i = 0; i < size; i++) { out.push(1/size) } return out } export function Add(left, right, out = new Map()) { for(let i = 0; i < left.size * right.size; i++) { let li = parseInt(i / left.size) + 1 let ri = (i % left.size) + 1 let key = li + ri let base = out.get(key) ?? 0 out.set(key, base + left.get(li) + right.get(ri)) } // for(let li = 0; li < left.size; li++) { // for(let ri = 0; ri < right.size; ri++) { // let i = li + ri // let b = out.get(i) ?? 0 // out.set(i, b + left.get(i) + right.get(i)) // } // } return out } export function Mul(left, to) { let out = left for(let i = 1; i < to; i++) { out = Add(out, left) } return out } // console.log(Weights(6)) // console.log(Add(Weights(6), Weights(6))) // console.log(Mul(Weights(6), 3)) export function WeightOf(size) { return 1 / size } function probSum2dN(N, S) { let P = 0 for(let r1 = 1; r1 < N + 1; r1++) { let r2 = S - r1 if(1 <= r2 && r2 <= N) { P += 1 } } return [ P, Math.pow(N, 2) ] } // function conv(a, b) { // let bf = b.reverse() // let len = (a.length) + (b.length) // let P = new Map() // for(let i = 1; i < len; i++) { // let topSliceRange = [ // Math.max(i - a.length, 0), // Math.min(i, b.length) // ] // let bottomSliceRange = [ // Math.max(b.length - i, 0), // Math.min(b.length, len - i) // ] // let topSlice = a.slice(...topSliceRange) // let bottomSlice = bf.slice(...bottomSliceRange) // P.set( // i + 1, // topSlice.reduce( // (a, v, i) => a + (v * bottomSlice[i]), // 0 // ) // ) // } // return P // } // const conv = (vec1, vec2) => { // if (vec1.length === 0 || vec2.length === 0) { // throw new Error('Vectors can not be empty!'); // } // const volume = vec1; // const kernel = vec2; // /* Initialized to zero by default */ // const convVec = new Float32Array(volume.length + kernel.length); // let i = 0; // for (let j = 0; j < kernel.length; ++j) { // convVec[j] = volume[0] * kernel[j]; // } // for (i = 1; i < volume.length; ++i) { // for (let j = 0; j < kernel.length; ++j) { // convVec[i + j] += volume[i] * kernel[j]; // } // } // return convVec; // }; // console.log( // conv( // Weights(6), // Weights(6) // // conv(Weights(6), Weights(6)) // ) // ) class Distribution extends Float32Array { static Die(size) { return new Distribution(1, size, 1 / size) } constructor(first, last, fill) { let len = (last + 1) - first let b = new ArrayBuffer(len * 4) super(b) this.first = first this.last = last if(fill) { this.fill(fill) } } forEach(func) { for(let i = this.first; i <= this.last; i++) { func(this.get(i), i) } } set(i, value) { super.set([ value ], i - this.first) } increase(i, value) { let index = i - this.first super.set([ this.at(index) + value ], index) } get(i) { return this.at(i - this.first) } contains(indice) { return indice >= this.first && indice <= this.last } } function conv(d1, d2) { let ax1 = d1.first + d2.first let ax2 = d1.last + d2.last console.log(ax1, ax2, ax2 - ax1) let Pc = new Distribution(ax1, ax2, 0) for(let S = ax1; S <= ax2; S++) { for(let r1 = d1.first; r1 <= d1.last; r1++) { let r2 = S - r1 if(d2.contains(r2)) { Pc.increase(S, d1.get(r1) * d2.get(r2)) } } } return Pc } // console.log(Distribution.Die(6)) // let a = Distribution.Die(12) // a.set(2, 0.000069) // a.forEach(console.log) console.log( conv( Distribution.Die(6), conv(Distribution.Die(6), Distribution.Die(6)) ) )