Hello, I must solve the equation z ^ 3 - 1 = 0, z is a complex number.

  1. The code works, only output one root of three, but true. What is boring to do to get three roots? It seems to me that the problem is that the starting point is not set (not transmitted), and therefore there is one root, and there would be different roots for different points, but I’m not sure about that.
  2. Based on the results, you will need to make a graph of decision pools, that is, it will be a complex plane on which each pixel will result in one of the solutions. How to do it, maybe someone knows? As it seems to me, it should be two cycles with a very small step, but what next?

Code :

#include <cmath> #include <iostream> using namespace std; class CComplex { public : double _re; double _im; CComplex(); CComplex(double re, double im); CComplex(const CComplex &pCopy); CComplex conjugate(); double complexfabs(); CComplex operator + (CComplex pAdd); CComplex operator - (CComplex pAdd); CComplex operator * (CComplex pMul); CComplex operator / (CComplex pDiv); CComplex uintpower(unsigned int n); friend ostream& operator << (ostream &out, const CComplex pVal) { out<<pVal._re<<(pVal._im < 0 ? " - " : " + ")<<fabs(pVal._im)<<"i"; return out; } }; CComplex::CComplex() { _re = _im = 0; } CComplex::CComplex(double re, double im) { _re = re; _im = im; } CComplex::CComplex(const CComplex &pCopy) { _re = pCopy._re; _im = pCopy._im; } CComplex CComplex::conjugate() { CComplex pThis = (*this); pThis._im *= -1; return pThis; } double CComplex::complexfabs() { return _re*_re + _im*_im; } CComplex CComplex::operator +(CComplex pAdd) { CComplex pThis = (*this); pThis._re += pAdd._re; pThis._im += pAdd._im; return pThis; } CComplex CComplex::operator - (CComplex pAdd) { CComplex pThis = (*this); pThis._re -= pAdd._re; pThis._im -= pAdd._im; return pThis; } CComplex CComplex::operator *(CComplex pMul) { CComplex pThis = (*this); pThis._re = _re*pMul._re - _im*pMul._im; pThis._im = _re*pMul._im + _im*pMul._re; return pThis; } CComplex CComplex::operator / (CComplex pDiv) { CComplex pThis = (*this); double divider = pDiv.complexfabs(); pThis = pThis*pDiv.conjugate(); pThis._re /= divider; pThis._im /= divider; return pThis; } CComplex CComplex::uintpower(unsigned int n) { CComplex pThis = CComplex(1, 0); for(unsigned int i = 0; i < n; i++) pThis = pThis*(*this); return pThis; } CComplex f(CComplex z, unsigned int n) { return z.uintpower(n) - CComplex(1, 0); } CComplex df(CComplex z, unsigned int n) { return CComplex(n, 0)*z.uintpower(n - 1); } int main() { unsigned int n = 3; unsigned int i; double err = 1e-12; CComplex z(1,1); std::cout << "First root" <<std::endl; for(i = 0; f(z, n).complexfabs() > err; i++) { z = z - f(z, n) / df(z, n); cout<<"\riteration "<<i + 1<<" root : "<<z<<std::endl; } system("pause"); return 0; } 

Closed due to the fact that off-topic participants Cerbo , nick_n_a , Xander , 0xdb , aleksandr barakin 14 Jan at 15:06 .

  • Most likely, this question does not correspond to the subject of Stack Overflow in Russian, according to the rules described in the certificate .
If the question can be reformulated according to the rules set out in the certificate , edit it .

  • four
    This question should be closed, because it is in mathematics, not programming. - Cerbo
  • It is necessary to solve the equation on paper, to trace the algorithm - and then transfer the algorithm to the computer. - nick_n_a

1 answer 1

The cube root has three answers, the difference between each answer is 2π/3 in the angular sense. You need to translate the first answer to the exponential format x+iy=r*exp(iw) . Other answers will be r*exp(i(w-2π/3)) and r*exp(i(w+2π/3)) . Further translate these answers back.

 r:=sqrt(x*x+y*y) w:=atan2(y,x) w2:=w-2π/3 w3:=w+2π/3 x2:=r*cos(w2) y2:=r*sin(w2) x3:=r*cos(w3) y3:=r*sin(w3) 

An example of the output of three solutions:

  for(i = 0; f(z, n).complexfabs() > err; i++) { z = z - f(z, n) / df(z, n); cout<<"\riteration "<<i + 1<<" root : "<<z<<std::endl; double r = sqrt(z._re*z._re+z._im*z._im); double w = atan2(z._im,z._re); double const PI = 3.1416; CComplex z2(r*cos(w-2.0*PI/3.0),r*sin(w-2.0*PI/3.0)); cout<<"\riteration "<<i + 1<<" root : "<<z2<<std::endl; CComplex z3(r*cos(w+2.0*PI/3.0),r*sin(w+2.0*PI/3.0)); cout<<"\riteration "<<i + 1<<" root : "<<z3<<std::endl; } //for 

The answer may be at the starting point (-1,1):

 iteration 1 root : -0.666667 + 0.833333i iteration 1 root : 1.05502 + 0.160678i iteration 1 root : -0.38835 - 0.994019i iteration 2 root : -0.508692 + 0.8411i iteration 2 root : 0.98276 + 0.0199854i iteration 2 root : -0.474064 - 0.861092i iteration 3 root : -0.49933 + 0.866269i iteration 3 root : 0.999876 - 0.000707022i iteration 3 root : -0.500542 - 0.865569i iteration 4 root : -0.5 + 0.866025i iteration 4 root : 1 - 4.72405e-06i iteration 4 root : -0.499995 - 0.866028i iteration 5 root : -0.5 + 0.866025i iteration 5 root : 1 - 4.89761e-06i iteration 5 root : -0.499996 - 0.866028i 

The main answer -0.5 + 0.866025i differs from the main answer, but the beautiful answer can be obtained from the second solution.

  • @ AlexGlebeTuplyu, what does it mean to move these roots back? - LavashLavashenko
  • The answers are r, w2 and r, w3 -> x2, y2 and x3, y3. - AlexGlebe
  • is there an opportunity to contact you? @AlexGlebe - LavashLavashenko
  • The difference between the three answers is accurate, and the approximation in the cycle, if it gives the accuracy of eps , then all three answers will have an error eps . - AlexGlebe
  • The theory is clear, but I don’t fully understand how it should be on the code and what you describe it turns out to be a “trick”, but again in this case there is no Newton method, where I set the starting point. If not right, correct me, please. - LavashLavashenko