File size: 8,386 Bytes
2ca80ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
"""
ANALYSIS: Elastic Modulus Saturation and Distance-Aware Alternatives

Current Issue:
--------------
Cosine similarity (normalized dot product) creates directional alignment measure
but ignores magnitude/distance. In low-dimensional spaces, this causes:

1. E ≈ 1.0 for almost all nonzero vectors (direction dominates)
2. Semantic class selection stuck in high-yield band (0.90-0.98)
3. Exclusion driven entirely by strain (ε), not true substrate support
4. System behaves as "distance filter wearing alignment mask"

Example from test output:
  Vector (0.35, 0.30): E=0.9991, ε=0.8628
  Vector (0.50, 0.50): E=0.9999, ε=0.6155
  Vector (0.10, 0.10): E=0.9999, ε=1.1811

All have near-unit elastic modulus despite vastly different distances!

Why This Happens:
-----------------
Current formula: E = (cos_similarity + 1.0) / 2.0

For any vector roughly pointing toward substrate direction:
  cos(θ) ≈ 1.0 when θ ≈ 0° (regardless of distance)
  → E ≈ 1.0

This is geometrically correct for angular alignment, but semantically
incomplete: a vector 10 units away in the same direction should NOT
have the same "rigidity" as one 0.01 units away.

Proposed Alternative: Distance-Aware Elastic Modulus
----------------------------------------------------

Blend proximity and alignment using different kernel functions:

Option 1: Multiplicative Coupling
----------------------------------
E = alignment_term × proximity_term

Where:
  alignment_term = (cos_similarity + 1.0) / 2.0  # Angular alignment
  proximity_term = exp(-distance² / 2σ²)          # Gaussian proximity kernel

This creates a proper "substrate field" where:
- High E requires BOTH correct direction AND close distance
- Far vectors (even aligned) get low E → low yield strength → early fracture
- Close vectors (even slightly misaligned) get high E → survive longer

Example with σ = 0.5:

Vector          | cos_sim | distance | alignment | proximity | E (product)
----------------|---------|----------|-----------|-----------|------------
(0.95, 0.92)    | 1.000   | 0.000    | 1.000     | 1.000     | 1.000
(0.35, 0.30)    | 0.999   | 0.863    | 0.999     | 0.037     | 0.037
(0.50, 0.50)    | 0.999   | 0.615    | 0.999     | 0.286     | 0.286
(0.10, 0.10)    | 0.999   | 1.181    | 0.999     | 0.002     | 0.002

Now E genuinely reflects "grounding strength" rather than just angle!

Option 2: Harmonic Mean (Balanced)
-----------------------------------
E = 2 / (1/alignment + 1/proximity)

Properties:
- Both factors must be high for high E
- More balanced than multiplication
- Penalizes imbalance (one factor low → E low)

Option 3: Weighted Sum (Tunable)
---------------------------------
E = α·alignment + (1-α)·proximity

Where α controls the balance:
  α = 0.7 → favor alignment (original behavior)
  α = 0.5 → equal weight
  α = 0.3 → favor proximity (tight substrate binding)

Option 4: RBF Kernel (Pure Proximity)
--------------------------------------
E = exp(-distance² / 2σ²)

Extreme case: ignore direction entirely, only distance matters.
Useful when substrate represents "allowed regions" rather than directions.

Implementation Example:
-----------------------
"""

import sys

# Avoid Windows console UnicodeEncodeError for optional fancy output.
if hasattr(sys.stdout, "reconfigure"):
    try:
        sys.stdout.reconfigure(encoding="utf-8", errors="replace")
    except Exception:
        pass

import math

