int main() { GaussianEliminator terminator(4); unsigned short int r1[] = {0, 1, 2}; unsigned short int r2[] = {1, 3}; unsigned short int r3[] = {0, 1}; unsigned short int r4[] = {3}; Equation eq; std::copy ( r1, r1 + 3, std::back_inserter ( eq ) ); terminator.addEquation(eq, true); eq.clear(); std::copy ( r2, r2 + 2, std::back_inserter ( eq ) ); terminator.addEquation(eq, true); eq.clear(); std::copy ( r3, r3 + 2, std::back_inserter ( eq ) ); terminator.addEquation(eq, false); eq.clear(); std::copy ( r4, r4 + 1, std::back_inserter ( eq ) ); terminator.addEquation(eq, true); std::vector <bool> sol = terminator.getSolution(); for (std::vector <bool>::iterator it = sol.begin(); it < sol.end(); it ++) std::cout << *it << std::endl; return 0; }
/*** * FUNCTION: Integrates equation using Simpson method * RETURN: Definite integral of equation * PARAM: [IN] equation - equation to integrate * PARAM: [IN] start - left integration border * PARAM: [IN] end - right integration border * PARAM: [IN] numIterations - number of iterations * SEE: write me * AUTHOR: Eliseev Dmitry ***/ Equation ParametricIntegrator::Simpson( const Equation &equation, const double start, const double end, const unsigned int numIterations ) { unsigned int i = 0; /* Timer creation */ Timer timer; /* Result equation */ Equation result = Equation(start) + Equation(end); /* Odd members */ Equation oddResult("0"); for (i = 1; i <= 2 * numIterations - 1; i+=2) oddResult += equation.GetEquation(start + (end - start) * i / (2 * numIterations)); /* Even members */ Equation evenResult("0"); for (i = 2; i <= 2 * numIterations - 2; i+=2) evenResult += equation.GetEquation(start + (end - start) * i / (2 * numIterations)); /* Add calculated values */ result += Equation("4") * oddResult + Equation("2") * evenResult; /* That's it */ result *= Equation((end - start) / (6 * numIterations)); result.Simplify(); /* Determine spent time */ numSeconds = timer.GetTimePassed(); return result; } /* End of 'Integrator::Simpson' method */
std::string operator()(Equation const & e, bool use_parenthesis = false) const { std::stringstream ss; ss << operator()(e.lhs()) << " = " << operator()(e.rhs()); static_cast<int>(use_parenthesis); //to silence unused parameter warnings return ss.str(); }
void slack_matrix::init_geqz_constraints(Matrix& m) { geqz_constraints = new bool[m.num_vars()]; memset(geqz_constraints, 0, m.num_vars()*sizeof(bool)); Matrix::iterator it = m.begin(); for(; it!= m.end(); it++) { bignum constant = it->second; if(constant > 0) continue; int index = -1; Equation* eq = it->first; for(int c=0; c<eq->num_entries(); c++) { bignum e = eq->get(c); if(e > 0){ index = -1; break; } else if(e<0 && index != -1) { index = -1; break; } else if(e<0) index = c; } // Mark entry as 1 if var has non-negativity constraint if(index != -1) geqz_constraints[index] = true; } }
int main() { std::cout << "Hello World" << std::endl; // a # b # c # d # e # f # g # h # i = 60 // a + 10 * b - c / d + 11 / e - f + 12 * g / h + i + 13 = 60 Equation eq; eq.logical(); return EXIT_SUCCESS; }
void CreateForces() { //Creates force objects that can be referenced by the body object. //You can have multiple references to the same force object. for (int i = 0; i < 6; i++) { Active1.listCoefficients().push_back(complex<double>(i+1,-i-1)); } //Create some equations with variables to add into derivative object Derivative Deriv1; Derivative Deriv2; Equation* temp; for (int i = 0; i < 6; i++) { Deriv1.listEquation().push_back(Equation()); Deriv2.listEquation().push_back(Equation()); temp = &(Deriv1.listEquation().at(i)); temp->setDataIndex(i); //Set first derivative for (int j = 0; j < 6; j++) { temp->setCoefficient(j+1,j+1); } //Set second derivative temp = &(Deriv2.listEquation().at(i)); temp->setDataIndex(i); for (int j = 0; j < 6; j++) { temp->setCoefficient(2*i+1,j*i+1); } } //add the two derivatives into the react force object React1.addDerivative(Deriv1, 0); React1.addDerivative(Deriv2, 1); //Add the two derivatives into the cross force object Cross1.addDerivative(Deriv1, 0); Cross1.addDerivative(Deriv2, 1); }
//----------------------------------------------------------------------------- void dolfin::solve(const Equation& equation, Function& u, std::vector<const BoundaryCondition*> bcs, const Form& J, Parameters parameters) { // Check that the problem is linear if (equation.is_linear()) dolfin_error("solve.cpp", "solve nonlinear variational problem", "Variational problem is linear"); // Solve nonlinear problem NonlinearVariationalProblem problem(*equation.lhs(), u, bcs, J); NonlinearVariationalSolver solver(problem); solver.parameters.update(parameters); solver.solve(); }
//----------------------------------------------------------------------------- void dolfin::solve(const Equation& equation, Function& u, std::vector<const DirichletBC*> bcs, const double tol, GoalFunctional& M) { // Solve linear problem if (equation.is_linear()) { LinearVariationalProblem problem(*equation.lhs(), *equation.rhs(), u, bcs); AdaptiveLinearVariationalSolver solver(problem, M); solver.solve(tol); } else { // Raise error if the problem is nonlinear (for now) dolfin_error("solve.cpp", "solve nonlinear variational problem adaptively", "Nonlinear adaptive solve not implemented without Jacobian"); } }
int main() { string str; while(getline(cin,str)) { Equation *EQ = new Equation(str); if(!(EQ->IsValid())) { cout << "Invalid Equation!\n"; continue; } EquationSolver *solver; if(EQ->IsLinear()) solver = new LinearEquationSolver(EQ); else solver = new NonLinearEquationSolver(EQ); solver->Solve(); vector<double> *SS = solver->GetSolutionSet(); vector<pair<long long, long long> > *FR = solver->GetFractions(); for(int i = 0; i < SS->size(); i++) cout << (*SS)[i] << endl; } return 0; }
//----------------------------------------------------------------------------- void dolfin::solve(const Equation& equation, Function& u, std::vector<const DirichletBC*> bcs, const Form& J, const double tol, GoalFunctional& M) { // Raise error if problem is linear if (equation.is_linear()) dolfin_error("solve.cpp", "solve nonlinear variational problem adaptively", "Variational problem is linear"); // Define nonlinear problem NonlinearVariationalProblem problem(*equation.lhs(), u, bcs, J); // Solve nonlinear problem adaptively AdaptiveNonlinearVariationalSolver solver(problem, M); solver.solve(tol); }
//----------------------------------------------------------------------------- void dolfin::solve(const Equation& equation, Function& u, std::vector<const BoundaryCondition*> bcs, Parameters parameters) { // Solve linear problem if (equation.is_linear()) { LinearVariationalProblem problem(*equation.lhs(), *equation.rhs(), u, bcs); LinearVariationalSolver solver(problem); solver.parameters.update(parameters); solver.solve(); } // Solve nonlinear problem else { NonlinearVariationalProblem problem(*equation.lhs(), u, bcs); NonlinearVariationalSolver solver(problem); solver.parameters.update(parameters); solver.solve(); } }
/*** * FUNCTION: Integrates equation using center-rectangles method * RETURN: Definite integral of equation * PARAM: [IN] equation - equation to integrate * PARAM: [IN] start - left integration border * PARAM: [IN] end - right integration border * PARAM: [IN] numIterations - number of iterations * SEE: write me * AUTHOR: Eliseev Dmitry ***/ Equation ParametricIntegrator::Rectangles( const Equation &equation, const double start, const double end, const unsigned int numIterations ) { double step = (end - start) / numIterations; unsigned int i = 0; /* Result equation */ Equation result("0"); Equation width(step); /* Timer creation */ Timer timer; /* For each iteration */ for (i = 0; i < numIterations; i++) result += width * equation.GetEquation(step * i); /* That's it */ result.Simplify(); /* Determine spent time */ numSeconds = timer.GetTimePassed(); return result; } /* End of 'Integrator::Rectangles' method */
bool GaussianEliminator::addEquation(Equation eq, bool term) { Row nrow; while(eq.size()) { unsigned short int fp = eq[0]; if (rows[fp].set){ eq += rows[fp].eq; term ^= constTerms[fp]; } else { rows[fp].set = true; rows[fp].eq = eq; constTerms[fp] = term; rowsUnset --; break; } } if (isSolvable()) return true; return false; }
void addVar(Variable var) { eq.push_back(var); }
void Newton::Solve(double xZ) { //cout << "\n Solving:" << inputEQ << " x0:" << xZ << endl; vector<string> TermInitiators; string temp; for(int i = 0; i < inputEQ.size(); i++) { ///Check for sign of leading term if(i == 0) { if(inputEQ[i]=='-') { //First term was negative //cout << inputEQ[i] << "<- 1 was neg" << endl; temp = temp + inputEQ[i]; } else { //First term was positive //cout << inputEQ[i] << "<- 1 was pos" << endl; temp = temp + '+'; temp = temp + inputEQ[i]; } } else { if( inputEQ[i] == '+' || inputEQ[i] == '-' ) { if(inputEQ[i-1] == '^' && inputEQ[i] == '-') { temp = temp + inputEQ[i]; } else { //End of term TermInitiators.push_back(temp); temp = ""; temp = temp + inputEQ[i]; } } else { //Term component temp = temp + inputEQ[i]; } } } //final push TermInitiators.push_back(temp); ///Now that we have terms in a vector of strings ///Pass that vector to the constructor of an ///Equation. double xIn = xZ; double xOut; double fX, fXPrime;//Results Equation * theEquation = new Equation(TermInitiators); ///creates an equation which can accept values ///Get derivative of equation theEquation->Derivative(); vector<string> pTermsInitiators; for(int i = 0; i < theEquation->PrimeTerms.size(); i++) { pTermsInitiators.push_back(theEquation->PrimeTerms[i].og); } Equation * thePrimeEquation = new Equation(pTermsInitiators); ///creates an equation of prime terms which can accept values /* x ------==Iterative Solving Part==------ x */ double a = 0,b = 0; double test = 0; xIn = 1; int j = 0; while(solved == false) { theEquation->plugin(xIn); a = theEquation->anzwer; thePrimeEquation->plugin(xIn); b = thePrimeEquation->anzwer; xOut = a / b; xOut = xIn - xOut; xIn = xOut; ///Test if close enough theEquation->plugin(xIn); test = theEquation->anzwer; if(test < TOLERABLEERROR) { //cout << "!!Decent!!" << endl; solved = true; } j++; } cout << "\n\nAnswer is: "<< xOut << " after " << j << " iterations." << endl; }
// -----------Private methods ------------------// void slack_matrix::populate_slack_matrix(Matrix& m) { /* * If the initial system is Ax <= b, * the slack matrix will contain it in the form * -x0 + y +Ax -b * and the last row is the objective function, initially -x0. */ Matrix::iterator it = m.begin(); int last = m.size()-1; /* vector<int> rows; std::set<int> used; for(int i=0; i <= last; i++) { int cur = rand()%(last+1); while(used.count(cur) > 0){ cur++; cur = cur%(last+1); } used.insert(cur); rows.push_back(cur); } */ int r = 0; int i = 0; for(; it!=m.end(); it++, r++, i++) { r = i;//rows[i]; // s0 entry is initially -1 for all rows sm->set(r, 0, -1); // In row r, set the corresponding slack variable to 1. sm->set(r, i+1, 1); Equation *eq = it->first; for(int c=0; c < eq->num_entries(); c++) { int start_index = index_mapping[c]; bignum coef = eq->get(c); sm->set(r, start_index, coef); /* Figure out whether we needed to split * x as x1-x2 for missing non-negative constraints */ if(geqz_constraints[c]) continue; sm->set(r, start_index+1, -coef); } //Deal with original constant sm->set_constant(r, -it->second); //Fill last slot with index of pivot variable for this row sm->set_pivot(r, i+1); } /* * Populate objective function row: Initially we want * to maximize -x0 */ sm->set(last+1, 0, -1); }
void Solver::solve(int printDebugInfo){ int i, j, k, l; std::vector<Equation*> eqs; getEquations(&eqs); int numRows = getSystemMatrixRows(), neq = eqs.size(), nconstraints=m_constraints.size(); // Compute RHS double * rhs = (double*)malloc(numRows*sizeof(double)); for(i=0; i<neq; ++i){ Equation * eq = eqs[i]; double Z = eq->getFutureVelocity() - eq->getVelocity(), GW = eq->getVelocity(), g = eq->getViolation(), a = eq->m_a, b = eq->m_b; rhs[i] = -a * g - b * GW - Z; // RHS = -a*g -b*G*W -Z } // Compute matrix S = G * inv(M) * G' = G * z // Should be easy, since we already got the entries from the user std::vector<int> Srow; std::vector<int> Scol; std::vector<double> Sval; for (int i = 0; i < neq; ++i){ for (int j = 0; j < neq; ++j){ // We are at element i,j in S Equation * ei = eqs[i]; Equation * ej = eqs[j]; double val = 0; int nonzero = 0; if(ei->getConnA() == ej->getConnA()){ val += ei->getGA().multiply(ej->getddA()); nonzero = 1; } if(ei->getConnA() == ej->getConnB()){ val += ei->getGA().multiply(ej->getddB()); nonzero = 1; } if(ei->getConnB() == ej->getConnA()){ val += ei->getGB().multiply(ej->getddA()); nonzero = 1; } if(ei->getConnB() == ej->getConnB()){ val += ei->getGB().multiply(ej->getddB()); nonzero = 1; } if(nonzero){ Srow.push_back(i); Scol.push_back(j); Sval.push_back(val); } } } // Add regularization to diagonal entries for (int i = 0; i < eqs.size(); ++i){ double eps = eqs[i]->m_epsilon; if(eps > 0){ int found = 0; // Find the corresponding triplet for(int j = 0; j < Srow.size(); ++j){ if(Srow[j] == i && Scol[j] == i){ Sval[j] += eps; found = 1; break; } } // Could not find triplet. Add it. if(!found){ Sval.push_back(eps); Srow.push_back(i); Scol.push_back(i); } } } // Print matrices if(printDebugInfo){ for (int i = 0; i < Srow.size(); ++i){ printf("(%d,%d) => %g\n",Scol[i],Srow[i],Sval[i]); } char empty = '0'; char tab = '\t'; printf("G = [\n"); for(int i=0; i<eqs.size(); ++i){ Equation * eq = eqs[i]; Connector * connA = eq->getConnA(); Connector * connB = eq->getConnB(); //printf("%d %d\n",connA->m_index,connB->m_index); int swapped = 0; if(connA->m_index > connB->m_index){ Connector * temp = connA; connA = connB; connB = temp; swapped = 1; } // Print empty until first for (int j = 0; j < 6*connA->m_index; ++j){ printf("%c\t",empty); } // Print contents of first ( 6 jacobian entries ) JacobianElement G = !swapped ? eq->getGA() : eq->getGB(); printf("%g%c%g%c%g%c%g%c%g%c%g%c", G.getSpatial().x(),tab, G.getSpatial().y(),tab, G.getSpatial().z(),tab, G.getRotational().x(),tab, G.getRotational().y(),tab, G.getRotational().z(),tab); // Print empty until second for (int j = 6*(connA->m_index+1); j < 6*connB->m_index; ++j){ printf("%c\t",empty); } // Print contents of second ( 6 jacobian entries ) JacobianElement G2 = !swapped ? eq->getGB() : eq->getGA(); printf("%g%c%g%c%g%c%g%c%g%c%g%c", G2.getSpatial().x(),tab, G2.getSpatial().y(),tab, G2.getSpatial().z(),tab, G2.getRotational().x(),tab, G2.getRotational().y(),tab, G2.getRotational().z(),tab); // Print empty until end of row for (int j = 6*(connB->m_index+1); j < getSystemMatrixCols(); ++j){ printf("%c\t",empty); } if(i == eqs.size()-1) printf("]\n"); else printf(";\n"); } printf("D = [\n"); for(int i=0; i<eqs.size(); ++i){ Equation * eq = eqs[i]; Connector * connA = eq->getConnA(); Connector * connB = eq->getConnB(); //printf("%d %d\n",connA->m_index,connB->m_index); int swapped = 0; if(connA->m_index > connB->m_index){ Connector * temp = connA; connA = connB; connB = temp; swapped = 1; } // Print empty until first for (int j = 0; j < 6*connA->m_index; ++j){ printf("%c\t",empty); } // Print contents of first ( 6 jacobian entries ) JacobianElement G = !swapped ? eq->getddA() : eq->getddB(); printf("%g%c%g%c%g%c%g%c%g%c%g%c", G.getSpatial().x(),tab, G.getSpatial().y(),tab, G.getSpatial().z(),tab, G.getRotational().x(),tab, G.getRotational().y(),tab, G.getRotational().z(),tab); // Print empty until second for (int j = 6*(connA->m_index+1); j < 6*connB->m_index; ++j){ printf("%c\t",empty); } // Print contents of second ( 6 jacobian entries ) JacobianElement G2 = !swapped ? eq->getddB() : eq->getddA(); printf("%g%c%g%c%g%c%g%c%g%c%g%c", G2.getSpatial().x(),tab, G2.getSpatial().y(),tab, G2.getSpatial().z(),tab, G2.getRotational().x(),tab, G2.getRotational().y(),tab, G2.getRotational().z(),tab); // Print empty until end of row for (int j = 6*(connB->m_index+1); j < getSystemMatrixCols(); ++j){ printf("%c\t",empty); } if(i == eqs.size()-1) printf("]\n"); else printf(";\n"); } printf("E = [\n"); for (int i = 0; i < eqs.size(); ++i){ // Rows for (int j = 0; j < eqs.size(); ++j){ // Cols if(i==j) printf("%g\t", eqs[i]->m_epsilon); else printf("0\t"); } if(i == eqs.size()-1) printf("]\n"); else printf(";\n"); } printf("S = [\n"); for (int i = 0; i < eqs.size(); ++i){ // Rows for (int j = 0; j < eqs.size(); ++j){ // Cols // Find element i,j int found = 0; for(int k = 0; k < Srow.size(); ++k){ if(Srow[k] == i && Scol[k] == j){ printf("%g\t", Sval[k]); found = 1; break; } } if(!found) printf("%c\t",empty); } if(i == eqs.size()-1) printf("]\n"); else printf(";\n"); } } // convert vectors to arrays int * aSrow = (int *) malloc ((Srow.size()+1) * sizeof (int)); int * aScol = (int *) malloc ((Scol.size()+1) * sizeof (int)); double * aSval = (double *) malloc ((Sval.size()+1) * sizeof (double)); for (int i = 0; i < Srow.size(); ++i){ aSval[i] = Sval[i]; aScol[i] = Scol[i]; aSrow[i] = Srow[i]; //printf("(%d,%d) = %g\n", Srow[i], Scol[i], Sval[i]); } void *Symbolic, *Numeric; double Info [UMFPACK_INFO], Control [UMFPACK_CONTROL]; // Default control umfpack_di_defaults (Control) ; // convert to column form int nz = Sval.size(), // Non-zeros n = eqs.size(), // Number of equations nz1 = std::max(nz,1) ; // ensure arrays are not of size zero. int * Ap = (int *) malloc ((n+1) * sizeof (int)) ; int * Ai = (int *) malloc (nz1 * sizeof (int)) ; double * lambda = (double *) malloc (n * sizeof (double)) ; double * Ax = (double *) malloc (nz1 * sizeof (double)) ; if (!Ap || !Ai || !Ax){ fprintf(stderr, "out of memory\n") ; } if(printDebugInfo) printf("n=%d, nz=%d\n",n, nz); // Triplet form to column form int status = umfpack_di_triplet_to_col (n, n, nz, aSrow, aScol, aSval, Ap, Ai, Ax, (int *) NULL) ; if (status < 0){ umfpack_di_report_status (Control, status) ; fprintf(stderr, "umfpack_di_triplet_to_col failed\n") ; exit(1); } // symbolic factorization status = umfpack_di_symbolic (n, n, Ap, Ai, Ax, &Symbolic, Control, Info) ; if (status < 0){ umfpack_di_report_info (Control, Info) ; umfpack_di_report_status (Control, status) ; fprintf(stderr,"umfpack_di_symbolic failed\n") ; exit(1); } // numeric factorization status = umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control, Info) ; if (status < 0){ umfpack_di_report_info (Control, Info) ; umfpack_di_report_status (Control, status) ; fprintf(stderr,"umfpack_di_numeric failed\n") ; exit(1); } // solve S*lambda = B status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, lambda, rhs, Numeric, Control, Info) ; umfpack_di_report_info (Control, Info) ; umfpack_di_report_status (Control, status) ; if (status < 0){ fprintf(stderr,"umfpack_di_solve failed\n") ; exit(1); } // Set current connector forces to zero resetConstraintForces(); // Store results // Remember that we need to divide lambda by the timestep size // f = G'*lambda for (int i = 0; i<eqs.size(); ++i){ Equation * eq = eqs[i]; double l = lambda[i] / eq->m_timeStep; JacobianElement GA = eq->getGA(); JacobianElement GB = eq->getGB(); Vec3 fA = GA.getSpatial() * l; Vec3 tA = GA.getRotational() * l; Vec3 fB = GB.getSpatial() * l; Vec3 tB = GB.getRotational() * l; // We are on row i in the matrix eq->getConnA()->m_force += fA; eq->getConnA()->m_torque += tA; eq->getConnB()->m_force += fB; eq->getConnB()->m_torque += tB; /* printf("forceA += %g %g %g\n", fA[0], fA[1], fA[2]); printf("torqueA += %g %g %g\n", tA[0], tA[1], tA[2]); printf("forceB += %g %g %g\n", fB[0], fB[1], fB[2]); printf("torqueB += %g %g %g\n", tB[0], tB[1], tB[2]); printf(" GAs = %g %g %g\n", GA.getSpatial()[0], GA.getSpatial()[1], GA.getSpatial()[2]); printf(" GBs = %g %g %g\n", GB.getSpatial()[0], GB.getSpatial()[1], GB.getSpatial()[2]); printf(" GAr = %g %g %g\n", GA.getRotational()[0], GA.getRotational()[1], GA.getRotational()[2]); printf(" GBr = %g %g %g\n", GB.getRotational()[0], GB.getRotational()[1], GB.getRotational()[2]); printf("\n"); */ } // Print matrices if(printDebugInfo){ printf("RHS = [\n"); for (int i = 0; i < eqs.size(); ++i){ printf("%g\n",rhs[i]); } printf("]\n"); printf("umfpackSolution = [\n"); for (int i = 0; i < eqs.size(); ++i){ printf("%g\n",lambda[i]); } printf("]\n"); printf("octaveSolution = S \\ RHS\n"); printf("Gt_lambda = [\n"); int numSlaves = m_slaves.size(); for(int i=0; i<numSlaves; ++i){ int Nconns = m_slaves[i]->numConnectors(); for(int j=0; j<Nconns; ++j){ Connector * c = m_slaves[i]->getConnector(j); printf("%g\n%g\n%g\n%g\n%g\n%g\n", c->m_force[0], c->m_force[1], c->m_force[2], c->m_torque[0], c->m_torque[1], c->m_torque[2]); } } printf("]\n"); } free(rhs); free(lambda); free(aSrow); free(aScol); free(aSval); free(Ap); free(Ai); free(Ax); umfpack_di_free_symbolic(&Symbolic); umfpack_di_free_numeric(&Numeric); }