// 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;
  }