def compute_elastic_modulus_distance_aware(
    candidate_vector, 
    substrate_vectors,
    mode='multiplicative',
    sigma=0.5,
    alpha=0.5
):
    """
    Compute elastic modulus with distance awareness.
    
    Args:
        candidate_vector: (x, y) coordinates
        substrate_vectors: List of verified substrate (x, y) coordinates
        mode: 'multiplicative', 'harmonic', 'weighted', 'rbf'
        sigma: Gaussian kernel bandwidth (for proximity term)
        alpha: Weight for alignment in 'weighted' mode
    
    Returns:
        E: Elastic modulus in [0, 1]
    """
    if not substrate_vectors:
        return 0.5  # Default
    
    # Find nearest substrate vector
    best_alignment = -1.0
    best_distance = float('inf')
    
    for substrate in substrate_vectors:
        # Cosine similarity (alignment)
        dot_prod = candidate_vector[0] * substrate[0] + candidate_vector[1] * substrate[1]
        cand_norm = math.sqrt(candidate_vector[0] ** 2 + candidate_vector[1] ** 2)
        subs_norm = math.sqrt(substrate[0] ** 2 + substrate[1] ** 2)
        
        if cand_norm > 0 and subs_norm > 0:
            cos_sim = dot_prod / (cand_norm * subs_norm)
        else:
            cos_sim = 0.0
        
        # Euclidean distance
        dist = math.sqrt(
            (candidate_vector[0] - substrate[0]) ** 2
            + (candidate_vector[1] - substrate[1]) ** 2
        )
        
        # Track best (highest alignment, lowest distance)
        if cos_sim > best_alignment:
            best_alignment = cos_sim
            best_distance = dist
    
    # Compute terms
    alignment_term = (best_alignment + 1.0) / 2.0  # Map [-1,1] → [0,1]
    proximity_term = math.exp(-(best_distance ** 2) / (2 * (sigma ** 2)))
    
    # Combine based on mode
    if mode == 'multiplicative':
        E = alignment_term * proximity_term
    
    elif mode == 'harmonic':
        if alignment_term > 0 and proximity_term > 0:
            E = 2.0 / (1.0/alignment_term + 1.0/proximity_term)
        else:
            E = 0.0
    
    elif mode == 'weighted':
        E = alpha * alignment_term + (1 - alpha) * proximity_term
    
    elif mode == 'rbf':
        E = proximity_term  # Pure proximity
    
    else:
        raise ValueError(f"Unknown mode: {mode}")
    
    return min(1.0, max(0.0, E))


# Demonstration
print("=" * 80)
print("ELASTIC MODULUS: COSINE-ONLY vs. DISTANCE-AWARE")
print("=" * 80)

substrate = [(0.95, 0.92)]
test_vectors = [
    (0.95, 0.92, "Substrate (exact match)"),
    (0.94, 0.91, "Very close, aligned"),
    (0.50, 0.50, "Medium distance, aligned"),
    (0.35, 0.30, "Far, aligned"),
    (0.10, 0.10, "Very far, aligned"),
]

print("\nSubstrate: (0.95, 0.92)")
print("\n" + "-" * 80)
print(f"{'Vector':<20} | {'Distance':<10} | {'E (cosine)':<12} | {'E (mult.)':<12} | {'E (harm.)':<12}")
print("-" * 80)

for x, y, label in test_vectors:
    # Cosine-only (current implementation)
    dot = x * substrate[0][0] + y * substrate[0][1]
    norm_v = math.sqrt(x ** 2 + y ** 2)
    norm_s = math.sqrt(substrate[0][0] ** 2 + substrate[0][1] ** 2)
    cos_sim = dot / (norm_v * norm_s) if norm_v > 0 and norm_s > 0 else 0
    E_cosine = (cos_sim + 1.0) / 2.0
    
    # Distance
    distance = math.sqrt((x - substrate[0][0]) ** 2 + (y - substrate[0][1]) ** 2)
    
    # Distance-aware modes
    E_mult = compute_elastic_modulus_distance_aware(
        (x, y), substrate, mode='multiplicative', sigma=0.5
    )
    E_harm = compute_elastic_modulus_distance_aware(
        (x, y), substrate, mode='harmonic', sigma=0.5
    )
    
    print(f"{label:<20} | {distance:>8.4f}   | {E_cosine:>10.4f}   | {E_mult:>10.4f}   | {E_harm:>10.4f}")

print("\n" + "=" * 80)
print("ANALYSIS:")
print("=" * 80)
print("• Cosine-only: E ≈ 1.0 for all (saturated)")
print("• Multiplicative: E reflects true grounding (distance × alignment)")
print("• Harmonic: Balanced, requires both factors high")
print("\nConclusion: Distance-aware E creates meaningful semantic classes,")
print("            enabling the yield strength mechanism to work as intended.")
print("=" * 80)

"""
Configuration Recommendation:
-----------------------------

For production deployment, use multiplicative coupling with tunable σ:

config.json addition:
{
  "elastic_modulus": {
    "mode": "multiplicative",
    "sigma": 0.5,
    "comment": "Gaussian kernel bandwidth for proximity term"
  }
}

Tuning guidelines:
- Small σ (0.3): Tight substrate binding, only very close vectors get high E
- Medium σ (0.5): Balanced, moderate proximity required
- Large σ (1.0): Loose binding, distance matters less

Different σ for different semantic classes:
- Verified facts: σ = 0.3 (tight binding)
- Contextual: σ = 0.5 (moderate)
- Creative: σ = 0.8 (loose, allow exploration)

This creates a "substrate field strength" model where different regions
of semantic space have different binding characteristics.
"""