// Solve vector<double> Solve(GiNaC::ex Ex, GiNaC::symbol Sym) { vector<double> Roots; unsigned Degree = Ex.degree(Sym); auto Coeffs = GetCoeffs(Ex, Sym); // Bhaskara. if (Degree == 2) { GiNaC::ex A = Coeffs[2]; GiNaC::ex B = Coeffs[1]; GiNaC::ex C = Coeffs[0]; GiNaC::ex Delta = B*B - 4 * A * C; // Guaranteed real roots. if (GiNaC::is_a<GiNaC::numeric>(Delta) && !GiNaC::ex_to<GiNaC::numeric>(Delta).is_negative()) { GiNaC::ex Delta = GiNaC::sqrt(B*B - 4 * A * C).evalf(); GiNaC::ex One = ((-B) + Delta)/(2*A); GiNaC::ex Two = ((-B) - Delta)/(2*A); if (GiNaC::is_a<GiNaC::numeric>(One)) Roots.push_back(GiNaC::ex_to<GiNaC::numeric>(One.evalf()).to_double()); if (GiNaC::is_a<GiNaC::numeric>(Two)) Roots.push_back(GiNaC::ex_to<GiNaC::numeric>(Two.evalf()).to_double()); } } // Cardano. else if (Degree == 3) { GiNaC::ex A = Coeffs[3]; GiNaC::ex B = Coeffs[2]; GiNaC::ex C = Coeffs[1]; GiNaC::ex D = Coeffs[1]; GiNaC::ex Delta0 = B*B - 3 * A * C; GiNaC::ex Delta1 = 2 * B*B*B - 9 * A * B * C + 27 * A * A * D; GiNaC::ex CD = Delta1 + GiNaC::sqrt(Delta1 * Delta1 - 4 * GiNaC::pow(Delta0, 3)); CD = CD/2; CD = GiNaC::pow(CD, GiNaC::numeric(1)/3); GiNaC::symbol U("u"); GiNaC::ex Var = GiNaC::numeric(-1)/(3 * A) * (B + U * CD + Delta0/(U * CD)); GiNaC::ex One = Var.subs(U == 1); GiNaC::ex Two = Var.subs(U == ((-1 + GiNaC::sqrt(GiNaC::numeric(-3)))/2)); GiNaC::ex Three = Var.subs(U == ((-1 - GiNaC::sqrt(GiNaC::numeric(-3)))/2)); if (GiNaC::is_a<GiNaC::numeric>(One)) Roots.push_back(GiNaC::ex_to<GiNaC::numeric>(One.evalf()).to_double()); if (GiNaC::is_a<GiNaC::numeric>(Two)) Roots.push_back(GiNaC::ex_to<GiNaC::numeric>(Two.evalf()).to_double()); if (GiNaC::is_a<GiNaC::numeric>(Three)) Roots.push_back(GiNaC::ex_to<GiNaC::numeric>(Three.evalf()).to_double()); } return Roots; }
MatrixWrapper::ColumnVector NonLinearAnalyticConditionalGaussian_Ginac::ExpectedValueGet() const { MatrixWrapper::ColumnVector u_num (u_size); MatrixWrapper::ColumnVector x_num (x_size); MatrixWrapper::ColumnVector func_num(func_size); GiNaC::ex substitute (func_size); MatrixWrapper::ColumnVector expected(func_size); u_num = ConditionalArgumentGet(1); x_num = ConditionalArgumentGet(0); // use Mu of additive noise if (cond_size!=0) for (unsigned int i=0; i<u_size; i++) for (unsigned int j=0; j<cond_size; j++) if (u_sym[i] == cond_sym[j]) u_num(i+1) += (this->AdditiveNoiseMuGet())(j+1); // evaluate func for (unsigned int i=0; i<func_size; i++) { // temp variable to substitute in substitute = func_sym(i,0); // substitute all u_sym with u_num for (unsigned int j=0; j<u_size; j++) substitute = substitute.subs( u_sym[j]==u_num(j+1) ); // substitute all x_sym with x_num for (unsigned int j=0; j<x_size; j++) substitute = substitute.subs( x_sym[j]==x_num(j+1) ); // build matrix func_num func_num(i+1) = GiNaC::ex_to<GiNaC::numeric>( substitute.evalf() ).to_double(); } expected = func_num; if (cond_size==0) expected += AdditiveNoiseMuGet(); return expected; }