59.2 求一元六次方程在区间内的所有不相等的实根

59.2.1 理论分析

在“59.1”中,我们已经求得一元六次方程在区间内不相等的实根的总个数。接下来,我们将具体求出方程在区间内的所有不相等的实根。

分两步进行:

第一步:将区间分成若干个只包含一个不相等实根的子区间。

1.1,计算整个区间[l,r]内实根的个数N(59.1中已经完成);

1.2,若该区间内实根的个数>1,用二分法将该区间对分,计算[l,(l+r)/2]内实根的个数;

1.3,若新区间内实根的个数>1,继续二分区间,计算新二分区间内实根的个数;

若新区间内实根的个数=0,计算[(l+r)/2,r]内实根的个数;

第二步:若新区间内实根的个数=1,用牛顿迭代法求得该实根。

在如下章节有介绍过牛顿迭代法:

“问题四十六:怎么用ray tracing画superellipsoid”

http://blog.csdn.net/libing_zeng/article/details/54564227

注意:

牛顿迭代法,求得的实根不一定是区间内的实根。

比如:

某一元六次方程在区间[-5,5]有-4、-3、-2、2、3、4六个实根,在区间[-2.5, -1.5]进行迭代时,我们是想求”-2”这个实根,但是迭代的结果可能是”2”。

这时,我们的做法是:舍弃结果,返回迭代失败,求根总次数+1(因为失败了一次,需要再来一次),区间二分回到第一步重新开始(理论上,只要区间足够小,一定可以迭代到满足精度要求的实根。也有例外情况,如果区间小到误差范围,又知道该区间内有一个实根,直接将区间端值作为要求的实根)

另外,数据类型最好用double

59.2.2 看C++代码实现

----------------------------------------------vec3.h ------------------------------------------

vec3.h

bool roots_equation_6th(float ee6[7], float a, float b, float tol, float (&roots)[7]);

----------------------------------------------vec3.cpp ------------------------------------------

vec3.cpp

bool get_equation_6th_function_and_derivative(float ee6[7], double xxx, double& fnc, double& drv) {/*determine function value and derivative value at xxx*/fnc = 0.0;drv = 0.0;for (int i=0; i<7; i++) {fnc = fnc + ee6[i]*pow(xxx, (6-i));if (i<6) {drv = drv + (6-i)*ee6[i]*pow(xxx, (5-i));}}return true;
}bool get_root_by_newton_iteration_for_equation_6th(float ee6[7], double x0[2], float tol, double (&root)[2]) {/*find the single root in the interval [x0[0], x0[1]] by newton iteration */double t_k, t_k1, ft_k, ft_d_k;int get = 0;double i0 = x0[0];double i1 = x0[1];for (int i=0; i<2; i++) {t_k = x0[i];for (int k=0; k<20; k++) {if (!(isnan(t_k))) {get_equation_6th_function_and_derivative(ee6, t_k, ft_k, ft_d_k);if ((ft_d_k != 0) && !(isnan(ft_k)) && !(isnan(ft_d_k))) {t_k1 = t_k - ft_k/ft_d_k;if (((fabs(t_k1)>=1e-2)&&(fabs((t_k1 - t_k)/t_k1) < tol)) ||((fabs(t_k1)<1e-2)&&(fabs((t_k1 - t_k)) < tol))) {if ((t_k1 > x0[0]) && (t_k1<=x0[1])) {root[1] = (fabs(t_k1)<(tol*10))? 0.0:t_k1;root[0] = 1.0;get ++;}else {x0[1] = (x0[0] + x0[1])/2;}break;}else {t_k = t_k1;}}else {break;}}else {break;}}if (get == 1) {break;}}root[0] = double(get);return true;
}bool roots_equation_6th(float ee6[7], float a, float b, float tol, float (&roots)[7]) {double root[2], xxx0[2], temp;double left = a;double right = b;int total_num, interval_num;
/*”total_num” for the whole interval; “interval_num” for every sub-interval*/int offset = 0;roots[0] = 0.0;roots_num_equation_6th(ee6, double(a), double(b), total_num);
/*determine the number of distinct real roots in the interval*/if (total_num == 0) {return true;}else {interval_num = total_num;for (int i=1; i<(total_num+1+offset); i++) {while(interval_num != 1) {
/*to find a sub-interval with one real root in*/if (left > right) {temp = left;left = right;right = temp;}right = (left + right)/2;roots_num_equation_6th(ee6, left, right, interval_num);if (interval_num == 0) {left = right;right = b;}}xxx0[0] = left;xxx0[1] = right;get_root_by_newton_iteration_for_equation_6th(ee6, xxx0, tol, root);if (root[0] != 0.0) {
/*if newton finds the root*/roots[0] = roots[0] + 1.0;roots[int(roots[0])] = root[1];left = right;right = b;}else if ((root[0] == 0.0)&&(fabs(left-right)<tol)&&(interval_num==1)) {
/*if newton doesn’t find the root, but the interval is small enough*/roots[0] = roots[0] + 1.0;roots[int(roots[0])] = left;left = right;right = b;}else {
/*newton failed to find the root in regular interval, we need another time to find the root with smaller interval*/offset ++;right = (left + right)/2;}roots_num_equation_6th(ee6, left, right, interval_num);}}return true;
}

