跳转到主要内容

一元二次、三次、四次方程求解和复数的运算

一元二次、三次、四次方程求解和复数的运算

对一元三次或者四次方程,是有数学公式求精确解的,可以不用迭代法。参考了维基的上的方法,现在我贴出一元二次、三次或者四次方程的LISP求解方法。使得在求解效率可以得到极大提高。
注明: 因为这几个方程的解有可能是复数,所以我对每个解都用表的形式来列出。
如果这个表的第二项为0,那么这个解是实数,否则是复数。
譬如 :\[x^4+3x^3+7x^2+2x-5 = 0\]

 

==》((-1.19281 -2.21406) (-1.19281 2.21406) (-1.24789 0) (0.633498 0))

意味着这个方程有两个实数解:-1.24789 , 0.633498
两个虚数解:-1.19281-2.21406 i ,-1.19281+2.21406i
另外在末尾附上验算测试函数。

解一元二次方程的LISP源码:

 

解一元三次方程的LISP源码:

 

解一元四次方程的解:

 

复数相关代码:

;;;=============================================================
;;;立方根(为解三次和四次方程编写,因expt函数第一个参数不能为负) 
;;;输入:x 实数                                                 
;;;输出:x 的立方根                                             
;;;=============================================================
(defun MATH:CubeRoot (x)
  (if (< x 0)
    (- (expt (- x) 0.33333333333333333333333))
    (expt x 0.33333333333333333333333)
  )
)
 
