/* evaluate the integrals for the given m[] using the cached values in vc, storing the integrals in val[], the error estimate in err[], and the dimension to subdivide next (the largest error contribution) in *mi */ static void eval_integral(valcache vc, const unsigned *m, unsigned fdim, unsigned dim, double V, unsigned *mi, double *val, double *err, double *val1) { double maxerr = 0; unsigned i, j; evals(vc, m, dim, fdim, dim, V, val); /* error estimates along each dimension by comparing val with lower-order rule in that dimension; overall (conservative) error estimate from maximum error of lower-order rules. */ memset(err, 0, sizeof(double) * fdim); *mi = 0; for (i = 0; i < dim; ++i) { double emax = 0; evals(vc, m, i, fdim, dim, V, val1); for (j = 0; j < fdim; ++j) { double e = fabs(val[j] - val1[j]); if (e > emax) emax = e; if (e > err[j]) err[j] = e; } if (emax > maxerr) { maxerr = emax; *mi = i; } } /* printf("eval: %g +/- %g (dim %u)\n", val[0], err[0], *mi); */ }
vec PolyTrajectoryGenerator::evaluateByCoefficientsMultiple(vec x, int sampleCount, vec coeff) { int coeffDegree = this->getBasisFunctionCount(); vec evals(sampleCount); for(int i = 0; i < sampleCount; ++i) { evals(i) = evaluateByCoefficientsSingle(x(i), coeff); } return evals; }
tensor2D eigenVectors(const tensor2D& t) { vector2D evals(eigenValues(t)); tensor2D evs ( eigenVector(t, evals.x()), eigenVector(t, evals.y()) ); return evs; }
tensor eigenVectors(const symmTensor& t) { vector evals(eigenValues(t)); tensor evs ( eigenVector(t, evals.x()), eigenVector(t, evals.y()), eigenVector(t, evals.z()) ); return evs; }
sexpr import(const std::vector<sexpr>& a, environment* env) { if (a.size() < 1) throw std::invalid_argument("<import>: Wrong number of arguments"); auto path = a[0].get<lisp_string>(); std::ifstream file(path); if (!file) throw std::invalid_argument("<import>: File not found: " + path); std::regex reg("([;]{2,}.*$)"); std::string line; std::string content; while (std::getline(file, line)) { content += std::regex_replace(line, reg, ""); } return evals(parse(tokenize(content)), env); }
Vector3f FlyingLayer::RotationMatrixToVector(const Matrix3x3f& rotationMatrix) const { static const float epsilon = 1e-6; const float cs = (rotationMatrix.trace() - 1.0)*0.5; if (cs > 1.0 - epsilon) { return Vector3f::Zero(); } else if (cs < epsilon - 1.0) { Eigen::SelfAdjointEigenSolver<Matrix3x3f> evals(rotationMatrix, Eigen::ComputeEigenvectors); Vector3f rotVector = evals.eigenvectors().col(2).transpose(); return rotVector.normalized()*M_PI; } else { const float sn = std::sqrt(1.0 - cs*cs); const float angle = std::acos(cs); const float multiplier = angle * 0.5 / sn; return Vector3f((rotationMatrix(2, 1) - rotationMatrix(1, 2))*multiplier, (rotationMatrix(0, 2) - rotationMatrix(2, 0))*multiplier, (rotationMatrix(1, 0) - rotationMatrix(0, 1))*multiplier); } }
EigenTypes::Vector3f MathUtility::RotationMatrixToVector(const EigenTypes::Matrix3x3f& rotationMatrix) { static const float epsilon = 1e-6f; const float cs = (rotationMatrix.trace() - 1.0f)*0.5f; if (cs > 1.0f - epsilon) { return EigenTypes::Vector3f::Zero(); } else if (cs < epsilon - 1.0f) { Eigen::SelfAdjointEigenSolver<EigenTypes::Matrix3x3f> evals(rotationMatrix, Eigen::ComputeEigenvectors); EigenTypes::Vector3f rotVector = evals.eigenvectors().col(2).transpose(); return rotVector.normalized()*(float)M_PI; } else { const float sn = std::sqrt(1.0f - cs*cs); const float angle = std::acos(cs); const float multiplier = angle * 0.5f / sn; return EigenTypes::Vector3f((rotationMatrix(2, 1) - rotationMatrix(1, 2))*multiplier, (rotationMatrix(0, 2) - rotationMatrix(2, 0))*multiplier, (rotationMatrix(1, 0) - rotationMatrix(0, 1))*multiplier); } }
/** * \ingroup eigen * Eigenvectors * \param m \f$m\f$ * \return a variable matrix with the * eigenvectors of \f$m\f$ stored in its columns. */ dmatrix eigenvectors(const dmatrix &m) { if (m.rowsize() != m.colsize()) { cerr << "error -- non square matrix passed to dmatrix eigenvectors(const dmatrix& m)\n"; ad_exit(1); } int rmin = m.rowmin(); int rmax = m.rowmax(); dmatrix evecs(rmin, rmax, rmin, rmax); dvector evals(rmin, rmax); eigens(m, evecs, evals); return evecs; }
vector<EquityResult> ShowdownEnumerator::calculateEquity (const vector<CardDistribution>& dists, const CardSet& board, boost::shared_ptr<PokerHandEvaluator> peval) const { if (peval.get() == NULL) throw runtime_error("ShowdownEnumerator, null evaluator"); assert(dists.size() > 1); const size_t ndists = dists.size(); vector<EquityResult> results(ndists, EquityResult()); size_t handsize = peval->handSize(); // the dsizes vector is a list of the sizes of the player hand // distributions vector<size_t> dsizes; for (size_t i=0; i<ndists; i++) { assert(dists[i].size() > 0); dsizes.push_back (dists[i].size()); } // need to figure out the board stuff, we'll be rolling the board into // the partitions to make enumeration easier down the line. size_t nboards = 0; size_t boardsize = peval->boardSize(); if (boardsize > 0) nboards++; // for the most part, these are allocated here to avoid contant stack // reallocation as we cycle through the inner loops SimpleDeck deck; CardSet dead; double weight; vector<CardSet> ehands (ndists+nboards); vector<size_t> parts (ndists+nboards); vector<CardSet> cardPartitions (ndists+nboards); vector<PokerHandEvaluation> evals (ndists); // NO BOARD // copy quickness CardSet * copydest = &ehands[0]; CardSet * copysrc = &cardPartitions[0]; size_t ncopy = (ndists+nboards)*sizeof(CardSet); Odometer o(dsizes); do { // colect all the cards being used by the players, skip out in the // case of card duplication bool disjoint = true; dead.clear (); weight = 1.0; for (size_t i=0; i<ndists+nboards; i++) { if (i<ndists) { cardPartitions[i] = dists[i][o[i]]; parts[i] = handsize-cardPartitions[i].size(); weight *= dists[i][cardPartitions[i]]; } else { // this allows us to have board distributions in the future cardPartitions[i] = board; parts[i] = boardsize-cardPartitions[i].size(); } disjoint = disjoint && dead.disjoint(cardPartitions[i]); dead |= cardPartitions[i]; } if (disjoint) { deck.reset (); deck.remove (dead); PartitionEnumerator2 pe(deck.size(), parts); do { // we use memcpy here for a little speed bonus memcpy (copydest, copysrc, ncopy); for (size_t p=0; p<ndists+nboards; p++) ehands[p] |= deck.peek(pe.getMask (p)); // TODO: do we need this if/else, or can we just use the if // clause? A: need to rework tracking of whether a board is needed if (nboards > 0) peval->evaluateShowdown (ehands, ehands[ndists], evals, results, weight); else peval->evaluateShowdown (ehands, board, evals, results, weight); } while (pe.next ()); } } while (o.next ()); return results; }
void MultiAppProjectionTransfer::execute() { _console << "Beginning projection transfer " << name() << std::endl; getAppInfo(); //////////////////// // We are going to project the solutions by solving some linear systems. In // order to assemble the systems, we need to evaluate the "from" domain // solutions at quadrature points in the "to" domain. Some parallel // communication is necessary because each processor doesn't necessarily have // all the "from" information it needs to set its "to" values. We don't want // to use a bunch of big all-to-all broadcasts, so we'll use bounding boxes to // figure out which processors have the information we need and only // communicate with those processors. // // Each processor will // 1. Check its local quadrature points in the "to" domains to see which // "from" domains they might be in. // 2. Send quadrature points to the processors with "from" domains that might // contain those points. // 3. Recieve quadrature points from other processors, evaluate its mesh // functions at those points, and send the values back to the proper // processor // 4. Recieve mesh function evaluations from all relevant processors and // decide which one to use at every quadrature point (the lowest global app // index always wins) // 5. And use the mesh function evaluations to assemble and solve an L2 // projection system on its local elements. //////////////////// //////////////////// // For every combination of global "from" problem and local "to" problem, find // which "from" bounding boxes overlap with which "to" elements. Keep track // of which processors own bounding boxes that overlap with which elements. // Build vectors of quadrature points to send to other processors for mesh // function evaluations. //////////////////// // Get the bounding boxes for the "from" domains. std::vector<MeshTools::BoundingBox> bboxes = getFromBoundingBoxes(); // Figure out how many "from" domains each processor owns. std::vector<unsigned int> froms_per_proc = getFromsPerProc(); std::vector<std::vector<Point> > outgoing_qps(n_processors()); std::vector<std::map<std::pair<unsigned int, unsigned int>, unsigned int> > element_index_map(n_processors()); // element_index_map[i_to, element_id] = index // outgoing_qps[index] is the first quadrature point in element if (! _qps_cached) { for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++) { MeshBase & to_mesh = _to_meshes[i_to]->getMesh(); LinearImplicitSystem & system = * _proj_sys[i_to]; FEType fe_type = system.variable_type(0); std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type)); QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order()); fe->attach_quadrature_rule(&qrule); const std::vector<Point> & xyz = fe->get_xyz(); MeshBase::const_element_iterator el = to_mesh.local_elements_begin(); const MeshBase::const_element_iterator end_el = to_mesh.local_elements_end(); unsigned int from0 = 0; for (processor_id_type i_proc = 0; i_proc < n_processors(); from0 += froms_per_proc[i_proc], i_proc++) { for (el = to_mesh.local_elements_begin(); el != end_el; el++) { const Elem* elem = *el; fe->reinit (elem); bool qp_hit = false; for (unsigned int i_from = 0; i_from < froms_per_proc[i_proc] && ! qp_hit; i_from++) { for (unsigned int qp = 0; qp < qrule.n_points() && ! qp_hit; qp ++) { Point qpt = xyz[qp]; if (bboxes[from0 + i_from].contains_point(qpt + _to_positions[i_to])) qp_hit = true; } } if (qp_hit) { // The selected processor's bounding box contains at least one // quadrature point from this element. Send all qps from this element // and remember where they are in the array using the map. std::pair<unsigned int, unsigned int> key(i_to, elem->id()); element_index_map[i_proc][key] = outgoing_qps[i_proc].size(); for (unsigned int qp = 0; qp < qrule.n_points(); qp ++) { Point qpt = xyz[qp]; outgoing_qps[i_proc].push_back(qpt + _to_positions[i_to]); } } } } } if (_fixed_meshes) _cached_index_map = element_index_map; } else { element_index_map = _cached_index_map; } //////////////////// // Request quadrature point evaluations from other processors and handle // requests sent to this processor. //////////////////// // Non-blocking send quadrature points to other processors. std::vector<Parallel::Request> send_qps(n_processors()); if (! _qps_cached) for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) if (i_proc != processor_id()) _communicator.send(i_proc, outgoing_qps[i_proc], send_qps[i_proc]); // Get the local bounding boxes. std::vector<MeshTools::BoundingBox> local_bboxes(froms_per_proc[processor_id()]); { // Find the index to the first of this processor's local bounding boxes. unsigned int local_start = 0; for (processor_id_type i_proc = 0; i_proc < n_processors() && i_proc != processor_id(); i_proc++) local_start += froms_per_proc[i_proc]; // Extract the local bounding boxes. for (unsigned int i_from = 0; i_from < froms_per_proc[processor_id()]; i_from++) local_bboxes[i_from] = bboxes[local_start + i_from]; } // Setup the local mesh functions. std::vector<MeshFunction *> local_meshfuns(froms_per_proc[processor_id()], NULL); for (unsigned int i_from = 0; i_from < _from_problems.size(); i_from++) { FEProblemBase & from_problem = *_from_problems[i_from]; MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); System & from_sys = from_var.sys().system(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); MeshFunction * from_func = new MeshFunction(from_problem.es(), *from_sys.current_local_solution, from_sys.get_dof_map(), from_var_num); from_func->init(Trees::ELEMENTS); from_func->enable_out_of_mesh_mode(OutOfMeshValue); local_meshfuns[i_from] = from_func; } // Recieve quadrature points from other processors, evaluate mesh frunctions // at those points, and send the values back. std::vector<Parallel::Request> send_evals(n_processors()); std::vector<Parallel::Request> send_ids(n_processors()); std::vector<std::vector<Real> > outgoing_evals(n_processors()); std::vector<std::vector<unsigned int> > outgoing_ids(n_processors()); std::vector<std::vector<Real> > incoming_evals(n_processors()); std::vector<std::vector<unsigned int> > incoming_app_ids(n_processors()); for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { // Use the cached qps if they're available. std::vector<Point> incoming_qps; if (! _qps_cached) { if (i_proc == processor_id()) incoming_qps = outgoing_qps[i_proc]; else _communicator.receive(i_proc, incoming_qps); // Cache these qps for later if _fixed_meshes if (_fixed_meshes) _cached_qps[i_proc] = incoming_qps; } else { incoming_qps = _cached_qps[i_proc]; } outgoing_evals[i_proc].resize(incoming_qps.size(), OutOfMeshValue); if (_direction == FROM_MULTIAPP) outgoing_ids[i_proc].resize(incoming_qps.size(), libMesh::invalid_uint); for (unsigned int qp = 0; qp < incoming_qps.size(); qp++) { Point qpt = incoming_qps[qp]; // Loop until we've found the lowest-ranked app that actually contains // the quadrature point. for (unsigned int i_from = 0; i_from < _from_problems.size(); i_from++) { if (local_bboxes[i_from].contains_point(qpt)) { outgoing_evals[i_proc][qp] = (* local_meshfuns[i_from])(qpt - _from_positions[i_from]); if (_direction == FROM_MULTIAPP) outgoing_ids[i_proc][qp] = _local2global_map[i_from]; } } } if (i_proc == processor_id()) { incoming_evals[i_proc] = outgoing_evals[i_proc]; if (_direction == FROM_MULTIAPP) incoming_app_ids[i_proc] = outgoing_ids[i_proc]; } else { _communicator.send(i_proc, outgoing_evals[i_proc], send_evals[i_proc]); if (_direction == FROM_MULTIAPP) _communicator.send(i_proc, outgoing_ids[i_proc], send_ids[i_proc]); } } //////////////////// // Gather all of the qp evaluations and pick out the best ones for each qp. //////////////////// for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { if (i_proc == processor_id()) continue; _communicator.receive(i_proc, incoming_evals[i_proc]); if (_direction == FROM_MULTIAPP) _communicator.receive(i_proc, incoming_app_ids[i_proc]); } std::vector<std::vector<Real> > final_evals(_to_problems.size()); std::vector<std::map<unsigned int, unsigned int> > trimmed_element_maps(_to_problems.size()); for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++) { MeshBase & to_mesh = _to_meshes[i_to]->getMesh(); LinearImplicitSystem & system = * _proj_sys[i_to]; FEType fe_type = system.variable_type(0); std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type)); QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order()); fe->attach_quadrature_rule(&qrule); const std::vector<Point> & xyz = fe->get_xyz(); MeshBase::const_element_iterator el = to_mesh.local_elements_begin(); const MeshBase::const_element_iterator end_el = to_mesh.local_elements_end(); for (el = to_mesh.active_local_elements_begin(); el != end_el; el++) { const Elem* elem = *el; fe->reinit (elem); bool element_is_evaled = false; std::vector<Real> evals(qrule.n_points(), 0.); for (unsigned int qp = 0; qp < qrule.n_points(); qp++) { Point qpt = xyz[qp]; unsigned int lowest_app_rank = libMesh::invalid_uint; for (unsigned int i_proc = 0; i_proc < n_processors(); i_proc++) { // Ignore the selected processor if the element wasn't found in it's // bounding box. std::map<std::pair<unsigned int, unsigned int>, unsigned int> & map = element_index_map[i_proc]; std::pair<unsigned int, unsigned int> key(i_to, elem->id()); if (map.find(key) == map.end()) continue; unsigned int qp0 = map[key]; // Ignore the selected processor if it's app has a higher rank than the // previously found lowest app rank. if (_direction == FROM_MULTIAPP) if (incoming_app_ids[i_proc][qp0 + qp] >= lowest_app_rank) continue; // Ignore the selected processor if the qp was actually outside the // processor's subapp's mesh. if (incoming_evals[i_proc][qp0 + qp] == OutOfMeshValue) continue; // This is the best meshfunction evaluation so far, save it. element_is_evaled = true; evals[qp] = incoming_evals[i_proc][qp0 + qp]; } } // If we found good evaluations for any of the qps in this element, save // those evaluations for later. if (element_is_evaled) { trimmed_element_maps[i_to][elem->id()] = final_evals[i_to].size(); for (unsigned int qp = 0; qp < qrule.n_points(); qp++) final_evals[i_to].push_back(evals[qp]); } } } //////////////////// // We now have just one or zero mesh function values at all of our local // quadrature points. Stash those values (and a map linking them to element // ids) in the equation systems parameters and project the solution. //////////////////// for (unsigned int i_to = 0; i_to < _to_problems.size(); i_to++) { _to_es[i_to]->parameters.set<std::vector<Real>*>("final_evals") = & final_evals[i_to]; _to_es[i_to]->parameters.set<std::map<unsigned int, unsigned int>*>("element_map") = & trimmed_element_maps[i_to]; projectSolution(i_to); _to_es[i_to]->parameters.set<std::vector<Real>*>("final_evals") = NULL; _to_es[i_to]->parameters.set<std::map<unsigned int, unsigned int>*>("element_map") = NULL; } for (unsigned int i = 0; i < _from_problems.size(); i++) delete local_meshfuns[i]; // Make sure all our sends succeeded. for (processor_id_type i_proc = 0; i_proc < n_processors(); i_proc++) { if (i_proc == processor_id()) continue; if (! _qps_cached) send_qps[i_proc].wait(); send_evals[i_proc].wait(); if (_direction == FROM_MULTIAPP) send_ids[i_proc].wait(); } if (_fixed_meshes) _qps_cached = true; _console << "Finished projection transfer " << name() << std::endl; }
void exec(const char *str, char *err) { // this function executes a given instruction. // all important functions are done from here. int eval(const char *str); void * evals(const char *str, const char data_type); strcpy(err,""); /* empty error container string */ char *exp = NULL; /* string containing evaluation expression */ char *asgn = NULL; /* string containing assignment variable name */ char data_type = '\0'; /* data type of variable to evaluate */ /* assignment analysis & error handling */ if((asgn=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *asgn='\0'; if(prechar(asgn,str,"=")=='=') /* check for = operator */ { /* ok, it is a variable assignment */ strtrm(asgn,' ','S'); if((*asgn==0)||(strlen(asgn)==0)) { /* error: assignment string is empty */ strcpy(err,"Assignment variable is not specified."); free(asgn); return; } else /* assignment string is NOT empty */ { char isid[2] = {'\0','\0'}; /* check identifier validity*/ isid[0] = id_check(asgn); if(isid[0]!=0) /* error: is not an identifier */ { if(isid[0]==1) /* error: var name starts with a number */ { strcpy(err,"Variable name cannot start with a number."); } else if(isid[0]==32) /* error: var name contains spaces */ { strcpy(err,"Variable name cannot contain spaces."); } else /* error: var name has illegal chars*/ { strcpy(err,"Variable name cannot contain ["); strcat(err,isid); strcat(err,"] character."); } free(asgn); return; } else /* success: assignment string is valid */ { /* allocate string exp */ if((exp=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *exp='\0'; /* now split the equation to get the exp. */ postchar(exp,str,"="); strtrm(exp,' ','S'); // find out the data type of the assignment // variable & store it in char data_type } } } else /* there is no assigment involved */ { /* allocate string exp */ if((exp=(char *)(malloc(sizeof(char)* (strlen(str)+1))))==NULL) allocerr(); *exp='\0'; strcpy(exp,str); strtrm(exp,' ','S'); /* de-allocate asgn */ free(asgn); asgn = NULL; } /* variable assignment */ if(asgn!=NULL) { /* possible variable data types */ long *i = NULL; // <- (int) short *n = NULL; // <- (int-) char *c = NULL; // <- (chr) double *d = NULL; // <- (real) float *f = NULL; // <- (real-) unsigned long *j = NULL; // <- (int+) unsigned short *m = NULL; // <- (int-+) unsigned char *a = NULL; // <- (chr+) switch(data_type) { case 'i': break; default: strcpy(err,"Fatal Data Transfer Error on ["); strcat(err,asgn); strcat(err,"] variable."); } /* de-allocate memory of data type */ switch(data_type) { case 'i': free(i); i = NULL; break; case 'n': free(n); n = NULL; break; case 'c': free(c); c = NULL; break; case 'd': free(d); d = NULL; break; case 'f': free(f); f = NULL; break; case 'j': free(j); j = NULL; break; case 'm': free(m); m = NULL; break; case 'a': free(a); a = NULL; break; } /* de-allocate asgn */ free(asgn); asgn = NULL; } else /* no assigment */ { // if there is no assignment then integer is considered // to be the default assignment data type for evaluation. puts(""); int _i=0; _i = eval(exp); printf("eval: %d\n",_i); data_type = 'i'; long *i = NULL; i=(long *)(evals(exp,data_type)); printf("evals: %ld\n",*i); free(i); i = NULL; void evali(const char *str, char *err, int *eval); evali(exp,err,&_i); printf("evali: %d\n",_i); printf("evali was invoked %d time(s).\n",evali_count); evali_count = 0; } free(exp); exp = NULL; }
int main(int argc, const char *argv[]) { const char *me; hestOpt *hopt=NULL; airArray *mop; double _tt[6], tt[7], ss, pp[3], qq[4], rot[9], mat1[9], mat2[9], tmp, evalA[3], evecA[9], evalB[3], evecB[9]; int roots; mop = airMopNew(); me = argv[0]; hestOptAdd(&hopt, NULL, "m00 m01 m02 m11 m12 m22", airTypeDouble, 6, 6, _tt, NULL, "symmtric matrix coeffs"); hestOptAdd(&hopt, "p", "vec", airTypeDouble, 3, 3, pp, "0 0 0", "rotation as P vector"); hestOptAdd(&hopt, "s", "scl", airTypeDouble, 1, 1, &ss, "1.0", "scaling"); hestParseOrDie(hopt, argc-1, argv+1, NULL, me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); ELL_6V_COPY(tt + 1, _tt); tt[0] = 1.0; TEN_T_SCALE(tt, ss, tt); ELL_4V_SET(qq, 1, pp[0], pp[1], pp[2]); ELL_4V_NORM(qq, qq, tmp); ell_q_to_3m_d(rot, qq); printf("%s: rot\n", me); printf(" %g %g %g\n", rot[0], rot[1], rot[2]); printf(" %g %g %g\n", rot[3], rot[4], rot[5]); printf(" %g %g %g\n", rot[6], rot[7], rot[8]); TEN_T2M(mat1, tt); ell_3m_mul_d(mat2, rot, mat1); ELL_3M_TRANSPOSE_IP(rot, tmp); ell_3m_mul_d(mat1, mat2, rot); TEN_M2T(tt, mat1); printf("input matrix = \n %g %g %g\n %g %g\n %g\n", tt[1], tt[2], tt[3], tt[4], tt[5], tt[6]); printf("================== tenEigensolve_d ==================\n"); roots = tenEigensolve_d(evalA, evecA, tt); printf("%s roots\n", airEnumStr(ell_cubic_root, roots)); testeigen(tt, evalA, evecA); printf("================== new eigensolve ==================\n"); roots = evals(evalB, tt[1], tt[2], tt[3], tt[4], tt[5], tt[6]); printf("%s roots: %g %g %g\n", airEnumStr(ell_cubic_root, roots), evalB[0], evalB[1], evalB[2]); roots = evals_evecs(evalB, evecB, tt[1], tt[2], tt[3], tt[4], tt[5], tt[6]); printf("%s roots\n", airEnumStr(ell_cubic_root, roots)); testeigen(tt, evalB, evecB); airMopOkay(mop); return 0; }
//A is an antisymmetric matrix and B is the output rotation matrix void make_rotation_matrix_notworking(const Array2 <doublevar> & A, Array2 <doublevar> & B) { int n=A.GetDim(0); assert(A.GetDim(1)==n); B.Resize(n,n); Array2 <dcomplex> skew(n,n),VL(n,n),VR(n,n); Array1 <dcomplex> evals(n); for(int i=0; i< n; i++) { for(int j=0; j < n; j++) { skew(i,j)=A(i,j); } } GeneralizedEigenSystemSolverComplexGeneralMatrices(skew,evals,VL,VR); cout << "evals " << endl; for(int i=0; i< n; i++) cout << evals(i) << " "; cout << endl; cout << "VR " << endl; for(int i=0; i< n; i++) { for(int j=0; j< n; j++) { cout << VR(i,j) << " "; } cout << endl; } cout << "VL " << endl; for(int i=0; i< n; i++) { for(int j=0; j< n; j++) { cout << VL(i,j) << " "; } cout << endl; } //this is horribly inefficient,most likely skew=dcomplex(0.0,0.); //we don't need that any more so we reuse it Array2 <dcomplex> work(n,n); work=dcomplex(0.0,0.); for(int i=0; i< n; i++) { skew(i,i)=exp(evals(i)); } for(int i=0; i< n; i++) { for(int j=0; j<n; j++) { for(int k=0; k< n; k++) { work(i,k)+=skew(i,j)*VR(j,k); } } } skew=dcomplex(0.,0.); for(int i=0; i< n; i++) { for(int j=0; j<n; j++) { for(int k=0; k< n; k++) { //skew(i,k)+=conj(VL(i,j))*work(j,k); skew(i,k)=conj(VR(j,i))*work(j,k); } } } cout << "rotation " << endl; for(int i=0; i< n; i++) { for(int j=0; j< n; j++) { cout << skew(i,j) << " "; } cout << endl; } }
int main(int argc, char *argv[]) { if(argc != 6 && argc != 7) { printf("usage: rrg N n s D seed (id_string)\n"); return 1; } time_t t1,t2,tI,tF; ITensor U,Dg,P,S; Index ei; // RRG structure parameters const int N = atoi(argv[1]); // should be n*(power of 2) const int n = atoi(argv[2]); // initial blocking size int w = n; // block size (scales with m) int ll = 0; // lambda block index int m = 0; // RG scale factor // AGSP and subspace parameters const double t = 0.3; // Trotter temperature const int M = 100; // num Trotter steps const int k = 1; // power of Trotter op (just use 1) const int s = atoi(argv[3]); // formal s param const int D = atoi(argv[4]); // formal D param // computational settings const bool doI = true; // diag restricted Hamiltonian iteratively? // setup random sampling std::random_device r; const int seed = atoi(argv[5]); fprintf(stderr,"seed is %d\n",seed); std::mt19937 gen(seed); std::uniform_real_distribution<double> udist(0.0,1.0); FILE *sxfl,*syfl,*szfl,*gsfl; char id[128],sxnm[256],synm[256],sznm[256],gsnm[256]; if(argc == 6) sprintf(id,"rrg-L%d-s%d-D%d",N,s,D); else sprintf(id,"%s",argv[6]); strcat(sxnm,id); strcat(sxnm,"-sx.dat"); strcat(synm,id); strcat(synm,"-sy.dat"); strcat(sznm,id); strcat(sznm,"-sz.dat"); strcat(gsnm,id); strcat(gsnm,"-gs.dat"); sxfl = fopen(sxnm,"a"); syfl = fopen(synm,"a"); szfl = fopen(sznm,"a"); gsfl = fopen(gsnm,"a"); // initialize Hilbert subspaces for each level m = 0,...,log(N/n) vector<SpinHalf> hsps; for(int x = n ; x <= N ; x *= 2) hsps.push_back(SpinHalf(x)); SpinHalf hs = hsps.back(); // generate product basis over m=0 Hilbert space auto p = int(pow(2,n)); vector<MPS> V1; for(int i = 0 ; i < p ; ++i) { InitState istate(hsps[0],"Dn"); for(int j = 1 ; j <= n ; ++j) if(i/(int)pow(2,j-1)%2) istate.set(j,"Up"); V1.push_back(MPS(istate)); } MPS bSpaceL(hsps[0]); MPS bSpaceR(hsps[0]); makeVS(V1,bSpaceL,LEFT); makeVS(V1,bSpaceR,RIGHT); // Hamiltonian parameters const double Gamma = 2.0; vector<double> J(2*(N-1)); fprintf(stdout,"# Hamiltonian terms Jx1,Jy1,Jx2,... (seed=%d)\n",seed); for(int i = 0 ; i < N-1 ; ++i) { J[2*i+0] = pow(udist(gen),Gamma); J[2*i+1] = pow(udist(gen),Gamma); fprintf(stdout,"%16.14f,%16.14f",J[2*i],J[2*i+1]); if(i != N-2) fprintf(stdout,","); } fprintf(stdout,"\n"); fflush(stdout); // initialize H for full system and extract block Hamiltonians AutoMPO autoH(hs); std::stringstream sts; auto out = std::cout.rdbuf(sts.rdbuf()); vector<vector<MPO> > Hs(hsps.size()); for(int i = 1 ; i < N ; ++i) { autoH += (J[2*(i-1)]-J[2*(i-1)+1]),"S+",i,"S+",i+1; autoH += (J[2*(i-1)]-J[2*(i-1)+1]),"S-",i,"S-",i+1; autoH += (J[2*(i-1)]+J[2*(i-1)+1]),"S+",i,"S-",i+1; autoH += (J[2*(i-1)]+J[2*(i-1)+1]),"S-",i,"S+",i+1; } auto H = toMPO<ITensor>(autoH,{"Exact",true}); std::cout.rdbuf(out); for(auto i : args(hsps)) extractBlocks(autoH,Hs[i],hsps[i]); vector<MPO> prodSz,prodSx,projSzUp,projSzDn,projSxUp,projSxDn; for(auto& it : hsps) { auto curSz = sysOp(it,"Sz",2.0).toMPO(); prodSz.push_back(curSz); auto curSx = sysOp(it,"Sx",2.0).toMPO(); prodSx.push_back(curSx); auto curSzUp = sysOp(it,"Id").toMPO(); curSzUp.plusEq(curSz); curSzUp /= 2.0; auto curSzDn = sysOp(it,"Id").toMPO(); curSzDn.plusEq(-1.0*curSz); curSzDn /= 2.0; auto curSxUp = sysOp(it,"Id").toMPO(); curSxUp.plusEq(curSx); curSxUp /= 2.0; auto curSxDn = sysOp(it,"Id").toMPO(); curSxDn.plusEq(-1.0*curSx); curSxDn /= 2.0; projSzUp.push_back(curSzUp); projSzDn.push_back(curSzDn); projSxUp.push_back(curSxUp); projSxDn.push_back(curSxDn); } // approximate the thermal operator exp(-H/t)^k using Trotter // and MPO multiplication; temperature of K is k/t time(&tI); MPO eH(hs); twoLocalTrotter(eH,t,M,autoH); auto K = eH; for(int i = 1 ; i < k ; ++i) { nmultMPO(eH,K,K,{"Cutoff",eps,"Maxm",MAXBD}); K.Aref(1) *= 1.0/norm(K.A(1)); } // INITIALIZATION: reduce dimension by sampling from initial basis, either // bSpaceL or bSpaceR depending on how the merge will work vector<MPS> Spre; for(ll = 0 ; ll < N/n ; ll++) { auto xs = ll % 2 ? 1 : n; // location of dangling Select index auto cur = ll % 2 ? bSpaceR : bSpaceL; Index si("ext",s,Select); // return orthonormal basis of evecs auto eigs = diagHermitian(-overlapT(cur,Hs[0][ll],cur),P,S,{"Maxm",s}); cur.Aref(xs) *= P*delta(commonIndex(P,S),si); regauge(cur,xs,{"Truncate",false}); Spre.push_back(cur); } time(&t2); fprintf(stderr,"initialization: %.f s\n",difftime(t2,tI)); // ITERATION: proceed through RRG hierarchy, increasing the scale m vector<MPS> Spost; for(m = 0 ; (int)Spre.size() > 1 ; ++m,w*=2) { fprintf(stderr,"Level %d (w = %d)\n",m,w); auto hs = hsps[m]; auto DD = D;//max(4,D/(int(log2(N/n)-m))); auto thr = 1e-8; Spost.clear(); // EXPAND STEP: for each block, expand dimension of subspace with AGSP operators for(ll = 0 ; ll < N/w ; ++ll) { MPO A(hs) , Hc = Hs[m][ll]; MPS pre = Spre[ll] , ret(hs); int xs = ll % 2 ? 1 : w; // STEP 1: extract filtering operators A from AGSP K time(&t1); restrictMPO(K,A,w*ll+1,DD,ll%2); time(&t2); fprintf(stderr,"trunc AGSP: %.f s\n",difftime(t2,t1)); // STEP 2: expand subspace using the mapping A:pre->ret time(&t1); ret = applyMPO(A,pre,ll%2,{"Cutoff",eps,"Maxm",MAXBD}); time(&t2); fprintf(stderr,"apply AGSP: %.f s\n",difftime(t2,t1)); // rotate into principal components of subspace, poxsibly reducing dimension // and stabilizing numerics, then store subspace in eigenbasis of block H time(&t1); diagHermitian(overlapT(ret,ret),U,Dg,{"Cutoff",thr}); time(&t2); ei = Index("ext",int(commonIndex(Dg,U)),Select); Dg.apply(invsqrt); ret.Aref(xs) *= dag(U)*Dg*delta(prime(commonIndex(Dg,U)),ei); fprintf(stderr,"rotate MPS: %.f s\n",difftime(t2,t1)); auto eigs = diagHermitian(-overlapT(ret,Hs[m][ll],ret),P,S); ret.Aref(xs) *= P*delta(commonIndex(P,S),ei); ret.Aref(xs) *= 1.0/sqrt(overlapT(ret,ret).real(ei(1),prime(ei)(1))); regauge(ret,xs,{"Cutoff",eps}); fprintf(stderr,"max m: %d\n",maxM(ret)); Spost.push_back(ret); } // MERGE/REDUCE STEP: construct tensor subspace, sample to reduce dimension Spre.clear(); for(ll = 0 ; ll < N/w ; ll+=2) { auto spL = Spost[ll]; // L subspace auto spR = Spost[ll+1]; // R subspace // STEP 1: find s lowest eigenpairs of restricted H time(&t1); auto tpH = tensorProdContract(spL,spR,Hs[m+1][ll/2]); tensorProdH<ITensor> resH(tpH); resH.diag(s,doI); P = resH.eigenvectors(); time(&t2); fprintf(stderr,"diag restricted H: %.f s\n",difftime(t2,t1)); // STEP 2: tensor viable sets on each side and reduce dimension MPS ret(hsps[m+1]); time(&t1); tensorProduct(spL,spR,ret,P,(ll/2)%2); time(&t2); fprintf(stderr,"tensor product (ll=%d): %.f s\n",ll,difftime(t2,t1)); Spre.push_back(ret); } } // EXIT: extract two lowest energy candidate states to determine gap auto res = Spre[0]; auto fi = Index("ext",s/2,Select); vector<MPS> resSz = {res,res}; // project to Sz sectors of the eigenspace diagHermitian(overlapT(res,prodSz[m],res),U,Dg); resSz[0].Aref(N) *= U*delta(commonIndex(U,Dg),fi); diagHermitian(overlapT(res,-1.0*prodSz[m],res),U,Dg); resSz[1].Aref(N) *= U*delta(commonIndex(U,Dg),fi); vector<MPS> evecs(2); for(int i : range(2)) { auto fc = resSz[i]; // diagonalize H within the Sz sectors auto eigs = diagHermitian(-overlapT(fc,H,fc),P,S); fc.Aref(N) *= (P*setElt(commonIndex(P,S)(1))); fc.orthogonalize({"Cutoff",epx,"Maxm",MAXBD}); fc.normalize(); if(i == 0) fprintf(stderr,"RRG gs energy: %17.14f\n",overlap(fc,H,fc)); evecs[i] = fc; } time(&t2); Real vz,vx; vz = overlap(evecs[0],prodSz[m],evecs[0]); vx = overlap(evecs[0],prodSx[m],evecs[0]); fprintf(stderr,"Vz,vx of 0 is: %17.14f,%17.14f\n",vz,vx); vz = overlap(evecs[1],prodSz[m],evecs[1]); vx = overlap(evecs[1],prodSx[m],evecs[1]); fprintf(stderr,"Vz,vx of 1 is: %17.14f,%17.14f\n",vz,vx); int x1_up = (vx > 0.0 ? 1 : 0); evecs[0] = exactApplyMPO(evecs[0],projSzUp[m],{"Cutoff",epx}); evecs[0] = exactApplyMPO(evecs[0],projSxUp[m],{"Cutoff",epx}); evecs[1] = exactApplyMPO(evecs[1],projSzDn[m],{"Cutoff",epx}); evecs[1] = exactApplyMPO(evecs[1],(x1_up?projSxUp[m]:projSxDn[m]),{"Cutoff",epx}); for(auto& it : evecs) it.normalize(); fprintf(stderr,"gs candidate energy: %17.14f\nRRG BD ",overlap(evecs[0],H,evecs[0])); for(const auto& it : evecs) fprintf(stderr,"%d ",maxM(it)); fprintf(stderr,"\telapsed: %.f s\n",difftime(t2,tI)); // CLEANUP: use DMRG to improve discovered evecs vector<Real> evals(2),e_prev(2); int max_iter = 30 , used_max = 0; Real flr = 1e-13 , over_conv = 1e-1 , gap = 1.0 , conv = over_conv*gap , max_conv = 1.0; for(int i = 0 ; i < (int)evecs.size() ; ++i) evals[i] = overlap(evecs[i],H,evecs[i]); for(int i = 0 ; (i < 2 || conv < max_conv) && i < max_iter ; ++i) { e_prev = evals; time(&t1); evals = dmrgMPO(H,evecs,8,{"Penalty",0.1,"Cutoff",epx}); time(&t2); gap = evals[1]-evals[0]; max_conv = 0.0; for(auto& j : range(2)) if(fabs(e_prev[j]-evals[j]) > max_conv) max_conv = e_prev[j]-evals[j]; fprintf(stderr,"DMRG BD "); for(const auto& it : evecs) fprintf(stderr,"%3d ",maxM(it)); fprintf(stderr,"\tgap: %e\tconv=%9.2e,%9.2e\telapsed: %.f s\n",gap, e_prev[0]-evals[0],e_prev[1]-evals[1],difftime(t2,t1)); conv = max(over_conv*gap,flr); if(i == max_iter) used_max = 1; } for(int i = 0 ; i < (int)evecs.size() ; ++i) { vz = overlap(evecs[i],prodSz[m],evecs[i]); vx = overlap(evecs[i],prodSx[m],evecs[i]); fprintf(stderr,"Vz,vx of %d is: %12.9f,%12.9f\n",i,vz,vx); } evecs[0] = exactApplyMPO(evecs[0],projSzUp[m],{"Cutoff",1e-16}); evecs[0] = exactApplyMPO(evecs[0],projSxUp[m],{"Cutoff",1e-16}); evecs[1] = exactApplyMPO(evecs[1],projSzDn[m],{"Cutoff",1e-16}); evecs[1] = exactApplyMPO(evecs[1],(x1_up?projSxUp[m]:projSxDn[m]),{"Cutoff",1e-16}); for(auto& it : evecs) it.normalize(); for(auto i : range(evecs.size())) evals[i] = overlap(evecs[i],H,evecs[i]); time(&tF); auto gsR = evecs[0]; auto ee = measEE(gsR,N/2); gap = evals[1]-evals[0]; fprintf(stderr,"gs: %17.14f gap: %15.9e ee: %10.8f\n",evals[0],gap,ee); fprintf(gsfl,"# GS data (L=%d s=%d D=%d seed=%d time=%.f)\n",N,s,D,seed,difftime(tF,tI)); if(used_max) fprintf(gsfl,"# WARNING max iterations reached\n"); fprintf(gsfl,"%17.14f\t%15.9e\t%10.8f\n",evals[0],gap,ee); // Compute two-point correlation functions in ground state via usual MPS method fprintf(sxfl,"# SxSx corr matrix (L=%d s=%d D=%d seed=%d)\n",N,s,D,seed); fprintf(syfl,"# SySy corr matrix (L=%d s=%d D=%d seed=%d)\n",N,s,D,seed); fprintf(szfl,"# SzSz corr matrix (L=%d s=%d D=%d seed=%d)\n",N,s,D,seed); for(int i = 1 ; i <= N ; ++i) { gsR.position(i,{"Cutoff",0.0}); auto SxA = hs.op("Sx",i); auto SyA = hs.op("Sy",i); auto SzA = hs.op("Sz",i); for(int j = 1 ; j <= N ; ++j) { if(j <= i) { fprintf(sxfl,"%15.12f\t",0.0); fprintf(syfl,"%15.12f\t",0.0); fprintf(szfl,"%15.12f\t",0.0); } else { auto SxB = hs.op("Sx",j); auto SyB = hs.op("Sy",j); auto SzB = hs.op("Sz",j); fprintf(sxfl,"%15.12f\t",measOp(gsR,SxA,i,SxB,j)); fprintf(syfl,"%15.12f\t",measOp(gsR,SyA,i,SyB,j)); fprintf(szfl,"%15.12f\t",measOp(gsR,SzA,i,SzB,j)); } } fprintf(sxfl,"\n"); fprintf(syfl,"\n"); fprintf(szfl,"\n"); } fclose(sxfl); fclose(syfl); fclose(szfl); fclose(gsfl); return 0; }
void ContactAngle2::doFrame(int frame) { StuntDouble* sd; int i; // set up the bins for density analysis Mat3x3d hmat = info_->getSnapshotManager()->getCurrentSnapshot()->getHmat(); RealType len = std::min(hmat(0, 0), hmat(1, 1)); RealType zLen = hmat(2,2); RealType dr = len / (RealType) nRBins_; RealType dz = zLen / (RealType) nZBins_; std::vector<std::vector<RealType> > histo; histo.resize(nRBins_); for (unsigned int i = 0; i < histo.size(); ++i){ histo[i].resize(nZBins_); std::fill(histo[i].begin(), histo[i].end(), 0.0); } if (evaluator1_.isDynamic()) { seleMan1_.setSelectionSet(evaluator1_.evaluate()); } Vector3d com(centroidX_, centroidY_, solidZ_); // now that we have the centroid, we can make cylindrical density maps Vector3d pos; RealType r; RealType z; for (sd = seleMan1_.beginSelected(i); sd != NULL; sd = seleMan1_.nextSelected(i)) { pos = sd->getPos() - com; // r goes from zero upwards r = sqrt(pow(pos.x(), 2) + pow(pos.y(), 2)); // z is possibly symmetric around 0 z = pos.z(); int whichRBin = int(r / dr); int whichZBin = int( (zLen/2.0 + z) / dz); if ((whichRBin < int(nRBins_)) && (whichZBin >= 0) && (whichZBin < int(nZBins_))) { histo[whichRBin][whichZBin] += sd->getMass(); } } for(unsigned int i = 0 ; i < histo.size(); ++i){ RealType rL = i * dr; RealType rU = rL + dr; RealType volSlice = NumericConstant::PI * dz * (( rU*rU ) - ( rL*rL )); for (unsigned int j = 0; j < histo[i].size(); ++j) { histo[i][j] *= PhysicalConstants::densityConvert / volSlice; } } std::vector<Vector<RealType, 2> > points; points.clear(); for (unsigned int j = 0; j < nZBins_; ++j) { // The z coordinates were measured relative to the selection // center of mass. However, we're interested in the elevation // above the solid surface. Also, the binning was done around // zero with enough bins to cover the zLength of the box: RealType thez = com.z() - solidZ_ - zLen/2.0 + dz * (j + 0.5); bool aboveThresh = false; bool foundThresh = false; int rloc = 0; for (std::size_t i = 0; i < nRBins_; ++i) { if (histo[i][j] >= threshDens_) aboveThresh = true; if (aboveThresh && (histo[i][j] <= threshDens_)) { rloc = i; foundThresh = true; aboveThresh = false; } } if (foundThresh) { Vector<RealType,2> point; point[0] = dr*(rloc+0.5); point[1] = thez; if (thez > bufferLength_) { points.push_back( point ); } } } int numPoints = points.size(); // Compute the average of the data points. Vector<RealType, 2> average = points[0]; int i0; for (i0 = 1; i0 < numPoints; ++i0) { average += points[i0]; } RealType invNumPoints = ((RealType)1)/(RealType)numPoints; average *= invNumPoints; DynamicRectMatrix<RealType> mat(4, 4); int row, col; for (row = 0; row < 4; ++row) { for (col = 0; col < 4; ++col){ mat(row,col) = 0.0; } } for (int i = 0; i < numPoints; ++i) { RealType x = points[i][0]; RealType y = points[i][1]; RealType x2 = x*x; RealType y2 = y*y; RealType xy = x*y; RealType r2 = x2+y2; RealType xr2 = x*r2; RealType yr2 = y*r2; RealType r4 = r2*r2; mat(0,1) += x; mat(0,2) += y; mat(0,3) += r2; mat(1,1) += x2; mat(1,2) += xy; mat(1,3) += xr2; mat(2,2) += y2; mat(2,3) += yr2; mat(3,3) += r4; } mat(0,0) = (RealType)numPoints; for (row = 0; row < 4; ++row) { for (col = 0; col < row; ++col) { mat(row,col) = mat(col,row); } } for (row = 0; row < 4; ++row) { for (col = 0; col < 4; ++col) { mat(row,col) *= invNumPoints; } } JAMA::Eigenvalue<RealType> eigensystem(mat); DynamicRectMatrix<RealType> evects(4, 4); DynamicVector<RealType> evals(4); eigensystem.getRealEigenvalues(evals); eigensystem.getV(evects); DynamicVector<RealType> evector = evects.getColumn(0); RealType inv = ((RealType)1)/evector[3]; // beware zero divide RealType coeff[3]; for (row = 0; row < 3; ++row) { coeff[row] = inv*evector[row]; } Vector<RealType, 2> center; center[0] = -((RealType)0.5)*coeff[1]; center[1] = -((RealType)0.5)*coeff[2]; RealType radius = sqrt(fabs(center[0]*center[0] + center[1]*center[1] - coeff[0])); int i1; for (i1 = 0; i1 < 100; ++i1) { // Update the iterates. Vector<RealType, 2> current = center; // Compute average L, dL/da, dL/db. RealType lenAverage = (RealType)0; Vector<RealType, 2> derLenAverage = Vector<RealType, 2>(0.0); for (i0 = 0; i0 < numPoints; ++i0) { Vector<RealType, 2> diff = points[i0] - center; RealType length = diff.length(); if (length > 1e-6) { lenAverage += length; RealType invLength = ((RealType)1)/length; derLenAverage -= invLength*diff; } } lenAverage *= invNumPoints; derLenAverage *= invNumPoints; center = average + lenAverage*derLenAverage; radius = lenAverage; Vector<RealType, 2> diff = center - current; if (fabs(diff[0]) <= 1e-6 && fabs(diff[1]) <= 1e-6) { break; } } RealType zCen = center[1]; RealType rDrop = radius; RealType ca; if (fabs(zCen) > rDrop) { ca = 180.0; } else { ca = 90.0 + asin(zCen/rDrop)*(180.0/M_PI); } values_.push_back( ca ); }