----------------------------------------------main.cpp ------------------------------------------

main.cpp

    int main(){
//        float ee6[7] = {1.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0};//x^6------------1
//        float ee6[7] = {1.0, -1.0,  0.0,  0.0,  0.0,  0.0,  0.0};//x^5*(x-1)------------2
//        float ee6[7] = {1.0, 0.0,  -1.0,  0.0,  0.0,  0.0,  0.0};//x^4*(x-1)*(x+1)------------3
//        float ee6[7] = {1.0,  0.0,  -5.0,  0.0,  4.0,  0.0,  0.0};//x^2*(x-1)*(x+1)*(x-2)*(x+2)------------5
//        float ee6[7] = {1.0,  3.0,  -5.0, -15.0,  4.0,  12.0,  0.0};//x*(x-1)*(x+1)*(x-2)*(x+2)*(x+3)------------6float ee6[7] = {1.0,  0.0, -0.4236111, 0.0,  0.050347222,  0.0, -0.0017361111};//(x-1/2)*(x+1/2)*(x-1/3)*(x+1/3)*(x-1/4)*(x+1/4)------------6float a = -2.5;float b =  2.5;int num;float tol = 1e-6;float roots[7];roots_num_equation_6th(ee6, a, b, num);std::cout << "the coefficients of the equation of 6th degree are:" << endl;for (int i=0; i<7; i++) {std::cout << ee6[i] << "  ";}std::cout << endl;std::cout << "the number of the roots of this equation is: " << num << endl;if (num > 0) {roots_equation_6th(ee6, a, b, tol, roots);std::cout << "the roots are: ";for (int j=1; j<(num+1); j++){std::cout << roots[j] << " ";}std::cout << endl;}
}

输出结果如下:

float ee6[7] ={1.0,  0.0, -0.4236111, 0.0,  0.050347222, 0.0, -0.0017361111};

//(x-1/2)*(x+1/2)*(x-1/3)*(x+1/3)*(x-1/4)*(x+1/4)------------6

float ee6[7] ={1.0,  3.0,  -5.0, -15.0, 4.0,  12.0,  0.0};

//x*(x-1)*(x+1)*(x-2)*(x+2)*(x+3)------------6

float ee6[7] ={1.0,  0.0,  -5.0, 0.0,  4.0,  0.0, 0.0};

//x^2*(x-1)*(x+1)*(x-2)*(x+2)------------5

float ee6[7] ={1.0,  0.0,  0.0, 0.0,  0.0,  0.0, 0.0};//x^6------------1

OK, 在这里就只测试这么几个方程。

后续在“用ray tracing画回旋体”时,生成每个图形可能会有成千上万次求解一元六次方程,区间在[0,1]。

by the way, 此刻发文时,已经完成“回旋体”图形的生成。所以,如上求解一元六次方程在区间内的所有不相等实根的程序在一定程度上是可靠的。

