| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- class Field {
- constructor(...sizes) {
- if (Array.isArray(sizes[0])) {
- this.data = sizes.shift()
- }
- this.n = sizes.length
- this.sizes = sizes
- this.data = []
- const g = (p, n) => {
- if (n < sizes.length) {
- const end = n === sizes.length - 1
- for (let i = 0; i < sizes[n]; i++) {
- p[i] = end ? 0 : []
- g(p[i], n + 1)
- }
- }
- }
- g(this.data, 0)
- }
- * indices() {
- const self = this
- const g = function*(p, n) {
- if (n === self.sizes.length) yield p
- const size = self.sizes[n]
- for (let i = 0; i < size; i++) {
- yield* g([...p, i], n + 1)
- }
- }
- yield* g([], 0)
- }
- get(...indices) {
- const g = (o, n) => {
- if (n === indices.length || n === this.sizes.length) return o
- const i = indices[n]
- const f = Math.floor(i)
- const r = i - f
- if (r) {
- // Return weighted value
- const a = g(o[f], n + 1)
- const b = g(o[f + 1], n + 1)
- return a * (1 - r) + b * r
- } else {
- return g(o[f], n + 1)
- }
- }
- return g(this.data, 0)
- }
- set(value, ...indices) {
- const g = (o, w, n) => {
- const end = (n === indices.length - 1 || n === this.sizes.length - 1)
- const i = indices[n]
- const f = Math.floor(i)
- const r = i - f
- if (r) {
- if (end) {
- // o[f] = 1, v = .3, w = 1 ... expected result o[f] = .3
- // value - o[f] = -.7 ... * w = 1.. yep
- o[f] = o[f] + (1 - r) * w * (value - o[f])
- o[f + 1] = o[f + 1] + r * w * (value - o[f + 1])
- } else {
- g(o[f], (1 - r) * w, n + 1)
- g(o[f + 1], r * w, n + 1)
- }
- } else {
- if (end) {
- o[f] = o[f] + w * (value - o[f])
- } else {
- g(o[f], w, n + 1)
- }
- }
- }
- return g(this.data, 1, 0)
- }
- }
- module.exports = Field
|