
    Ri]R                     4   d dl Zd dlmZmZmZ d dlmZmZ d dl	Z	d dl
Z
dej                  dej                  fdZdej                  dej                  fdZdZ ej                  d d	e      Z ee      Z ee      Zd
Zdej                  dej                  fdZ ee      Z ej,                  e      Zded <    ej0                  d	ed	z         Zedz   ej4                  dz  z  Ze G d d             Z G d d      Z G d d      Z	 	 	 d/dee   dedede de deee   ef   fdZ!	 	 	 	 	 	 	 	 d0de de deded ed!e d"e"d#e"de#fd$Z$d%e#ddfd&Z%e&d'k(  rEej                  jO                  d(        e	jN                  d(        e$ddd)d*d+d,d-.      Z( e%e(       yy)1    N)ListTupleCallable)	dataclassfieldxreturnc                 N    t        j                  t         j                  | z        S )u8   Analytical solution to -u'' = π² sin(πx), u(0)=u(1)=0)npsinpir   s    0/home/per/Documents/Singularity computer/ex02.pytrue_solutionr      s    66"%%!)    c                 v    t         j                  dz  t        j                  t         j                  | z        z  S )u   f(x) = π² sin(πx)   )r   r   r   r   s    r   source_termr      s&    55!8bffRUUQY'''r            x_ptsc                     t        j                  t        |       t        f      }t	        dt        dz         D ]5  }t        j
                  |t         j                  z  | z        |dd|dz
  f<   7 |S )uE   Build the basis matrix B[i,k] = sin(k π x_i), shape (N_pts, N_basis)r   N)r   zeroslenN_BASISranger   r   )r   Bks      r   basis_matrixr    $   s_    
#e*g&'A1gk" .FF1ruu9u,-!QqS&	.Hr         ?r   c                       e Zd ZU dZej
                  ed<   dZej
                  ed<   dZej
                  ed<    e	d      Z
