rei-lang 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +230 -191
  2. package/PEACE_USE_CLAUSE.md +95 -0
  3. package/README.md +257 -186
  4. package/bin/rei.js +259 -144
  5. package/dist/index.d.mts +257 -0
  6. package/dist/index.d.ts +181 -93
  7. package/dist/index.js +5710 -239
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +8741 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/package.json +73 -62
  12. package/spec/REI_BNF_v0.2.md +398 -0
  13. package/spec/REI_BNF_v0.3.md +358 -0
  14. package/spec/REI_SPEC_v0.1.md +587 -0
  15. package/theory/LICENSE-THEORY.md +57 -0
  16. package/theory/README.md +85 -0
  17. package/theory/category-c-design.md +502 -0
  18. package/theory/core-theories-11-14.md +799 -0
  19. package/theory/core-theories-15-21.md +675 -0
  20. package/theory/core-theories-8-10.md +582 -0
  21. package/theory/d-fumt-overview.md +99 -0
  22. package/theory/genesis-axiom-system.md +124 -0
  23. package/theory/gft-theory.md +160 -0
  24. package/theory/index.ts +9 -0
  25. package/theory/notation-equivalence.md +134 -0
  26. package/theory/semantic-compressor.ts +903 -0
  27. package/theory/stdlib-tier1-design.md +477 -0
  28. package/theory/theories-11-14.ts +466 -0
  29. package/theory/theories-15-21.ts +762 -0
  30. package/theory/theories-22-28.ts +794 -0
  31. package/theory/theories-29-35.ts +607 -0
  32. package/theory/theories-36-42.ts +937 -0
  33. package/theory/theories-43-49.ts +1298 -0
  34. package/theory/theories-50-56.ts +1449 -0
  35. package/theory/theories-57-66.ts +1724 -0
  36. package/theory/theories-67.ts +1696 -0
  37. package/theory/theories-8-10.ts +284 -0
  38. package/dist/index.cjs +0 -3282
  39. package/dist/index.cjs.map +0 -1
  40. package/dist/index.d.cts +0 -169
