void CEquSystem::addVariable(CVariable *pVar, size_t numVar)
{
	auto **ppVar = varPntr() + numVar;
	if (*ppVar)
		pVar->setSameVarNextEqu(*(ppVar + nVar()));
	else
		*ppVar = pVar;

	*(ppVar + nVar()) = pVar;
}
void CEquSystem::closeVarloop() const
{
	// Make the loop of all appearance of given variable in different equations
	for (auto i = nVar(); i--;) {
		auto pVar = variable(i);
		if (pVar) {
			auto pVarNextEqu = variable(i + nVar());
			pVar->setSameVarNextEqu(pVarNextEqu);
			while (pVarNextEqu->sameVarNextEqu() != pVar)
				pVarNextEqu = pVarNextEqu->sameVarNextEqu();

			pVar->setSameVarPrevEqu(pVarNextEqu);
		}
	}
}
Пример #3
0
//prints all variables and their values
void printVars(){
    int i=0;
    while(i < nVar()){
        printf("%s = %d\n", vars_ident[i],vars_value[i]);
        i++;
    }
}
Пример #4
0
//search for curr_var in the variable array and returns its index
//if curr_var is not in the array yet, insert curr_var to the array
int findVarIdx(char curr_var[]){
    int i,idx=-1;
    for(i=0;i<nVar();i++){
        if(strcmp(curr_var,vars_ident[i])==0){
            idx = i;
            break;
        }
    }
    //if curr_var not in array, add
    if(idx==-1){
        idx = nVar();
        strcpy(vars_ident[idx],curr_var);
    }

    return idx;
}
Пример #5
0
SGD::SGD() {
    double tPrev, t, step;
    rowvec parameter(2), gradient(2), gradientLocal(2), gradientOld(2), nVar(2);
    double localE;
    int correlationLength;
    long idum;
    writeToFile = false;

    //--------------------------------------------------------------------------
    // MPI
    int myRank, nNodes;
    MPI_Comm_size(MPI_COMM_WORLD, &nNodes);
    MPI_Comm_rank(MPI_COMM_WORLD, &myRank);

    //--------------------------------------------------------------------------
    // Reading data from QD.ini
    if (myRank == 0) {
        cout << "Reading configuration from file " << endl;
        ini INIreader("QD.ini");

        McSamples = (int) INIreader.GetDouble("SGD", "McSamples");
        importanceSampling = INIreader.GetBool("SGD", "importanceSampling");
        thermalization = (int) INIreader.GetDouble("SGD", "thermalization");
        SGDSamples = INIreader.GetInt("SGD", "SGDSamples");

        dim = INIreader.GetInt("SGD", "dim");
        alpha = INIreader.GetDouble("SGD", "alpha");
        beta = INIreader.GetDouble("SGD", "beta");
        w = INIreader.GetDouble("SGD", "w");
        nParticles = INIreader.GetInt("SGD", "nParticles");
        m = INIreader.GetInt("SGD", "m");
        correlationLength = INIreader.GetInt("SGD", "correlationLength");

        usingJastrow = INIreader.GetBool("SGD", "usingJastrow");
        writeToFile = INIreader.GetBool("SGD", "writeToFile");
        fileName = INIreader.GetString("SGD", "fileName");

        fMax = INIreader.GetDouble("SGD", "fMax");
        fMin = INIreader.GetDouble("SGD", "fMin");
        omega = INIreader.GetDouble("SGD", "omega");
        expo = INIreader.GetDouble("SGD", "expo");
        A = INIreader.GetDouble("SGD", "A");
        a = INIreader.GetDouble("SGD", "a");
        maxStep = INIreader.GetDouble("SGD", "maxStep");
    }

    //--------------------------------------------------------------------------
    // Broadcasting data to all nodes.
    if (myRank == 0)
        cout << "Broadcasting data to nodes." << endl;

    MPI_Bcast(&McSamples, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&SGDSamples, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&importanceSampling, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&thermalization, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&dim, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&alpha, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&beta, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&w, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&nParticles, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&usingJastrow, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&m, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&correlationLength, 1, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Bcast(&fMax, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&fMin, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&omega, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&expo, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&A, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&a, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Bcast(&maxStep, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);

#if 0
    cout
            << "\t A = " << A
            << "\t a = " << a
            << "\t maxStep = " << maxStep
            << "\t expo = " << expo
            << "\t omega = " << omega
            << "\t fMin = " << fMin
            << "\t fMax = " << fMax
            << endl;
#endif
    //--------------------------------------------------------------------------
    //Initializing and thermalizing walkers.

    if (myRank == 0)
        cout << "Initializing and thermalizing walkers." << endl;

    WaveFunction * walker[m];

    idum = -1 - myRank - time(NULL);

    Orbital *orbital = new QDOrbital(dim, alpha, w);
    Jastrow * jastrow = NULL;
    if (usingJastrow)
        jastrow = new QDJastrow(dim, nParticles, beta);

    Hamiltonian *hamiltonian = new QDHamiltonian(dim, nParticles, w, usingJastrow);
    WaveFunction *wf = new WaveFunction(dim, nParticles, idum, orbital, jastrow, hamiltonian);

    // If we are using brute force sampling we have to calculate 
    // the optimal step length.
    if (!importanceSampling)
        wf->setOptimalStepLength();


    // Thermalizing walker.
    int k = 0;
    int thermCorr = m*correlationLength;

    for (int i = 0; i <= thermalization + thermCorr; i++) {
        for (int j = 0; j < nParticles; j++) {
            if (importanceSampling)
                wf->tryNewPosition(j);
            else
                wf->tryNewPositionBF(j);
        }

        // Storing walker.
        if (i > thermalization) {
            if ((i - thermalization) % (correlationLength) == 0) {
                if (myRank == 999)
                    cout << "k = " << k << endl;
                walker[k] = wf->clone();
                k++;
            }
        }
    }

    /*
     for (int k = 0; k < m; k++) {
            // Giving each walker a unique seed.
            idum = -1 - myRank - time(NULL) - k;
        
            Orbital *orbital = new QDOrbital(dim, alpha, w);
            Jastrow * jastrow = NULL;
            if (usingJastrow)
                jastrow = new QDJastrow(dim, nParticles, beta);

            Hamiltonian *hamiltonian = new QDHamiltonian(dim, nParticles, w, usingJastrow);
            WaveFunction *wf = new WaveFunction(dim, nParticles, idum, orbital, jastrow, hamiltonian);

            // If we are using brute force sampling we have to calculate 
            // the optimal step length.
            if (!importanceSampling)
                wf->setOptimalStepLength();

            // Thermalizing walker.
            for (int i = 0; i < thermalization; i++) {
                for (int j = 0; j < nParticles; j++) {
                    if (importanceSampling)
                        wf->tryNewPosition(j);
                    else
                        wf->tryNewPositionBF(j);
                }
            }

            // Storing walker.
            walker[k] = wf;
        }
     **/
    //--------------------------------------------------------------------------
    ofstream outStream;
    if (myRank == 0) {
        cout << "Starting minimizing process " << endl;
        cout << "SGA samples = " << SGDSamples;
        cout << "\t omega = " << w;
        cout << "\t alpha_0 = " << alpha;
        cout << "\t beta_0 = " << beta;
        cout << endl;

        outStream.open((const char*) &fileName[0]);

        // Writing to file
        outStream << SGDSamples << " " << McSamples << " " << m*nNodes << " " << nParticles << " " << w << endl;
    }
    //--------------------------------------------------------------------------
    tPrev = 0;
    parameter(0) = alpha;
    parameter(1) = beta;
    nVar(0) = 5;
    nVar(1) = 5;
    gradientOld = zeros(1, 2);
    //-------------------------------------------------------------------------- 
    // Starting SGD algortithm.
    //-------------------------------------------------------------------------- 
    for (int sample = 1; sample <= SGDSamples; sample++) {

        // Moving walkers        
        E = 0;
        accepted = 0;
        gradient = zeros(1, 2);
        gradientLocal = zeros(1, 2);

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < McSamples; j++) {
                for (int k = 0; k < nParticles; k++) {
                    if (importanceSampling) {
                        accepted += walker[i]->tryNewPosition(k);
                    } else {
                        accepted += walker[i]->tryNewPositionBF(k);
                    }
                }
                localE = walker[i]->sampleEnergy();
                E += localE; // / nParticles;
                gradient += walker[i]->getVariationGradient();
                gradientLocal += walker[i]->getVariationGradient() * localE;
                //}
            }
        }

        //----------------------------------------------------------------------
        // Collecting results.
        MPI_Allreduce(MPI_IN_PLACE, &E, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
        MPI_Allreduce(MPI_IN_PLACE, &gradient(0), 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
        MPI_Allreduce(MPI_IN_PLACE, &gradient(1), 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
        MPI_Allreduce(MPI_IN_PLACE, &gradientLocal(0), 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
        MPI_Allreduce(MPI_IN_PLACE, &gradientLocal(1), 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
        E /= (nNodes * m * McSamples);
        gradient /= (nNodes * m * McSamples);
        gradientLocal /= (nNodes * m * McSamples);

        // The total variational gradient
        gradient = 2 * (gradientLocal - gradient * E);
        //----------------------------------------------------------------------
        // Algoritm for the new step length
        //----------------------------------------------------------------------
        double x = -dot(gradient, gradientOld);
        f = fMin + (fMax - fMin) / (1 - (fMax / fMin) * exp(-x / omega));
        t = tPrev + f;

        if (t < 0)
            t = 0;
        //----------------------------------------------------------------------
        // Printing progress
        if (myRank == 0 && sample % 100) {
            fflush(stdout);
            cout
                    << "SGA cycle = " << sample
                    << "\t alpha = " << parameter(0)
                    << "\t beta = " << parameter(1)
                    << "\t E = " << E
                    << "\t t = " << t
                    << "\t step = " << step
                    << "\xd";
        }

        //----------------------------------------------------------------------
        for (int i = 0; i < 2; i++) {
            if (gradient(i) * gradientOld(i) < 0)
                nVar(i)++;

            // Calulating new step lengths.
#if 0
            step = gradient(i) * a / pow(nVar(i), expo);
            if (fabs(step) > maxStep)
                step *= maxStep / fabs(step);

#else
            // Calculating new step lengths.
            double gamma = a / pow(t + A, expo);
            step = gamma * gradient(i);
            if (fabs(step) > maxStep)
                step *= maxStep / fabs(step);
#endif
            parameter(i) -= step;

            // We don't allow negative parameters
            parameter(i) = abs(parameter(i));
        }

        //----------------------------------------------------------------------
        // Setting the new parameters
        for (int i = 0; i < m; i++)
            walker[i]->setNewVariationalParameters(parameter(0), parameter(1));

        // Writing to file
        if (myRank == 0)
            outStream << parameter(0) << " " << parameter(1) << endl;
        //----------------------------------------------------------------------
        // Storing previous values.
        tPrev = t;
        gradientOld = gradient;
    }

    if (myRank == 0) {
        cout
                << endl
                << "Finished. Ending parameters: "
                << "\t alpha = " << parameter(0)
                << "\t beta = " << parameter(1)
                << "\xd";
        //<< endl;
        outStream.close();
    }
    //--------------------------------------------------------------------------
    // Cleaning up
    //for (int i = 0; i < m; i++)
    //delete walker[i];

}
Пример #6
0
    Task* create_guessing_task(std::string identifier, Log* log, Stepper* stepper, Wave* varyingWave,
			       Wave* evWave, double tol, size_t nPeriod, size_t showAllIterates, long secvar)
    {
      Task* task = new Task
	([=]() mutable
	 {
	   varyingWave->lock();
	   
	   size_t nVar(stepper->n_variables());
	   size_t nFunc(stepper->n_functions());	   
	   double t(stepper->t());
	   
	   auto f = [nVar,nFunc,stepper,nPeriod,tol,t](const double* x, double* rhs)
	   {
	     stepper->reset(t,x);
	     stepper->advance(nPeriod);
	     for(size_t i(0);i<nVar;++i)
	       rhs[i]=stepper->x()[i]-x[i];
	     for(size_t i(0);i<nVar*nVar;++i)
	       rhs[i+nVar]=stepper->jac()[i];	     
	     // subtract 1 from the diagonal of the Jacobian
	     for(size_t i(0);i<nVar;++i)
	       rhs[nVar+i*(nVar+1)]-=1.0;
	   };

	   double* x(new double[nVar]);
	   for(size_t i(0);i<nVar;++i)
	     x[i]=varyingWave->data()[i+1];
	   varyingWave->pop_back(1+nVar+nFunc);
	   bool success(false);
	   try
	     {
	       success=newton(int(nVar),x,f,false,tol);
	     }
	   catch(std::string error)
	     {
	       success=false;
	       log->push<Log::ERROR>(error);
	     }
	   if(!success)
	     {
	       log->push<Log::ERROR>("Newton iteration did not converge\n");
	     }
	   else
	     {
	       // get eigenvalue and eigenvector info
	       VecD evals,evecs;
	       VecSZ types;
	       double* jac(new double[nVar*nVar]);
	       for(size_t i(0);i<nVar*nVar;++i)
		 jac[i]=stepper->jac()[i];
	       if(secvar>=0) // in Poincare mode, restore the artificial zero-multiplier to 1
		 jac[size_t(secvar)*(nVar+1)]=1;
	       floquet(nVar,jac,evals,evecs,types);
	       evWave->push_back(&evals[0],nVar*2);
	       evWave->push_back(&evecs[0],nVar*nVar);
	       for(size_t i(0);i<types.size();++i)
		 evWave->push_back(double(types[i]));
	       delete[] jac;

	       size_t factor(showAllIterates?nPeriod:1);
	       stepper->reset(t,x);
	       for(size_t j(0);j<factor;++j)
		 {
		   try
		     {
		       stepper->advance(nPeriod/factor);
		     }
		   catch(std::string error)
		     {
		       log->push<Log::ERROR>(error);
		       success=false;
		       break;
		     }
		   varyingWave->push_back(stepper->t());
		   varyingWave->push_back(stepper->x(),nVar);
		   varyingWave->push_back(stepper->func(),nFunc);
		 }
	     }
	   delete[] x;

	   if(success)
	     log->push<Log::SUCCESS>(identifier);
	   else
	     log->push<Log::FAIL>(identifier);

	   varyingWave->unlock();
	 });
      return task;

    }  
Пример #7
0
    Task* create_guessing_task(std::string identifier, Log* log, EquationSystem* eqsys,
			       Wave* varyingWave, Wave* evWave, double tol)
    {

      size_t nVar(eqsys->n_variables());
      size_t nFunc(eqsys->n_functions());
      
      auto f_(eqsys->f());
      auto dfdx_(eqsys->dfdx());

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
      Newton::F f = eqsys->dfdx()?
	Newton::F([f_,dfdx_,nVar](const double* x, double* rhs)
		  {
		    f_(x,rhs);
		    dfdx_(x,rhs+nVar);
		  }):
	Newton::F(f_);
            
      auto ff(eqsys->func());

      bool genJac = eqsys->dfdx()?false:true;
      
      Task* task = new Task
	([nVar,nFunc,f,ff,varyingWave,evWave,tol,genJac,identifier,log]() mutable
	 {
	   varyingWave->lock();
	   double* x(new double[nVar]);
	   double* funcs(new double[nFunc]);
	   double t(varyingWave->data()[0]);
	   for(size_t i(0);i<nVar;++i)
	     x[i]=varyingWave->data()[i+1];
	   varyingWave->pop_back(1+nVar+nFunc);
	   bool success(false);
	   
	   try
	     {
	       success=newton(int(nVar),x,f,genJac,tol);
	     }
	   catch(std::string error)
	     {
	       success=false;
	       log->push<Log::ERROR>(error);
	     }
	   if(!success)
	     log->push<Log::ERROR>("Newton iteration did not converge\n");
	   else
	     {
	       // get eigenvalue and eigenvector info
	       double* rhs(new double[nVar*(nVar+1)]);
	       f(x,rhs);
	       double* jac=rhs+nVar;
	       VecD evals,evecs;
	       VecSZ types;
	       eigen(nVar,jac,evals,evecs,types);
	       evWave->push_back(&evals[0],nVar*2);
	       evWave->push_back(&evecs[0],nVar*nVar);
	       for(size_t i(0);i<types.size();++i)
		 evWave->push_back(double(types[i]));
	       /*	       for(size_t i(0),size(size_t(evWave->data_max()));i<size;++i)
			       std::cout<<evWave->data()[i]<<std::endl;*/
	       delete[] rhs;
	     }
	   varyingWave->push_back(t);
	   varyingWave->push_back(x,nVar);
	   if(nFunc)
	     {
	       ff(x,funcs);
	       varyingWave->push_back(funcs,nFunc);
	     }
	   
	   delete[] x;
	   delete[] funcs;
	   
	   if(success)
	     log->push<Log::SUCCESS>(identifier);
	   else
	     log->push<Log::FAIL>(identifier);

	   varyingWave->unlock();
	   });
      
#pragma clang diagnostic pop

      return task;
      
    }