e	ed<    e	d      Ze	ed<    e	d      Ze	ed	<   d
Ze	ed<   dZeed<   d Zy)SignalzKA candidate solution: compressed representation in basis-coefficient space.representationNu_valuesresidualinflossresidual_lossboundary_loss        solution_lossr   
generationc                 \    d| j                   dd| j                  dd| j                  ddS )Nz	Signal(L=.2ez, R=z, B=))r(   r)   r*   )selfs    r   __repr__zSignal.__repr__L   s7    499S/d.@.@-ET$J\J\]`Iaabccr   )__name__
__module____qualname____doc__r   ndarray__annotations__r%   r&   floatr(   r)   r*   r,   r-   intr2    r   r   r#   r#   @   so    UJJHbjjHbjj,D% <M5' <M5'M5Jdr   r#   c                   p    e Zd ZdZ	 	 	 ddededej                  fdZdedefd	Z	dede
fd
Zdede
fdZy)PDEVerifieruZ  
    VERIFIER (V): Computes how well a candidate satisfies the PDE.
    Cost: O(N_colloc · N_basis) — EXPENSIVE relative to generation.

    Loss = residual_loss + λ · boundary_loss

    residual_loss = ||-u'' - f||²₂  (strong-form PDE residual)
    boundary_loss = u(0)² + u(1)²   (Dirichlet BCs, automatically satisfied by basis)
    N	lambda_bclambda_solutionsolution_targetc                 p    || _         || _        || _        t        j                  t
        dz        | _        y )Nr   )r>   r?   r@   r   sumf_vals	f_sq_norm)r1   r>   r?   r@   s       r   __init__zPDEVerifier.__init__[   s/     #..	*r   signalr	   c                    |j                   }t        |z  }||_        t        t        |z  z  }| t        z
  }||_        t        j                  |dz        }|d   dz  |d   dz  z   }|| j                  |z  z   }| j                  G| j                  dkD  r8t        j                  || j                  z
  dz        }	|| j                  |	z  z  }nd}	||_        ||_        ||_        |	|_        |S )z2Compute loss for a signal. Mutates and returns it.r   r   r+   )r$   B_collocr%   laplacian_eigenvaluesrC   r&   r   meanr>   r@   r?   r)   r*   r(   r,   )
r1   rF   suu_ppr&   r)   bc_loss
total_lossr,   s
             r   verifyzPDEVerifier.verifyg   s    !! qL 0145 56>"!, A$'AbE1H$ #T^^g%==
+0D0Dq0HGGQ)=)=%=!$CDM$..>>JM,& ,r   c                    |j                   }t        j                  t        j                  |             xrV t        j                  t        j                  |             xr+ t        j
                  t        j                  |            dk  S )z+Stage 1: Is this signal structurally valid?    .A)r$   r   anyisnanisinfmaxabs)r1   rF   rL   s      r   structural_checkzPDEVerifier.structural_check   sc    !!FF288A;'' (FF288A;''(rvvay!C'	)r   c                     t         |j                  z  }t        j                  t        j                  |            dk  xr t        j
                  |      dk  S )z<Stage 2: Is the reconstructed solution physically plausible?d   2   )rI   r$   r   rW   rX   std)r1   rF   rM   s      r   semantic_checkzPDEVerifier.semantic_check   sD    v,,,rvvay!C' q	B	 r   )      Y@r+   N)r3   r4   r5   r6   r9   r   r7   rE   r#   rQ   boolrY   r^   r;   r   r   r=   r=   P   sq     !!$&*	
+
+ 
+ 	
+#V # #J)v )$ ) V    r   r=   c                   x    e Zd ZdZefdefdZddej                  de	fdZ
ded	edee	   fd
Zddee	   defdZy)SignalGeneratoru4  
    GENERATOR (G): Creates candidate solution signals cheaply.
    Cost: O(N_basis) — CHEAP.

    The "kernel" W ∈ R^{N_basis × N_basis} is a learned matrix that maps
    a random seed vector into the space of plausible solutions.

    Over generations, W evolves to produce only low-loss signals.
    n_basisc                    || _         t        j                  |      t        j                  j	                  ||      dz  z   | _        t        j                         | _        d| _	        | j
                  j                         g| _
        y )N皙?g?)rc   r   eyerandomrandnWTRUE_SIGNALcopybiastemperatureevolution_history)r1   rc   s     r   rE   zSignalGenerator.__init__   sa    299??7G#Dt#KK$$&	  59FFKKM?r   Nseedr	   c                     |6t         j                  j                  | j                        | j                  z  }| j
                  |z  | j                  z   }t        j                  |      dz  }t        |      S )u@   Generate one candidate solution from a random seed. O(N_basis²)       @r$   )	r   rg   rh   rc   rm   ri   rl   tanhr#   )r1   ro   rL   s      r   generatezSignalGenerator.generate   s_    <99??4<<043C3CCD FFTMDII% GGAJQ''r   nr-   c                    t         j                  j                  || j                        | j                  z  }g }t        |      D ]  }|dk(  r:| j                  t         j                  j                  | j                        dz  z   }n| j                  ||   z  | j                  z   }t        j                  |      dz  }|j                  t        ||              |S )u1   Generate n candidates cheaply. O(n · N_basis²).r   re   rq   )r$   r-   )r   rg   rh   rc   rm   r   rl   ri   rs   appendr#   )r1   ru   r-   seedssignalsirL   s          r   generate_batchzSignalGenerator.generate_batch   s    		4<<043C3CCq 	LAQII		 = DDFFU1X%		1
S ANN6zJK	L r   	survivorslearning_ratec                    t        |      dk(  ryt        j                  |D cg c]  }|j                   c}d      }|j	                         | _        |dt        dt        |             D ]  }	 t        j                  j                  | j                  |j                  d      d   }| j                  |z  | j
                  z   }|j                  |z
  }| xj                  |t        j                  ||      z  z  c_	        | xj
                  ||z  dz  z  c_         t        j                  j                  | j                  d      }|dkD  r| xj                  d|z  z  c_	        | xj                  d	z  c_        t        | j                  d
      | _        | j                  j!                  | j                  j	                                yc c}w # t        j                  j                  $ r Y w xY w)uM  
        FEEDBACK: Update kernel to produce signals closer to survivors.
        This is the "learning" step — the kernel compresses successful patterns.

        Strategy: Move W so that random seeds map closer to successful signals.
        We use a simple online update: W ← W + α · (s_survivor - W·seed) · seed^T
        r   N)axis   )rcond皙?fro
   g\(\?g{Gz?)r   r   rK   r$   rk   rl   minlinalglstsqri   LinAlgErrorouternormrm   rW   rn   rw   )	r1   r|   r}   sig
avg_signalseed_approxprederrorw_norms	            r   evolvezSignalGenerator.evolve   s    y>Q WWIFSc00FQO
OO%	 5c"c)n56 	5C iioodffc6H6HPToUVWX 66K'$))3D&&-E FFmbhhuk&BBBFII.44I	5  .B;FFb6k!F 	D t//6%%dffkkm4; G 99(( s   G09GG.-G.N)r   )r3   r4   r5   r6   r   r:   rE   r   r7   r#   rt   r   r{   r9   r   r;   r   r   rb   rb      sf     '. C C(RZZ (6 (  f )5V )5U )5r   rb   ry   	thresholdsurvivor_rateelite_countmax_survivorsc           
         | D cg c]  }|j                   t        d      k  s| }}|sg |fS t        |d       }t        dt	        t        j                  t        |      |z              dz
        }||   j                   }	t        ||	      }
|D cg c]  }|j                   |
k  s| }}t        |      |k  r|d| }t        |      |kD  r|d| }||
fS c c}w c c}w )ah  Kill signals with loss above threshold. Return survivors and cutoff.

    The cutoff is adaptive: it is never lower than the current threshold,
    but it is also raised to keep roughly the best `survivor_rate` fraction
    of verified candidates. This prevents selection starvation when losses
    are orders of magnitude larger than the threshold guess.
    r'   c                     | j                   S r   r(   rL   s    r   <lambda>zselect.<locals>.<lambda>  s
    QVV r   keyr   r   N)r(   r9   sortedrW   r:   mathceilr   )ry   r   r   r   r   rL   verifiedverified_sortedquantile_idxadaptive_cutoffcutoffr|   s               r   selectr      s     #<aaffuU|&;<H<9}X+;<Oq#diiO(<}(LMNQRRSL%l388OO,F+@qqvv/?@I@ 9~##L[1	 9~%n}-	f' = As   CCC(C  max_generations	pool_sizeinitial_thresholdthreshold_decaytarget_losspatiencestop_on_targetstop_on_plateauc                 
   t        t              }t        ddt              }	|}
g g g g g g g d}d}t	        d      }d}t        d	       t        d
       t        d	       t        dt         d       t        dt                t        d|        t        d| d|        t        d       t        d       t        |       D ]  }|j                  ||      }|D ]7  }|	j                  |      s|	j                  |      s'|	j                  |       9 t        ||
      \  }}|
|z  }
|j                  |d       |D cg c]  }|j                  t	        d      k  s| }}|rt        |d       }t	        t!        j"                  |D cg c]  }|j                   c}            }|j                  |k  r|j                  }|}d}n|dz  }t$        |j&                  z  }t         j(                  j+                  |t        z
        t         j(                  j+                  t              z  }nt	        d      }t	        d      }|d   j-                  |       |d   j-                  |       |d   j-                  |       |d   j-                  t/        |             |d   j-                  |       |d   j-                  |       |d   j-                  t         j(                  j+                  |j0                  d             |d z  dk(  s|d!k  r,t        d"|d#d$t/        |      d#d%|d&d'|d&d(|d&d)|d&       |r||k  rt        d*| d+| d,        n |s||k\  st        d-| d.| d/        n t        d0       t        d1       t        d	       ||j&                  }t$        |z  }t         j(                  j+                  |t        z
        t         j(                  j+                  t              z  }t!        j2                  t!        j4                  |t        z
              }t        d2|d3       t        d4|d3       t        d5|d3       t        d6dz           t!        j4                  |      d7kD  }t        d8t!        j6                  |       d9t                t        d:       t!        j8                  t!        j4                  |            ddd;   dd! }|D ]%  }|dk(  rd<nd=} t        d>|dz    d?||   d@|         ' t!        j2                  t!        j4                  |j:                              }!t        dA|!d3       ||dB<   nt        dC       ||dD<   |S c c}w c c}w )Eu   
    Solve -u'' = π² sin(πx) using the Lossy Signal Generator + Verifier.

    This is the CCT-ODE loop:
      dS/dt = G(S) - V(S)
    where G generates new candidates and V kills high-loss ones.
    )rc   r_   rS   )r>   r?   r@   )r-   	best_lossmedian_lossr   r   l2_errorkernel_fro_normNr'   r   zF======================================================================u7   CCT-ODE PDE SOLVER:  -u'' = π² sin(πx),  u(0)=u(1)=0u   Basis: sin(kπx), k=1..z    (BCs satisfied automatically)zCollocation points: zPool size/generation: zInitial threshold floor: z	, decay: u   True solution: u(x) = sin(πx)zF----------------------------------------------------------------------g333333?)r}   c                     | j                   S r   r   r   s    r   r   zsolve_pde.<locals>.<lambda>j  s
    AFF r   r   r   r-   r   r   r   r   r   r   r   r      zGen 3dz | survivors: z | best loss: r/   z | median: z | L2 err: u    | θ: u   
  ✓ CONVERGED at generation z	 (loss < r0   u   
  ⚠ Stopped at generation u    — no improvement for z genszG
======================================================================RESULTSz
  Final loss:           z.6eu     Relative L² error:    z  Max pointwise error:  z  Generations:          gMbP?z
  Active basis functions: /z  Top 5 coefficients:rH   u    ← TRUE (k=1) z    k=z: z+.6fz
  Max PDE residual:     best_signalz
  No valid signal found.	generator)rb   r   r=   u_truer9   printN_COLLOCr   r{   rY   r^   rQ   r   r   r(   r   r   medianrI   r$   r   r   rw   r   ri   rW   rX   rB   argsortr&   )"r   r   r   r   r   r   r   r   r   verifiercurrent_thresholdhistorybest_signal_everbest_loss_everstagnant_gensgenry   r   r|   used_thresholdrL   valid_signalsbestr   u_predl2_errs_bestr   	max_errorsignificanttop_idxidxmarkerresidual_maxs"                                     r   	solve_pder   "  sM   $  0IUCQWXH) G 5\NM	(O	
CD	(O	#G9,L
MN	 

+,	"9+
./	%&7%8	/AR
ST	*,	(O_% ?**9c:  	!C,,S1**3/OOC 	! %+74E$F!	>_, 	$7 %,Eqqvve/DEE}*:;D		=*Ia166*I JKKyy>)!%#'  !"  3 33FYY^^FVO4ryy~~f7MMF,K5\F 	$$S)##N3%%k2##C	N3##N3
""6*!"))"))..e*LM 8q=C!GDRs9~b.A B  .s3;{3>O P#CLs/CE F
 n{:4SE;-qQR}823%7OPXzY^_`?H 
/	)	(O#!00F"99>>&6/2RYY^^F5KKFF266&6/23	*>#*>?@)(389(389(q	23 ffVnt+,RVVK-@,A7)LM%'**RVVF^,TrT22A6 	@C*-(&FF3q5'F3K#5fX>?	@
 vvbff%5%>%>?@*<*<=>!'*+$GKN_ F +Js   U$U$U)resultsc                 	   	 ddl m} ddlm} | j                  d      }|t        d       y|j                  d      } |d	d
|dd      }|j                  |d         }t        j                  ddd      }t        |      }||z  }	t        |      }
|j                  ||
ddd       |j                  ||	ddd       |j                  d       |j                  d       |j!                  d       |j#                          |j%                  dd       |j'                  ddd| d    d!   d"|j(                  d#d$t+        d%d&d'(      )       |j                  |d*         }|	|
z
  }|j                  ||d+d,-       |j-                  ||ddd+.       |j/                  dd/d'0       |j                  d       |j                  d1       |j!                  d2t        j0                  t        j2                  |            d"d3       |j%                  dd       |j                  |d4         }t5        |5      }t7               }|j9                  |       |j:                  }|j                  t<        |d6d7-       |j/                  dd/d'0       |j                  d       |j                  d8       |j!                  d9       |j%                  dd       |j                  |d:         }| d;   }|j?                  || d<   d=d	d>       |j?                  || d?   d@dd'dAB       |j                  dC       |j                  dD       |j!                  dE       |j#                          |j%                  dd       |j                  |dF         }|j?                  || d    dGd	-       |j                  dC       |j                  dH       |j!                  dI       |j%                  dd       |j                  |dJ         }t        j@                  dtB        dz         }|jE                  ||dKdLdM       |jE                  dgdNgdOdPddQR       |j                  dS       |j                  dT       |j!                  dU       |j#                          |j%                  dd       |jG                  ddV       |jI                  dWdXdYZ       t        d[       y# t        $ r t        d       Y yw xY w)\z>
    Create a multi-panel summary plot for the PDE solve.
    r   N)GridSpecu/     (matplotlib not available — skipping plots)r   u1     (no valid best signal found — skipping plots))   r   )figsizer      gffffff?)figurehspacewspace)r   r   r   i,  zk-g      @u   True: sin(πx))	linewidthlabelzr--rq   zCCT-ODEr   zu(x)zSolution ComparisonTg333333?)alphag{Gz?ffffff?u
   L² err = r   rH   r/   	   toproundwheatg      ?)boxstyle	facecolorr   )	transformfontsizevabbox)r   r   purpleg      ?)r   )r   colorr   )r   r   ErrorzPointwise Error (max = r0   )r   r   rr   tealg333333?ResidualzPDE Residual (-u'' - f))r   r   r-   r   zb-z	Best Lossr   grayzMedian Loss)r   r   r   