@@ -0,0 +1,607 @@
1
+ // ============================================================
2
+ // Rei (0₀式) — Theory #29–#35 Implementation
3
+ // #29 Supersymmetric Mathematics Theory (超対称数学理論)
4
+ // #30 Multi-Dimensional Mathematical Structure Theory (多次元数理構造理論)
5
+ // #31 Consciousness Mathematics Theory (意識数理学)
6
+ // #32 Probability Fate Theory (確率運命理論)
7
+ // #33 Line System Theory (線体系理論)
8
+ // #34 UMTE — Unified Mathematical Theory of Everything (万物数理統一理論)
9
+ // #35 Holographic Mathematical Projection Theory (ホログラフィック数式投影理論)
10
+ // Author: Nobuki Fujimoto
11
+ // ============================================================
12
+
13
+ import { MultiDimNumber } from '../core/types';
14
+
15
+ // ============================================================
16
+ // #29 Supersymmetric Mathematics Theory (超対称数学理論)
17
+ // ============================================================
18
+
19
+ /**
20
+ * Supersymmetric pair: every mathematical entity has a "partner"
21
+ * with dual properties.
22
+ *
23
+ * In Rei: center ↔ periphery form a supersymmetric pair.
24
+ * The partner of a value has complementary structure.
25
+ */
26
+ export interface SuperSymPair {
27
+ readonly kind: 'supersym';
28
+ readonly boson: MultiDimNumber; // original (center-dominant)
29
+ readonly fermion: MultiDimNumber; // partner (periphery-dominant)
30
+ readonly symmetryBreaking: number; // 0 = perfect symmetry
31
+ }
32
+
33
+ /**
34
+ * Create a supersymmetric partner of a MultiDimNumber.
35
+ * The partner swaps the roles of center and periphery.
36
+ */
37
+ export function superSymPartner(md: MultiDimNumber): MultiDimNumber {
38
+ const mean = md.neighbors.reduce((a, b) => a + b, 0) / md.neighbors.length;
39
+ return {
40
+ center: mean,
41
+ neighbors: md.neighbors.map(() => md.center),
42
+ mode: md.mode,
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Create a supersymmetric pair.
48
+ */
49
+ export function superSymPair(md: MultiDimNumber): SuperSymPair {
50
+ const partner = superSymPartner(md);
51
+ const breakingMeasure = Math.abs(md.center - partner.center) /
52
+ (Math.abs(md.center) + Math.abs(partner.center) + 1e-10);
53
+
54
+ return {
55
+ kind: 'supersym',
56
+ boson: md,
57
+ fermion: partner,
58
+ symmetryBreaking: breakingMeasure,
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Check if a pair is in perfect supersymmetry.
64
+ */
65
+ export function isPerfectSuperSym(pair: SuperSymPair, epsilon: number = 0.01): boolean {
66
+ return pair.symmetryBreaking < epsilon;
67
+ }
68
+
69
+ /**
70
+ * Supersymmetric transform: apply f to original, g to partner,
71
+ * then combine results preserving symmetry.
72
+ */
73
+ export function superSymTransform(
74
+ pair: SuperSymPair,
75
+ f: (md: MultiDimNumber) => number,
76
+ g: (md: MultiDimNumber) => number
77
+ ): { bosonResult: number; fermionResult: number; preserved: boolean } {
78
+ const br = f(pair.boson);
79
+ const fr = g(pair.fermion);
80
+ return {
81
+ bosonResult: br,
82
+ fermionResult: fr,
83
+ preserved: Math.abs(br - fr) < 0.01 * (Math.abs(br) + Math.abs(fr) + 1e-10),
84
+ };
85
+ }
86
+
87
+
88
+ // ============================================================
89
+ // #30 Multi-Dimensional Mathematical Structure Theory
90
+ // (多次元数理構造理論)
91
+ // ============================================================
92
+
93
+ /**
94
+ * Multi-layered structure: nested MultiDimNumbers
95
+ * where each neighbor can itself be a MultiDimNumber.
96
+ */
97
+ export interface NestedMDim {
98
+ readonly kind: 'nested';
99
+ readonly center: number;
100
+ readonly children: readonly (number | NestedMDim)[];
101
+ readonly depth: number;
102
+ }
103
+
104
+ /**
105
+ * Create a nested structure from a flat MultiDimNumber.
106
+ * Each neighbor becomes a sub-structure at the next level.
107
+ */
108
+ export function nestify(md: MultiDimNumber, maxDepth: number = 3): NestedMDim {
109
+ if (maxDepth <= 0) {
110
+ return { kind: 'nested', center: md.center, children: md.neighbors, depth: 0 };
111
+ }
112
+
113
+ const children: (number | NestedMDim)[] = md.neighbors.map((n, i) => {
114
+ if (Math.abs(n) > 1) {
115
+ // Create sub-structure from significant neighbors
116
+ const subNeighbors = md.neighbors.map(m => m * (i + 1) / md.neighbors.length);
117
+ return nestify(
118
+ { center: n, neighbors: subNeighbors, mode: md.mode },
119
+ maxDepth - 1
120
+ );
121
+ }
122
+ return n;
123
+ });
124
+
125
+ return { kind: 'nested', center: md.center, children, depth: maxDepth };
126
+ }
127
+
128
+ /**
129
+ * Flatten a nested structure back to a single MultiDimNumber.
130
+ */
131
+ export function flatten(nested: NestedMDim): MultiDimNumber {
132
+ const neighbors = nested.children.map(child => {
133
+ if (typeof child === 'number') return child;
134
+ return child.center + flatten(child).neighbors.reduce((a, b) => a + b, 0) / flatten(child).neighbors.length;
135
+ });
136
+
137
+ return { center: nested.center, neighbors, mode: 'weighted' };
138
+ }
139
+
140
+ /**
141
+ * Compute the total depth of a nested structure.
142
+ */
143
+ export function nestedDepth(nested: NestedMDim): number {
144
+ let maxChildDepth = 0;
145
+ for (const child of nested.children) {
146
+ if (typeof child !== 'number') {
147
+ maxChildDepth = Math.max(maxChildDepth, nestedDepth(child));
148
+ }
149
+ }
150
+ return 1 + maxChildDepth;
151
+ }
152
+
153
+ /**
154
+ * Count total nodes in a nested structure.
155
+ */
156
+ export function nestedSize(nested: NestedMDim): number {
157
+ let count = 1; // this node
158
+ for (const child of nested.children) {
159
+ if (typeof child === 'number') {
160
+ count += 1;
161
+ } else {
162
+ count += nestedSize(child);
163
+ }
164
+ }
165
+ return count;
166
+ }
167
+
168
+
169
+ // ============================================================
170
+ // #31 Consciousness Mathematics Theory (意識数理学)
171
+ // ============================================================
172
+
173
+ /**
174
+ * Consciousness model: awareness emerges from the integration
175
+ * of information across a structure (Integrated Information Theory
176
+ * inspired, adapted for Rei's center-periphery).
177
+ *
178
+ * Φ (phi) = integrated information = measure of consciousness
179
+ */
180
+ export interface ConsciousnessState {
181
+ readonly kind: 'consciousness';
182
+ readonly phi: number; // integrated information
183
+ readonly awarenessLevel: number; // 0-1 normalized awareness
184
+ readonly selfModel: MultiDimNumber; // internal self-representation
185
+ readonly stimulusHistory: readonly number[];
186
+ }
187
+
188
+ /**
189
+ * Compute integrated information (Φ) for a MultiDimNumber.
190
+ * Φ measures how much the whole is greater than the sum of its parts.
191
+ */
192
+ export function computePhi(md: MultiDimNumber): number {
193
+ const allValues = [md.center, ...md.neighbors];
194
+ const total = allValues.reduce((s, v) => s + Math.abs(v), 0);
195
+ if (total === 0) return 0;
196
+
197
+ // Whole system entropy
198
+ const probs = allValues.map(v => Math.abs(v) / total + 1e-10);
199
+ const wholeEntropy = -probs.reduce((s, p) => s + p * Math.log2(p), 0);
200
+
201
+ // Sum of parts entropy (center alone + each neighbor alone)
202
+ const centerEntropy = Math.abs(md.center) > 0 ?
203
+ -Math.abs(md.center / total) * Math.log2(Math.abs(md.center / total) + 1e-10) : 0;
204
+ const partsEntropy = md.neighbors.reduce((s, n) => {
205
+ const p = Math.abs(n) / total + 1e-10;
206
+ return s - p * Math.log2(p);
207
+ }, centerEntropy);
208
+
209
+ // Φ = how much information is lost when system is partitioned
210
+ return Math.max(0, wholeEntropy - partsEntropy * 0.5);
211
+ }
212
+
213
+ /**
214
+ * Create initial consciousness state.
215
+ */
216
+ export function consciousnessInit(md: MultiDimNumber): ConsciousnessState {
217
+ const phi = computePhi(md);
218
+ return {
219
+ kind: 'consciousness',
220
+ phi,
221
+ awarenessLevel: Math.min(1, phi / Math.log2(md.neighbors.length + 2)),
222
+ selfModel: md,
223
+ stimulusHistory: [],
224
+ };
225
+ }
226
+
227
+ /**
228
+ * Process a stimulus: consciousness responds to external input.
229
+ */
230
+ export function processStimulus(
231
+ state: ConsciousnessState,
232
+ stimulus: number
233
+ ): ConsciousnessState {
234
+ // Self-model updates based on stimulus
235
+ const newCenter = state.selfModel.center * 0.9 + stimulus * 0.1;
236
+ const newNeighbors = state.selfModel.neighbors.map((n, i) =>
237
+ n * 0.95 + stimulus * 0.05 * Math.cos(i * Math.PI / 4)
238
+ );
239
+
240
+ const newSelf: MultiDimNumber = {
241
+ center: newCenter,
242
+ neighbors: newNeighbors,
243
+ mode: state.selfModel.mode,
244
+ };
245
+
246
+ const newPhi = computePhi(newSelf);
247
+
248
+ return {
249
+ kind: 'consciousness',
250
+ phi: newPhi,
251
+ awarenessLevel: Math.min(1, newPhi / Math.log2(newNeighbors.length + 2)),
252
+ selfModel: newSelf,
253
+ stimulusHistory: [...state.stimulusHistory, stimulus],
254
+ };
255
+ }
256
+
257
+
258
+ // ============================================================
259
+ // #32 Probability Fate Theory (確率運命理論)
260
+ // ============================================================
261
+
262
+ /**
263
+ * Fate model: outcomes determined by probability distributions
264
+ * that can be "fated" (deterministic) or "chanced" (random).
265
+ */
266
+ export interface FateState {
267
+ readonly kind: 'fate';
268
+ readonly probabilities: readonly number[]; // probability distribution
269
+ readonly fateWeight: number; // 0 = pure chance, 1 = pure fate
270
+ readonly history: readonly number[]; // past outcomes
271
+ }
272
+
273
+ /**
274
+ * Create a fate state from a MultiDimNumber.
275
+ * Neighbor magnitudes become probability weights.
276
+ */
277
+ export function fateFromMDim(md: MultiDimNumber, fateWeight: number = 0.5): FateState {
278
+ const total = md.neighbors.reduce((s, n) => s + Math.abs(n), 0) || 1;
279
+ const probs = md.neighbors.map(n => Math.abs(n) / total);
280
+
281
+ return {
282
+ kind: 'fate',
283
+ probabilities: probs,
284
+ fateWeight: Math.max(0, Math.min(1, fateWeight)),
285
+ history: [],
286
+ };
287
+ }
288
+
289
+ /**
290
+ * Sample an outcome from the fate distribution.
291
+ * fateWeight controls the blend between deterministic and random.
292
+ */
293
+ export function fateSample(state: FateState, seed?: number): {
294
+ outcome: number;
295
+ newState: FateState;
296
+ } {
297
+ // Deterministic component: always pick the highest probability
298
+ const maxIdx = state.probabilities.indexOf(Math.max(...state.probabilities));
299
+
300
+ // Random component: weighted random selection
301
+ const rand = seed !== undefined ?
302
+ Math.abs(Math.sin(seed * 12345.6789)) :
303
+ Math.random();
304
+
305
+ let cumulative = 0;
306
+ let randomIdx = 0;
307
+ for (let i = 0; i < state.probabilities.length; i++) {
308
+ cumulative += state.probabilities[i];
309
+ if (rand < cumulative) {
310
+ randomIdx = i;
311
+ break;
312
+ }
313
+ }
314
+
315
+ // Blend: fate vs chance
316
+ const outcome = state.fateWeight > 0.5 ? maxIdx : randomIdx;
317
+
318
+ return {
319
+ outcome,
320
+ newState: {
321
+ ...state,
322
+ history: [...state.history, outcome],
323
+ },
324
+ };
325
+ }
326
+
327
+ /**
328
+ * Compute the entropy of a fate distribution.
329
+ * Low entropy = highly fated, High entropy = highly random.
330
+ */
331
+ export function fateEntropy(state: FateState): number {
332
+ return -state.probabilities.reduce((s, p) => {
333
+ if (p <= 0) return s;
334
+ return s + p * Math.log2(p);
335
+ }, 0);
336
+ }
337
+
338
+
339
+ // ============================================================
340
+ // #33 Line System Theory (線体系理論)
341
+ // ============================================================
342
+
343
+ /**
344
+ * Line: all phenomena can be expressed as lines
345
+ * with properties of direction, intensity, and curvature.
346
+ */
347
+ export interface MathLine {
348
+ readonly kind: 'line';
349
+ readonly start: { x: number; y: number };
350
+ readonly end: { x: number; y: number };
351
+ readonly intensity: number; // 0-1 brightness/strength
352
+ readonly curvature: number; // 0 = straight, >0 = curved
353
+ }
354
+
355
+ /**
356
+ * Convert a MultiDimNumber to a set of lines.
357
+ * Center = origin, each neighbor defines an endpoint.
358
+ */
359
+ export function toLines(md: MultiDimNumber): MathLine[] {
360
+ const N = md.neighbors.length;
361
+ return md.neighbors.map((n, i) => {
362
+ const angle = (2 * Math.PI * i) / N;
363
+ const length = Math.abs(n);
364
+ return {
365
+ kind: 'line' as const,
366
+ start: { x: 0, y: 0 },
367
+ end: { x: length * Math.cos(angle), y: length * Math.sin(angle) },
368
+ intensity: Math.abs(n) / (Math.max(...md.neighbors.map(Math.abs)) || 1),
369
+ curvature: 0,
370
+ };
371
+ });
372
+ }
373
+
374
+ /**
375
+ * Line intersection: find where two lines cross.
376
+ */
377
+ export function lineIntersect(a: MathLine, b: MathLine): { x: number; y: number } | null {
378
+ const dx1 = a.end.x - a.start.x;
379
+ const dy1 = a.end.y - a.start.y;
380
+ const dx2 = b.end.x - b.start.x;
381
+ const dy2 = b.end.y - b.start.y;
382
+
383
+ const denom = dx1 * dy2 - dy1 * dx2;
384
+ if (Math.abs(denom) < 1e-10) return null; // Parallel
385
+
386
+ const t = ((b.start.x - a.start.x) * dy2 - (b.start.y - a.start.y) * dx2) / denom;
387
+
388
+ return {
389
+ x: a.start.x + t * dx1,
390
+ y: a.start.y + t * dy1,
391
+ };
392
+ }
393
+
394
+ /**
395
+ * Line field energy: total "visual energy" of a set of lines.
396
+ */
397
+ export function lineFieldEnergy(lines: MathLine[]): number {
398
+ return lines.reduce((s, line) => {
399
+ const length = Math.sqrt(
400
+ (line.end.x - line.start.x) ** 2 + (line.end.y - line.start.y) ** 2
401
+ );
402
+ return s + length * line.intensity;
403
+ }, 0);
404
+ }
405
+
406
+
407
+ // ============================================================
408
+ // #34 UMTE — Unified Mathematical Theory of Everything
409
+ // (万物数理統一理論)
410
+ // ============================================================
411
+
412
+ /**
413
+ * UMTE: every mathematical theory is an aspect of a single
414
+ * unified structure. In Rei, this is expressed as:
415
+ *
416
+ * UMTE(σ) = Σ_theory weight_theory · project(σ, theory)
417
+ *
418
+ * Each theory provides a "view" (projection) of the same σ.
419
+ */
420
+ export type TheoryProjection = (md: MultiDimNumber) => number;
421
+
422
+ export interface UMTEFramework {
423
+ readonly kind: 'umte';
424
+ readonly theories: readonly { name: string; weight: number; project: TheoryProjection }[];
425
+ readonly unifiedValue: number;
426
+ }
427
+
428
+ /**
429
+ * Create a UMTE framework with multiple theory projections.
430
+ */
431
+ export function umteCreate(
432
+ theories: { name: string; weight: number; project: TheoryProjection }[]
433
+ ): UMTEFramework {
434
+ return {
435
+ kind: 'umte',
436
+ theories,
437
+ unifiedValue: 0,
438
+ };
439
+ }
440
+
441
+ /**
442
+ * Evaluate the unified value by combining all theory projections.
443
+ */
444
+ export function umteEvaluate(framework: UMTEFramework, md: MultiDimNumber): UMTEFramework {
445
+ const totalWeight = framework.theories.reduce((s, t) => s + t.weight, 0) || 1;
446
+ const unifiedValue = framework.theories.reduce(
447
+ (s, t) => s + (t.weight / totalWeight) * t.project(md),
448
+ 0
449
+ );
450
+
451
+ return { ...framework, unifiedValue };
452
+ }
453
+
454
+ /**
455
+ * Default UMTE with standard theory projections.
456
+ */
457
+ export function umteDefault(): UMTEFramework {
458
+ return umteCreate([
459
+ {
460
+ name: 'algebraic',
461
+ weight: 1.0,
462
+ project: (md) => md.center + md.neighbors.reduce((a, b) => a + b, 0),
463
+ },
464
+ {
465
+ name: 'geometric',
466
+ weight: 1.0,
467
+ project: (md) => {
468
+ const vals = md.neighbors.filter(n => n > 0);
469
+ return vals.length > 0 ? Math.pow(vals.reduce((a, b) => a * b, 1), 1 / vals.length) : 0;
470
+ },
471
+ },
472
+ {
473
+ name: 'harmonic',
474
+ weight: 0.8,
475
+ project: (md) => {
476
+ const nonZero = md.neighbors.filter(n => Math.abs(n) > 1e-10);
477
+ return nonZero.length > 0 ? nonZero.length / nonZero.reduce((s, n) => s + 1 / n, 0) : 0;
478
+ },
479
+ },
480
+ {
481
+ name: 'entropic',
482
+ weight: 0.6,
483
+ project: (md) => {
484
+ const total = md.neighbors.reduce((s, n) => s + Math.abs(n), 0) || 1;
485
+ return -md.neighbors.reduce((s, n) => {
486
+ const p = Math.abs(n) / total + 1e-10;
487
+ return s + p * Math.log2(p);
488
+ }, 0);
489
+ },
490
+ },
491
+ {
492
+ name: 'topological',
493
+ weight: 0.5,
494
+ project: (md) => {
495
+ // Count sign changes (topological feature)
496
+ let changes = 0;
497
+ for (let i = 0; i < md.neighbors.length; i++) {
498
+ const next = md.neighbors[(i + 1) % md.neighbors.length];
499
+ if (md.neighbors[i] * next < 0) changes++;
500
+ }
501
+ return changes;
502
+ },
503
+ },
504
+ ]);
505
+ }
506
+
507
+
508
+ // ============================================================
509
+ // #35 Holographic Mathematical Projection Theory
510
+ // (ホログラフィック数式投影理論)
511
+ // ============================================================
512
+
513
+ /**
514
+ * Holographic projection: project a high-dimensional structure
515
+ * onto a lower-dimensional "hologram" that preserves all information.
516
+ *
517
+ * In Rei: a MultiDimNumber (N+1 values) is projected to
518
+ * a holographic encoding (fewer values + reconstruction key).
519
+ */
520
+ export interface Hologram {
521
+ readonly kind: 'hologram';
522
+ readonly projection: readonly number[]; // reduced representation
523
+ readonly reconstructionKey: readonly number[]; // needed to restore
524
+ readonly originalDim: number;
525
+ readonly projectedDim: number;
526
+ readonly fidelity: number; // 0-1, how much info is preserved
527
+ }
528
+
529
+ /**
530
+ * Project a MultiDimNumber to a hologram.
531
+ * Uses principal component analysis (simplified).
532
+ */
533
+ export function holographicProject(
534
+ md: MultiDimNumber,
535
+ targetDim: number = 3
536
+ ): Hologram {
537
+ const allValues = [md.center, ...md.neighbors];
538
+ const N = allValues.length;
539
+ const mean = allValues.reduce((s, v) => s + v, 0) / N;
540
+
541
+ // Simplified PCA: keep the largest components
542
+ const centered = allValues.map(v => v - mean);
543
+ const sorted = centered
544
+ .map((v, i) => ({ value: v, index: i }))
545
+ .sort((a, b) => Math.abs(b.value) - Math.abs(a.value));
546
+
547
+ const projection = sorted.slice(0, targetDim).map(s => s.value);
548
+ const reconstructionKey = [mean, ...sorted.slice(0, targetDim).map(s => s.index)];
549
+
550
+ // Fidelity: proportion of variance captured
551
+ const totalVariance = centered.reduce((s, v) => s + v * v, 0);
552
+ const capturedVariance = projection.reduce((s, v) => s + v * v, 0);
553
+ const fidelity = totalVariance > 0 ? capturedVariance / totalVariance : 1;
554
+
555
+ return {
556
+ kind: 'hologram',
557
+ projection,
558
+ reconstructionKey,
559
+ originalDim: N,
560
+ projectedDim: targetDim,
561
+ fidelity,
562
+ };
563
+ }
564
+
565
+ /**
566
+ * Reconstruct a MultiDimNumber from a hologram.
567
+ */
568
+ export function holographicReconstruct(hologram: Hologram): MultiDimNumber {
569
+ const mean = hologram.reconstructionKey[0] as number;
570
+ const indices = hologram.reconstructionKey.slice(1) as number[];
571
+ const N = hologram.originalDim;
572
+
573
+ // Reconstruct: fill known components, interpolate rest
574
+ const values = new Array(N).fill(mean);
575
+ for (let i = 0; i < hologram.projection.length; i++) {
576
+ const idx = indices[i];
577
+ if (idx !== undefined && idx < N) {
578
+ values[idx] = hologram.projection[i] + mean;
579
+ }
580
+ }
581
+
582
+ return {
583
+ center: values[0],
584
+ neighbors: values.slice(1),
585
+ mode: 'weighted',
586
+ };
587
+ }
588
+
589
+ /**
590
+ * Compute holographic information density.
591
+ */
592
+ export function holographicDensity(hologram: Hologram): number {
593
+ return hologram.fidelity * hologram.originalDim / hologram.projectedDim;
594
+ }
595
+
596
+ /**
597
+ * Multi-resolution holographic projection:
598
+ * create holograms at different resolutions.
599
+ */
600
+ export function multiResHologram(
601
+ md: MultiDimNumber,
602
+ resolutions: number[] = [1, 2, 4, 8]
603
+ ): Hologram[] {
604
+ return resolutions
605
+ .filter(r => r <= md.neighbors.length + 1)
606
+ .map(r => holographicProject(md, r));
607
+ }