Guest User

anonymous

a guest
Jan 5th, 2011
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.23 KB | None | 0 0
  1. #include "maths.h"
  2. #include <limits>
  3.  
  4. inline void skip_ws(const char*& str){
  5.     while(*str == ' ') str++;
  6. }
  7.  
  8. //== COMPLEX ==//
  9.  
  10. Complex::Complex(double a, double b) : a(a), b(b) {}
  11.  
  12. Complex::Complex(double a) : a(a), b(0) {}
  13.  
  14. Complex::Complex() : a(0), b(0) {}
  15.  
  16. Complex operator + (Complex A, Complex B){
  17.     return Complex(A.a+B.a, A.b+B.b);
  18. }
  19. Complex operator - (Complex A, Complex B){
  20.     return Complex(A.a-B.a, A.b-B.b);
  21. }
  22. Complex operator * (Complex A, Complex B){
  23.     return Complex(A.a*B.a - A.b*B.b, A.a*B.b + A.b*B.a);
  24. }
  25. Complex operator / (Complex A, Complex B){
  26.     return Complex( (A.a*B.a+A.b*B.b) / (B.a*B.a+B.b*B.b), (A.b*B.a-A.a*B.b) / (B.a*B.a+B.b*B.b) );
  27. }
  28. bool operator == (Complex A, Complex B){
  29.     return abs(A.a-B.a) < std::numeric_limits<double>::epsilon()*256
  30.         && abs(A.b-B.b) < std::numeric_limits<double>::epsilon()*256;
  31. }
  32.  
  33. std::ostream& operator << (std::ostream& out, Complex c){
  34.     out << "(" << c.a << ", " << c.b << "i)";
  35.     return out;
  36. }
  37.  
  38.  
  39. //== ELEMENT ==//
  40.  
  41. Element::Element() : b(0), ref(0) {}
  42.  
  43. Element::Element(Base* b) : b(b), ref(new int(1)) {}
  44.  
  45. Element::Element(const Element& e){
  46.     b = e.b;
  47.     ref = e.ref;
  48.     if(ref) (*ref)++;
  49. }
  50.  
  51. Element::~Element(){
  52.     rem();
  53. }
  54.  
  55. Element& Element::operator = (const Element& e){
  56.     if(&e == this) return *this;
  57.     rem();
  58.     b = e.b;
  59.     ref = e.ref;
  60.     if(ref) (*ref)++;
  61.     return *this;
  62. }
  63.  
  64. void Element::rem(){
  65.     if(!ref) return;
  66.     (*ref)--;
  67.     if(*ref == 0){
  68.         delete b;
  69.         delete ref;
  70.     }
  71. }
  72.  
  73. std::ostream& operator << (std::ostream& out, Element e){
  74.     if(e.b) e.b->print(out);
  75.     else out << " [null] ";
  76.     return out;
  77. }
  78.  
  79. //== NUMBER ==//
  80. Number::Number(int i) : num(i), den(1) {}
  81.    
  82. Number::Number() : num(0), den(1) {}
  83.  
  84. Number::Number(int n, int d){
  85.     int g = gcd(n, d);
  86.     num = n/g;
  87.     den = d/g;
  88. }
  89.    
  90. Number::Number(const char*& str){
  91.     num = 0;
  92.     den = 1;
  93.        
  94.     bool dot = 0;
  95.     while(*str >= '0' && *str <= '9' || *str == '.'){
  96.         if(*str == '.') dot = 1;
  97.         else{
  98.             num = num*10 + *str - '0';
  99.             if(dot) den *= 10;
  100.         }
  101.         str++;
  102.     }
  103. }
  104.  
  105. int Number::gcd(int a, int b){
  106.     if(a != 0 && b != 0) while(a % b != 0){
  107.         a = a % b;
  108.         std::swap(a, b);
  109.     }
  110.     return b;
  111. }
  112.    
  113. Element Number::simplify(){
  114.     return new Number(num, den);
  115. }
  116.  
  117. Base::Type Number::type() { return Base::number; }
  118.  
  119. void Number::print(std::ostream& out){
  120.     out<< " [" << num << "/" << den << "] ";
  121. }
  122.  
  123. Complex Number::eval(Complex x){
  124.     return double(num)/den;
  125. }
  126. std::vector<Complex> Number::solve(){
  127.     return std::vector<Complex>();
  128. }
  129. Element Number::coefficient(){
  130.     return new Number(num, den);
  131. }
  132. unsigned Number::degree(){
  133.     return 0;
  134. }
  135. //== X ==//
  136. X::X() {}
  137.  
  138. X::X(const char*& str){
  139.     str++;
  140. }
  141.  
  142. Element X::simplify(){
  143.     return new X();
  144. }
  145.  
  146. Base::Type X::type() { return Base::x; }
  147.  
  148. void X::print(std::ostream& out){
  149.     out << " X ";
  150. }
  151.  
  152. Complex X::eval(Complex x){
  153.     return x;
  154. }
  155. std::vector<Complex> X::solve(){
  156.     std::vector<Complex> root;
  157.     root.push_back(0);
  158.     return root;
  159. }
  160. Element X::coefficient(){
  161.     return new Number(1);
  162. }
  163. unsigned X::degree(){
  164.     return 1;
  165. }
  166. //== MONO ==//
  167. Mono::Mono() {}
  168. Mono::Mono(const char*& str){
  169.     bool mul = 1;
  170.     if(*str == '-') num.push_back(new Number(-1));
  171.     else if(*str != '+') str--;
  172.     str++;
  173.  
  174.     skip_ws(str);
  175.  
  176.     while(1){
  177.         if(*str >= '0' && *str <= '9'){
  178.             if(mul) num.push_back(new Number(str));
  179.             else den.push_back(new Number(str));
  180.         }
  181.         else if(*str == '('){
  182.             str++;
  183.             if(mul) num.push_back(new Poly(str));
  184.             else den.push_back(new Poly(str));
  185.         }
  186.         else if(*str == 'x'){
  187.             if(mul) num.push_back(new X(str));
  188.             else den.push_back(new X(str));
  189.         }
  190.         else if(*str == '/'){
  191.             mul = 0;
  192.             str++;
  193.         }
  194.         else if(*str == '*'){
  195.             mul = 1;
  196.             str++;
  197.         }
  198.         else break;
  199.         skip_ws(str);
  200.     }
  201. }
  202.  
  203. Element Mono::simplify(){
  204.     Element e;
  205.     for(unsigned i = 0; i < num.size(); i++)
  206.         if(e.b == 0) e = num[i].b->simplify();
  207.         else e = e * num[i];
  208.  
  209.     if(e.b == 0) e = new Number(1);
  210.     for(unsigned i = 0; i < den.size(); i++)
  211.         e = e / den[i];
  212.  
  213.     return e;
  214. }
  215. Base::Type Mono::type() { return Base::mono; }
  216.  
  217. void Mono::print(std::ostream& out){
  218.     out << " {";
  219.     for(unsigned i = 0; i < num.size(); i++){
  220.         if(i != 0) out << "*";
  221.         num[i].b->print(out);
  222.     }
  223.     for(unsigned i = 0; i < den.size(); i++){
  224.         out << "/";
  225.         den[i].b->print(out);
  226.     }
  227.     out << "} ";
  228. }
  229.  
  230. Complex Mono::eval(Complex x){
  231.     Complex n = 1, d = 1;
  232.     for(unsigned i = 0; i < num.size(); i++) n = n * num[i].b->eval(x);
  233.     for(unsigned i = 0; i < den.size(); i++) d = d * den[i].b->eval(x);
  234.     return n/d;
  235. }
  236.  
  237. Element Mono::coefficient(){
  238.     for(unsigned i = 0; i < num.size(); i++) if(num[i].b->type() == Base::number) return num[i];
  239.     return new Number(1);
  240. }
  241. unsigned Mono::degree(){
  242.     unsigned deg = 0;
  243.     for(unsigned i = 0; i < num.size(); i++) if(num[i].b->type() == Base::x) deg++;
  244.     return deg;
  245. }
  246.  
  247. std::vector<Complex> Mono::solve(){
  248.     std::vector<Complex> root;
  249.  
  250.     if(den.size()){
  251.  
  252.         Mono mn, md;
  253.         mn.num = num;
  254.         md.num = den;
  255.  
  256.         std::vector<Complex> nroot = mn.simplify().b->solve();
  257.         for(unsigned i = 0; i < nroot.size(); i++)
  258.             if(! (md.eval(nroot[i]) == 0) ) root.push_back(nroot[i]);
  259.  
  260.     }else root.push_back(0);
  261.  
  262.     return root;
  263. }
  264.  
  265. //== POLY ==//
  266. Poly::Poly() {}
  267. Poly::Poly(const char*& str){
  268.     while(*str == ' ') str++;
  269.        
  270.     bool sgn = 1;
  271.     while(*str != 0 && *str != ')' && *str != '='){
  272.         if(!sgn && *str != '+' && *str != '-'); //throw MADNESS;
  273.         sgn = 0;
  274.         num.push_back(new Mono(str));
  275.         while(*str == ' ') str++;
  276.     }
  277.     if(*str == ')') str++;
  278. }
  279. Element Poly::simplify() {
  280.     Element e;
  281.     for(unsigned i = 0; i < num.size(); i++)
  282.         if(e.b == 0) e = num[i].b->simplify();
  283.         else e = e + num[i];
  284.  
  285.     if(e.b == 0) e = new Number(0);
  286.     return e;
  287. }
  288. Base::Type Poly::type() { return Base::poly; }
  289.  
  290. void Poly::print(std::ostream& out){
  291.     out << " (";
  292.     for(unsigned i = 0; i < num.size(); i++){
  293.         if(i != 0) out << "+";
  294.         num[i].b->print(out);
  295.     }
  296.     out << ") ";
  297. }
  298.  
  299. Complex Poly::eval(Complex x){
  300.     Complex c = 0;
  301.     for(unsigned i = 0; i < num.size(); i++) c = c + num[i].b->eval(x);
  302.     return c;
  303. }
  304. std::vector<Complex> Poly::solve(){
  305.     unsigned deg=0;
  306.     Element coef;
  307.  
  308.     for(unsigned i = 0; i < num.size(); i++){
  309.         unsigned tdeg = num[i].b->degree();
  310.         if(tdeg > deg){
  311.             deg = tdeg;
  312.             coef = num[i].b->coefficient();
  313.         }
  314.     }
  315.     for(unsigned i = 0; i < num.size(); i++) num[i] = num[i]/coef;
  316.  
  317.     std::vector<Complex> approx(deg);
  318.  
  319.     for(unsigned i = 0; i < deg; i++)
  320.         approx[i] = Complex( rand()%32768/65536.0, rand()%32768/65536.0 );
  321.    
  322.     while(1){
  323.         std::vector<Complex> root(deg);
  324.  
  325.         bool end = true;
  326.  
  327.         for(unsigned i = 0; i < deg; i++){
  328.             root[i] = 1;
  329.             for(unsigned j = 0; j < approx.size(); j++)
  330.                 if(i != j) root[i] = root[i] * (approx[i]-approx[j]);
  331.             root[i] = approx[i] - eval(approx[i])/root[i];
  332.  
  333.             end &= eval(root[i]) == 0;
  334.         }
  335.  
  336.         if(end) return root;
  337.         else approx = root;
  338.     }
  339. }
  340.  
  341. //== EQUATION ==//
  342.  
  343. Equation::Equation(const char *str){
  344.     e = new Poly(str);
  345.  
  346.     while(*str == ' ') str++;
  347.     if(*str == '='){
  348.         str++;
  349.         e = e + Element(new Number(-1))*Element(new Poly(str));
  350.     }
  351. }
  352.  
  353. std::vector<Complex> Equation::solve(){
  354.     e = e.b->simplify();
  355.     std::cout << e << '\n';
  356.     return e.b->solve();
  357. }
  358.  
  359. //these two will never be called
  360. Element Poly::coefficient(){
  361.     return Element();
  362. }
  363. unsigned Poly::degree(){
  364.     return 0;
  365. }
Advertisement
Add Comment
Please, Sign In to add comment