GenerationLosszLoss Convergence (CCT-ODE))r   r   zr-u   Relative L² ErrorzError Convergence)r   r   	steelblueo)linefmt	markerfmtbasefmtr!   crimsonDzTrue (only k=1))r   r   r   r   zBasis index kzCoefficient s_kzSignal Spectrum (in sine basis)   zpde_cct_ode_results.png   tight)dpibbox_inchesu$     ✓ Saved: pde_cct_ode_results.png)%matplotlib.pyplotpyplotmatplotlib.gridspecr   ImportErrorr   getr   add_subplotr   linspacer    r   plot
set_xlabel
set_ylabel	set_titlelegendgridtext	transAxesdictfill_betweenaxhlinerW   rX   r#   r=   rQ   r&   x_collocsemilogyaranger   stemset_xlimsavefig)r   pltr   r   figgsax1x_fineB_fineu_pred_fineu_true_fineax2r   ax3best_signal_objr   r&   ax4gensax5ax6k_valss                         r   visualize_resultsr)    s}   '0
 [['F~AB
**X*
&C	!Qs4	=B //"T(
#C[[As#F&!F6/K'KHHV[$#=MHNHHV[%3iHHNN3NN6MM'(JJLHHTHHH
WZ(,S12--7gSA   //"T(
#C+%EHHVUHH4VUASAKKK,NN3NN7MM+BFF266%=,A#+FaHIHHTH //"T(
#CF3O}HOOO$''HHHXx3H7KKK,NN3NN:MM+,HHTH //"T(
#C< DLLw{+TQkLRLL   NN< NN6MM./JJLHHTH //"T(
#CLLwz*DAL>NN< NN'(MM%&HHTH //"T(
#CYYq'A+&FHHVV[CHNHH	
	   NN?#NN$%MM34JJLHHTHLLBKK)sKH	
01U  ?@s   S S"!S"__main__*   g      @gQ?g|=(   F)r   r   r   r   r   r   r   )r   r   r   )r   r   g      $@r   g:0yE>r   TT))numpyr   typingr   r   r   dataclassesr   r   rg   r   r7   r   r   r   r  r  rC   r   r   r    rI   r   rj   r  	k_indicesr   rJ   r#   r=   rb   r9   r:   r   r`   r  r   r)  r3   ro   r   r;   r   r   <module>r1     ss    ( ( (  RZZ BJJ (2:: ("** (
 2;;q!X&x " 

 rzz  ! bhhwA BIIa1%	#Q,255!84  d d dG  G T]5 ]5N  !&\!! ! 	!
 ! 4<!J  #! UUU U 	U
 U U U U 
Upq2t q2 q2p zIINN2FKKOG g r   