test1978 commited on
Commit
35fa4cc
·
verified ·
1 Parent(s): cfaa098

Delete matrix_model.py

Browse files
Files changed (1) hide show
  1. matrix_model.py +0 -481
matrix_model.py DELETED
@@ -1,481 +0,0 @@
1
- """
2
- Matrix Model - TRULY FINAL CORRECTED Implementation
3
- ABC Model with Weighted Adjacency Matrix (THREE components)
4
-
5
- CRITICAL INSIGHT FROM abc_model.py:
6
- - piece_positions stored as (x, y) tuples
7
- - BUT MB_current = a_product @ c0 produces [x, y, 1] homogeneous coords
8
- - These are the SAME locations!
9
-
10
- For matrix computations with B matrices, we MUST use homogeneous coordinates [x, y, 1]
11
- to match the algebraic structure.
12
-
13
- Implements Definition from Section 6:
14
- W[i,j](t) = A[i,j](t) ⊙ S[i,j](t) ⊙ F[i,j](t)
15
-
16
- Author: Chaim Duchovny
17
- Date: January 25, 2026 (TRULY FINAL CORRECTED)
18
- """
19
-
20
- import numpy as np
21
- from typing import Tuple
22
-
23
- class ABCModelDynamic:
24
- """ABC Model with displacement-based B matrices."""
25
-
26
- def __init__(self, n: int = 2, t: float = 1.0, T: float = 1.41):
27
- """Initialize for 2D board."""
28
- self.n = n
29
- self.t = t
30
- self.T = T
31
- self.c0 = np.array([0.0, 0.0, 1.0])
32
- self.B_blocks = []
33
- self.piece_positions = [] # Stores (x, y) tuples
34
- self.a_product = np.eye(3)
35
- self.kappa = {}
36
- self.delta = {}
37
- self.stage = 0
38
- self.MB_current = self.c0.copy()
39
- self.MB_previous = self.c0.copy()
40
- self.history = []
41
-
42
- def create_B_displacement(self, dx: float, dy: float) -> np.ndarray:
43
- """Create displacement matrix B."""
44
- B = np.array([
45
- [1.0, 0.0, dx],
46
- [0.0, 1.0, dy],
47
- [0.0, 0.0, 1.0]
48
- ])
49
- return B
50
-
51
- def add_piece(self, position: tuple, delta_values: tuple, kappa_vector: np.ndarray = None):
52
- """
53
- Add a piece at position with delta values and tokenized vector.
54
-
55
- Args:
56
- position: (x, y) tuple - 2D coordinates from board
57
- delta_values: (δ₁, δ₂, δ₃) tuple
58
- kappa_vector: tokenized vector κ(B_i)
59
- """
60
- x, y = position
61
- current_MB = self.MB_current.copy()
62
- dx = x - current_MB[0]
63
- dy = y - current_MB[1]
64
-
65
- B_i = self.create_B_displacement(dx, dy)
66
- idx = len(self.B_blocks)
67
-
68
- self.B_blocks.append(B_i)
69
- self.piece_positions.append((x, y)) # Store as 2D tuple (board representation)
70
- self.a_product = self.a_product @ B_i
71
-
72
- self.MB_previous = self.MB_current.copy()
73
- self.MB_current = self.a_product @ self.c0 # Homogeneous coords [x, y, 1]
74
-
75
- self.delta[idx] = delta_values
76
-
77
- if kappa_vector is None:
78
- kappa_vector = np.array(delta_values)
79
- self.kappa[idx] = kappa_vector
80
-
81
- self.stage += 1
82
-
83
- self.history.append({
84
- 'stage': self.stage,
85
- 'SB_position': (x, y),
86
- 'displacement': (dx, dy),
87
- 'B_i': B_i.copy(),
88
- 'a_t': self.a_product.copy(),
89
- 'MB_prev': self.MB_previous.copy(),
90
- 'MB_curr': self.MB_current.copy(),
91
- 'delta': delta_values,
92
- 'kappa': kappa_vector.copy() if kappa_vector is not None else None
93
- })
94
-
95
-
96
- class WeightedMatrixABC:
97
- """
98
- Compute weighted adjacency matrix from ABCModelDynamic.
99
-
100
- CRITICAL: Converts (x,y) tuples to homogeneous coords [x,y,1]
101
- to match algebraic structure of B matrices from abc_model.py
102
-
103
- Implements Definition from Section 6:
104
- W[i,j](t) = A[i,j](t) ⊙ S[i,j](t) ⊙ F[i,j](t)
105
- """
106
-
107
- def __init__(self, abc_model: ABCModelDynamic, sigma: float = 1.0):
108
- """
109
- Initialize with ABC model instance.
110
-
111
- Args:
112
- abc_model: ABCModelDynamic instance
113
- sigma: Standard deviation for Gaussian spatial kernel
114
- """
115
- self.abc = abc_model
116
- self.n = abc_model.n
117
- self.t = abc_model.t
118
- self.T = abc_model.T
119
- self.sigma = sigma
120
- self.positions = None # Will store homogeneous coords [x, y, 1]
121
- self.D = None
122
- self.A = None
123
- self.S = None
124
- self.F = None
125
- self.W = None
126
-
127
- def compute_piece_positions(self) -> np.ndarray:
128
- """
129
- Extract positions from ABC model and convert to homogeneous coordinates.
130
-
131
- In abc_model.py:
132
- - piece_positions are (x, y) tuples
133
- - MB_current = a_product @ c0 produces [x, y, 1]
134
-
135
- For matrix computations, convert to homogeneous coords to match
136
- the algebraic structure of B matrices.
137
-
138
- Returns: Array of shape (num_pieces, 3) with homogeneous coords [x, y, 1]
139
- """
140
- positions = []
141
- for pos in self.abc.piece_positions:
142
- # pos is (x, y) from piece_positions
143
- x, y = pos
144
- # Convert to homogeneous coordinates to align with B matrix algebra
145
- positions.append(np.array([x, y, 1.0]))
146
-
147
- self.positions = np.array(positions)
148
- return self.positions
149
-
150
- def compute_distance_matrix(self) -> np.ndarray:
151
- """
152
- Compute pairwise Euclidean distances using 2D components only.
153
-
154
- Even though positions are [x, y, 1], we compute distance using only [x, y]
155
- D[i,j] = ||[x_i, y_i] - [x_j, y_j]||₂
156
- """
157
- if self.positions is None:
158
- self.compute_piece_positions()
159
-
160
- num = len(self.positions)
161
- D = np.zeros((num, num))
162
-
163
- for i in range(num):
164
- for j in range(num):
165
- # Use only 2D coordinates for distance
166
- pos_i = self.positions[i][:2]
167
- pos_j = self.positions[j][:2]
168
- D[i, j] = np.linalg.norm(pos_i - pos_j)
169
-
170
- self.D = D
171
- return D
172
-
173
- def compute_adjacency_matrix(self) -> np.ndarray:
174
- """
175
- Compute Adjacency Matrix (Definition 6.2).
176
-
177
- A[i,j] = 1 if:
178
- - k ≤ D[i,j] ≤ K (grid-adjacent)
179
- - i == j AND i is isolated (no neighbors in [k,K])
180
-
181
- A[i,j] = 0 otherwise
182
- """
183
- if self.D is None:
184
- self.compute_distance_matrix()
185
-
186
- num = len(self.positions)
187
- A = np.zeros((num, num))
188
-
189
- # Identify isolated pieces
190
- isolated = set()
191
- for i in range(num):
192
- has_neighbor = False
193
- for j in range(num):
194
- if i != j and self.t <= self.D[i, j] <= self.T:
195
- has_neighbor = True
196
- break
197
- if not has_neighbor:
198
- isolated.add(i)
199
-
200
- # Fill adjacency matrix
201
- for i in range(num):
202
- for j in range(num):
203
- # Check adjacency distance
204
- if i != j and self.t <= self.D[i, j] <= self.T:
205
- A[i, j] = 1.0
206
- # Check if isolated piece
207
- elif i == j and i in isolated:
208
- A[i, j] = 1.0
209
-
210
- self.A = A
211
- return A
212
-
213
- def compute_spatial_matrix(self) -> np.ndarray:
214
- """
215
- Compute Spatial Matrix (Definition 6.3).
216
-
217
- S[i,j](t) = exp(-||c_i(t) - c_j(t)||² / (2σ²))
218
-
219
- Gaussian kernel based on Euclidean distance.
220
- """
221
- if self.D is None:
222
- self.compute_distance_matrix()
223
-
224
- num = len(self.positions)
225
- S = np.zeros((num, num))
226
-
227
- for i in range(num):
228
- for j in range(num):
229
- S[i, j] = np.exp(-self.D[i, j]**2 / (2 * self.sigma**2))
230
-
231
- self.S = S
232
- return S
233
-
234
- def compute_feature_matrix(self) -> np.ndarray:
235
- """
236
- Compute Feature Matrix (Definition 6.4).
237
-
238
- F[i,j](t) = <κ(B_i), κ(B_j)> / (||κ(B_i)|| · ||κ(B_j)||)
239
-
240
- Cosine similarity between tokenized vectors.
241
- """
242
- num = len(self.positions)
243
- F = np.zeros((num, num))
244
-
245
- # Extract tokenized vectors
246
- kappas = []
247
- for i in range(num):
248
- if i in self.abc.kappa:
249
- kappas.append(self.abc.kappa[i])
250
- else:
251
- # Default: use delta as feature vector
252
- if i in self.abc.delta:
253
- kappas.append(np.array(self.abc.delta[i]))
254
- else:
255
- kappas.append(np.array([1.0, 1.0, 1.0]))
256
-
257
- # Compute cosine similarity
258
- for i in range(num):
259
- for j in range(num):
260
- kappa_i = kappas[i]
261
- kappa_j = kappas[j]
262
-
263
- dot_product = np.dot(kappa_i, kappa_j)
264
- norm_i = np.linalg.norm(kappa_i)
265
- norm_j = np.linalg.norm(kappa_j)
266
-
267
- if norm_i > 0 and norm_j > 0:
268
- F[i, j] = dot_product / (norm_i * norm_j)
269
- else:
270
- F[i, j] = 0.0
271
-
272
- self.F = F
273
- return F
274
-
275
- def compute_weighted_matrix(self) -> np.ndarray:
276
- """
277
- Compute Weighted Matrix (Definition from Section 6).
278
-
279
- W[i,j](t) = A[i,j](t) ⊙ S[i,j](t) ⊙ F[i,j](t)
280
-
281
- Returns: W - the full weighted matrix
282
- """
283
- if self.A is None:
284
- self.compute_adjacency_matrix()
285
- if self.S is None:
286
- self.compute_spatial_matrix()
287
- if self.F is None:
288
- self.compute_feature_matrix()
289
-
290
- # Hadamard product (element-wise multiplication)
291
- W = self.A * self.S * self.F
292
-
293
- self.W = W
294
- return W
295
-
296
- def compute_manhattan_distance(self, other: 'WeightedMatrixABC') -> float:
297
- """
298
- Compute Manhattan distance between two weighted matrices.
299
-
300
- distance = ||W_1 - W_2||₁
301
- """
302
- if self.W is None:
303
- self.compute_weighted_matrix()
304
- if other.W is None:
305
- other.compute_weighted_matrix()
306
-
307
- W1 = self.W
308
- W2 = other.W
309
-
310
- # Pad to same size
311
- size = max(len(W1), len(W2))
312
- W1_padded = np.zeros((size, size))
313
- W2_padded = np.zeros((size, size))
314
- W1_padded[:len(W1), :len(W1)] = W1
315
- W2_padded[:len(W2), :len(W2)] = W2
316
-
317
- return np.linalg.norm(W1_padded - W2_padded, ord=1)
318
-
319
-
320
- # ============================================================================
321
- # EXAMPLE 1: Two Adjacent Pieces (matches abc_model.py format)
322
- # ============================================================================
323
-
324
- def example_1():
325
- """Two adjacent pieces - exactly like abc_model.py."""
326
- print("\n" + "="*80)
327
- print("EXAMPLE 1: Two Adjacent Pieces")
328
- print("="*80)
329
-
330
- game = ABCModelDynamic(n=2, t=1.0, T=1.41)
331
-
332
- # Add pieces exactly like abc_model.py does
333
- game.add_piece((1.0, 0.0), (1.0, 1.0, 1.0),
334
- kappa_vector=np.array([1.0, 1.0, 1.0]))
335
-
336
- game.add_piece((1.0, 1.0), (1.0, 1.1, 1.0),
337
- kappa_vector=np.array([1.0, 1.1, 1.0]))
338
-
339
- print("\nABC Model piece_positions (as stored in abc_model.py):")
340
- print(f" Piece 0: {game.piece_positions[0]} (tuple from board)")
341
- print(f" Piece 1: {game.piece_positions[1]} (tuple from board)")
342
-
343
- print("\nABC Model MB positions (homogeneous coords):")
344
- for i, move in enumerate(game.history):
345
- print(f" Piece {i}: MB_curr = {move['MB_curr']} (homogeneous)")
346
-
347
- matrix = WeightedMatrixABC(game, sigma=1.0)
348
-
349
- # Extract and convert to homogeneous coordinates
350
- positions = matrix.compute_piece_positions()
351
- print("\nConverted to homogeneous coordinates for matrix computations:")
352
- print(positions)
353
-
354
- # Distance matrix
355
- D = matrix.compute_distance_matrix()
356
- print("\n1. DISTANCE MATRIX D[i,j] (2D distance only):")
357
- print(D.round(3))
358
- print(f"\nD[0,1] = {D[0,1]:.3f} ∈ [{game.t}, {game.T}]? {game.t <= D[0,1] <= game.T} ✓")
359
-
360
- # Adjacency matrix
361
- A = matrix.compute_adjacency_matrix()
362
- print("\n2. ADJACENCY MATRIX A[i,j]:")
363
- print(A.astype(int))
364
-
365
- # Spatial matrix
366
- S = matrix.compute_spatial_matrix()
367
- print("\n3. SPATIAL MATRIX S[i,j] (Gaussian):")
368
- print(S.round(3))
369
-
370
- # Feature matrix
371
- F = matrix.compute_feature_matrix()
372
- print("\n4. FEATURE MATRIX F[i,j] (cosine similarity):")
373
- print(F.round(3))
374
-
375
- # Weighted matrix
376
- W = matrix.compute_weighted_matrix()
377
- print("\n5. WEIGHTED MATRIX W[i,j] = A ⊙ S ⊙ F:")
378
- print(W.round(3))
379
- print(f"\nW[0,1] = {A[0,1]:.0f} × {S[0,1]:.3f} × {F[0,1]:.3f} = {W[0,1]:.3f} ✓")
380
-
381
- print("\n" + "="*80)
382
-
383
-
384
- # ============================================================================
385
- # EXAMPLE 2: Three Pieces with Isolation
386
- # ============================================================================
387
-
388
- def example_2():
389
- """Three pieces with mixed adjacency."""
390
- print("\n" + "="*80)
391
- print("EXAMPLE 2: Three Pieces with Isolation")
392
- print("="*80)
393
-
394
- game = ABCModelDynamic(n=2, t=1.0, T=1.41)
395
-
396
- game.add_piece((0.0, 0.0), (1.0, 1.0, 1.0),
397
- kappa_vector=np.array([1.0, 1.0, 1.0]))
398
-
399
- game.add_piece((1.0, 0.0), (1.0, 1.0, 1.0),
400
- kappa_vector=np.array([1.0, 1.0, 1.0]))
401
-
402
- game.add_piece((3.0, 3.0), (1.0, 1.1, 1.0),
403
- kappa_vector=np.array([1.0, 1.1, 1.0]))
404
-
405
- print("\nPiece Positions (from abc_model.py storage):")
406
- for i, pos in enumerate(game.piece_positions):
407
- mb = game.history[i]['MB_curr']
408
- print(f" Piece {i}: stored={pos}, MB={mb}")
409
-
410
- matrix = WeightedMatrixABC(game, sigma=1.0)
411
-
412
- # Distance matrix
413
- D = matrix.compute_distance_matrix()
414
- print("\n1. DISTANCE MATRIX D[i,j]:")
415
- print(D.round(3))
416
- print(f"\nD[0,1] = {D[0,1]:.3f} → adjacent ✓")
417
- print(f"D[0,2] = {D[0,2]:.3f} → isolated")
418
- print(f"D[1,2] = {D[1,2]:.3f} → isolated")
419
-
420
- # Adjacency matrix
421
- A = matrix.compute_adjacency_matrix()
422
- print("\n2. ADJACENCY MATRIX A[i,j]:")
423
- print(A.astype(int))
424
- print(f"\nA[0,1] = {int(A[0,1])} (adjacent) ✓")
425
- print(f"A[2,2] = {int(A[2,2])} (isolated piece!) ✓")
426
-
427
- # Spatial matrix
428
- S = matrix.compute_spatial_matrix()
429
- print("\n3. SPATIAL MATRIX S[i,j]:")
430
- print(S.round(3))
431
-
432
- # Feature matrix
433
- F = matrix.compute_feature_matrix()
434
- print("\n4. FEATURE MATRIX F[i,j]:")
435
- print(F.round(3))
436
-
437
- # Weighted matrix
438
- W = matrix.compute_weighted_matrix()
439
- print("\n5. WEIGHTED MATRIX W[i,j] = A ⊙ S ⊙ F:")
440
- print(W.round(6))
441
- print(f"\nW[0,1] = {A[0,1]:.0f} × {S[0,1]:.3f} × {F[0,1]:.3f} = {W[0,1]:.3f} ✓")
442
- print(f"W[2,2] = {A[2,2]:.0f} × {S[2,2]:.3f} × {F[2,2]:.3f} = {W[2,2]:.3f} ✓")
443
- print(f"W[0,2] = {A[0,2]:.0f} × {S[0,2]:.6f} × {F[0,2]:.3f} = {W[0,2]:.6f} ✓")
444
-
445
- print("\n" + "="*80)
446
-
447
-
448
- if __name__ == "__main__":
449
- print("\n" + "="*80)
450
- print("WEIGHTED MATRIX IMPLEMENTATION (TRULY FINAL CORRECTED)")
451
- print("Section 6: W[i,j](t) = A[i,j] ⊙ S[i,j] ⊙ F[i,j]")
452
- print("Aligned with abc_model.py: Converts (x,y) to [x,y,1] homogeneous coords")
453
- print("="*80)
454
-
455
- example_1()
456
- example_2()
457
-
458
- print("\n" + "="*80)
459
- print("KEY ALIGNMENT WITH abc_model.py")
460
- print("="*80)
461
- print("""
462
- abc_model.py structure:
463
- - piece_positions: stored as (x, y) tuples [2D board representation]
464
- - MB_current: calculated as a_product @ c0 = [x, y, 1] [homogeneous]
465
- - These represent the SAME location on the board
466
-
467
- matrix_model.py now:
468
- - Reads piece_positions as (x, y) from abc_model
469
- - Converts to [x, y, 1] homogeneous coordinates
470
- - Computes distances using 2D components [x, y]
471
- - Applies matrix algebra correctly
472
-
473
- Result:
474
- - Pieces treated as [x, y, 1] internally
475
- - Positions (1.0, 0.0) → [1.0, 0.0, 1.0]
476
- - Positions (1.0, 1.0) → [1.0, 1.0, 1.0]
477
- - Matrix dimensions: num_pieces × num_pieces
478
- - Distance uses only 2D components
479
- - Full algebraic alignment with abc_model.py
480
- """)
481
- print("="*80 + "\n")