happysxyf 发表于 2017-1-18 20:07:30

解方程工具equation.exe


高次方程求解,三次方程参考范盛金的公式,四次方程采用费拉里降次为两个二次方程,五次方程没有精确的求根公式,采用牛顿迭代法(利用导线逼近0点)进而降次为四次方程,再套用费拉里将次(包含复数解)。
EQUATION.EXE

摘要:
=============================================================================
这是一个专注解方程和方程组的简单工具,帮助那些想快速计算出结果的童鞋们。求解
结果精确到小数点后12位,且支持复根。
=============================================================================

用法:
-----------------------------------------------------------------------------
equation ||
-----------------------------------------------------------------------------
/H显示帮助信息
/O求解一元方程
/M求解多元方程组
/R求解单位复元根
-----------------------------------------------------------------------------

示例:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
equation /O3 0 5 -6 -9      //求解一元四次方程3x^4+0x^3+5x^2-6x-9=0
The solution of the equation 3x^4+0x^3+5x^2-6x-9=0 is:
┌────────────────────────┐
Imag   root: -0.252438186547+1.696390660707i
               -0.252438186547-1.696390660707i
Real   root:1.293411063722
               -0.788534690627
└────────────────────────┘

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
equation /R5                  //求解5次复元根 x^5-1=0
┌────────────────────────┐
        x[ 1]= 0.309016994375+0.951056516295i
        x[ 2]=-0.809016994375+0.587785252292i
        x[ 3]=-0.809016994375-0.587785252292i
        x[ 4]= 0.309016994375-0.951056516295i
        x[ 5]= 1.000000000000-0.000000000000i