;;;=============================================================
;;;复数加复数                                                   
;;;输入:Z1--复数,Z2--复数                                     
;;;输出:复数跟实数相加的结果                                   
;;;=============================================================
(defun Math:C+C (z1 z2)
  (mapcar '+ z1 z2)
)
 
;;;=============================================================
;;;复数减复数                                                   
;;;输入:Z1--复数,Z2--复数                                     
;;;输出:复数跟实数相减的结果                                   
;;;=============================================================
(defun math:C-C (z1 z2)
  (mapcar '- Z1 Z2)
)
 
;;;=============================================================
;;;复数乘复数                                                   
;;;输入:Z1--复数,Z2--复数                             	
;;;输出:复数跟实数相乘的结果                           	
;;;=============================================================
(defun Math:C*C (Z1 Z2)
  (list
    (- (* (car Z1) (car z2)) (* (cadr z1) (cadr z2)))
    (+ (* (car Z1) (cadr Z2)) (* (cadr z1) (car Z2)))
  )
)
 
;;;=============================================================
;;;复数除以复数                                         	
;;;输入:Z1--复数,Z2--复数                             	
;;;输出:复数跟实数相除的结果                           	
;;;=============================================================
(defun Math:C/C (Z1 Z2 / a b c d N)
  (setq a (car  z1))
  (setq b (cadr z1))
  (setq c (car  z2))
  (setq d (cadr z2))
  (setq N (float (+ (* c c) (* d d))))
  (if (not (zerop N))
    (list
      (/ (+ (* a c) (* b d)) N)
      (/ (- (* b c) (* a d)) N)
    )
  )
)
 
;;;=============================================================
;;;复数加实数                                           	
;;;输入:Z --复数,R --实数                             	
;;;输出:复数跟实数相加的结果                           	
;;;=============================================================
(defun Math:C+R (Z R)
  (list (+ (car z) R) (cadr z))
)
 
;;;=============================================================
;;;复数减实数                                           	
;;;输入:Z --复数,R --实数                             	
;;;输出:复数跟实数相减的结果                           	
;;;=============================================================
(defun Math:C-R (Z R)
  (list (- (car z) R) (cadr z))
)
 
;;;=============================================================
;;;复数乘实数                                           	
;;;输入:Z --复数,R --实数                             	
;;;输出:复数跟实数相乘的结果                           	
;;;=============================================================
(defun Math:C*R (Z R)
  (list (* (car z) R) (* (cadr z) R))
)
 
;;;=============================================================
;;;复数除以实数                                         	
;;;输入:Z --复数,R --实数                             	
;;;输出:复数跟实数相除的结果                           	
;;;=============================================================
(defun Math:C/R (Z R)
  (if (not (zerop R))
    (list (/ (car z) R) (/ (cadr z) R))
  )
)
 
;;;=============================================================
;;;复数的模                                             	
;;;输入:Z --复数                                       	
;;;输出:复数的模,即复数代表的矢量长度                 	
;;;=============================================================
(defun MATH:CNormal (Z)
  (distance '(0 0) Z)
)
 
;;;=============================================================
;;;复数的平方根                                         	
;;;输入:Z --复数                                       	
;;;输出:复数的平方根,以复数形式表达,有两个解         	
;;;=============================================================
(defun Math:CSqrt (Z / x y a r)
  (setq x (car z))
  (setq y (cadr z))
  (if (equal y 0 1e-14)
    (if (> x 0)
      (list (list (setq x (sqrt x)) 0) (list (- x) 0))
      (list (list 0 (setq y (sqrt (- x)))) (list 0 (- y)))
    )
    (progn
      (setq a (* (atan y x) 0.5))
      (setq r (sqrt (distance '(0 0) Z)))
      (setq x (* r (cos a)))
      (setq y (* r (sin a)))
      (list (list x y) (list (- x) (- y)))
    )
  )
)
 
;;;=============================================================
;;;复数的方根                                           	
;;;输入:Z --复数, n --正整数                           	
;;;输出:复数的n次方根,以复数形式表达,有n个解。       	
;;;=============================================================
(defun MATH:CRoot (Z n / r a b i s 2Pi)
  (if (and (= (type n) 'INT) (> n 0))
    (progn
      (setq r (expt (distance '(0 0) z) (/ 1. n)))
      (setq a (atan (cadr z) (car z)))
      (setq i 0)
      (setq 2Pi (+ pi pi))
      (repeat n
        (setq b (/ (+ a (* i 2Pi)) n))
        (setq s (cons (list (* r (cos b)) (* r (sin b))) s))
        (setq i (1+ i))
      )
      (reverse s)
    )
  )
)
 
;;;=============================================================
;;;复数的实幂指数                                       	
;;;输入:Z --复数, x -- 实数                            	
;;;输出:复数Z 的x次幂,以复数形式表达。                	
;;;=============================================================
(defun MATH:CRPower (Z x / a r)
  (setq a (atan (cadr Z) (car Z)))
  (setq r (expt (distance '(0 0) Z) x))
  (list (* r (cos (* a x))) (* r (sin (* a x))))
)
 
;;;=============================================================
;;;复数的复幂指数                                       	
;;;输入:Z1 --复数, Z2 -- 复数                          	
;;;输出:复数Z1的Z2次幂,以复数形式表达。               	
;;;=============================================================
(defun MATH:CZPower (Z1 Z2 / a r x y k)
  (if (> (setq r (distance '(0 0) Z1)) 1e-20)
    (progn 
      (setq a (atan (cadr Z1) (car Z1)))
      (setq x (car z2))
      (setq y (cadr z2))
      (setq k (log r))
      (setq r (exp (- (* k x) (* y a))))
      (setq a (+ (* k y) (* x a)))
      (list (* r (cos a)) (* r (sin a)))
    )
  )
)
 
;;;=============================================================
;;;复数的自然对数                                        	
;;;输入:Z --复数                                       	
;;;输出:复数Z 的自然对数,以复数形式表达。             	
;;;=============================================================
(defun MATH:CExp (Z / r)
  (if (> (setq r (distance '(0 0) Z)) 1e-20)
    (list (log r) (atan (cadr Z) (car Z)))
  )
)
 
;;;=============================================================
;;;复数的余弦                                           	
;;;输入:Z --复数                                          	
;;;输出:复数Z 的余弦,以复数形式表达。                 	
;;;=============================================================
(defun MATH:CCOS (Z / x y c s u v)
  (setq x (car z))
  (setq y (cadr z))
  (if (equal y 0 1e-20)
    (list (cos x) 0)
    (progn
      (setq c (* 0.5 (cos x)))
      (setq s (* 0.5 (sin x)))
      (setq u (exp y))
      (setq v (exp (- y)))
      (list (* c (+ v u)) (* s (- v u)))
    )
  )
)
 
;;;=============================================================
;;;复数的正弦                                          		
;;;输入:Z --复数                                       	
;;;输出:复数Z 的正弦,以复数形式表达。                 	
;;;=============================================================
(defun MATH:CSIN (Z / x y c s u v)
  (setq x (car z))
  (setq y (cadr z))
  (if (equal y 0 1e-20)
    (list (sin x) 0)
    (progn
      (setq s (* 0.5 (sin x)))
      (setq c (* 0.5 (cos x)))
      (setq u (exp (- y)))
      (setq v (exp y))
      (list (* s (+ v u)) (* c (- v u)))
    )
  )
)
 
;;;=============================================================
;;;复数的正切                                           	
;;;输入:Z --复数                                       	
;;;输出:复数Z 的正切,以复数形式表达。                 	
;;;=============================================================
(defun MATH:CTAN (Z / x y c s u v)
  (MATH:C/C (MATH:CSIN Z) (MATH:CCOS Z))
)
 
;;;=============================================================
;;;实系数的复数多项式运算                               	
;;;输入:Z --复数, RealNumbers --实系数列表             	
;;;输出:根据实系数多项式复数方程值,用复数表示。       	
;;;=============================================================
(defun MATH:CReal_Polynomial (Z RealNumbers / f)
  (cond
    ( (cdr RealNumbers) 
      (setq f (MATH:C*R Z (car RealNumbers)))
      (repeat (- (length RealNumbers) 2)
        (setq RealNumbers (cdr RealNumbers))
        (setq f (MATH:C+R f (car RealNumbers)))
        (setq f (MATH:C*C f Z))
      )
      (setq f (MATH:C+R f (cadr RealNumbers)))
    )
    ( (car RealNumbers) (list (car RealNumbers) 0))
  )
)
 
;;;=============================================================
;;;虚系数的复数多项式运算                               	
;;;输入:Z --复数, ImaginaryNumbers--复系数列表         	
;;;输出:根据复系数多项式复数方程值,用复数表示。       	
;;;=============================================================
(defun MATH:CImaginary_Polynomial (Z ImaginaryNumbers / f)
  (if (setq f (car ImaginaryNumbers))
    (progn
      (repeat (1- (length ImaginaryNumbers))
        (setq ImaginaryNumbers (cdr ImaginaryNumbers))
        (setq f (MATH:C*C f Z)) 
        (setq f (MATH:C+C f (car ImaginaryNumbers)))
      )
      f
    )
  )
)

分类