| … | … | @@ -88,6 +88,7 @@ static double recv[TOTAL], fid[TOTAL], cumw[TOTAL]; |
| 88 | 88 | static int phic[TOTAL]; |
| 89 | 89 | |
| 90 | 90 | static int ea[NEMAX], eb[NEMAX]; /* undirected edges */ |
| 91 | static unsigned char sev[NEMAX]; /* 1 = severed this generation (exogenous fragmentation) */ |
| 91 | 92 | static double ua[NEMAX], ub[NEMAX]; /* each endpoint's own willingness */ |
| 92 | 93 | static double qa[NEMAX], qb[NEMAX]; /* observed yield per unit channel */ |
| 93 | 94 | static int stub[NSTUB]; |
| … | … | @@ -116,7 +117,7 @@ static int build_graph(void) |
| 116 | 117 | } |
| 117 | 118 | |
| 118 | 119 | /* returns final mean phi; reports k, fidelity, largest-component fraction, phi in/out of it */ |
| 119 | | static double run(int evolve_k,double kfix,int shuffled,double cost, |
| 120 | static double run(int evolve_k,double kfix,int shuffled,double cost,double frag, |
| 120 | 121 | double *k_end,double *f_end,double *phi_start, |
| 121 | 122 | double *lcc_frac,double *phi_in,double *phi_out) |
| 122 | 123 | { |
| … | … | @@ -130,11 +131,15 @@ static double run(int evolve_k,double kfix,int shuffled,double cost, |
| 130 | 131 | for(int g=0;g<GEN;g++){ |
| 131 | 132 | for(int i=0;i<TOTAL;i++) phic[i]=phi(seq[i]); |
| 132 | 133 | ne=build_graph(); |
| 134 | /* EXOGENOUS FRAGMENTATION: sever a random fraction of edges, independent of cost and of |
| 135 | anyone's willingness. This is the knob that varies partitioning WITHOUT varying cost. */ |
| 136 | for(int e=0;e<ne;e++) sev[e] = (urand()<frag)?1:0; |
| 133 | 137 | for(int i=0;i<TOTAL;i++) recv[i]=0.0; |
| 134 | 138 | |
| 135 | 139 | double costg=cost; |
| 136 | 140 | for(int r=0;r<TROUND;r++){ |
| 137 | 141 | for(int e=0;e<ne;e++){ |
| 142 | if(sev[e]){ qa[e]=0; qb[e]=0; continue; } |
| 138 | 143 | int a=ea[e], b=eb[e]; |
| 139 | 144 | double gc=ua[e]*ub[e]; /* BILATERAL: both must open */ |
| 140 | 145 | double a2b=((double)phic[a]/PHIMAX)*gc; |
| … | … | @@ -198,7 +203,7 @@ static double run(int evolve_k,double kfix,int shuffled,double cost, |
| 198 | 203 | |
| 199 | 204 | /* Q5: did the effective graph actually partition? */ |
| 200 | 205 | for(int i=0;i<TOTAL;i++){ uf[i]=i; csz[i]=0; } |
| 201 | | for(int e=0;e<ne;e++) if(ua[e]*ub[e] > EPS) uni(ea[e],eb[e]); |
| 206 | for(int e=0;e<ne;e++) if(!sev[e] && ua[e]*ub[e] > EPS) uni(ea[e],eb[e]); |
| 202 | 207 | for(int i=0;i<TOTAL;i++) csz[find(i)]++; |
| 203 | 208 | int best=0,bi=0; |
| 204 | 209 | for(int i=0;i<TOTAL;i++) if(csz[i]>best){ best=csz[i]; bi=i; } |
| … | … | @@ -219,69 +224,48 @@ static double run(int evolve_k,double kfix,int shuffled,double cost, |
| 219 | 224 | |
| 220 | 225 | int main(void) |
| 221 | 226 | { |
| 222 | | unsigned long long seeds[10]; |
| 227 | unsigned long long seeds[8]; |
| 223 | 228 | seeds[0]=0x9e3779b97f4a7c15ULL; seeds[1]=0xd1b54a32d192ed03ULL; seeds[2]=0x2545f4914f6cdd1dULL; |
| 224 | | for(int i=3;i<10;i++) seeds[i]=0x9e3779b97f4a7c15ULL ^ (0x100000001b3ULL*(unsigned long long)(i+1)); |
| 225 | | int NS=10; |
| 229 | for(int i=3;i<8;i++) seeds[i]=0x9e3779b97f4a7c15ULL ^ (0x100000001b3ULL*(unsigned long long)(i+1)); |
| 230 | int NS=8; |
| 226 | 231 | |
| 227 | | printf("=== PARTITION: bilateral junctions that can CLOSE — can the network break apart\n"); |
| 228 | | printf(" and privatize catalysis with no container? ===\n"); |
| 229 | | printf(" Junction conductance g = u_a * u_b (BOTH ends must open; either can close).\n"); |
| 230 | | printf(" Willingness is NOT renormalised, so edges can vanish and the graph can fragment.\n"); |
| 231 | | printf(" A unit updates toward yield-per-unit-channel-opened; no type information anywhere.\n"); |
| 232 | | printf(" No compartments, no space, no assortment, no group selection. %d units, %d gens.\n",TOTAL,GEN); |
| 233 | | printf(" REFERENCE: ribozyme well-mixed 5.99->5.50; coupling FRESH k=0 4.69, k=1 5.36.\n\n"); |
| 232 | printf("=== PARTITION CHECK AT MATCHED PARTITIONING ===\n"); |
| 233 | printf(" The original claim -- \"partitioning and gating are anti-correlated\" -- came from a sweep\n"); |
| 234 | printf(" where MAINTENANCE COST moved both variables at once. Partitioning was never varied\n"); |
| 235 | printf(" independently. Here cost is held FIXED and the graph is fragmented EXOGENOUSLY by\n"); |
| 236 | printf(" severing a random fraction of edges, which is blind to cost, willingness and quality.\n"); |
| 237 | printf(" If gating's advantage over the shuffled control falls as fragmentation rises at CONSTANT\n"); |
| 238 | printf(" cost, the causal claim holds. If it stays flat, the original correlation was cost.\n\n"); |
| 234 | 239 | |
| 235 | | printf(" arm | mean phi (start->end of %2d) | k end | largest comp | phi in / out\n",PHIMAX); |
| 236 | | printf(" -------------------------+-----------------------------+-------+--------------+--------------\n"); |
| 237 | | |
| 238 | | double costs[]={0.0,0.10,0.20,0.30,0.40,0.50}; |
| 239 | | int NC=(int)(sizeof(costs)/sizeof(costs[0])); |
| 240 | | struct { const char*name; int ev; double kf; int sh; } arms[]={ |
| 241 | | {"k=0 public good ", 0, 0.0, 0}, |
| 242 | | {"k=1 gating ", 0, 1.0, 0}, |
| 243 | | {"k=1 SHUFFLED ", 0, 1.0, 1}, |
| 244 | | {"k free (0.10) ", 1, 0.0, 0}, |
| 245 | | }; |
| 246 | | int NA=4; |
| 247 | | double bestrise=-1e9; double bestcost=-1; int partitioned_anywhere=0; |
| 240 | double costs[]={0.00,0.10}; |
| 241 | double frags[]={0.00,0.20,0.40,0.60,0.80}; |
| 242 | int NC=2, NF=5; |
| 248 | 243 | |
| 249 | 244 | for(int c=0;c<NC;c++){ |
| 250 | | printf(" --- maintenance cost = %.2f ---\n",costs[c]); |
| 251 | | double e_k0=0,e_k1=0,e_sh=0; |
| 252 | | for(int a=0;a<NA;a++){ |
| 253 | | double S=0,E=0,K=0,F=0,Lc=0,Pi=0,Po=0; double ev[16]; |
| 245 | printf(" --- maintenance cost held at %.2f ---\n",costs[c]); |
| 246 | printf(" sever frac | k=1 gating | shuffled | largest comp | GAIN vs shuffled\n"); |
| 247 | printf(" -----------+------------+----------+--------------+-----------------\n"); |
| 248 | double g0=0,gl=0; int nrow=0; |
| 249 | for(int f=0;f<NF;f++){ |
| 250 | double eg=0,es=0,lc=0; |
| 254 | 251 | for(int s=0;s<NS;s++){ |
| 255 | | double ke,fe,ps,lf,pi,po; RNG=seeds[s]; |
| 256 | | double e=run(arms[a].ev,arms[a].kf,arms[a].sh,costs[c],&ke,&fe,&ps,&lf,&pi,&po); |
| 257 | | ev[s]=e; E+=e; S+=ps; K+=ke; F+=fe; Lc+=lf; Pi+=pi; Po+= isnan(po)?pi:po; |
| 252 | double ke,fe,ps,lf,pi,po; |
| 253 | RNG=seeds[s]; eg+=run(0,1.0,0,costs[c],frags[f],&ke,&fe,&ps,&lf,&pi,&po); lc+=lf; |
| 254 | RNG=seeds[s]; es+=run(0,1.0,1,costs[c],frags[f],&ke,&fe,&ps,&lf,&pi,&po); |
| 258 | 255 | } |
| 259 | | S/=NS;E/=NS;K/=NS;F/=NS;Lc/=NS;Pi/=NS;Po/=NS; |
| 260 | | double sd=0; for(int s=0;s<NS;s++) sd+=(ev[s]-E)*(ev[s]-E); sd=sqrt(sd/(NS-1)); |
| 261 | | printf(" %s | %.2f -> %5.2f +- %.2f | k %.3f | largest comp %5.1f%% | phi in/out %.2f/%.2f\n", |
| 262 | | arms[a].name,S,E,sd,K,100.0*Lc,Pi,Po); |
| 263 | | if(a==0) e_k0=E; if(a==1){ e_k1=E; if(Lc<0.90) partitioned_anywhere=1; |
| 264 | | if(E-S>bestrise){ bestrise=E-S; bestcost=costs[c]; } } |
| 265 | | if(a==2) e_sh=E; |
| 256 | eg/=NS;es/=NS;lc/=NS; |
| 257 | double gain=eg-es; |
| 258 | printf(" %.2f | %5.2f | %5.2f | %5.1f%% | %+.2f\n", |
| 259 | frags[f],eg,es,100.0*lc,gain); |
| 260 | if(f==0) g0=gain; |
| 261 | gl=gain; nrow++; |
| 266 | 262 | } |
| 267 | | printf(" gating gain over public good %+.2f | over shuffled %+.2f\n\n", e_k1-e_k0, e_k1-e_sh); |
| 263 | printf(" gain at 0%% severing %+.2f -> at 80%% severing %+.2f (change %+.2f)\n\n", g0, gl, gl-g0); |
| 268 | 264 | } |
| 269 | 265 | |
| 270 | | printf(" Q5 did the graph EVER partition (largest comp <90%%)? %s\n", partitioned_anywhere?"YES":"NO"); |
| 271 | | printf(" best phi change from start, k=1 arm: %+.2f at cost %.2f\n\n", bestrise, bestcost); |
| 272 | | if(!partitioned_anywhere) |
| 273 | | printf(" => THE TEST STILL DID NOT RUN. Across the whole cost sweep the effective graph stayed\n" |
| 274 | | " one giant component. Partitioning was never achieved, so nothing here speaks to\n" |
| 275 | | " whether a partitioned network could privatize catalysis. Report as an invalid\n" |
| 276 | | " experiment, NOT as a null.\n"); |
| 277 | | else if(bestrise>0.5) |
| 278 | | printf(" => phi ROSE above its random start somewhere in the sweep, in a partitioning regime.\n" |
| 279 | | " Check the shuffled control at that cost before claiming a crossing.\n"); |
| 280 | | else |
| 281 | | printf(" => HONEST NULL, AND IT IS THE THIRD. The graph does partition somewhere in the sweep,\n" |
| 282 | | " and catalysis is STILL not privatized: phi never rises above its random start.\n" |
| 283 | | " Wiring, persistence and now a partitionable bilateral network with closing costs\n" |
| 284 | | " all fail. That convergence is the result -- nothing privatizes a catalytic public\n" |
| 285 | | " good without a supplied unit of selection.\n"); |
| 266 | printf(" READ: if GAIN collapses toward zero as severing rises while cost is constant, the\n"); |
| 267 | printf(" original causal claim is supported. If GAIN is roughly flat across the severing sweep,\n"); |
| 268 | printf(" fragmentation per se does NOT destroy gating and the original anti-correlation was\n"); |
| 269 | printf(" driven by maintenance cost -- the same confound that retracted Test B's T4.\n"); |
| 286 | 270 | return 0; |
| 287 | 271 | } |