field.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. class Field {
  2. constructor(...sizes) {
  3. if (Array.isArray(sizes[0])) {
  4. this.data = sizes.shift()
  5. }
  6. this.n = sizes.length
  7. this.sizes = sizes
  8. this.data = []
  9. const g = (p, n) => {
  10. if (n < sizes.length) {
  11. const end = n === sizes.length - 1
  12. for (let i = 0; i < sizes[n]; i++) {
  13. p[i] = end ? 0 : []
  14. g(p[i], n + 1)
  15. }
  16. }
  17. }
  18. g(this.data, 0)
  19. }
  20. * indices() {
  21. const self = this
  22. const g = function*(p, n) {
  23. if (n === self.sizes.length) yield p
  24. const size = self.sizes[n]
  25. for (let i = 0; i < size; i++) {
  26. yield* g([...p, i], n + 1)
  27. }
  28. }
  29. yield* g([], 0)
  30. }
  31. get(...indices) {
  32. const g = (o, n) => {
  33. if (n === indices.length || n === this.sizes.length) return o
  34. const i = indices[n]
  35. const f = Math.floor(i)
  36. const r = i - f
  37. if (r) {
  38. // Return weighted value
  39. const a = g(o[f], n + 1)
  40. const b = g(o[f + 1], n + 1)
  41. return a * (1 - r) + b * r
  42. } else {
  43. return g(o[f], n + 1)
  44. }
  45. }
  46. return g(this.data, 0)
  47. }
  48. set(value, ...indices) {
  49. const g = (o, w, n) => {
  50. const end = (n === indices.length - 1 || n === this.sizes.length - 1)
  51. const i = indices[n]
  52. const f = Math.floor(i)
  53. const r = i - f
  54. if (r) {
  55. if (end) {
  56. // o[f] = 1, v = .3, w = 1 ... expected result o[f] = .3
  57. // value - o[f] = -.7 ... * w = 1.. yep
  58. o[f] = o[f] + (1 - r) * w * (value - o[f])
  59. o[f + 1] = o[f + 1] + r * w * (value - o[f + 1])
  60. } else {
  61. g(o[f], (1 - r) * w, n + 1)
  62. g(o[f + 1], r * w, n + 1)
  63. }
  64. } else {
  65. if (end) {
  66. o[f] = o[f] + w * (value - o[f])
  67. } else {
  68. g(o[f], w, n + 1)
  69. }
  70. }
  71. }
  72. return g(this.data, 1, 0)
  73. }
  74. }
  75. module.exports = Field