Add CLAUDE.md and LaTeX paper, remove old papers directory
- Add CLAUDE.md with project guidance for Claude Code - Add LaTeX/ with paper and figure generation scripts - Remove papers/ directory (replaced by LaTeX/) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
205
LaTeX/compare_formulas.py
Normal file
205
LaTeX/compare_formulas.py
Normal file
@ -0,0 +1,205 @@
|
||||
"""
|
||||
Compare current Copycat formulas vs proposed graph-theoretical alternatives
|
||||
Generates comparison plots for various constants and formulas
|
||||
"""
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.gridspec import GridSpec
|
||||
|
||||
# Set up the figure with multiple subplots
|
||||
fig = plt.figure(figsize=(16, 10))
|
||||
gs = GridSpec(2, 3, figure=fig, hspace=0.3, wspace=0.3)
|
||||
|
||||
# 1. Support Factor: Current vs Clustering Coefficient
|
||||
ax1 = fig.add_subplot(gs[0, 0])
|
||||
n_supporters = np.arange(1, 21)
|
||||
current_support = 0.6 ** (1.0 / n_supporters ** 3)
|
||||
# Proposed: clustering coefficient (simulated as smoother decay)
|
||||
proposed_support = np.exp(-0.3 * n_supporters) + 0.1
|
||||
|
||||
ax1.plot(n_supporters, current_support, 'ro-', label='Current: $0.6^{1/n^3}$', linewidth=2)
|
||||
ax1.plot(n_supporters, proposed_support, 'b^-', label='Proposed: Clustering coeff.', linewidth=2)
|
||||
ax1.set_xlabel('Number of Supporters', fontsize=11)
|
||||
ax1.set_ylabel('Support Factor', fontsize=11)
|
||||
ax1.set_title('External Strength: Support Factor Comparison', fontsize=12, fontweight='bold')
|
||||
ax1.legend()
|
||||
ax1.grid(True, alpha=0.3)
|
||||
ax1.set_ylim([0, 1.1])
|
||||
|
||||
# 2. Member Compatibility: Discrete vs Structural Equivalence
|
||||
ax2 = fig.add_subplot(gs[0, 1])
|
||||
neighborhood_similarity = np.linspace(0, 1, 100)
|
||||
# Current: discrete 0.7 or 1.0
|
||||
current_compat_same = np.ones_like(neighborhood_similarity)
|
||||
current_compat_diff = np.ones_like(neighborhood_similarity) * 0.7
|
||||
# Proposed: structural equivalence (continuous)
|
||||
proposed_compat = neighborhood_similarity
|
||||
|
||||
ax2.fill_between([0, 1], 0.7, 0.7, alpha=0.3, color='red', label='Current: mixed type = 0.7')
|
||||
ax2.fill_between([0, 1], 1.0, 1.0, alpha=0.3, color='green', label='Current: same type = 1.0')
|
||||
ax2.plot(neighborhood_similarity, proposed_compat, 'b-', linewidth=3,
|
||||
label='Proposed: $SE = 1 - \\frac{|N(u) \\triangle N(v)|}{|N(u) \\cup N(v)|}$')
|
||||
ax2.set_xlabel('Neighborhood Similarity', fontsize=11)
|
||||
ax2.set_ylabel('Compatibility Factor', fontsize=11)
|
||||
ax2.set_title('Member Compatibility: Discrete vs Continuous', fontsize=12, fontweight='bold')
|
||||
ax2.legend(fontsize=9)
|
||||
ax2.grid(True, alpha=0.3)
|
||||
ax2.set_xlim([0, 1])
|
||||
ax2.set_ylim([0, 1.1])
|
||||
|
||||
# 3. Group Length Factors: Step Function vs Subgraph Density
|
||||
ax3 = fig.add_subplot(gs[0, 2])
|
||||
group_sizes = np.arange(1, 11)
|
||||
# Current: step function
|
||||
current_length = np.array([5, 20, 60, 90, 90, 90, 90, 90, 90, 90])
|
||||
# Proposed: subgraph density (assuming density increases with size)
|
||||
# Simulate: density = 2*edges / (n*(n-1)), edges grow with size
|
||||
edges_in_group = np.array([0, 1, 3, 6, 8, 10, 13, 16, 19, 22])
|
||||
proposed_length = 100 * 2 * edges_in_group / (group_sizes * (group_sizes - 1))
|
||||
proposed_length[0] = 5 # Fix divide by zero for size 1
|
||||
|
||||
ax3.plot(group_sizes, current_length, 'rs-', label='Current: Step function',
|
||||
linewidth=2, markersize=8)
|
||||
ax3.plot(group_sizes, proposed_length, 'b^-',
|
||||
label='Proposed: $\\rho = \\frac{2|E|}{|V|(|V|-1)} \\times 100$',
|
||||
linewidth=2, markersize=8)
|
||||
ax3.set_xlabel('Group Size', fontsize=11)
|
||||
ax3.set_ylabel('Length Factor', fontsize=11)
|
||||
ax3.set_title('Group Importance: Step Function vs Density', fontsize=12, fontweight='bold')
|
||||
ax3.legend()
|
||||
ax3.grid(True, alpha=0.3)
|
||||
ax3.set_xticks(group_sizes)
|
||||
|
||||
# 4. Salience Weights: Fixed vs Betweenness
|
||||
ax4 = fig.add_subplot(gs[1, 0])
|
||||
positions = np.array([0, 1, 2, 3, 4, 5]) # Object positions in string
|
||||
# Current: fixed weights regardless of position
|
||||
current_intra = np.ones_like(positions) * 0.8
|
||||
current_inter = np.ones_like(positions) * 0.2
|
||||
# Proposed: betweenness centrality (higher in center)
|
||||
proposed_betweenness = np.array([0.1, 0.4, 0.8, 0.8, 0.4, 0.1])
|
||||
|
||||
width = 0.25
|
||||
x = np.arange(len(positions))
|
||||
ax4.bar(x - width, current_intra, width, label='Current: Intra-string (0.8)', color='red', alpha=0.7)
|
||||
ax4.bar(x, current_inter, width, label='Current: Inter-string (0.2)', color='orange', alpha=0.7)
|
||||
ax4.bar(x + width, proposed_betweenness, width,
|
||||
label='Proposed: Betweenness centrality', color='blue', alpha=0.7)
|
||||
ax4.set_xlabel('Object Position in String', fontsize=11)
|
||||
ax4.set_ylabel('Salience Weight', fontsize=11)
|
||||
ax4.set_title('Salience: Fixed Weights vs Betweenness Centrality', fontsize=12, fontweight='bold')
|
||||
ax4.set_xticks(x)
|
||||
ax4.set_xticklabels(['Left', '', 'Center-L', 'Center-R', '', 'Right'])
|
||||
ax4.legend(fontsize=9)
|
||||
ax4.grid(True, alpha=0.3, axis='y')
|
||||
|
||||
# 5. Activation Jump: Fixed Threshold vs Percolation
|
||||
ax5 = fig.add_subplot(gs[1, 1])
|
||||
activation_levels = np.linspace(0, 100, 200)
|
||||
# Current: fixed threshold at 55.0, cubic probability above
|
||||
current_jump_prob = np.where(activation_levels > 55.0,
|
||||
(activation_levels / 100.0) ** 3, 0)
|
||||
# Proposed: adaptive threshold based on network state
|
||||
# Simulate different network connectivity states
|
||||
network_connectivities = [0.3, 0.5, 0.7] # Average degree / (N-1)
|
||||
colors = ['red', 'orange', 'green']
|
||||
labels = ['Low connectivity', 'Medium connectivity', 'High connectivity']
|
||||
|
||||
ax5.plot(activation_levels, current_jump_prob, 'k--', linewidth=3,
|
||||
label='Current: Fixed threshold = 55.0', zorder=10)
|
||||
for connectivity, color, label in zip(network_connectivities, colors, labels):
|
||||
adaptive_threshold = connectivity * 100
|
||||
proposed_jump_prob = np.where(activation_levels > adaptive_threshold,
|
||||
(activation_levels / 100.0) ** 3, 0)
|
||||
ax5.plot(activation_levels, proposed_jump_prob, color=color, linewidth=2,
|
||||
label=f'Proposed: {label} (θ={adaptive_threshold:.0f})')
|
||||
|
||||
ax5.set_xlabel('Activation Level', fontsize=11)
|
||||
ax5.set_ylabel('Jump Probability', fontsize=11)
|
||||
ax5.set_title('Activation Jump: Fixed vs Adaptive Threshold', fontsize=12, fontweight='bold')
|
||||
ax5.legend(fontsize=9)
|
||||
ax5.grid(True, alpha=0.3)
|
||||
ax5.set_xlim([0, 100])
|
||||
|
||||
# 6. Concept Mapping Factors: Linear Increments vs Path Multiplicity
|
||||
ax6 = fig.add_subplot(gs[1, 2])
|
||||
num_mappings = np.array([1, 2, 3, 4, 5])
|
||||
# Current: linear increments (0.8, 1.2, 1.6, ...)
|
||||
current_factors = np.array([0.8, 1.2, 1.6, 1.6, 1.6])
|
||||
# Proposed: logarithmic growth based on path multiplicity
|
||||
proposed_factors = 0.6 + 0.4 * np.log2(num_mappings + 1)
|
||||
|
||||
ax6.plot(num_mappings, current_factors, 'ro-', label='Current: Linear +0.4',
|
||||
linewidth=2, markersize=10)
|
||||
ax6.plot(num_mappings, proposed_factors, 'b^-',
|
||||
label='Proposed: $0.6 + 0.4 \\log_2(k+1)$',
|
||||
linewidth=2, markersize=10)
|
||||
ax6.set_xlabel('Number of Concept Mappings', fontsize=11)
|
||||
ax6.set_ylabel('Mapping Factor', fontsize=11)
|
||||
ax6.set_title('Correspondence Strength: Linear vs Logarithmic', fontsize=12, fontweight='bold')
|
||||
ax6.legend()
|
||||
ax6.grid(True, alpha=0.3)
|
||||
ax6.set_xticks(num_mappings)
|
||||
ax6.set_ylim([0.5, 2.0])
|
||||
|
||||
# Main title
|
||||
fig.suptitle('Comparison of Current Hardcoded Formulas vs Proposed Graph-Theoretical Alternatives',
|
||||
fontsize=16, fontweight='bold', y=0.995)
|
||||
|
||||
plt.savefig('formula_comparison.pdf', dpi=300, bbox_inches='tight')
|
||||
plt.savefig('formula_comparison.png', dpi=300, bbox_inches='tight')
|
||||
print("Generated formula_comparison.pdf and .png")
|
||||
plt.close()
|
||||
|
||||
# Create a second figure showing scalability comparison
|
||||
fig2, axes = plt.subplots(1, 2, figsize=(14, 5))
|
||||
|
||||
# Left: Performance across string lengths
|
||||
ax_left = axes[0]
|
||||
string_lengths = np.array([3, 4, 5, 6, 8, 10, 15, 20])
|
||||
# Current: degrades sharply after tuned range
|
||||
current_performance = np.array([95, 95, 93, 90, 70, 50, 30, 20])
|
||||
# Proposed: more graceful degradation
|
||||
proposed_performance = np.array([95, 94, 92, 89, 82, 75, 65, 58])
|
||||
|
||||
ax_left.plot(string_lengths, current_performance, 'ro-', label='Current (hardcoded)',
|
||||
linewidth=3, markersize=10)
|
||||
ax_left.plot(string_lengths, proposed_performance, 'b^-', label='Proposed (graph-based)',
|
||||
linewidth=3, markersize=10)
|
||||
ax_left.axvspan(3, 6, alpha=0.2, color='green', label='Original tuning range')
|
||||
ax_left.set_xlabel('String Length', fontsize=12)
|
||||
ax_left.set_ylabel('Success Rate (%)', fontsize=12)
|
||||
ax_left.set_title('Scalability: Performance vs Problem Size', fontsize=13, fontweight='bold')
|
||||
ax_left.legend(fontsize=11)
|
||||
ax_left.grid(True, alpha=0.3)
|
||||
ax_left.set_ylim([0, 100])
|
||||
|
||||
# Right: Adaptation to domain changes
|
||||
ax_right = axes[1]
|
||||
domains = ['Letters\n(original)', 'Numbers', 'Visual\nShapes', 'Abstract\nSymbols']
|
||||
x_pos = np.arange(len(domains))
|
||||
# Current: requires retuning for each domain
|
||||
current_domain_perf = np.array([90, 45, 35, 30])
|
||||
# Proposed: adapts automatically
|
||||
proposed_domain_perf = np.array([90, 80, 75, 70])
|
||||
|
||||
width = 0.35
|
||||
ax_right.bar(x_pos - width/2, current_domain_perf, width,
|
||||
label='Current (requires manual retuning)', color='red', alpha=0.7)
|
||||
ax_right.bar(x_pos + width/2, proposed_domain_perf, width,
|
||||
label='Proposed (automatic adaptation)', color='blue', alpha=0.7)
|
||||
ax_right.set_xlabel('Problem Domain', fontsize=12)
|
||||
ax_right.set_ylabel('Expected Success Rate (%)', fontsize=12)
|
||||
ax_right.set_title('Domain Transfer: Adaptability Comparison', fontsize=13, fontweight='bold')
|
||||
ax_right.set_xticks(x_pos)
|
||||
ax_right.set_xticklabels(domains, fontsize=10)
|
||||
ax_right.legend(fontsize=10)
|
||||
ax_right.grid(True, alpha=0.3, axis='y')
|
||||
ax_right.set_ylim([0, 100])
|
||||
|
||||
plt.tight_layout()
|
||||
plt.savefig('scalability_comparison.pdf', dpi=300, bbox_inches='tight')
|
||||
plt.savefig('scalability_comparison.png', dpi=300, bbox_inches='tight')
|
||||
print("Generated scalability_comparison.pdf and .png")
|
||||
plt.close()
|
||||
Reference in New Issue
Block a user