dicedicedice/experiment.js

204 lines
4.4 KiB
JavaScript

// 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))
)
)