GSL中的多维求根

多维求根

    本章介绍多维求根(用n个未知数中的n个方程求解非线性系统)的函数。 本库为各种迭代求解器和收敛测试提供了低级组件。用户可以将它们组合起来以实现所需的解决方案,同时可以完全访问迭代的中间步骤。每类方法都使用相同的框架,因此您可以在运行时在求解器之间切换,而无需重新编译程序。求解器的每个实例都会跟踪自己的状态,从而允许将求解器用于多线程程序中。求解器是基于原始的Fortran库MINPACK。

    头文件gsl_multiroot.h包含多维求根函数和相关声明的原型。

38.1 概述

    多维求根的问题需要含有n个变量xin个方程fi的联立解,

fi(x1, . . . , xn) = 0   for i = 1 . . . n.

    一般来说,对于n维系统没有可用的交叉方法,也没有办法知道是否存在任何解。所有的算法都是从使用牛顿迭代的一种变体的初始猜测开始的,

     其中x, f为矢量,J为雅可比矩阵Jij =fi/∂xj 。可以使用其他策略来扩大收敛区域。这些包括要求在牛顿法提出的每一步上减少范数|f|,或者在|f|的负梯度方向上采取最陡的下降步骤。

在一个框架中可以使用几种寻根算法。用户为算法提供高级驱动程序,本库提供每个步骤所需的单独函数。迭代有三个主要阶段步骤,分别如下,

• 初始化算法T的求解器状态s

• 使用迭代T更新s

• 测试s收敛性,必要时重复迭代

    雅可比矩阵的计算可能是有问题的,要么因为导数的编程是棘手的,要么因为矩阵的n2项的计算变得过于昂贵。基于这些原因,本库提供的算法根据导数是否可用分为两类。

使用解析雅可比矩阵求解器的状态保存在gsl_multiroot_fdfsolver结构中。由用户提供函数及其导数的更新过程。

    不使用解析雅可比矩阵的求解器的状态保存在gsl_multiroot_fsolver结构中。更新过程只使用函数求值(而不是导数)。算法通过近似方法估计矩阵JJ−1。

38.2 初始化求解器

以下函数初始化多维求解器,包含带有或不带有导数。求解器本身只取决于问题的维数和算法,可以在不同的问题中重用。

gsl_multiroot_fsolver

    这是一个不带导数的多维求的根工作空间。

gsl_multiroot_fdfsolver

这是一个使用导数进行多维求根的工作空间。

gsl_multiroot_fsolver * gsl_multiroot_fsolver_alloc(const gsl_multiroot_fsolver_type * T, size_t n)

    本函数返回一个指针,指向n维系统中新分配的类型为T的求解器实例。例如,下面的代码创建了一个混合求解器的实例,来解决一个三维方程组:

const gsl_multiroot_fsolver_type * T = gsl_multiroot_fsolver_hybrid;

gsl_multiroot_fsolver * s = gsl_multiroot_fsolver_alloc (T, 3);

如果没有足够的内存来创建求解器,则函数返回一个空指针,用错误代码GSL_ENOMEM调用错误处理程序。

gsl_multiroot_fdfsolver * gsl_multiroot_fdfsolver_alloc(

const gsl_multiroot_fdfsolver_type * T, size_t n)

    本函数返回一个指针,指向在n维系统中新分配的类型为T的导数求解器实例。例如,下面的代码创建了一个牛顿-拉夫森求解器的实例,用于2维方程组:

const gsl_multiroot_fdfsolver_type * T = gsl_multiroot_fdfsolver_newton;

gsl_multiroot_fdfsolver * s = gsl_multiroot_fdfsolver_alloc (T, 2);

    如果没有足够的内存来创建求解器,则函数返回一个空指针,用错误代码GSL_ENOMEM调用错误处理程序。

int gsl_multiroot_fsolver_set(gsl_multiroot_fsolver * s, gsl_multiroot_function * f,

const gsl_vector* x)

int gsl_multiroot_fdfsolver_set(gsl_multiroot_fdfsolver * s,

sl_multiroot_function_fdf * fdf, const gsl_vector * x)

    这两个函数用函数f或函数和导数fdf,设置,或重置,一个现有的求解器s,并初始猜测值x。注意初始位置是从x复制的,这个参数不会被后续的迭代修改。

void gsl_multiroot_fsolver_free(gsl_multiroot_fsolver * s)

void gsl_multiroot_fdfsolver_free(gsl_multiroot_fdfsolver * s)

    这两个函数释放求解器s使用的所有内存。

const char * gsl_multiroot_fsolver_name(const gsl_multiroot_fsolver * s)

const char * gsl_multiroot_fdfsolver_name(const gsl_multiroot_fdfsolver * s)

    这两个函数返回一个指向求解器名称的指针。例如:

printf ("s is a '%s' solver\n", gsl_multiroot_fdfsolver_name (s));

    将打印出类似如下内容 s is a 'newton' solver.

猜你喜欢

转载自blog.csdn.net/yxmlhc/article/details/120591409