OpenCASCADE解非线性方程组

eryar@163.com

Abstract. 在科学技术领域里常常提出求解非线性方程组的问题,例如,用非线性函数拟合实验数据问题、非线性网络问题、几何上的曲线曲面求交问题等。OpenCASCADE中有关于非线性方程组定义的类及其求解类,本文主要介绍如何在OpenCASCADE中定义非线性方程组,及对其进行求解。

Key Words. Function Set, Function Set Root, Newton Raphson Algorithm

1.Introduction

在科学技术领域里常常提出求解非线性方程组的问题,例如,用非线性函数拟合实验数据问题、非线性网络问题等。在几何造型中很多问题也可以利用非线性方程组来解决。如曲线的光顺,曲线求交、曲面求交、Blend造型问题等。

OpenCASCADE提供了非线性方程组的类math_FunctionSet,可以先从类图上来看看有哪些算法使用了这个类:

图1 曲线光顺包FaireCurve

图2 Blending Surface between two surfaces

感兴趣的同学可以自己打开OpenCASCADE的类索引文件查看。可以看到很多算法涉及到方程组的求解问题。本文主要介绍如何定义非线性方程组及对其进行求解。理解这些套路后,对math_FunctionSet相关的派生类及其用用途就会有个清晰的认识,便于对源码的理解。

2.Function Set Definition

设有非线性方程组

为实变量的非线方程函数。引入向量形式表示,引进记号:

于是非线性方程组可以简单记作:F(x)=0。我们的问题是寻求X使F(X)=0,这个X就是非线性方程组的解。

OpenCASCADE中使用类math_FunctionSet来表示方程组,这是个抽象类,定义了如下纯虚函数:

l NbVariables():变量的个数,即末知量的个数;

l NbEquations():方程的个数,即方程组中有几个方程;

l Value(const math_Vector&X, math_Vector& F):方程组的值,即代入变量每个方程的值;

3.Function Set Root Algorithm

解非线性方程组的牛顿法和解方程式的思路一样,要求方程有一阶导数。而非线性方程组即是要求有偏导数。由fi(x)偏导数作成的矩阵记为J(x)或F’(x),称为F(x)的Jacobi矩阵:

求解非线性方程组的牛顿法为:

其中xk为方程线的近似解向量。

OpenCASCADE中也提供了非线性方程组的求解类,如:math_FunctionSetRoot,math_NewtonFunctionSetRoot。而使用这些类的输入都是要求具有一阶偏导数的线性方程组的定义math_FunctionSetWithDerivaties。这个类定义了具有一阶偏导数的非线性方程组,其纯虚函数除了前面说明的几个以外,还增加了如下两个:

l Derivatives(const math_Vector& X, math_Matrix& D):一阶偏导数值,即计算Jacobi矩阵;

l Values(const math_Vector& X, math_Vector& F, math_Matrix& D):计算方程的值及一阶偏导数矩阵Jacobi矩阵。

4.Code Example

下面给出一个具体的例子来说明这些类的用法。设有非线性方程组:

从几何上看其解就是圆心在原点,半径为2的圆与曲线的交点:

图3 圆与曲线求交

下面我们使用OpenCASCADE来对上述问题进行求解。首先定义这个非线性方程组:

#include <math_FunctionSet.hxx>
#include <math_FunctionSetWithDerivatives.hxx>
#include <math_FunctionSetRoot.hxx> #pragma comment(lib, "TKernel.lib")
#pragma comment(lib, "TKMath.lib") class MyFunctionSet : public math_FunctionSetWithDerivatives
{
public:
virtual Standard_Integer NbVariables() const
{
return ;
} virtual Standard_Integer NbEquations() const
{
return ;
} virtual Standard_Boolean Value(const math_Vector& X, math_Vector& F)
{
F() = X() * X() + X() * X() - 4.0; F() = Pow(M_E, X()) + X() - 1.0; return Standard_True;
} virtual Standard_Boolean Derivatives(const math_Vector& X, math_Matrix& D)
{
// matrix D is Jacobi matrix.
D(, ) = 2.0 * X();
D(, ) = 2.0 * X(); D(, ) = Pow(M_E, X());
D(, ) = 1.0; return Standard_True;
} virtual Standard_Boolean Values(const math_Vector& X, math_Vector& F, math_Matrix& D)
{
Value(X, F); Derivatives(X, D); return Standard_True;
} private:
}; void test()
{
MyFunctionSet aFunctionSet;
math_FunctionSetRoot aSolver(aFunctionSet); math_Vector aStartingPoint(, ); // 1. (1.0, 1.0)
aStartingPoint() = 1.0;
aStartingPoint() = 1.0; aSolver.Perform(aFunctionSet, aStartingPoint); if (aSolver.IsDone())
{
aSolver.Dump(std::cout);
} // 2. (1.0, -1.0)
aStartingPoint() = 1.0;
aStartingPoint() = -1.0; aSolver.Perform(aFunctionSet, aStartingPoint); if (aSolver.IsDone())
{
aSolver.Dump(std::cout);
}
} int main(int argc, char* argv[])
{
test(); return ;
}

上述代码先定义了带有一阶偏导数的非线性方程组类:MyFunctionSet,因为有两个变量及两个方程,再分别实现计算方程值及偏导数的虚函数。

然后使用类math_FunctionSetRoot来对方程组进行求解,求解的结果如下图所示:

图4 非线性方程组求解结果

由图3可知,两个曲线相交有两个交点,但是使用类math_FunctionSetRoot一次只能计算一个解。从图4的计算结果还可以看出,初值的选择对解的影响很大,既影响计算结果,也影响迭代次数。

5.Conclusion

