如何在R中分析求解三次方程(精确解)?

时间:2014-03-23 23:49:16

标签: r equation cubic

我试图在R中以分析方式得到立方方程的解,而非数值。

我抬头看了互联网,得到了立方根的公式,并编写了以下代码: 链接是:http://www.math.vanderbilt.edu/~schectex/courses/cubic/

cub <- function(a,b,c,d) {
  p <- -b/3/a
  q <- p^3 + (b*c-3*a*(d))/(6*a^2)
  r <- c/3/a
  x <- (q+(q^2+(r-p^2)^3)^0.5)^(1/3)+(q-(q^2+(r-p^2)^3)^0.5)^(1/3)+p
  x
}

然而,这个功能在大多数情况下都不起作用,我猜它是因为公式中负数的力量,例如我注意到R不能得到(-8)^的实根。 (1/3)即-2。但我不确定如何修复我的代码,以便它可以用来解决一般的精确立方解决方案。

感谢。

4 个答案:

答案 0 :(得分:3)

试试这个:

# calcaulate -8 as a complex number
z <- as.complex(-8)  # or z <- -8 + 0i

# find all three cube roots
zroot3 <- z^(1/3) * exp(2*c(0:2)*1i*pi/3)
zroot3
## [1]  1+1.732051i -2+0.000000i  1-1.732051i


# check that all three cube roots cube to original
zroot3^3
## [1] -8+0i -8+0i -8-0i

答案 1 :(得分:2)

我使用polyroot()See here了解更多详情。

polyroot(z = c(8,0,0,1))
# [1]  1+1.732051i -2+0.000000i  1-1.732051i

答案 2 :(得分:1)

如果你只想要真正的根,那么这里是另一个选择:

> x <- c( -8,8 )
> sign(x) * abs(x)^(1/3)
[1] -2  2

或者您可能对Ryacas包或其他选项的多项式包感兴趣。

答案 3 :(得分:0)

这是一个计算所有分析解决方案的函数:&#39; cubsol&#39; 。任何评论都是最受欢迎的。一个问题 - 目前代码搜索的效率相当低,真正的解决方案是由...生成的三个复杂的解决方案... s2 = cuberoot(q-s0 ^ 0.5); xtemp [1:3]&lt; - s1 + s2 + p;在计算它之前,是否有更有效的方法来了解它是哪一个?

# -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# Return all  the complex cube roots of a number
cuberoot <- function(x){
  return( as.complex(x)^(1/3)*exp(c(0,2,4)*1i*pi/3) );
}
# -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -   -
# cubsol solves analytically the cubic equation and
# returns a list whose first element is the real roots and the
# second element the complex roots.
# test with :
#a = -1; b=-10; c=0; d=50; x=0.01*(-1000:1500); plot(x,a*x^3+b*x^2+c*x+d,t='l'); abline(h=0)
# coefs = c(a,b,c,d)
cubsol <- function(coeffs) {
  if (!(length(coeffs) == 4)){
    stop('Please provide cubsol with a 4-vector of coefficients')
  }
  a = coeffs[1]; b=coeffs[2]; c=coeffs[3]; d=coeffs[4];
  rts = list();  

  p <- -b/3/a
  q <- p^3 + (b*c-3*a*(d))/(6*a^2)
  r <- c/3/a

  s0 = q^2+(r-p^2)^3; 
  xtemp = as.complex(rep(0,9));    
  if (s0 >= 0){ nReRts=1; } else {nReRts=3; }
  # Now find all the roots in complex space:
  s0 = as.complex(s0);
  s1 = cuberoot(q+s0^0.5)
  s2 = cuberoot(q-s0^0.5);
  xtemp[1:3] <- s1+ s2 +p;  # I think this is meant to always contain
                            # the sure real soln.
  # Second and third solution;
  iSqr3 = sqrt(3)*1i; 
  xtemp[4:6] = p - 0.5*(s1+s2 + iSqr3*(s1-s2));
  xtemp[7:9] = p - 0.5*(s1+s2 - iSqr3*(s1-s2));
  ind1 = which.min(abs(a*xtemp[1:3]^3 + b*xtemp[1:3]^2 +c*xtemp[1:3] +d))
  ind2 = 3+which.min(abs(a*xtemp[4:6]^3 + b*xtemp[4:6]^2 +c*xtemp[4:6] +d))
  ind3 = 6+which.min(abs(a*xtemp[7:9]^3 + b*xtemp[7:9]^2 +c*xtemp[7:9] +d))

  if (nReRts == 1){  
    rts[[1]] = c(Re(xtemp[ind1])); 
    rts[[2]] = xtemp[c(ind2,ind3)]
  } else {  # three real roots
    rts[[1]] = Re(xtemp[c(ind1,ind2,ind3)]); 
    rts[[2]] = numeric();
  }
  return(rts)

} # end of function cubsol