@aleph-ai/tinyaleph 1.6.2 → 1.7.1

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.
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Quantum Fiber Bundle Theory
3
+ *
4
+ * Implements the geometric structure for state evolution and protection:
5
+ * - Principal Bundle Framework (Base manifold M, Total space P)
6
+ * - Berry Connection & Curvature
7
+ * - Holonomy Operator for path-dependent memory
8
+ * - Chern Classes for topological invariants
9
+ *
10
+ * Based on 01_FIBER_BUNDLES.md
11
+ */
12
+
13
+ import { Complex, normalizeComplex } from './primeon_z_ladder_u.js';
14
+
15
+ /**
16
+ * Represents a point in the Base Manifold M (Configuration Space)
17
+ */
18
+ class ManifoldPoint {
19
+ constructor(coordinates) {
20
+ this.coordinates = coordinates; // Array of numbers
21
+ }
22
+
23
+ distance(other) {
24
+ return Math.sqrt(this.coordinates.reduce((sum, val, i) => sum + Math.pow(val - other.coordinates[i], 2), 0));
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Geometric Phase Tracker using Berry Connection
30
+ */
31
+ class BerryConnection {
32
+ constructor(dimension) {
33
+ this.dimension = dimension;
34
+ this.history = [];
35
+ }
36
+
37
+ /**
38
+ * Calculate local connection 1-form: A = i⟨ψ|d|ψ⟩
39
+ * @param {Complex[]} psi Current state vector
40
+ * @param {Complex[]} d_psi Change in state vector
41
+ * @returns {Complex} Connection value
42
+ */
43
+ calculateConnection(psi, d_psi) {
44
+ // Inner product ⟨ψ|d|ψ⟩
45
+ let inner = new Complex(0, 0);
46
+ for (let i = 0; i < psi.length; i++) {
47
+ // ⟨ψ| is conjugate
48
+ const bra = Complex.conj(psi[i]);
49
+ const term = Complex.mul(bra, d_psi[i]);
50
+ inner = Complex.add(inner, term);
51
+ }
52
+
53
+ // A = i * inner
54
+ return Complex.mul(new Complex(0, 1), inner);
55
+ }
56
+
57
+ /**
58
+ * Calculate Berry Curvature 2-form: F_μν = ∂_μA_ν - ∂_νA_μ - i[A_μ,A_ν]
59
+ * Simplified for abelian U(1) case: F = dA
60
+ * @param {Complex} A_mu Connection in direction mu
61
+ * @param {Complex} A_nu Connection in direction nu
62
+ * @param {number} d_mu Step size in mu
63
+ * @param {number} d_nu Step size in nu
64
+ */
65
+ calculateCurvature(A_mu, A_nu, d_mu, d_nu) {
66
+ // Approximation of dA
67
+ const dA = Complex.sub(A_nu, A_mu);
68
+ return Complex.scale(dA, 1 / (d_mu * d_nu)); // Simplified numerical derivative
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Holonomy Operator for Path-Dependent Memory
74
+ * U(C) = P exp(-i∮_C A_μdR^μ)
75
+ */
76
+ class HolonomyOperator {
77
+ constructor() {
78
+ this.phase = new Complex(1, 0); // Start with identity
79
+ this.pathIntegral = new Complex(0, 0);
80
+ }
81
+
82
+ /**
83
+ * Update holonomy along a path segment
84
+ * @param {Complex} connection Local Berry connection A
85
+ * @param {number} stepSize Path segment length dR
86
+ */
87
+ transport(connection, stepSize) {
88
+ // Integral accumulation: ∫ A dR
89
+ const term = Complex.scale(connection, stepSize);
90
+ this.pathIntegral = Complex.add(this.pathIntegral, term);
91
+
92
+ // U = exp(-i * integral)
93
+ const phaseArg = -1 * this.pathIntegral.re; // simplified for U(1) real phase
94
+ // In full SU(N) this would be matrix exponential
95
+
96
+ // Update phase factor
97
+ // Note: A is imaginary-valued for normalized states, so -i*A is real
98
+ // If A = i*a, then -i*A = a.
99
+ // For general complex A:
100
+ const exponent = Complex.mul(new Complex(0, -1), term);
101
+ this.phase = Complex.mul(this.phase, Complex.exp(exponent.re)); // Approximation
102
+ }
103
+
104
+ /**
105
+ * Get current holonomy factor
106
+ */
107
+ getFactor() {
108
+ return this.phase;
109
+ }
110
+
111
+ reset() {
112
+ this.phase = new Complex(1, 0);
113
+ this.pathIntegral = new Complex(0, 0);
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Topological Protection via Chern Classes
119
+ */
120
+ class TopologicalProtection {
121
+ constructor() {
122
+ this.chernNumber = 0;
123
+ }
124
+
125
+ /**
126
+ * Calculate First Chern Class c1 = 1/2π tr(F)
127
+ * @param {Complex} curvature Berry curvature F
128
+ */
129
+ calculateChernClass(curvature) {
130
+ // For U(1), trace is just the value
131
+ // c1 = F / 2π
132
+ // Taking imaginary part as F should be purely imaginary for unitary evolution
133
+ return curvature.im / (2 * Math.PI);
134
+ }
135
+
136
+ /**
137
+ * Integrate Chern class over manifold to get Chern number
138
+ * @param {Complex[]} curvatures Array of curvature values over the manifold
139
+ */
140
+ computeChernNumber(curvatures) {
141
+ let sum = 0;
142
+ for (const F of curvatures) {
143
+ sum += this.calculateChernClass(F);
144
+ }
145
+ // Chern number should be an integer for closed manifolds
146
+ this.chernNumber = Math.round(sum);
147
+ return this.chernNumber;
148
+ }
149
+
150
+ /**
151
+ * Check if state is topologically protected (non-zero Chern number)
152
+ */
153
+ isProtected() {
154
+ return this.chernNumber !== 0;
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Fiber Bundle Manager
160
+ * Orchestrates the geometric components
161
+ */
162
+ class FiberBundle {
163
+ constructor(dimension) {
164
+ this.dimension = dimension;
165
+ this.connection = new BerryConnection(dimension);
166
+ this.holonomy = new HolonomyOperator();
167
+ this.topology = new TopologicalProtection();
168
+ this.currentState = null;
169
+ }
170
+
171
+ /**
172
+ * Evolve state and update geometric factors
173
+ * @param {Complex[]} newState New state vector
174
+ * @param {number} stepSize Distance moved in parameter space
175
+ */
176
+ evolve(newState, stepSize = 0.01) {
177
+ if (!this.currentState) {
178
+ this.currentState = newState;
179
+ return;
180
+ }
181
+
182
+ // Calculate change d|ψ⟩
183
+ const d_psi = newState.map((v, i) => Complex.sub(v, this.currentState[i]));
184
+
185
+ // Calculate Connection A
186
+ const A = this.connection.calculateConnection(this.currentState, d_psi);
187
+
188
+ // Update Holonomy
189
+ this.holonomy.transport(A, stepSize);
190
+
191
+ // Update state
192
+ this.currentState = newState;
193
+
194
+ return {
195
+ connection: A,
196
+ holonomy: this.holonomy.getFactor()
197
+ };
198
+ }
199
+ }
200
+
201
+ export {
202
+ ManifoldPoint,
203
+ BerryConnection,
204
+ HolonomyOperator,
205
+ TopologicalProtection,
206
+ FiberBundle
207
+ };
@@ -5,9 +5,39 @@
5
5
  import { OscillatorBank } from './oscillator.js';
6
6
 
7
7
  class KuramotoModel extends OscillatorBank {
8
- constructor(frequencies, couplingStrength = 0.3) {
9
- super(frequencies);
10
- this.K = couplingStrength;
8
+ /**
9
+ * Create a Kuramoto synchronization model
10
+ * @param {number[]|OscillatorBank} frequenciesOrBank - Array of frequencies or an existing OscillatorBank
11
+ * @param {number|object} [couplingOrOptions=0.3] - Coupling strength (number) or options object
12
+ */
13
+ constructor(frequenciesOrBank, couplingOrOptions = 0.3) {
14
+ if (frequenciesOrBank instanceof OscillatorBank) {
15
+ // Use existing OscillatorBank's oscillators
16
+ super([]); // Initialize with empty array
17
+ this.oscillators = frequenciesOrBank.oscillators;
18
+ this.primeList = frequenciesOrBank.primeList || frequenciesOrBank.oscillators.map(o => o.freq);
19
+
20
+ // Parse options
21
+ if (typeof couplingOrOptions === 'object') {
22
+ this.K = couplingOrOptions.coupling ?? 0.3;
23
+ } else {
24
+ this.K = couplingOrOptions;
25
+ }
26
+ } else {
27
+ // Traditional constructor with frequencies array
28
+ super(frequenciesOrBank);
29
+ this.K = typeof couplingOrOptions === 'object'
30
+ ? (couplingOrOptions.coupling ?? 0.3)
31
+ : couplingOrOptions;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Single step forward in time
37
+ * @param {number} dt - Timestep
38
+ */
39
+ step(dt) {
40
+ this.tick(dt);
11
41
  }
12
42
 
13
43
  orderParameter() {
@@ -2,7 +2,24 @@
2
2
  * Lyapunov exponent estimation from phase histories
3
3
  */
4
4
 
5
- function estimateLyapunov(oscillators, windowSize = 20) {
5
+ /**
6
+ * Estimate Lyapunov exponent from time series or oscillators
7
+ * @param {number[]|object[]} historyOrOscillators - Time series array or oscillator objects
8
+ * @param {number} [windowSize=20] - Window size for computation
9
+ * @returns {number} Estimated Lyapunov exponent
10
+ */
11
+ function estimateLyapunov(historyOrOscillators, windowSize = 20) {
12
+ // Handle both signatures: number[] (time series) or oscillator objects
13
+ if (!historyOrOscillators || historyOrOscillators.length === 0) return 0;
14
+
15
+ // Check if input is a raw number array (time series)
16
+ if (typeof historyOrOscillators[0] === 'number') {
17
+ return estimateLyapunovFromTimeSeries(historyOrOscillators, windowSize);
18
+ }
19
+
20
+ // Otherwise treat as oscillator objects
21
+ const oscillators = historyOrOscillators;
22
+ if (!oscillators[0] || !oscillators[0].phaseHistory) return 0;
6
23
  if (oscillators[0].phaseHistory.length < windowSize) return 0;
7
24
 
8
25
  let sumLog = 0, count = 0;
@@ -19,13 +36,92 @@ function estimateLyapunov(oscillators, windowSize = 20) {
19
36
  return count > 0 ? sumLog / count : 0;
20
37
  }
21
38
 
39
+ /**
40
+ * Estimate Lyapunov exponent from a time series (number array)
41
+ * Uses the Rosenstein algorithm approximation
42
+ * @param {number[]} history - Time series data
43
+ * @param {number} [windowSize=20] - Window size
44
+ * @returns {number} Estimated Lyapunov exponent
45
+ */
46
+ function estimateLyapunovFromTimeSeries(history, windowSize = 20) {
47
+ if (history.length < windowSize + 1) return 0;
48
+
49
+ let sumLog = 0;
50
+ let count = 0;
51
+
52
+ // Compute average log divergence over window
53
+ for (let i = 1; i < Math.min(history.length, windowSize); i++) {
54
+ const d0 = Math.abs(history[i] - history[i - 1]);
55
+ if (d0 > 1e-10) {
56
+ // Find nearby point and track divergence
57
+ const neighbors = [];
58
+ for (let j = 0; j < history.length; j++) {
59
+ if (Math.abs(j - i) > 1) {
60
+ const dist = Math.abs(history[j] - history[i]);
61
+ if (dist > 1e-10 && dist < 0.5) {
62
+ neighbors.push({ j, dist });
63
+ }
64
+ }
65
+ }
66
+
67
+ if (neighbors.length > 0) {
68
+ neighbors.sort((a, b) => a.dist - b.dist);
69
+ const nearIdx = neighbors[0].j;
70
+ const initialDist = neighbors[0].dist;
71
+
72
+ // Track divergence
73
+ const evolvedDist = Math.abs(
74
+ history[Math.min(i + windowSize, history.length - 1)] -
75
+ history[Math.min(nearIdx + windowSize, history.length - 1)]
76
+ );
77
+
78
+ if (evolvedDist > 1e-10) {
79
+ sumLog += Math.log(evolvedDist / initialDist) / windowSize;
80
+ count++;
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ return count > 0 ? sumLog / count : 0;
87
+ }
88
+
89
+ /**
90
+ * Classify stability based on Lyapunov exponent
91
+ * @param {number} lyapunovExponent - The Lyapunov exponent
92
+ * @returns {'stable'|'unstable'|'chaotic'|'collapsed'} Stability classification
93
+ */
22
94
  function classifyStability(lyapunovExponent) {
23
- if (lyapunovExponent < -0.1) return 'STABLE';
24
- if (lyapunovExponent > 0.1) return 'CHAOTIC';
25
- return 'MARGINAL';
95
+ if (lyapunovExponent < -0.1) return 'collapsed'; // Strong convergence
96
+ if (lyapunovExponent < 0) return 'stable'; // Weak convergence
97
+ if (lyapunovExponent < 0.5) return 'unstable'; // Weak divergence
98
+ return 'chaotic'; // Strong divergence
26
99
  }
27
100
 
28
- function adaptiveCoupling(baseCoupling, lyapunovExponent, gain = 0.5) {
101
+ /**
102
+ * Compute adaptive coupling strength based on coherence or Lyapunov exponent
103
+ * @param {number} coherenceOrBase - Coherence value (0-1) or base coupling strength
104
+ * @param {number} [baseStrengthOrLyapunov=0.3] - Base strength (for coherence mode) or Lyapunov exponent
105
+ * @param {number} [gain=0.5] - Gain factor for legacy mode
106
+ * @returns {number} Adapted coupling strength
107
+ */
108
+ function adaptiveCoupling(coherenceOrBase, baseStrengthOrLyapunov = 0.3, gain = 0.5) {
109
+ // If first arg is between 0 and 1 and second is small, treat as coherence mode
110
+ // adaptiveCoupling(coherence, baseStrength?)
111
+ if (coherenceOrBase >= 0 && coherenceOrBase <= 1 &&
112
+ (baseStrengthOrLyapunov >= 0.05 && baseStrengthOrLyapunov <= 1)) {
113
+ const coherence = coherenceOrBase;
114
+ const baseStrength = baseStrengthOrLyapunov;
115
+
116
+ // High coherence = stronger coupling, low coherence = weaker coupling
117
+ // Scale coupling between 0.5x and 1.5x base strength based on coherence
118
+ return baseStrength * (0.5 + coherence);
119
+ }
120
+
121
+ // Legacy mode: adaptiveCoupling(baseCoupling, lyapunovExponent, gain?)
122
+ const baseCoupling = coherenceOrBase;
123
+ const lyapunovExponent = baseStrengthOrLyapunov;
124
+
29
125
  if (lyapunovExponent < -0.1) return baseCoupling * (1 + gain);
30
126
  if (lyapunovExponent > 0.1) return baseCoupling * (1 - gain);
31
127
  return baseCoupling;
@@ -49,8 +49,39 @@ class Oscillator {
49
49
  * Collection of coupled oscillators
50
50
  */
51
51
  class OscillatorBank {
52
- constructor(frequencies) {
53
- this.oscillators = frequencies.map(f => new Oscillator(f));
52
+ /**
53
+ * Create an OscillatorBank
54
+ * @param {number|number[]} sizeOrFrequencies - Either a number (size) or array of frequencies
55
+ * @param {number[]} [defaultPrimes] - Optional default primes for size-based construction
56
+ */
57
+ constructor(sizeOrFrequencies, defaultPrimes = null) {
58
+ if (typeof sizeOrFrequencies === 'number') {
59
+ // Size-based constructor: create oscillators with first N primes as frequencies
60
+ const primes = defaultPrimes || this._generatePrimes(sizeOrFrequencies);
61
+ this.oscillators = primes.slice(0, sizeOrFrequencies).map(p => new Oscillator(p));
62
+ this.primeList = primes.slice(0, sizeOrFrequencies);
63
+ } else {
64
+ // Frequency array constructor
65
+ this.oscillators = sizeOrFrequencies.map(f => new Oscillator(f));
66
+ this.primeList = sizeOrFrequencies;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Generate first N primes (helper)
72
+ */
73
+ _generatePrimes(n) {
74
+ const primes = [];
75
+ let num = 2;
76
+ while (primes.length < n) {
77
+ let isPrime = true;
78
+ for (let i = 2; i <= Math.sqrt(num); i++) {
79
+ if (num % i === 0) { isPrime = false; break; }
80
+ }
81
+ if (isPrime) primes.push(num);
82
+ num++;
83
+ }
84
+ return primes;
54
85
  }
55
86
 
56
87
  tick(dt, couplingFn) {
@@ -68,6 +99,21 @@ class OscillatorBank {
68
99
  }
69
100
  }
70
101
 
102
+ /**
103
+ * Excite oscillators based on prime frequencies
104
+ * @param {number[]} primes - Array of prime numbers to excite
105
+ * @param {number} [amount=0.5] - Excitation amount
106
+ */
107
+ excite(primes, amount = 0.5) {
108
+ const primeSet = new Set(primes);
109
+ for (let i = 0; i < this.oscillators.length; i++) {
110
+ // Match by prime frequency
111
+ if (primeSet.has(this.primeList[i]) || primeSet.has(this.oscillators[i].freq)) {
112
+ this.oscillators[i].excite(amount);
113
+ }
114
+ }
115
+ }
116
+
71
117
  decayAll(rate = 0.02, dt = 1) {
72
118
  for (const osc of this.oscillators) {
73
119
  osc.decay(rate, dt);
@@ -488,5 +488,7 @@ export {
488
488
  shannonEntropyNats,
489
489
  probsOf,
490
490
  normalize,
491
- C
491
+ normalize as normalizeComplex,
492
+ C,
493
+ C as Complex
492
494
  };
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Quantum Hash Topology
3
+ *
4
+ * Implements Quantum Hash functions and topological analysis:
5
+ * - Quantum Round Function
6
+ * - Linearity Measures
7
+ * - Collision Detection via Interference
8
+ * - Topological Protection
9
+ *
10
+ * Based on 04_QUANTUM_HASH.md
11
+ */
12
+
13
+ import { Complex, normalizeComplex } from './primeon_z_ladder_u.js';
14
+
15
+ /**
16
+ * Quantum Hash Function Core
17
+ */
18
+ class QuantumHash {
19
+ constructor(bitWidth = 32) {
20
+ this.bitWidth = bitWidth;
21
+ this.N = Math.pow(2, bitWidth);
22
+ }
23
+
24
+ /**
25
+ * Classical Hash Function placeholder (e.g., simplified SHA-like)
26
+ * @param {number} x Input
27
+ * @returns {number} Hash output
28
+ */
29
+ classicalHash(x) {
30
+ // Simple mixing for demo
31
+ let h = x * 0x45d9f3b;
32
+ h = ((h >>> 16) ^ h) * 0x45d9f3b;
33
+ h = ((h >>> 16) ^ h);
34
+ return h >>> 0; // Ensure unsigned 32-bit
35
+ }
36
+
37
+ /**
38
+ * Quantum Round Function
39
+ * R_q: |x⟩ → 1/√2(|f(x)⟩ + i|f(x⊕k)⟩)
40
+ * Creates superposition of hash of x and hash of x XOR k
41
+ */
42
+ roundFunction(x, k) {
43
+ const fx = this.classicalHash(x);
44
+ const fxk = this.classicalHash(x ^ k);
45
+
46
+ const state = [
47
+ { val: fx, amp: new Complex(1/Math.sqrt(2), 0) },
48
+ { val: fxk, amp: new Complex(0, 1/Math.sqrt(2)) }
49
+ ];
50
+
51
+ return state;
52
+ }
53
+
54
+ /**
55
+ * Linearity Measure
56
+ * L(f) = Pr[f(x⊕y) = f(x)⊕f(y)]
57
+ * Assesses resistance to differential attacks
58
+ */
59
+ measureLinearity(samples = 100) {
60
+ let matches = 0;
61
+
62
+ for (let i = 0; i < samples; i++) {
63
+ const x = Math.floor(Math.random() * this.N);
64
+ const y = Math.floor(Math.random() * this.N);
65
+
66
+ const f_xy = this.classicalHash(x ^ y);
67
+ const fx_fy = this.classicalHash(x) ^ this.classicalHash(y);
68
+
69
+ if (f_xy === fx_fy) {
70
+ matches++;
71
+ }
72
+ }
73
+
74
+ return matches / samples;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Collision Detection using Quantum Interference
80
+ */
81
+ class CollisionDetector {
82
+ constructor(hashFunction) {
83
+ this.hash = hashFunction;
84
+ }
85
+
86
+ /**
87
+ * Detect Collision Amplitude
88
+ * |ψ_c⟩ = 1/√N ∑_{x,y} |x,y⟩|H(x)⊕H(y)⟩
89
+ *
90
+ * Simplified simulation of collision search
91
+ */
92
+ detectCollision(targetHash, maxSteps = 1000) {
93
+ // Grover-like search simulation
94
+ // In a real quantum computer, this amplifies amplitude of solution
95
+
96
+ // Classical simulation of the "Interference" check
97
+ // I(x,y) = |⟨H(x)|H(y)⟩|²
98
+
99
+ for (let i = 0; i < maxSteps; i++) {
100
+ const x = Math.floor(Math.random() * this.hash.N);
101
+ const hx = this.hash.classicalHash(x);
102
+
103
+ // Check for collision (constructive interference)
104
+ if (hx === targetHash) {
105
+ return { found: true, preimage: x, steps: i };
106
+ }
107
+ }
108
+
109
+ return { found: false, steps: maxSteps };
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Topological Protection for Hash States
115
+ */
116
+ class HashTopology {
117
+ constructor() {
118
+ this.connection = new Complex(0, 0);
119
+ }
120
+
121
+ /**
122
+ * Modified Connection Form
123
+ * A_H = A + H(x)dx
124
+ */
125
+ updateConnection(baseConnection, hashValue, stepSize) {
126
+ // H(x) contribution
127
+ // Map hash to phase/amplitude
128
+ const hashTerm = new Complex(hashValue * 1e-9, 0); // Scale down
129
+ const term = Complex.scale(hashTerm, stepSize);
130
+
131
+ return Complex.add(baseConnection, term);
132
+ }
133
+ }
134
+
135
+ export {
136
+ QuantumHash,
137
+ CollisionDetector,
138
+ HashTopology
139
+ };