└────────────────────────┘

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
equation /M                     //进入方程组模式

           ---Quit using "q"
        {2                      //此处输入方程组个数
        Equation coefficients:
        3 2 5                   //第一个方程式的系数
        6 9 1                   //第二个方程式的系数
        Solution of equations:
        ┌───────────────┐
          x= 2.866666793823
          x=-1.800000071526
        └───────────────┘
        {{q                     //输入q退出该模式

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


equation.c源码(采取POS开源协议,即发布的每个作品都开源):
/*
    CONSOLE SOLVING EQUATION TOOLS, COPYRIGHT@2016~2018 BY HAPPY
    EQUATION.EXE
    VERSION 1.0
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

//定义帮助说明//////////////////////////////////////////////////////
#define HELPINFORMATION "\
SOLVING EQUATION TOOLS, COPYRIGHT@2016~2018 BY HAPPY, VERSION 1.0\n\
-----------------------------------------------------------------\n\
equation ||\n\
-----------------------------------------------------------------\n\
/HDisplays help information\n\
/OSolves the univariate equation\n\
/MSolving Systems of multivariable Equations\n\
/RSolve the unit root\n\
-----------------------------------------------------------------\n\
12/03/2016\n"
////////////////////////////////////////////////////////////////////

/***************功能函数群***************/
void equation_set(int n)
{
    int i, j, m, r, k=0, t, mark;
    float a;
    printf("Equation coefficients:\n");
    r=n;
    for(j=0; j<n; j++){   
      for(i=0; i<r+1; i++){   
            scanf("%f", &a);
      }
      if(a!=0){mark=j;}
    }
    //系数修正
    for(j=0; j<n; j++){
      if(a+a != 0){   
            for(i=0; i<r+1; i++){   
                a += a;
            }
      }
    }

    if(r==n)
    {   
      printf("Solution of equations:\n");
      for(t=0; t<n-1; t++)
            for(m=0; m<n; m++)
                for(j=0; j<n; j++)
                  if(j!=m)   
                  {
                        float b= a/a;
                        for(i=0; i<n+1; i++)
                            a -= a*b;                     
                  }
      for(j=0; j<n; j++)   
      {   
                a /=a;   
                a /=a;
      }
    }
    printf("┌───────────────┐\n");
    for(j=0; j<r; j++){   
      printf("   x[%d]=%15.12f\n", j, a);
    }
    printf("└───────────────┘\n");
}

void twice(double a, double b, double c)
{
    double x1,x2,den=2*a,delt=b*b-4*a*c;
    if(a==0){
      if(b==0){
            printf("Not a real equation");
      }
      else{
            printf("Reduced to once equation\nReal   root: x=%.12lf",-c/b);
      }
    }
    else{   
      if(delt>0){
            x1=-b/den+sqrt(delt)/den;
            x2=-b/den-sqrt(delt)/den;
            printf("Real   root: %15.12lf\n               %15.12lf",x1,x2);
      }
      else if(delt==0){
            printf("Double root: %15.12lf",-b/den);
      }
      else if(delt<0){
            x1=sqrt(-delt)/den;
            printf("Imag   root: %15.12lf+%.12lfi\n               %15.12lf-%.12lfi",-b/den,x1,-b/den,x1);
      }
    }
}

double thice(double a, double b, double c, double d, int gk)
{
    double A=b*b-3*a*c,B=b*c-9*a*d,C=c*c-3*b*d,delta=B*B-4*A*C;
    if(A==0 && B==0){
      if(gk!=1){printf("Triple real: %15.12lf",-b/(3*a));}
      return -b/(3*a);
    }
    else if(delta>0){
      double Y1=A*b+3*a*(-B+sqrt(delta))/2.0,Y2=A*b+3*a*(-B-sqrt(delta))/2.0;
      Y1=(Y1>0)? pow(Y1,1.0/3.0) :-pow(-Y1,1.0/3.0);
      Y2=(Y2>0)? pow(Y2,1.0/3.0) :-pow(-Y2,1.0/3.0);
      double x1=(-b-Y1-Y2)/(3.0*a);
      double prr=(-2*b+Y1+Y2)/(6.0*a),pri=(Y1-Y2)*sqrt(3)/(6.0*a);
      if(gk!=1){printf("Firstreal: %15.12lf\nImag   root: %15.12lf+%.12lfi\n               %15.12lf-%.12lfi",x1,prr,pri,prr,pri);}
      return x1;
    }
    else if(delta==0){
      if(gk!=1){printf("Double real: %15.12lf\n               Otherreal: %15.12lf\n",-B/(2.0*A),-b/a+B/A);}
      if(-B/(2.0*A) > -b/a+B/A){
            return -B/(2.0*A);
      }else{
            return -b/a+B/A;
      }
    }
    else if(delta<0){
      double r=acos((2*A*b-3*a*B)/(2*A*sqrt(A)));   
      double x1=(-b-2.0*sqrt(A)*cos(r/3.0))/(3.0*a);
      double x2=(-b-2*sqrt(A)*cos((r+2*M_PI)/3.0))/(3.0*a);
      double x3=(-b-2*sqrt(A)*cos((r+4*M_PI)/3.0))/(3.0*a);
      if(gk!=1){printf("Triple real: %15.12lf\n               %15.12lf\n               %15.12lf",x1,x2,x3);}
      double tempv;
      if(x1 > x2){
            tempv=x1;
      }else{
            tempv=x2;
      }
      if(tempv > x3){
            return tempv;
      }else{
            return x3;
      }
    }
}

void foice(double a, double b, double c, double d, double e)
{
    double y,f,M,N,P;
    int i;
    b/=a;c/=a;d/=a;e/=a;a=1;
    f=8;
    f=-4.0*c;
    f=-(8.0*e-2.0*b*d);
    f=-e*(b*b-4.0*c)-d*d;
    y=thice(f,f,f,f,1);
    M=sqrt(8.0*y+b*b-4.0*c);
    N=b*y-d;
    if(M==0){
      P=sqrt(y*y-e);
      twice(2.0,b,2.0*(y+P));
      printf("\n");
      twice(2.0,b,2.0*(y-P));
    }else{
      twice(2.0,b+M,2.0*(y+N/M));
      printf("\n");
      twice(2.0,b-M,2.0*(y-N/M));
    }
}

void fifth(double a, double b, double c, double d, double e, double f)
{
   double r,x,F,F1;
   b/=a;c/=a;d/=a;e/=a;f/=a;
   a=-1.0;
    do
    {
         x=a;
         F=x*x*x*x*x+b*x*x*x*x+c*x*x*x+d*x*x+e*x+f;
         F1=5*x*x*x*x+4*b*x*x*x+3*c*x*x+2*d*x+e;
         a=x-F/F1;   
    }
    while(fabs(x-a)>=1e-10);
    double e1=-f/x,d1=(e1-e)/x,c1=(d1-d)/x,b1=(c1-c)/x;
    foice(1.0,b1,c1,d1,e1);
    printf ("\nIterative: %15.12lf",x);
}

/***************业务函数群***************/
//字符串转等式
char* atop(char *s)
{
    if(atof(s)>=0){
      char *r=malloc(strlen(s)+strlen("+")+1);
      strcpy(r,"+");strcat(r,s);
      return r;
    }
    return s;
}
//解多元方程组
void Multivariable_Equations()
{
    char str;
    puts("   ---Quit using \"q\"");
    while(printf("{"),fgets(str,7,stdin)!=NULL){
      char *i=strchr(str,'\n');
      if(i!=NULL){*i='\0';}
      if (i!=str){
            if(!strcmp(str,"q")){break;}
            equation_set(atoi(str));
      }
    }
}
//解一元高次方程
void Univariate_Equation(int argc, char** argv)
{
    if(argc==4){
      printf("The solution of the equation %sx%s=0 is: \n",argv,atop(argv));
      printf("┌────────────────────────┐\n");
      if(atof(argv)==0){printf("Not a real equation");}else{printf("%15.12lf",-atof(argv)/atof(argv));}
      printf("\n└────────────────────────┘");
    }
    else if(argc==5){
      printf("The solution of the equation %sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv));
      printf("┌────────────────────────┐\n");
      twice(atof(argv),atof(argv),atof(argv));
      printf("\n└────────────────────────┘");
    }
    else if(argc==6){
      printf("The solution of the equation %sx^3%sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv),atop(argv));
      printf("┌────────────────────────┐\n");
      if(atof(argv)==0){
            printf("Reduced to a quadratic equation\n");
            twice(atof(argv),atof(argv),atof(argv));
      }
      else{
            thice(atof(argv),atof(argv),atof(argv),atof(argv),0);
      }
      printf("\n└────────────────────────┘");
    }
    else if(argc==7){
      printf("The solution of the equation %sx^4%sx^3%sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv),atop(argv),atop(argv));
      printf("┌────────────────────────┐\n");
      if(atof(argv)==0){
            printf("Reduced to cubic equation\n");
            if(atof(argv)==0){
                printf("Reduced to a quadratic equation\n");
                twice(atof(argv),atof(argv),atof(argv));
            }else{
                thice(atof(argv),atof(argv),atof(argv),atof(argv),0);
            }
      }
      else{
            foice(atof(argv),atof(argv),atof(argv),atof(argv),atof(argv));
      }
      printf("\n└────────────────────────┘");
    }
    else if(argc==8){
      printf("The solution of the equation %sx^5%sx^4%sx^3%sx^2%sx%s=0 is: \n",argv,atop(argv),atop(argv),atop(argv),atop(argv),atop(argv));
      printf("┌────────────────────────┐\n");
      if(atof(argv)==0){
            printf("Reduced to foice equation\n");
            if(atof(argv)==0){
                printf("Reduced to cubic equation\n");
                if(atof(argv)==0){
                  printf("Reduced to a quadratic equation\n");
                  twice(atof(argv),atof(argv),atof(argv));
                }else{
                  thice(atof(argv),atof(argv),atof(argv),atof(argv),0);
                }
               
            }else{
                foice(atof(argv),atof(argv),atof(argv),atof(argv),atof(argv));
            }
      }else{
            fifth(atof(argv),atof(argv),atof(argv),atof(argv),atof(argv),atof(argv));
      }
      printf("\n└────────────────────────┘");
    }

}
//单位元根
void Unit_Root(int argc, char** argv)
{
    if(argc!=3){
      printf("Missing parameters\n");
                exit(1);
        }
    int i, n=atoi(argv);
    printf("┌──────────────────────┐\n");
    for(i=1; i<n; i++){
      if(i==n){printf("   r[%2d]=%15.12lf%.12lfi",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));break;}
      if(sin(2*i*M_PI/n)<0){
            printf("   r[%2d]=%15.12lf%.12lfi\n",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));
      }
      else{
            printf("   r[%2d]=%15.12lf+%.12lfi\n",i,cos(2*i*M_PI/n),sin(2*i*M_PI/n));
      }   
    }
    printf("   r[%2d]= 1.000000000000", n);
    printf("\n└──────────────────────┘");
}

/*************MAIN主函数入口*************/
int main(int argc, char** argv)
{
    if( (argc >1) && (argv=='/') )
    {
      switch(argv)
      {
            case 'H':
            case 'h':
                fputs(HELPINFORMATION,stdout);
                exit(0);

            case 'M':
            case 'm':
                Multivariable_Equations();
                break;

            case 'O':
            case 'o':
                Univariate_Equation(argc, argv);
                break;

            case 'R':
            case 'r':
                Unit_Root(argc, argv);
                break;

            default:
                fputs(HELPINFORMATION,stdout);
                exit(1);
      }
      return 0;

    }
    fputs(HELPINFORMATION,stdout);
    exit(1);
}

落叶 发表于 2017-1-18 20:42:16

我win732位系统,运行你的程序一闪就没了!

happysxyf 发表于 2017-1-18 20:57:01

落叶 发表于 2017-1-18 20:42
我win732位系统,运行你的程序一闪就没了!

命令行程序,跟之前的计算器用法一样。
在cmd窗口输入equation /O3 0 5 -6 -9
我的程序都是在一天之内写的,不可能有太多时间去写界面,所以都是命令行程序。就像你用的dir命令一样。
命令行具有启动快,速度快,内存占用小的优点。

落叶 发表于 2017-1-18 21:06:47

打开cmd窗口运行成功,用命令行输入对打字速度要求较高。

happysxyf 发表于 2017-1-18 21:22:06

落叶 发表于 2017-1-18 21:06
打开cmd窗口运行成功,用命令行输入对打字速度要求较高。

没有啊,直接复制粘贴就能运行,连按键都不需要,命令行的好处就是直接复制粘贴。这些都是批处理算法流中的,都是可以用来批量无人值守,自动计算的,需要批处理或者lua语言的调用。

核心算法都在那了,只需要加个界面就能像你的计算器一样点击运行了,但是写界面我还得花1天时间,就暂时没界面,我现在正在开发自己的高精度算法库,所以时间比较紧。

落叶 发表于 2017-1-18 21:31:11

高精度算法库,反正切函数的迭代式会推导吗?我不会推导,用的方法速度较慢。
宝宝说:“反三角函数可以以三角函数为基础,使用牛顿迭代法求解。“,但是我不会,你数学很强,知道是怎么回事吗?

mathematica 发表于 2017-1-19 09:01:45

赞!
比我牛逼
不过我一般都用mathematica解方程!

happysxyf 发表于 2017-1-19 12:55:58

mathematica 发表于 2017-1-19 09:01
赞!
比我牛逼
不过我一般都用mathematica解方程!

mathematica虽好,但是mathematica也是程序啊。而且我发现mathematica在某些情况下给出的解是错误的。而且mathematica不免费。我用的还是旧版本。

happysxyf 发表于 2017-1-19 13:08:05

math_humanbeing 发表于 2017-1-19 09:08
我突然想到一个问题,解高次方程可以用galois理论,那么求解过程到底能不能机械化?

galois理论仅仅是根塔理论,而且他21岁就为了女人草率的去决斗而丢了性命。他的理论也如同他本人一样,只有在有根式解的前提下奏效。

而我的程序是数值解,就是用浮点复数去表示解,一个实系数高次方程可以没有根式解,但必须复数解。我只是用导线逼近下复数解而已,得出的结果都是浮点复数,而不是根式。所以我完全是用C语言程序设计的思想去做的。

即便是mathmatica也不可能给出复杂高次方程的根式解。

mathematica 发表于 2017-3-20 12:08:36

我觉得先确定根的范围,
然后随机生成数,然后用牛顿迭代法求解方程
页: [1] 2
查看完整版本: 解方程工具equation.exe