问题五十九:怎么求一元六次方程在区间内的所有不相等的实根(2)相关推荐

  1. 问题五十九:怎么求一元六次方程在区间内的所有不相等的实根(3)——修正一个问题

    前续:问题五十九:怎么求一元六次方程在区间内的所有不相等的实根(2) 我们在画"问题六十"的各种回旋体时,遇到这样的问题: 当"基本曲线"的控制点为: //8- ...

  2. 问题五十九:怎么求一元六次方程在区间内的所有不相等的实根(1)

    为什么要求一元六次方程在某区间的所有根? 原因是: 后面在用ray tracing画回旋体(rotational sweeping/ revolution)时,若侧面曲线是三次b样条曲线,求光线和回旋 ...

  3. 问题六十二:怎么求一元十次方程在区间内的所有不相等的实根(2)——修正“区间端点零值”问题

    前续"问题六十二:怎么求一元十次方程在区间内的所有不相等的实根"和"问题五十九:怎么求一元六次方程在区间内的所有不相等的实根(3)--修正一个问题" 不管是求解 ...

  4. [Python从零到壹] 五十九.图像增强及运算篇之图像锐化Scharr、Canny、LOG实现边缘检测

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  5. Python编程基础:第五十九节 守护线程Daemon Threading

    第五十九节 守护线程Daemon Threading 前言 实践 前言 守护线程是在后台运行的线程,对程序的运行并不重要,你的程序在退出前不会等待守护线程的完成,此类线程的特点是,当程序中主线程及所有 ...

  6. JavaScript学习(五十九)—原型、原型链、闭包以及闭包的不足

    JavaScript学习(五十九)-原型.原型链.闭包以及闭包的不足 一.什么是闭包? 所谓闭包就是指被定义在其他函数内部的函数. 闭包函数可以访问它所在的函数的所有变量. 文字太抽象了,画图解释一下 ...

  7. 陈艾盐:《春燕》百集访谈节目第五十九集

    <春燕>访谈节目共120集,每月分10集播出,记录了上百位企业家对"慈善"的各种不同见解,通过讲述社会真善美的故事,让更多的人了解慈善.发扬慈善精神,构建更加美好,和谐 ...

  8. 达芬奇密码 第五十九章

    达芬奇密码 第五十九章[@more@] 第五十九章 纽约市莱克星顿大街的天主事工会总部里,男接待员意外地接到了阿林加洛沙主教的电话,于是他问候道:"晚上好,先生." "有 ...

  9. 互联网创新创业大赛优秀范例_第五十九期创业沙龙——“互联网+”大学生创新创业大赛实践案例...

    原标题:第五十九期创业沙龙--"互联网+"大学生创新创业大赛实践案例 第五十九期创业沙龙 第六届"互联网+".2020年"创青春"系列竞赛开 ...

最新文章

  1. 学python需要什么文化基础-和尧名大叔一起从0开始学Python编程-循环
  2. python是c语言写的吗-python是用c写的吗
  3. 使用commandfield删除、修改gridview
  4. cactus java,使用cactus实现对servlet进行单元测试
  5. SAP S/4HANA使用ABAP获得生产订单的状态 1
  6. 语言求余和乘除优先级_愉快地学Java语言:第二章基本程序设计 第2讲
  7. junit junit_使用junit做其他事情
  8. P5714 【深基3.例7】肥胖问题--python3实现
  9. web访问负载均衡的实现
  10. jQuery UI基础 学习笔记
  11. mongodb远程连接windows
  12. SpringBoot与JPA
  13. 计算机应用基础 项目4-5 分析商品销售业绩 ppt课件,计算机应用基础课件项目四汇总.ppt...
  14. OA办公系统 Springboot vue 前后分离 跨域 Activiti6 工作流 集成代码生成器
  15. 手机屏幕物理点击器是什么原理_手机触摸屏的原理是什么?
  16. 神奇的多项式求导矩阵与积分矩阵
  17. html语言hr ,HTML hr是什么意思?
  18. 为什么说手游代理是目前比较具有优势的创业方式呢?
  19. 利用winHex对文件进行修复
  20. 计算机专业课程对比,国内外高校非计算机专业计算机课程设置对比与研究

热门文章

  1. 大数据下,谁来保护裸奔的个人隐私
  2. 微积分8--相关变化率
  3. IOS KVO与NSNotificationCenter简单使用
  4. Nginx作为web服务器的安装配置
  5. 如何用Lucene实现实时搜索--Tripod
  6. 设计中最困难的部分是决定设计什么
  7. Leetcode 712.两个字符串的最小ASCII删除和
  8. 【CV】如何使用Tensorflow提供的Object Detection API--3--手工标注数据
  9. CC1101魔幻的收发切换机制
  10. 【干货】深度学习实验流程及PyTorch提供的解决方案