Skip to content

Instantly share code, notes, and snippets.

@marionette-of-u
Created August 11, 2015 11:36
Show Gist options
  • Save marionette-of-u/52179d0d2fe0a26d497f to your computer and use it in GitHub Desktop.
Save marionette-of-u/52179d0d2fe0a26d497f to your computer and use it in GitHub Desktop.
代数方程式の数値解を全部出力しようとして複素数に対応してなかったせいで途中でハングするプログラムです
std::vector<numeric> nth_root(const ex &f_, const symbol &x, const numeric epsilon = std::numeric_limits<double>::epsilon()){
ex f = f_;
std::vector<numeric> result;
int deg = f.degree(x);
result.reserve(deg);
ex g = f.diff(x);
numeric xn = deg / 2.0, xm;
for(; ; ){
xm = xn - ex_to<numeric>(f.subs(x == xn)) / ex_to<numeric>(g.subs(x == xn));
if(abs(xn - xm) < epsilon){
result.push_back(xm);
int ndeg = deg;
if(ndeg - 1 == 0){ break; }
ex nf;
std::map<int, ex> fcoeff;
if(is_a<add>(f)){
for(auto iter = f.begin(); iter != f.end(); ++iter){
fcoeff.insert(std::make_pair(iter->degree(x), iter->lcoeff(x)));
}
}else{
fcoeff.insert(std::make_pair(f.degree(x), f.lcoeff(x)));
}
auto iter = fcoeff.rbegin();
ex b = 1;
do{
--ndeg;
if(iter->second.degree(x) == ndeg + 1){
b = iter->second.lcoeff(x) + b * xm;
++iter;
}else{
b *= xm;
}
nf += pow(x, ndeg) * b;
}while(ndeg > 0);
f = nf;
g = f.diff(x);
--deg;
}
xn = xm;
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment