//! @brief Sets the size of the system from the number of vertices in the graph. int XC::BandArpackSOE::setSize(Graph &theGraph) { int result = 0; size= checkSize(theGraph); // determine the number of superdiagonals and subdiagonals theGraph.getBand(numSubD,numSuperD); const int newSize = size * (2*numSubD + numSuperD +1); if(newSize > A.Size()) A.resize(newSize); A.Zero(); factored = false; // invoke setSize() on the XC::Solver EigenSolver *theSolvr = this->getSolver(); int solverOK = theSolvr->setSize(); if(solverOK < 0) { std::cerr << "WARNING: BandArpackSOE::setSize :"; std::cerr << " solver failed setSize()\n"; return solverOK; } return result; }
int main(int, char**) { cout.precision(3); EigenSolver<MatrixXf> es; MatrixXf A = MatrixXf::Random(4,4); es.compute(A, /* computeEigenvectors = */ false); cout << "The eigenvalues of A are: " << es.eigenvalues().transpose() << endl; es.compute(A + MatrixXf::Identity(4,4), false); // re-use es to compute eigenvalues of A+I cout << "The eigenvalues of A+I are: " << es.eigenvalues().transpose() << endl; return 0; }
AsymptoticNewmark::AsymptoticNewmark(Scalar beta, Scalar gamma, int DOFS, Scalar massDamp, Scalar stiffDamp, Scalar ts, const Reference<Mesh>& m, const Reference<NodeIndexer>& nodeIndexer, ReducedHyperelasticMaterial* mater) :Intergrator(DOFS, massDamp, stiffDamp, ts){ int orderCount = mater->getNonlinearAsymptoticOrder(); int entrys = orderCount*dofs; d = allocAligned<Scalar>(entrys); v = allocAligned<Scalar>(entrys); a = allocAligned<Scalar>(entrys); pre_d = allocAligned<Scalar>(entrys); pre_v = allocAligned<Scalar>(entrys); pre_a = allocAligned<Scalar>(entrys); externalVirtualWork = allocAligned<Scalar>(entrys); memset(d, 0, entrys*sizeof(Scalar)); memset(v, 0, entrys*sizeof(Scalar)); memset(a, 0, entrys*sizeof(Scalar)); memset(pre_d, 0, entrys*sizeof(Scalar)); memset(pre_v, 0, entrys*sizeof(Scalar)); memset(pre_a, 0, entrys*sizeof(Scalar)); memset(externalVirtualWork, 0, entrys*sizeof(Scalar)); mesh = m; indexer = nodeIndexer; material = mater; betaDeltaT2 = beta*timeStep*timeStep; gammaDeltaT = gamma*timeStep; minusBetaDeltaT2 = timeStep*timeStep*Scalar(0.5) - betaDeltaT2; minusGammaDeltaT = timeStep - gammaDeltaT; totalDofs = indexer->getMatrixOrder(mesh); frequencies2 = allocAligned<Scalar>(dofs); basises = allocAligned<Scalar>(dofs*totalDofs); SparseMatrixAssembler M(totalDofs); SparseMatrixAssembler K(totalDofs); material->generateMassMatrix(mesh, indexer, M); material->generateStiffnessMatrix(mesh, indexer, K); EigenSolver slover; slover.getEigenValVectors(dofs, M, K, frequencies2, basises); material->preprocessWithReduction(mesh, indexer); loadFactors = allocAligned<Scalar>(orderCount); fullDisplacements = allocAligned<Scalar>(orderCount*totalDofs); vwBuffer = allocAligned<Scalar>(totalDofs); #ifdef ODER_DEBUG for (int i = 0; i < dofs; i++){ if (frequencies2[i] < 0.0) Severe("Stiffness Matrix is not semi-define"); } #endif }
template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m) { EigenSolver<MatrixType> eig; VERIFY_RAISES_ASSERT(eig.eigenvectors()); VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors()); VERIFY_RAISES_ASSERT(eig.pseudoEigenvalueMatrix()); VERIFY_RAISES_ASSERT(eig.eigenvalues()); MatrixType a = MatrixType::Random(m.rows(),m.cols()); eig.compute(a, false); VERIFY_RAISES_ASSERT(eig.eigenvectors()); VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors()); }
int SymArpackSOE::setSize(Graph &theGraph) { int result = 0; int oldSize = size; size = theGraph.getNumVertex(); // fist itearte through the vertices of the graph to get nnz Vertex *theVertex; int newNNZ = 0; VertexIter &theVertices = theGraph.getVertices(); while ((theVertex = theVertices()) != 0) { const ID &theAdjacency = theVertex->getAdjacency(); newNNZ += theAdjacency.Size(); } nnz = newNNZ; if (colA != 0) delete [] colA; colA = new int[newNNZ]; if (colA == 0) { opserr << "WARNING SymArpackSOE::SymArpackSOE :"; opserr << " ran out of memory for colA with nnz = "; opserr << newNNZ << " \n"; size = 0; nnz = 0; result = -1; } factored = false; if (rowStartA != 0) delete [] rowStartA; rowStartA = new int[size+1]; if (rowStartA == 0) { opserr << "SymArpackSOE::ran out of memory for rowStartA." << endln; result = -1; } // fill in rowStartA and colA if (size != 0) { rowStartA[0] = 0; int startLoc = 0; int lastLoc = 0; for (int a=0; a<size; a++) { theVertex = theGraph.getVertexPtr(a); if (theVertex == 0) { opserr << "WARNING:SymArpackSOE::setSize :"; opserr << " vertex " << a << " not in graph! - size set to 0\n"; size = 0; return -1; } const ID &theAdjacency = theVertex->getAdjacency(); int idSize = theAdjacency.Size(); // now we have to place the entries in the ID into order in colA for (int i=0; i<idSize; i++) { int row = theAdjacency(i); bool foundPlace = false; for (int j=startLoc; j<lastLoc; j++) if (colA[j] > row) { // move the entries already there one further on // and place col in current location for (int k=lastLoc; k>j; k--) colA[k] = colA[k-1]; colA[j] = row; foundPlace = true; j = lastLoc; } if (foundPlace == false) // put in at the end colA[lastLoc] = row; lastLoc++; } rowStartA[a+1] = lastLoc;; startLoc = lastLoc; } } // begin to choose different ordering schema. // cout << "Enter DOF Numberer Type: \n"; // cout << "[1] Minimum Degree, [2] Nested Dissection, [3] RCM: "; int LSPARSE = 1; // cin >> LSPARSE; // call "C" function to form elimination tree and do the symbolic factorization. // nblks = symFactorization(rowStartA, colA, size, LSPARSE); nblks = symFactorization(rowStartA, colA, size, LSPARSE, &xblk, &invp, &rowblks, &begblk, &first, &penv, &diag); // invoke setSize() on the Solver EigenSolver *theSolvr = this->getSolver(); int solverOK = theSolvr->setSize(); if (solverOK < 0) { opserr << "WARNING:BandArpackSOE::setSize :"; opserr << " solver failed setSize()\n"; return solverOK; } return result; }
void computeSimpleStars(StarSet& stars, SparseOptimizer* optimizer, EdgeLabeler* labeler, EdgeCreator* creator, OptimizableGraph::Vertex* gauge_, std::string edgeTag, std::string vertexTag, int level, int step, int backboneIterations, int starIterations, double rejectionThreshold, bool debug){ cerr << "preforming the tree actions" << endl; HyperDijkstra d(optimizer); // compute a spanning tree based on the types of edges and vertices in the pool EdgeTypesCostFunction f(edgeTag, vertexTag, level); d.shortestPaths(gauge_, &f, std::numeric_limits< double >::max(), 1e-6, false, std::numeric_limits< double >::max()/2); HyperDijkstra::computeTree(d.adjacencyMap()); // constructs the stars on the backbone BackBoneTreeAction bact(optimizer, vertexTag, level, step); bact.init(); cerr << "free edges size " << bact.freeEdges().size() << endl; // perform breadth-first visit of the visit tree and create the stars on the backbone d.visitAdjacencyMap(d.adjacencyMap(),&bact,true); stars.clear(); for (VertexStarMultimap::iterator it=bact.vertexStarMultiMap().begin(); it!=bact.vertexStarMultiMap().end(); it++){ stars.insert(it->second); } cerr << "stars.size: " << stars.size() << endl; cerr << "size: " << bact.vertexStarMultiMap().size() << endl; // for each star // for all vertices in the backbone, select all edges leading/leaving from that vertex // that are contained in freeEdges. // mark the corresponding "open" vertices and add them to a multimap (vertex->star) // select a gauge in the backbone // push all vertices on the backbone // compute an initial guess on the backbone // one round of optimization backbone // lock all vertices in the backbone // push all "open" vertices // for each open vertex, // compute an initial guess given the backbone // do some rounds of solveDirect // if (fail) // - remove the vertex and the edges in that vertex from the star // - make the structures consistent // pop all "open" vertices // pop all "vertices" in the backbone // unfix the vertices in the backbone int starNum=0; for (StarSet::iterator it=stars.begin(); it!=stars.end(); it++){ Star* s =*it; HyperGraph::VertexSet backboneVertices = s->_lowLevelVertices; HyperGraph::EdgeSet backboneEdges = s->_lowLevelEdges; if (backboneEdges.empty()) continue; // cerr << "optimizing backbone" << endl; // one of these should be the gauge, to be simple we select the fisrt one in the backbone OptimizableGraph::VertexSet gauge; gauge.insert(*backboneVertices.begin()); s->gauge()=gauge; s->optimizer()->push(backboneVertices); s->optimizer()->setFixed(gauge,true); s->optimizer()->initializeOptimization(backboneEdges); s->optimizer()->computeInitialGuess(); s->optimizer()->optimize(backboneIterations); s->optimizer()->setFixed(backboneVertices, true); // cerr << "assignind edges.vertices not in bbone" << endl; HyperGraph::EdgeSet otherEdges; HyperGraph::VertexSet otherVertices; std::multimap<HyperGraph::Vertex*, HyperGraph::Edge*> vemap; for (HyperGraph::VertexSet::iterator bit=backboneVertices.begin(); bit!=backboneVertices.end(); bit++){ HyperGraph::Vertex* v=*bit; for (HyperGraph::EdgeSet::iterator eit=v->edges().begin(); eit!=v->edges().end(); eit++){ OptimizableGraph::Edge* e = (OptimizableGraph::Edge*) *eit; HyperGraph::EdgeSet::iterator feit=bact.freeEdges().find(e); if (feit!=bact.freeEdges().end()){ // edge is admissible otherEdges.insert(e); bact.freeEdges().erase(feit); for (size_t i=0; i<e->vertices().size(); i++){ OptimizableGraph::Vertex* ve= (OptimizableGraph::Vertex*)e->vertices()[i]; if (backboneVertices.find(ve)==backboneVertices.end()){ otherVertices.insert(ve); vemap.insert(make_pair(ve,e)); } } } } } // RAINER TODO maybe need a better solution than dynamic casting here?? OptimizationAlgorithmWithHessian* solverWithHessian = dynamic_cast<OptimizationAlgorithmWithHessian*>(s->optimizer()->solver()); if (solverWithHessian) { s->optimizer()->push(otherVertices); // cerr << "optimizing vertices out of bbone" << endl; // cerr << "push" << endl; // cerr << "init" << endl; s->optimizer()->initializeOptimization(otherEdges); // cerr << "guess" << endl; s->optimizer()->computeInitialGuess(); // cerr << "solver init" << endl; s->optimizer()->solver()->init(); // cerr << "structure" << endl; if (!solverWithHessian->buildLinearStructure()) cerr << "FATAL: failure while building linear structure" << endl; // cerr << "errors" << endl; s->optimizer()->computeActiveErrors(); // cerr << "system" << endl; solverWithHessian->updateLinearSystem(); // cerr << "directSolove" << endl; } else { cerr << "FATAL: hierarchical thing cannot be used with a solver that does not support the system structure construction" << endl; } // // then optimize the vertices one at a time to check if a solution is good for (HyperGraph::VertexSet::iterator vit=otherVertices.begin(); vit!=otherVertices.end(); vit++){ OptimizableGraph::Vertex* v=(OptimizableGraph::Vertex*)(*vit); v->solveDirect(); // cerr << " " << d; // if a solution is found, add a vertex and all the edges in //othervertices that are pointing to that edge to the star s->_lowLevelVertices.insert(v); for (HyperGraph::EdgeSet::iterator eit=v->edges().begin(); eit!=v->edges().end(); eit++){ OptimizableGraph::Edge* e = (OptimizableGraph::Edge*) *eit; if (otherEdges.find(e)!=otherEdges.end()) s->_lowLevelEdges.insert(e); } } //cerr << endl; // relax the backbone and optimize it all // cerr << "relax bbone" << endl; s->optimizer()->setFixed(backboneVertices, false); //cerr << "fox gauge bbone" << endl; s->optimizer()->setFixed(s->gauge(),true); //cerr << "opt init" << endl; s->optimizer()->initializeOptimization(s->_lowLevelEdges); optimizer->computeActiveErrors(); double initialChi = optimizer->activeChi2(); int starOptResult = s->optimizer()->optimize(starIterations); //cerr << starOptResult << "(" << starIterations << ") " << endl; double finalchi=-1.; cerr << "computing star: " << starNum << endl; int vKept=0, vDropped=0; if (!starIterations || starOptResult > 0 ){ optimizer->computeActiveErrors(); finalchi = optimizer->activeChi2(); #if 1 s->optimizer()->computeActiveErrors(); // cerr << "system" << endl; if (solverWithHessian) solverWithHessian->updateLinearSystem(); HyperGraph::EdgeSet prunedStarEdges = backboneEdges; HyperGraph::VertexSet prunedStarVertices = backboneVertices; for (HyperGraph::VertexSet::iterator vit=otherVertices.begin(); vit!=otherVertices.end(); vit++){ //discard the vertices whose error is too big OptimizableGraph::Vertex* v=(OptimizableGraph::Vertex*)(*vit); MatrixXd h(v->dimension(), v->dimension()); for (int i=0; i<v->dimension(); i++){ for (int j=0; j<v->dimension(); j++) h(i,j)=v->hessian(i,j); } EigenSolver<Eigen::MatrixXd> esolver; esolver.compute(h); VectorXcd ev= esolver.eigenvalues(); double emin = std::numeric_limits<double>::max(); double emax = -std::numeric_limits<double>::max(); for (int i=0; i<ev.size(); i++){ emin = ev(i).real()>emin ? emin : ev(i).real(); emax = ev(i).real()<emax ? emax : ev(i).real(); } double d=emin/emax; // cerr << " " << d; if (d>rejectionThreshold){ // if a solution is found, add a vertex and all the edges in //othervertices that are pointing to that edge to the star prunedStarVertices.insert(v); for (HyperGraph::EdgeSet::iterator eit=v->edges().begin(); eit!=v->edges().end(); eit++){ OptimizableGraph::Edge* e = (OptimizableGraph::Edge*) *eit; if (otherEdges.find(e)!=otherEdges.end()) prunedStarEdges.insert(e); } //cerr << "K( " << v->id() << "," << d << ")" ; vKept ++; } else { vDropped++; //cerr << "R( " << v->id() << "," << d << ")" ; } } s->_lowLevelEdges=prunedStarEdges; s->_lowLevelVertices=prunedStarVertices; #endif //cerr << "addHedges" << endl; //now add to the star the hierarchical edges std::vector<OptimizableGraph::Vertex*> vertices(2); vertices[0]= (OptimizableGraph::Vertex*) *s->_gauge.begin(); for (HyperGraph::VertexSet::iterator vit=s->_lowLevelVertices.begin(); vit!=s->_lowLevelVertices.end(); vit++){ OptimizableGraph::Vertex* v=(OptimizableGraph::Vertex*)*vit; vertices[1]=v; if (v==vertices[0]) continue; OptimizableGraph::Edge* e=creator->createEdge(vertices); //rr << "creating edge" << e << Factory::instance()->tag(vertices[0]) << "->" << Factory::instance()->tag(v) <endl; if (e) { e->setLevel(level+1); optimizer->addEdge(e); s->_starEdges.insert(e); } else { cerr << "HERE" << endl; cerr << "FATAL, cannot create edge" << endl; } } } cerr << " gauge: " << (*s->_gauge.begin())->id() << " kept: " << vKept << " dropped: " << vDropped << " edges:" << s->_lowLevelEdges.size() << " hedges" << s->_starEdges.size() << " initial chi " << initialChi << " final chi " << finalchi << endl; if (debug) { char starLowName[100]; sprintf(starLowName, "star-%04d-low.g2o", starNum); ofstream starLowStream(starLowName); optimizer->saveSubset(starLowStream, s->_lowLevelEdges); } bool labelOk=false; if (!starIterations || starOptResult > 0) labelOk = s->labelStarEdges(0, labeler); if (labelOk) { if (debug) { char starHighName[100]; sprintf(starHighName, "star-%04d-high.g2o", starNum); ofstream starHighStream(starHighName); optimizer->saveSubset(starHighStream, s->_starEdges); } } else { cerr << "FAILURE: " << starOptResult << endl; } starNum++; //label each hierarchical edge s->optimizer()->pop(otherVertices); s->optimizer()->pop(backboneVertices); s->optimizer()->setFixed(s->gauge(),false); } StarSet stars2; // now erase the stars that have 0 edges. They r useless for (StarSet::iterator it=stars.begin(); it!=stars.end(); it++){ Star* s=*it; if (s->lowLevelEdges().size()==0) { delete s; } else stars2.insert(s); } stars=stars2; }
SGMatrix<float64_t> CUWedge::diagonalize(SGNDArray<float64_t> C, SGMatrix<float64_t> V0, double eps, int itermax) { int d = C.dims[0]; int L = C.dims[2]; SGMatrix<float64_t> V; if (V0.num_rows == d && V0.num_cols == d) { V = V0.clone(); } else { Map<MatrixXd> C0(C.get_matrix(0),d,d); EigenSolver<MatrixXd> eig; eig.compute(C0); // sort eigenvectors MatrixXd eigenvectors = eig.pseudoEigenvectors(); MatrixXd eigenvalues = eig.pseudoEigenvalueMatrix(); bool swap = false; do { swap = false; for (int j = 1; j < d; j++) { if ( eigenvalues(j,j) > eigenvalues(j-1,j-1) ) { std::swap(eigenvalues(j,j),eigenvalues(j-1,j-1)); eigenvectors.col(j).swap(eigenvectors.col(j-1)); swap = true; } } } while(swap); V = SGMatrix<float64_t>::create_identity_matrix(d,1); Map<MatrixXd> EV(V.matrix, d,d); EV = eigenvalues.cwiseAbs().cwiseSqrt().inverse() * eigenvectors.transpose(); } Map<MatrixXd> EV(V.matrix, d,d); index_t * Cs_dims = SG_MALLOC(index_t, 3); Cs_dims[0] = d; Cs_dims[1] = d; Cs_dims[2] = L; SGNDArray<float64_t> Cs(Cs_dims,3); sg_memcpy(Cs.array, C.array, Cs.dims[0]*Cs.dims[1]*Cs.dims[2]*sizeof(float64_t)); MatrixXd Rs(d,L); std::vector<float64_t> crit; crit.push_back(0.0); for (int l = 0; l < L; l++) { Map<MatrixXd> Ci(C.get_matrix(l),d,d); Map<MatrixXd> Csi(Cs.get_matrix(l),d,d); Ci = 0.5 * (Ci + Ci.transpose()); Csi = EV * Ci * EV.transpose(); Rs.col(l) = Csi.diagonal(); crit.back() += Csi.cwiseAbs2().sum() - Rs.col(l).cwiseAbs2().sum(); } float64_t iter = 0; float64_t improve = 10; while (improve > eps && iter < itermax) { MatrixXd B = Rs * Rs.transpose(); MatrixXd C1 = MatrixXd::Zero(d,d); for (int id = 0; id < d; id++) { // rowSums for (int l = 0; l < L; l++) { Map<MatrixXd> Csi(Cs.get_matrix(l),d,d); C1.row(id) += Csi.row(id) * Rs(id,l); } } MatrixXd D0 = B.cwiseProduct(B.transpose()) - B.diagonal() * B.diagonal().transpose(); MatrixXd A0 = MatrixXd::Identity(d,d) + (C1.cwiseProduct(B) - B.diagonal().asDiagonal() * C1.transpose()).cwiseQuotient(D0+MatrixXd::Identity(d,d)); EV = A0.inverse() * EV; Map<MatrixXd> C0(C.get_matrix(0),d,d); MatrixXd Raux = EV * C0 * EV.transpose(); MatrixXd aux = Raux.diagonal().cwiseAbs().cwiseSqrt().asDiagonal().inverse(); EV = aux * EV; crit.push_back(0.0); for (int l = 0; l < L; l++) { Map<MatrixXd> Ci(C.get_matrix(l),d,d); Map<MatrixXd> Csi(Cs.get_matrix(l),d,d); Csi = EV * Ci * EV.transpose(); Rs.col(l) = Csi.diagonal(); crit.back() += Csi.cwiseAbs2().sum() - Rs.col(l).cwiseAbs2().sum(); } improve = CMath::abs(crit.back() - crit[iter]); iter++; } if (iter == itermax) SG_SERROR("Convergence not reached\n") return V; }