综上所述,OpenCASCADE的math工具箱中提供了方程组的定义、求解功能。其中对非线性方程组求解使用的是Newton迭代法,所以要求方程组必须实现计算一阶偏导数的虚函数,即计算Jacobi矩阵。

从OpenCASCADE类图中可以看出,方程组定义类用在了很多地方,所以理解上述对方程组的定义及解的用法,对其他使用这个派生类的地方更容易其源码。

6.References

  1. 同济大学数学教研室. 高等数学 第四版. 高等教育出版社. 2004
  2. 易大义, 沈云宝, 李有法. 计算方法. 浙江大学出版社. 2002

OpenCASCADE解非线性方程组的更多相关文章

  1. 牛顿迭代法解非线性方程组(MATLAB版)

    牛顿迭代法,又名切线法,这里不详细介绍,简单说明每一次牛顿迭代的运算:首先将各个方程式在一个根的估计值处线性化(泰勒展开式忽略高阶余项),然后求解线性化后的方程组,最后再更新根的估计值.下面以求解最简 ...

  2. Matlab-6:解非线性方程组newton迭代法

    函数文件: function x=newton_Iterative_method(f,n,Initial) x0=Initial; tol=1e-11; x1=x0-Jacobian(f,n,x0)\ ...

  3. Python最小二乘法解非线性超定方程组

    求解非线性超定方程组,网上搜到的大多是线性方程组的最小二乘解法,对于非线性方程组无济于事. 这里分享一种方法:SciPy库的scipy.optimize.leastsq函数. import numpy ...

  4. 【高斯消元解xor方程组】BZOJ2466-[中山市选2009]树

    [题目大意] 给出一棵树,初始状态均为0,每反转一个节点的状态,相邻的节点(父亲或儿子)也会反转,问要使状态均为1,至少操作几次? [思路] 一场大暴雨即将来临,白昼恍如黑夜!happy! 和POJ1 ...

  5. poj1830(高斯消元解mod2方程组)

    题目链接:http://poj.org/problem?id=1830 题意:中文题诶- 思路:高斯消元解 mod2 方程组 有 n 个变元,根据给出的条件列 n 个方程组,初始状态和终止状态不同的位 ...

  6. poj1681(枚举or高斯消元解mod2方程组)

    题目链接: http://poj.org/problem?id=1681 题意: 有一个包含 n * n 个方格的正方形, w 表示其所在位置为白色, y 表示其所在位置为黄色. 对 (i, j) 位 ...

  7. poj1222(枚举or高斯消元解mod2方程组)

    题目链接: http://poj.org/problem?id=1222 题意: 有一个 5 * 6 的初始矩阵, 1 表示一个亮灯泡, 0 表示一个不亮的灯泡. 对 (i, j) 位置进行一次操作则 ...

  8. POJ 1222 EXTENDED LIGHTS OUT(高斯消元解XOR方程组)

    http://poj.org/problem?id=1222 题意:现在有5*6的开关,1表示亮,0表示灭,按下一个开关后,它上下左右的灯泡会改变亮灭状态,要怎么按使得灯泡全部处于灭状态,输出方案,1 ...

  9. poj1753(高斯消元解mod2方程组)

    题目链接:http://poj.org/problem?id=1753 题意:一个 4*4 的棋盘,初始时上面放满了黑色或白色的棋子.对 (i, j) 位置进行一次操作后 (i, j), (i + 1 ...

随机推荐

  1. flatMap作用

    总结:1. map会将每一条输入映射为一个新对象.{苹果,梨子}.map(去皮) = {去皮苹果,去皮梨子} 其中: “去皮”函数的类型为:A => B 2.flatMap包含两个操作:会将每一 ...

  2. Car Talk2

    #! /usr/bin/python # -*- coding: utf-8 -*- # # # “Recently I had a visit with my mom and we realized ...

  3. javascript中的那些宽度和高度

    window.outerHeight和window.outerWidth  表示整个浏览器窗体的大小,包括任务栏等.       IE9及以上 window.innerHeight和window.in ...

  4. SPFA的小优化

    标签:闲扯 SPFA的小优化 1. 向队尾加入元素时,如果它比对首还优,就把把它直接和队首交换. 拿一个双端队列来实现 (手写 , head ,tail   STLdeque亲测及其慢) 这个小优化其 ...

  5. [NOIP2009提高组]靶形数独

    题目:洛谷P1074.Vijos P1755.codevs1174. 题目大意:给你一个数独,让你填完这个数独,并要求得分最大,问这个得分是多少(不能填完输出-1). 每个格子的得分是当前格子所填的数 ...

  6. win2003系统同步Linux ntp server批处理

    最后更新时间: 2018/12/15 一般windows配置时间服务器,只需要在windows系统右下角,点时间,里面配置好对应NTP服务器地址就行, 至多再修改一下注册表 HKEY_LOCAL_MA ...

  7. 【Codeforces Round #422 (Div. 2) B】Crossword solving

    [题目链接]:http://codeforces.com/contest/822/problem/B [题意] 让你用s去匹配t,问你最少需要修改s中的多少个字符; 才能在t中匹配到s; [题解] O ...

  8. 【转】 HTML解析:基于XPath的C#类库HtmlAgiliytyPack

    [转] HTML解析:基于XPath的C#类库HtmlAgiliytyPack 最近处于毕业设计开始阶段,前期工作需要去国外的一些专业数据库网站比对一些所需TF家族信息,为了快捷方便,想到用程序去帮助 ...

  9. 使用ThoughtWorks.QRCode生成二维码

    新建Windows应用程序,加入引用ThoughtWorks.QRCode.dll,编写代码生成二维码. using System; using System.Drawing; using Syste ...

  10. 用Hexo搭建个人博客

    博客地址: http://astraylinux.com/ 文章地址: http://astraylinux.com/2015/06/02/linux-Init-Hexo/ Step 1 Instal ...