DSQSS  1.1
dla_alg.cc
説明を見る。
00001 
00002 #include "dla_alg.h"
00003 
00004 //######################################################################
00005 
00006 int main(int argc, char** argv) {
00007 
00008   HFILE = "hamiltonian.xml"; 
00009   AFILE = "algorithm.xml"; 
00010   if ( argc > 1 ) { HFILE = argv[1]; }
00011   if ( argc > 2 ) { AFILE = argv[2]; }
00012   printf("HFILE= %s\n", HFILE);
00013   printf("AFILE= %s\n", AFILE);
00014 
00015   // t@C XML IuWFNgɓǂݍ
00016 
00017   XML::Block X(HFILE,"Hamiltonian");
00018   FALG = fopen(AFILE,"w");
00019 //FALG = stdout;
00020 
00021   XML::Block& XGEN = X["General"];
00022   GENERAL G(XGEN);
00023   Site        = new SITE[NSTYPE];
00024   Source      = new SOURCE[NSTYPE];
00025   Interaction = new INTERACTION[NITYPE];
00026   Vertex      = new VERTEX[NVTYPE];
00027 
00028   // eIuWFNg̃Zbg
00029 
00030   for (int i=0; i<X.NumberOfBlocks(); i++) {
00031     XML::Block& B = X[i];
00032     const string& name = B.getName();
00033     if ( name == "Site" ) { 
00034       int id = B["STYPE"].getInteger();
00035       Site[id].load(B);
00036       //      Site[id].dump();
00037     }
00038     else if ( name == "Source" ) { 
00039       int id = B["TTYPE"].getInteger();
00040       Source[id].load(B);
00041       //      Source[id].dump();
00042       //      Vertex[Source[id].VTYPE].dump();
00043     }
00044     else if ( name == "Interaction" ) { 
00045       int id = B["ITYPE"].getInteger();
00046       Interaction[id].load(B);
00047       //      Interaction[id].dump();
00048       //      Vertex[Interaction[id].VTYPE].dump();
00049     }
00050   }
00051 
00052   // Um̌vZ
00053 
00054   for (int i=0; i<NVTYPE; i++) {
00055     Vertex[i].Grouping();
00056   }
00057   // [̐łɑΉo[ebNXł͋ʂ EBASE gD
00058   G.WeightDiagonal = -INF;
00059 
00060   for (int i=0; i<NSTYPE; i++) {
00061     VERTEX& V = Site[i].V();
00062     double eb = V.ComputeEBASE();
00063     if ( G.WeightDiagonal < 0.5 * eb ) G.WeightDiagonal = 0.5 * eb;
00064   }
00065 
00066   for (int i=0; i<NSTYPE; i++) {
00067     VERTEX& V = Site[i].V();
00068     V.EBASE = 2.0 * G.WeightDiagonal;
00069   }
00070 
00071   // ݍpɑΉo[ebNXł͂ꂼ•ʂ EBASE gD
00072 
00073   for (int i=0; i<NITYPE; i++) {
00074     VERTEX& V = Interaction[i].V();
00075     V.EBASE = V.ComputeEBASE();
00076   }
00077 
00078   for (int i=0; i<NVTYPE; i++) Vertex[i].ComputeScatteringProbability();
00079 
00080   for (int i=0; i<NSTYPE; i++) {
00081     Site[i].SetInitialHeadTypeProbability();
00082   }
00083 
00084   for (int i=0; i<NITYPE; i++) {
00085     Interaction[i].SetVertexDensity();
00086   }
00087 
00088   // t@Cւ̏o
00089 
00090   fprintf(FALG,"<Algorithm>\n");
00091   G.write();
00092   for (int i=0; i<NSTYPE; i++) Site[i].write();
00093   for (int i=0; i<NITYPE; i++) Interaction[i].write();
00094   for (int i=0; i<NVTYPE; i++) Vertex[i].write();
00095   fprintf(FALG,"\n</Algorithm>\n");
00096 
00097   delete [] Site;
00098   delete [] Source;
00099   delete [] Interaction;
00100   delete [] Vertex;
00101 
00102 }
00103 
00104 //######################################################################
00105 
00106 GENERAL::GENERAL(XML::Block& X) {
00107 
00108   NHTYPE = 0;
00109   NXMAX = 0;
00110 
00111   comment = X["Comment"].getJoinedString();
00112   NSTYPE = X["NSTYPE"].getInteger();
00113   NITYPE = X["NITYPE"].getInteger();
00114   NXMAX  = X["NXMAX" ].getInteger();
00115   NVTYPE = NSTYPE + NITYPE;
00116 
00117 }
00118 
00119 //======================================================================
00120 
00121 void GENERAL::write() {
00122   fprintf( FALG, "\n");
00123   fprintf( FALG, "  <Comment>\n");
00124   fprintf( FALG, "    %s\n", comment.c_str() );
00125   fprintf( FALG, "  </Comment>\n");
00126   fprintf( FALG, "\n");
00127   fprintf( FALG, "  <General>\n");
00128   fprintf( FALG, "    <NSTYPE> %2d </NSTYPE>\n", NSTYPE);
00129   fprintf( FALG, "    <NITYPE> %2d </NITYPE>\n", NITYPE);
00130   fprintf( FALG, "    <NVTYPE> %2d </NVTYPE>\n", NVTYPE);
00131   fprintf( FALG, "    <NXMAX>  %2d </NXMAX>\n",  NXMAX );
00132   fprintf( FALG, "    <WDIAG>  %24.16f </WDIAG>\n",  WeightDiagonal );
00133   fprintf( FALG, "  </General>\n");
00134 }
00135 
00136 //######################################################################
00137 
00138 void SITE::load(XML::Block& X) {
00139   ID    = X["STYPE"].getInteger();
00140   TTYPE = X["TTYPE"].getInteger();
00141   NX    = X["NX"].getInteger();
00142   _T = &Source[TTYPE];
00143 }
00144 
00145 //======================================================================
00146 
00147 void SITE::SetInitialHeadTypeProbability() {
00148   VTYPE = Source[TTYPE].VTYPE;
00149 // WormCreationNewState( xi, ch)  
00150 // "xi". .. the initial local state
00151 // "ch" ... the scattering channel id
00152   WormCreationNewState.init(2,NXMAX,2*NXMAX); 
00153   WormCreationNewState.set_all(STATE::UNDEF);
00154   WormCreationDirection.init(2,NXMAX,2*NXMAX);
00155   WormCreationDirection.set_all(DIR::UNDEF);
00156   WormCreationProbability.init(2,NXMAX,2*NXMAX);
00157   WormCreationProbability.set_all(0.0);
00158   NumberOfChannels = new int[NX];
00159   VERTEX& V = Vertex[VTYPE];
00160   for ( int i=0; i<V.NICG; i++ ) {
00161     InitialConfigurationGroup& icg = V.ICG(i);
00162     for ( int j=0; j<icg.NIC; j++ ) {
00163       InitialConfiguration& ic = icg.IC[j];
00164       if ( ic.INC == DIR::UNDEF ) {
00165         int x0 = ic.State[0];
00166         int NCH = ic.NCH;
00167         NumberOfChannels[x0] = NCH;
00168         for (int c=0; c<NCH; c++) {
00169           int st = ic.FinalState[c];
00170           int out = ic.FinalDirection[c];
00171           double p = ic.ScatteringProbability[c];
00172           WormCreationNewState(x0,c) = st;
00173           WormCreationDirection(x0,c) = out;
00174           WormCreationProbability(x0,c) = p;
00175         }
00176       }
00177     }
00178   }
00179 }
00180 
00181 //======================================================================
00182 
00183 void SITE::write() {
00184   fprintf(FALG,"\n");
00185   fprintf(FALG,"  <Site>\n");
00186   fprintf(FALG,"    <STYPE> %d </STYPE>\n", ID);
00187   fprintf(FALG,"    <NumberOfStates> %d </NumberOfStates>\n", NX);
00188   fprintf(FALG,"    <VertexTypeOfSource> %d </VertexTypeOfSource>\n", VTYPE);
00189   //printf("    <EBASE> %24.16f </EBASE>\n", V().EBASE );
00190   //fprintf(FALG,"    <EBASE> %24.16f </EBASE>\n", V().EBASE );
00191   for (int x0=0; x0<NX; x0++) {
00192     fprintf(FALG,"    <InitialConfiguration>\n");
00193     fprintf(FALG,"      <State> %d </State>\n", x0);
00194     int NCH = NumberOfChannels[x0];
00195     fprintf(FALG,"      <NumberOfChannels> %d </NumberOfChannels>\n", NCH);
00196     for (int c=0; c<NCH; c++) {
00197       int diri = WormCreationDirection( x0, c);
00198       int xnew = WormCreationNewState( x0, c);
00199       double p = WormCreationProbability( x0, c);
00200       if ( p == 0.0 ) continue;
00201       fprintf(FALG,"      <Channel> %4d %4d %24.16f </Channel>\n", diri, xnew, p );
00202     }
00203     fprintf(FALG,"    </InitialConfiguration>\n");
00204   }
00205   fprintf(FALG,"  </Site>\n");
00206 }
00207 
00208 //======================================================================
00209 
00210 void SITE::dump() {
00211   printf("\n");
00212   printf("SITE[%d]> tt=%2d, NX=%2d\n", ID, TTYPE, NX);
00213   if ( NumberOfChannels == 0 ) {
00214     printf(" ... Channels have not been defined yet.\n");
00215   } else {
00216     for (int x=0; x<NX; x++) {
00217       printf("  x=%2d : ", x);
00218       int NCH = NumberOfChannels[x];
00219       printf("  NCH= %d\n", NCH);
00220       for (int c=0; c<NCH; c++) {
00221         printf("   %2d %2d %8.3f\n", 
00222           WormCreationDirection(x,c), 
00223           WormCreationNewState(x,c), 
00224           WormCreationProbability(x,c));
00225       }
00226     }
00227   }
00228 }
00229 
00230 //######################################################################
00231 
00232 void SOURCE::load(XML::Block& X) {
00233   ID    = X["TTYPE"].getInteger();
00234   VTYPE = ID;
00235   VERTEX& V = Vertex[VTYPE];
00236   _V = &V;
00237   V.ID = VTYPE;
00238   V.NBODY = 1;
00239   V.CATEGORY = VCAT::WORM;
00240   V.load(X);
00241 }
00242 
00243 //======================================================================
00244 
00245 void SOURCE::dump() {
00246   printf("SOURCE[%d]> vt=%2d\n", ID, VTYPE);
00247 }
00248 
00249 //######################################################################
00250 
00251 void INTERACTION::load(XML::Block& X) {
00252   ID    = X["ITYPE"].getInteger();
00253   VTYPE = ID + NSTYPE;
00254   _V = &(Vertex[VTYPE]);
00255   NBODY = X["NBODY"].getInteger();
00256   V().ID = VTYPE;
00257   V().NBODY = NBODY;
00258   V().CATEGORY = VCAT::INT;
00259   V().load(X);
00260 }
00261 
00262 //======================================================================
00263 
00264 void INTERACTION::SetVertexDensity() {
00265   VERTEX& V = Vertex[VTYPE];
00266   IndexSystem& I = V.Weight.index_system();
00267   int* x = new int[I.dimension()]; //edit sakakura
00268 //  int x[I.dimension()];
00269   VertexDensity.init( NBODY , NXMAX , ARRAY::EOL );
00270   IndexSystem& J = VertexDensity.index_system();
00271 //  int y[J.dimension()];
00272   int* y = new int[J.dimension()]; //edit sakakura
00273   VertexDensity.set_all(0.0);
00274   for ( int g=0; g<V.NICG; g++ ) {
00275     InitialConfigurationGroup& G = V.ICG(g);
00276     for ( int c=0; c<G.NIC; c++ ) {
00277       InitialConfiguration& C = G.IC[c];
00278       if ( ! C.isKink() ) {
00279         int sti = C.STI;
00280         double w = C.vertex_weight();
00281         I.coord(sti,x);
00282         for (int i=0; i<NBODY; i++) y[i] = x[2*i];
00283         VertexDensity(y) = w;
00284       }
00285     }
00286   }
00287   delete []x;
00288   delete []y;
00289 }
00290 
00291 //======================================================================
00292 
00293 void INTERACTION::write() {
00294   fprintf(FALG,"\n");
00295   fprintf(FALG,"  <Interaction>\n");
00296   fprintf(FALG,"    <ITYPE> %d </ITYPE>\n", ID);
00297   fprintf(FALG,"    <VTYPE> %d </VTYPE>\n", VTYPE);
00298   fprintf(FALG,"    <NBODY> %d </NBODY>\n", NBODY);
00299   fprintf(FALG,"    <EBASE> %24.16f </EBASE>\n", V().EBASE );
00300   if ( VertexDensity.isDefined() ) {
00301     IndexSystem& I = VertexDensity.index_system();
00302 //    int x[NBODY];
00303     int* x = new int[NBODY]; //edit sakakura
00304     for (int i=0; i<I.size(); i++) {
00305       double d = VertexDensity[i];
00306       if ( d > 0.0 ) {
00307         I.coord( i, x);
00308         fprintf(FALG,"    <VertexDensity> ");
00309         for (int j=0; j<NBODY; j++) fprintf(FALG," %2d", x[j]);
00310         fprintf(FALG," %24.16f </VertexDensity>\n", d);
00311       }
00312     }
00313     delete []x;
00314   } else {
00315 //  fprintf(FALG,"  VertexDensity is not defined.\n");
00316   }
00317   fprintf(FALG,"  </Interaction>\n");
00318 }
00319 
00320 //======================================================================
00321 
00322 void INTERACTION::dump() {
00323   printf("INTERACTION[%d] ", ID);
00324   printf(", vt=%2d", VTYPE);
00325   printf(", nb=%2d", NBODY);
00326   printf("\n");
00327   if ( VertexDensity.isDefined() ) {
00328     IndexSystem& I = VertexDensity.index_system();
00329 //    int x[NBODY];
00330     int* x = new int[NBODY]; //edit sakakura
00331     for (int i=0; i<I.size(); i++) {
00332       if ( VertexDensity[i] > 0.0 ) {
00333         I.coord( i, x);
00334         printf(" x= (");
00335         for (int j=0; j<I.dimension(); j++) printf(" %1d", x[j]);
00336         printf(")");
00337         printf(" density= %8.3f\n", VertexDensity[i]);
00338         printf("\n");
00339       }
00340     }
00341     delete []x;
00342   } else {
00343     printf("  VertexDensity is not defined.\n");
00344   }
00345 }
00346 
00347 //######################################################################
00348 
00349 void VERTEX::load(XML::Block& X) {
00350   NLEG = 2 * NBODY;
00351   Weight.init("Weight",NLEG,NXMAX,ARRAY::EOL);
00352   setINDX(Weight.index_system());
00353   Weight.set_all(0.0);
00354   NST = Weight.size();
00355   SiteTypeOfLeg.init("STYPE",1,NLEG);
00356   SiteTypeOfLeg.set_all(STYPE::UNDEF);
00357   for (int i=0; i<NBODY; i++) {
00358     int st = X["STYPE"].getInteger(i);
00359     SiteTypeOfLeg[2*i]   = st;
00360     SiteTypeOfLeg[2*i+1] = st;
00361   }
00362   int*  x = new int [NLEG];
00363   for (int i=0; i<X.NumberOfBlocks(); i++) {
00364     XML::Block& B = X[i];
00365     const string& name = B.getName();
00366     if ( name == "Weight" ) {
00367       for (int i=0; i<NLEG; i++) x[i] = B.getInteger(i);
00368       Weight(x) = B.getDouble(NLEG);
00369     }
00370   }
00371   EBASE = 0.0;
00372   delete [] x;
00373 }
00374 
00375 //======================================================================
00376 
00377 int VERTEX::NumberOfValidInitialConfigurations() {
00378   int c = 0;
00379   for (int i=0; i<NICG; i++) {
00380     int n = ICG(i).NumberOfValidInitialConfigurations();
00381     c += n;
00382   }
00383   return c;
00384 }
00385 
00386 //======================================================================
00387 
00388 void VERTEX::Grouping() {
00389 
00390 //printf("VERTEX::Grouping> Start ID=%d\n", ID);
00391 //printf("VERTEX::Grouping> Start.\n");
00392 //printf("VERTEX::Grouping> Pass 1\n");
00393 
00394   int NICmax = 2 * NBODY * NXMAX + 1;
00395 //ICG.init( 1, (NST+1)*NXMAX ); // 傫߂ɂƂĂD
00396   checked.init( 3, NST, NLEG , NXMAX );
00397   checked.set_all(0);
00398   int* x = new int[NLEG];
00399 //  int x[NLEG];
00400   NICG = 0;
00401   if ( isWorm() ) {
00402     for (int sti=0; sti<NST; sti++) {
00403       if ( testForbidden(sti) ) continue;
00404       if ( testKink(sti) ) continue;
00405       int inc = DIR::UNDEF;
00406       int xinc = STATE::UNDEF;
00407       InitialConfigurationGroup& icg = *(new InitialConfigurationGroup);
00408       icg.init(*this, NBODY , sti, inc, xinc);
00409       add_ICG( icg );
00410 //printf("VERTEX::Grouping> New initial configuration group. ID= %d\n", NICG);
00411       NICG++;
00412     }
00413   } else {
00414 
00415     for (int sti=0; sti<NST; sti++) {
00416       INDX().coord(sti,x);
00417       if ( testForbidden(sti) ) continue;
00418       for (int inc=0; inc<NLEG; inc++) {
00419         int xinc_old = x[inc];
00420         int st = SiteTypeOfLeg[inc];
00421         SOURCE& W = Source[Site[st].TTYPE];
00422         for (int xinc=0; xinc<NXMAX; xinc++) {
00423 //W.V().Weight.index_system().dump();
00424           double ww = W.Weight( xinc_old , xinc );
00425           /*
00426 printf(" sti= %d =(", sti);
00427 for (int i=0; i<NLEG; i++) printf(" %d", x[i]);
00428 printf("), inc= %d, xinc= %d --> %d, ww= %8.3f\n", inc, xinc_old, xinc, ww);
00429           */
00430           if ( ww == 0.0 ) continue;
00431           if ( checked( sti, inc , xinc) == 1 ) continue;
00432 
00433 //printf("VERTEX::Grouping> New initial configuration group. ID= %d\n", NICG);
00434           InitialConfigurationGroup& icg = *(new InitialConfigurationGroup);
00435           icg.init( *this, NBODY, sti, inc, xinc);
00436           add_ICG( icg );
00437           NICG++;
00438         }
00439       }
00440     }
00441 //printf(" NICG= %d, icg.size()= %d\n", NICG, icg.size());
00442   }
00443   delete []x;
00444 }
00445 
00446 //======================================================================
00447 
00448 double VERTEX::ComputeEBASE() {
00449 
00450 // ŌvZ EBASE ͔ΊpԂł̃oEXmO
00451 // ƂȂ邽߂̕KvȔ]n~gjAi = -H jւ
00452 // t̍ŏlłDڃV~[g
00453 // yAn~gjA H' Ƃ -H' = -H + ebase 
00454 // ł邩CH = H' + ebase ƂȂC
00455 // vZɂPinteraction C EBASE SGlM[
00456 // ߂ƂłƂ̃n~gjA
00457 // vZGlM[D
00458 //
00459 // EBASE ̂Ƃ͔CӐ邪CƂɂāC
00460 // oEX肵Ȃ肷Dł̃|V[́C
00461 //
00462 // @iPj[CłɊւẮCƂΊpoEX
00463 // @@@@ĂCΊpԊԂ̒ڑJڂD
00464 // @@@@‚܂CEBASE KvȂ傫ƂāC
00465 //         [mP菬ȂĂCł
00466 //         mPŋN悤ɂD
00467 // @iQjʏ̑ݍpo[ebNXɂ‚ẮCΊp
00468 // @@@@oEXȂ͈͂őΊpd݂ŏɂƂD
00469 //
00470 // łD
00471 
00472   for (int icg=0; icg<NICG; icg++) ICG(icg).ResetWeight();
00473 
00474   double eb;
00475   if        ( CATEGORY == VCAT::TERM ) {
00476     eb = 1.0;
00477   } else if ( CATEGORY == VCAT::WORM ) {
00478     eb = -INF;
00479     for (int icg=0; icg<NICG; icg++) {
00480       double e = ICG(icg).sum_of_all_weights();
00481       if ( eb < e ) eb = e;
00482     }
00483   } else if ( CATEGORY == VCAT::INT ) {
00484     eb = -INF;
00485     for (int icg=0; icg<NICG; icg++) {
00486       double e = ICG(icg).ebase();
00487       if ( eb < e ) eb = e;
00488     }
00489   } else { printf("VERTEX::ComputeEBASE> Error.\n"); exit(0); }
00490   return eb;
00491 
00492 }
00493 
00494 //======================================================================
00495 
00496 void VERTEX::ComputeScatteringProbability() {
00497 
00498 //printf("\nVERTEX::ComputeScatteringProbability> Start.\n");
00499   NICV = 0;
00500   for (int icg=0; icg<NICG; icg++) {
00501     ICG(icg).ResetWeight();
00502     ICG(icg).numbering(NICV);
00503     ICG(icg).ScatteringProbability();
00504   }
00505 //printf("\nVERTEX::ComputeScatteringProbability> End.\n");
00506 
00507 }
00508 
00509 //======================================================================
00510 
00511 void VERTEX::dump() {
00512   printf("VERTEX[%d] cat= %d", ID, CATEGORY);
00513   printf(" nb= %d", NBODY);
00514   printf(" nl= %d", NLEG);
00515   printf(" ncig= %d", NICG);
00516   printf(" eb= %8.3f", EBASE);
00517   printf(" st= (");
00518   for (int i=0; i<NLEG; i++) printf(" %1d", SiteTypeOfLeg(i));
00519   printf(")\n");
00520   int* x = new int[NLEG]; //edit sakakura
00521 //  int x[NLEG];
00522   for (int i=0; i<NST; i++) {
00523     if ( (!testKink(i)) || Weight[i] != 0.0) {
00524       if ( testKink(i) ) { printf(" kink:yes "); } else { printf(" kink:no  "); }
00525       if ( Weight[i] == 0.0 ) { printf(" w=0:yes "); } else { printf(" w=0:no  "); }
00526       INDX().coord(i,x);
00527       printf(" (");
00528       for (int j=0; j<NLEG; j++) printf(" %1d", x[j]);
00529       printf(") --> w= %8.3f\n", Weight[i]);
00530     }
00531   }
00532   for (int i=0; i<NICG; i++) {
00533     printf("\n");
00534     ICG(i).dump();
00535   }
00536   delete []x;
00537 }
00538 
00539 //======================================================================
00540 
00541 void VERTEX::write() {
00542   fprintf(FALG,"\n");
00543   fprintf(FALG,"  <Vertex>\n");
00544   fprintf(FALG,"    <VTYPE> %d </VTYPE>\n", ID);
00545   fprintf(FALG,"    <VCATEGORY> %d </VCATEGORY>\n", CATEGORY);
00546   fprintf(FALG,"    <NBODY> %d </NBODY>\n", NBODY);
00547   int NICW = NumberOfValidInitialConfigurations();
00548   fprintf(FALG,"    <NumberOfInitialConfigurations> %d </NumberOfInitialConfigurations>\n", NICW);
00549   for (int i=0; i<NICG; i++) ICG(i).write();
00550   fprintf(FALG,"\n  </Vertex>\n");
00551 }
00552 
00553 //======================================================================
00554 
00555 bool VERTEX::testKink(int ist) {
00556   //printf("VERTEX::testKink> D = %d\n", D);
00557   int* x = new int [NLEG];
00558   INDX().coord(ist,x);
00559   bool ans = false;
00560   for (int i=0; i<NLEG/2; i++) {
00561     if ( x[2*i] != x[2*i+1] ) ans = true;
00562   }
00563   delete [] x;
00564   return ans;
00565 }
00566 
00567 //======================================================================
00568 
00569 bool VERTEX::testForbidden(int ist) {
00570   if ( ! testKink(ist) ) return false;
00571   if ( Weight[ist] > 0.0 ) return false;
00572   return true;
00573 }
00574 
00575 //######################################################################
00576 
00577 void InitialConfigurationGroup::init( 
00578   VERTEX& v, int nbody , int sti, int inc, int xinc ) {
00579   // handling a group of initial configurations 
00580   // that scatters into each other
00581 
00582 //printf("InitialConfigurationGroup::init> Start. icg=%d\n", ID);
00583 
00584   /*
00585 printf("nbody= %d, nicmax= %d, sti= %d, inc= %d, xinc= %d\n",
00586 nbody, NICmax, sti, inc, xinc);
00587   */
00588 
00589   _V = &v;
00590   NBODY = nbody;
00591   NLEG = 2 * nbody;
00592 
00593 //int x[NLEG];
00594 //int y[NLEG];
00595   int* x = new int[NLEG]; //edit sakakura
00596   int* y = new int[NLEG];
00597   IndexSystem& INDX = V().INDX();
00598   INDX.coord(sti,x);
00599   if ( inc != DIR::UNDEF ) x[inc] = xinc; 
00600   // x[l] is the local state on the l-th leg 
00601   // just after the entrance of the incoming 
00602   // worm head (before its outgoing).
00603 
00604   /*
00605 if (MON) {
00606 printf("InitialConfigurationGroup::init> ");
00607 printf("Grouping the configs related to ... \n");
00608 printf("  ...  nb= %d, sti= %d (", nbody, sti);
00609 for (int i=0; i<NLEG; i++) printf(" %1d", x[i]);
00610 printf("), hti= %d, inc= %d\n", hti, inc);
00611 }
00612   */
00613 
00614   int sitei = inc / 2;
00615   int diri  = inc % 2;
00616 
00617 // ŏɃO[vɑԐJEg
00618 
00619   NIC=0;
00620   if ( inc == DIR::UNDEF ) NIC=1; // [̏ꍇ 
00621   for (int out=0; out<NLEG; out++) {
00622     for (int xout=0; xout<NXMAX; xout++) { 
00623       // xout is the new local state on the outgoing leg
00624       for (int d=0; d<NLEG; d++) y[d] = x[d];
00625       y[out] = xout;
00626       int stf = INDX(y);
00627       if ( stf == STATE::UNDEF ) continue;
00628       if ( V().testForbidden(stf) ) continue; 
00629       NIC++;
00630     }  
00631   }
00632 
00633   U.init("U",1,NIC);
00634   U.set_all(0.0);
00635   //  W.init("W",2,NIC,NIC);
00636   //  W.set_all(0.0);
00637   //  P.init("P",2,NIC,NIC);
00638   //  P.set_all(0.0);
00639   IC.init(1,NIC);
00640 
00641   int ic=0;
00642   if ( inc == DIR::UNDEF ) { // [̏ꍇ
00643     IC[ic].init( V(), sti, inc, xinc, NIC );
00644     ic++;
00645   }
00646   for (int out=0; out<NLEG; out++) {
00647     for (int xout=0; xout<NXMAX; xout++) { 
00648     // xout is the new local state on the outgoing leg
00649       for (int d=0; d<NLEG; d++) y[d] = x[d];
00650       y[out] = xout;
00651       /*
00652 printf(" (");
00653 for (int i=0; i<INDX.dimension(); i++) printf(" %d", y[i]);
00654 printf(")\n");
00655       */
00656       int stf = INDX(y);
00657       if ( stf == STATE::UNDEF ) continue;
00658       if ( V().testForbidden(stf) ) continue; 
00659       IC[ic].init( V(), stf, out, x[out], NIC );
00660       V().checked( stf , out , x[out]) = 1;
00661       ic++;
00662     }  
00663   }
00664   delete []x;
00665   delete []y;
00666 //if (MON) printf("InitialConfigurationGroup::init> End.\n");
00667 
00668 }
00669 
00670 //======================================================================
00671 
00672 int InitialConfigurationGroup::NumberOfValidInitialConfigurations() {
00673   int c = 0;
00674   for (int i=0; i<NIC; i++) {
00675     if ( IC[i].isValid() ) c++;
00676   }
00677   return c;
00678 }
00679 
00680 //======================================================================
00681 
00682 void InitialConfigurationGroup::ResetWeight() {
00683   for (int i=0; i<NIC; i++) {
00684     U[i] = IC[i].weight();
00685     /*
00686     for (int j=0; j<NIC; j++) {
00687       W(i,j) = 0.0;
00688       P(i,j) = 0.0;
00689     }
00690     */
00691   }
00692 }
00693 
00694 //======================================================================
00695 
00696 int InitialConfigurationGroup::number_of_diagonal_states() {
00697   int n = 0;
00698   for (int i=0; i<NIC; i++) { if ( ! IC[i].isKink() ) n++; }
00699   return n;
00700 }
00701 
00702 //======================================================================
00703 
00704 int InitialConfigurationGroup::number_of_offdiagonal_states() {
00705   return NIC - number_of_diagonal_states();
00706 }
00707 
00708 //======================================================================
00709 
00710 double InitialConfigurationGroup::minimum_diagonal_weight() {
00711   double dmin = INF;
00712   for (int i=0; i<NIC; i++) {
00713     if ( ! IC[i].isKink() ) {
00714       if ( U[i] < dmin ) dmin = U[i];
00715     }
00716   }
00717   return dmin;
00718 }
00719 
00720 //======================================================================
00721 
00722 double InitialConfigurationGroup::maximum_diagonal_weight() {
00723   double dmax = -INF;
00724   for (int i=0; i<NIC; i++) {
00725     if ( ! IC[i].isKink() ) {
00726       if ( U[i] > dmax ) dmax = U[i];
00727     }
00728   }
00729   return dmax;
00730 }
00731 
00732 //======================================================================
00733 
00734 double InitialConfigurationGroup::maximum_offdiagonal_weight() {
00735   double omax = -INF;
00736   for (int i=0; i<NIC; i++) {
00737     if ( IC[i].isKink() ) {
00738       if ( U[i] > omax ) omax = U[i];
00739     }
00740   }
00741   return omax;
00742 }
00743 
00744 //======================================================================
00745 
00746 double InitialConfigurationGroup::sum_of_all_weights() {
00747   double sum = 0.0;
00748   for (int i=0; i<NIC; i++) sum += U[i];
00749   return sum;
00750 }
00751 
00752 //======================================================================
00753 
00754 double max( double& d0, double& d1, double& d2) {
00755   double d = d0;
00756   if ( d1 > d ) d = d1;
00757   if ( d2 > d ) d = d2;
00758   return d;
00759 }
00760 
00761 //======================================================================
00762 
00763 double InitialConfigurationGroup::ebase() {
00764 
00765 //if ( MON ) printf("InitialConfigurationGroup::ebase> Start.\n");
00766 
00767   double eb, eb0, eb1, eb2;
00768 
00769   int nd = number_of_diagonal_states();
00770   int no = NIC - nd;
00771   if ( nd == 0 ) {
00772     eb = -INF; // ΊpȂ ebase ͊֌WȂ̂ŁC‚łnjD
00773   } else {
00774     double dmax = maximum_diagonal_weight();
00775     double dmin = minimum_diagonal_weight();
00776     double omax = maximum_offdiagonal_weight();
00777     double sum  = sum_of_all_weights();
00778     // eb0 ... ŒႱꂾ͑Ȃƕ̑ΊpłĂ܂D
00779     // eb1 ... ŒႱꂾ͑ȂƔΊpԂł̃oEXĂ܂D
00780     // eb2 ... ŒႱꂾ͑ȂƔΊpԊԂ̒ڑJڂĂ܂D
00781     eb0 = -dmin; 
00782     eb1 = ( 2.0 * omax - sum ) / (double)nd; 
00783 //  eb2 = -INF;
00784 //  eb2 = sum - 2.0 * dmax;
00785     if ( eb0 >= eb1 ) { eb = eb0; } else { eb = eb1; }
00786 
00787     double ww = 0.0;
00788     for (int i=0; i<NIC; i++) {
00789       if ( ! IC[i].isKink() ) {
00790         double wt = IC[i].worm_weight();
00791         if ( fabs(ww)>EPS && fabs(wt)>EPS && wt!=ww ) {
00792           printf("InitialConfigurationGroup::ebase> Error.\n");
00793           printf("  The worm weights of non-kinks are not equal.\n");
00794           dump();
00795           exit(0);
00796         }
00797         ww = IC[i].worm_weight();
00798       }
00799     }
00800     // ܂Ńn~gjAd݂Ƀ[d݂̂ɊÂ eb 
00801     // vZĂCEBASE ͍ŏIIɂ̓n~gjAւ̕t
00802     // 烏[d݂܂̑傫ɖ߂ȂƂȂD
00803     eb /= ww; 
00804   }
00805 
00806 //if ( MON ) printf("InitialConfigurationGroup::ebase> End.\n");
00807 
00808   return eb;
00809 
00810 }
00811 
00812 //======================================================================
00813 
00814 void InitialConfigurationGroup::add_to_diagonal_element(double E) {
00815 
00816   for (int i=0; i<NIC; i++) {
00817     if ( ! IC[i].isKink() ) U[i] += E;
00818   }
00819 
00820 }
00821 
00822 //======================================================================
00823 
00824 void InitialConfigurationGroup::numbering(int& ic) {
00825 
00826   for (int i=0; i<NIC; i++) {
00827     if ( U[i] > -EPS && U[i] < EPS ) {
00828       IC[i].id() = ICONF::UNDEF;
00829     } else {
00830       IC[i].id() = ic;
00831       ic++;
00832     }
00833   }
00834 
00835 }
00836 
00837 //======================================================================
00838 
00839 void InitialConfigurationGroup::ScatteringProbability() {
00840 
00841 //printf("\nInitialConfigurationGroup::ScatteringProbability> Start. ICG= %d\n", ID);
00842 //if (MON) dump();
00843 
00844 // NIC ͎nԂ̐DU ͎nԂ̏d݁DUP ͑傫ɕבւd݁D
00845   Array<int> PERM("PERM");
00846   PERM.init(1,NIC);
00847   bubble_sort( NIC , U , PERM ); 
00848 
00849   Array<double> UP("UP");
00850   UP.init(1,NIC);
00851   for (int i=0; i<NIC; i++) { UP[i] = U[PERM[i]]; }
00852 
00853   Array<double> P("P");
00854   Array<double> W("W");
00855   Array<double> WP("WP");
00856   P.init(2,NIC,NIC);
00857   W.init(2,NIC,NIC);
00858   WP.init(2,NIC,NIC);
00859 
00860   SolveWeightEquation(NIC,UP,WP);
00861 
00862 /*
00863   for (int i=0; i<NIC; i++) { 
00864     for (int j=0; j<NIC; j++) W(PERM[i],PERM[j]) = WP(i,j); 
00865   }
00866 */
00867 
00868   IndexSystem& INDX = V().INDX();
00869   for (int i=0; i<NIC; i++) {
00870     int I = PERM[i];
00871     if ( -EPS < U[I] && U[I] < EPS ) continue;
00872     int nc = 0;
00873     for (int j=0; j<NIC; j++) {
00874       int J = PERM[j];
00875       if ( -EPS < U[J] && U[J] < EPS ) continue;
00876       W(I,J) = WP(i,j);
00877       P(I,J) = W(I,J) / U[I];
00878       if ( P(I,J) > EPS ) {
00879         double p = P(I,J);
00880         int stf = IC[J].STI;
00881         int out = IC[J].INC;
00882         int xout = STATE::UNDEF;
00883         if ( out != DIR::UNDEF ) {
00884           xout = INDX.coord( stf , out );
00885         }
00886         IC[I].FinalDirection[nc] = out;
00887         IC[I].FinalState[nc] = xout;
00888         IC[I].ScatteringProbability[nc] = p;
00889         nc++;
00890       }
00891     }
00892     IC[I].NCH = nc;
00893   }
00894 
00895 //if (MON) printf("  ==>\n");
00896 
00897 }
00898 
00899 //======================================================================
00900 
00901 void InitialConfigurationGroup::dump() {
00902   for (int i=0; i<NIC; i++) {
00903     IC[i].dump();
00904   }
00905   for (int i=0; i<NIC; i++) {
00906     printf("(%d)", i);
00907     printf(" ID= %2d", IC[i].id());
00908     printf(" : U= %4.1f", U[i]);
00909     /*
00910     printf(" , W= ");
00911     for (int j=0; j<NIC; j++) {
00912       printf(" %4.1f", W(i,j));
00913     }
00914     printf(" , P= ");
00915     for (int j=0; j<NIC; j++) {
00916       printf(" %6.3f", P(i,j));
00917     }
00918     printf("\n");
00919     */
00920   }  
00921 }
00922 
00923 //======================================================================
00924 
00925 void InitialConfigurationGroup::write() {
00926   for (int i=0; i<NIC; i++) {
00927     IC[i].write();
00928   }
00929 }
00930 
00931 //######################################################################
00932 
00933 void InitialConfiguration::init( 
00934   VERTEX& v, int sti , int inc , int xinc, int NICmax ) {
00935   // define an initial configuration for which
00936   // the initial vertex state is "sti"
00937   // the incoming worm head is coming on the "inc"-th leg
00938   // the new state on the leg after the passage of the worm head is "xinc"
00939 
00940   setV(v);
00941   STI = sti;
00942   INC = inc;
00943   XINC = xinc;
00944   NLEG = V().NLEG;
00945   NBODY = 2 * NLEG;
00946   State = new int[NLEG];
00947   ScatteringProbability = new double[NICmax];
00948   FinalState = new int[NICmax];
00949   FinalDirection = new int[NICmax];
00950   V().INDX().coord(STI,State);
00951   NCH = 0;
00952 }
00953 
00954 //======================================================================
00955 
00956 bool InitialConfiguration::isValid() { 
00957   if ( INC == DIR::UNDEF ) return false;
00958   if ( fabs(weight()) < EPS ) return false;
00959   return true; 
00960 }
00961 
00962 //======================================================================
00963 
00964 bool InitialConfiguration::isKink() {
00965   return V().testKink(STI);
00966 }
00967 
00968 //======================================================================
00969 
00970 double InitialConfiguration::weight() {
00971   double w = vertex_weight() * worm_weight();
00972   return w;
00973 }
00974 
00975 //======================================================================
00976 
00977 double InitialConfiguration::vertex_weight() {
00978   double ws = V().Weight[STI]; 
00979   if ( ! isKink() ) ws += V().EBASE;
00980   return ws;
00981 }
00982 
00983 //======================================================================
00984 
00985 double InitialConfiguration::worm_weight() {
00986   double ww;
00987   if (INC == DIR::UNDEF) {
00988     ww = 1.0;
00989   } else {
00990     int stype = V().SiteTypeOfLeg[INC];
00991     int ttype = Site[stype].TTYPE;
00992     SOURCE& T = Source[ttype];
00993     ww = T.Weight( XINC , State[INC] );
00994   }
00995   return ww;
00996 }
00997 
00998 //======================================================================
00999 
01000 void InitialConfiguration::dump() {
01001   double wv,ww;
01002   if ( INC == DIR::UNDEF ) {
01003     wv = 1.0;
01004     ww = 1.0;
01005   } else {
01006     wv = vertex_weight();
01007     ww = worm_weight();
01008   }
01009   printf(" IC(%3d) : nleg= %2d, sti= %4d (", id(), NLEG, STI);
01010   for (int i=0; i<NLEG; i++) {
01011     printf(" %1d", State[i]);
01012   }
01013   printf("), inc= %2d, xinc= %2d ", INC, XINC);
01014   printf("--> wv= %8.3f, ww= %8.3f, w= %8.3f\n", wv, ww, wv*ww);
01015   if (NCH != 0) {
01016     for (int i=0; i<NCH; i++) {
01017       printf("   Channel[%d] : out= %d, xout= %d, prob= %8.3f\n",
01018         i, FinalDirection[i], FinalState[i], ScatteringProbability[i]
01019       );
01020     }
01021   }
01022 }
01023 
01024 //======================================================================
01025 
01026 void InitialConfiguration::write() {
01027   if ( ! isValid() ) return;
01028   fprintf(FALG,"\n");
01029   fprintf(FALG,"    <InitialConfiguration>\n");
01030   fprintf(FALG,"      <State> ");
01031   for (int i=0; i<NLEG; i++) fprintf(FALG," %d", State[i]);
01032   fprintf(FALG," </State>\n");
01033   fprintf(FALG,"      <IncomingDirection> %d </IncomingDirection>\n", INC);
01034   fprintf(FALG,"      <NewState> %d </NewState>\n", XINC);
01035   fprintf(FALG,"      <NumberOfChannels> %d </NumberOfChannels>\n", NCH);
01036   for (int ch=0; ch<NCH; ch++) {
01037     int out = FinalDirection[ch];
01038     int xout = FinalState[ch];
01039     double p = ScatteringProbability[ch];
01040     fprintf(FALG,"      <Channel> %4d %4d %24.16f </Channel>\n", out, xout, p );
01041   }
01042   fprintf(FALG,"    </InitialConfiguration>\n");
01043 }
01044 
01045 //######################################################################
01046 
01047 void QUANTITY::load(XML::Block& X) {
01048   ID = X["QTYPE"].getInteger();
01049   NAME = X["Name"].getString();
01050   Value.init(2,NSTYPE,NXMAX);
01051   Value.set_all(0.0);
01052   isDefined.init(2,NSTYPE,NXMAX);
01053   isDefined.set_all(false);
01054   for (int i=0; i<X.NumberOfBlocks(); i++) {
01055     XML::Block& B = X[i];
01056     if ( B.getName() == "Value" ) {
01057       int st = B.getInteger(0);
01058       int x = B.getInteger(1);
01059       double v = B.getDouble(2);
01060       isDefined(st,x) = true;
01061       Value(st,x) = v;
01062     }
01063   }
01064 }
01065 
01066 //======================================================================
01067 
01068 void QUANTITY::write() {
01069   fprintf(FALG,"\n");
01070   fprintf(FALG,"  <Quantity>\n");
01071   fprintf(FALG,"    <QTYPE> %d </QTYPE>\n", getID());
01072   fprintf(FALG,"    <Name> %s </Name>\n", getName().c_str());
01073   for (int st=0; st<NSTYPE; st++) {
01074     for (int x=0; x<NXMAX; x++) {
01075       if ( isDefined(st,x) ) {
01076         fprintf(FALG,"    <Value> %d %d %24.16f </Value>\n",
01077           st, x, Value(st,x));
01078       }
01079     }
01080   }
01081   fprintf(FALG,"  </Quantity>\n");
01082 }
01083 
01084 //######################################################################
01085 
01086 //######################################################################
01087 
01088 void SolveWeightEquation(int N, Array<double>& V, Array<double>& W) {
01089 
01090 /*
01091   for (int i=0; i<N; i++) {
01092     printf("V[%d] = %8.3f\n", i, V[i]);
01093   }
01094 */
01095 
01096   W.set_all(0.0);
01097 
01098   int p,q;
01099   double V_first;
01100   double V_second;
01101   double V_third;
01102   double V_first_new;
01103   double V_second_new;
01104   int N_first;   // the number of the largest elements
01105   int N_second;  // the number of the second largest
01106 
01107 // d͂ԂčŏR‚̏d݂Ƃ̔ԍ擾D
01108   while ( V[1] > EPS ) {
01109     V_first = V[0];
01110     for (p=0; p<N; p++) if ( V[p] != V_first ) break;
01111     N_first = p;
01112     if ( p == N ) {
01113       V_second = 0.0;
01114       V_third = 0.0;
01115       N_second = 0;
01116     } else {
01117       V_second = V[p];
01118       for (q=p; q<N; q++) if ( V[q] != V_second ) break;
01119       if ( q == N ) {
01120         V_third = 0.0;
01121       } else {
01122         V_third = V[q];
01123       }
01124       N_second = q-p;
01125     }
01126 
01127 //ȉł́CV[i] <= w_i oāCW(i,j) = w_{ij} ȂC
01128 //̕CV[i] ĂDׂĂ V[i] OɂȂID
01129 
01130     double dw1; // decrement of the first largest element
01131     double dw2; // decrement of the second largest element
01132     if ( N_first == 1 ) {  
01133 //őEFCgPƂ̏Ԃ̂ƂCőEFCgƑQEFCg̊Ԃ̑Jڂ
01134 //ĂD
01135       double x = V_first - V_second;
01136       double y = (double)(N_second - 1) * (V_second - V_third);
01137       if ( x < y ) { 
01138 //őEFCg傫ȂƂCőEFCgQEFCgɓȂ܂ʼnD
01139         dw1 = (V_first-V_second) / ( 1.0 - 1.0 / (double)(N_second));
01140         dw2 = dw1 / (double)N_second;
01141         V_second_new = V_second - dw2;
01142         V_first_new  = V_second_new;
01143       } else { 
01144 // őEFCg傫ƂCQEFCgREFCgƓȂ܂ʼnD
01145         dw2 = V_second - V_third;
01146         dw1 = dw2 * (double)N_second;
01147         V_second_new = V_third;
01148         V_first_new  = V_first - dw1;
01149       }
01150       V[0] = V_first_new;
01151       for (int i=1; i<1+N_second; i++) {
01152         W(0,i) += dw2;
01153         W(i,0) += dw2;
01154         V[i] = V_second_new;
01155       }
01156     } else { 
01157 //̏ԂőEFCgƂƂC݂ɈڂςJڊm𓱓āC
01158 //QEFCgƓɂȂ܂ʼnD
01159       dw1 = (V_first - V_second) / (double)( N_first-1 );
01160       for (int i=0; i<N_first; i++) {
01161         V[i] = V_second;
01162         for (int j=0; j<N_first; j++) {
01163           if ( i==j ) continue;
01164           W(i,j) += dw1;
01165         }
01166       }
01167     }
01168   }
01169   if ( V[0] > 0.0 ) {
01170     W(0,0) += V[0];
01171     V[0] = 0.0;
01172   }
01173 
01174 }
01175 
01176 //======================================================================
01177 
01178 void bubble_sort(int N, Array<double>& V, Array<int>& I) {
01179   for (int i=0; i<N; i++) I[i] = i;
01180   for (int i=0; i<N-1; i++) {
01181     for (int j=i+1; j<N; j++) {
01182       if ( V[I[i]] < V[I[j]] ) {
01183         int ii = I[i];
01184         I[i] = I[j];
01185         I[j] = ii;
01186       }
01187     }
01188   }
01189 }
 全て クラス ネームスペース ファイル 関数 変数 型定義 列挙型の値 フレンド マクロ定義