本文主要是介绍OpenNL线性系统求解库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
OpenNL 是一个用于求解大型稀疏线性系统的C开发库。 它包括一个易于使用的用于组装矩阵的 API,以及用于对称和非对称系统的各种迭代求解器。 OpenNL API 在 geogram/NL/nl.h 中声明。
NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎
1、求解线性系统
让我们从一个简单的例子开始。 假设你要求解以下线性系统:
[ 1 2 ] [x] [5][ 3 4 ] [y] = [6]
首先,你需要声明将存储系统解的变量。 然后,我们创建一个 OpenNL 上下文,并声明变量的数量:
double x,y;nlNewContext();nlSolverParameteri(NL_NB_VARIABLES, 2);
现在我们可以构建线性系统了。 线性系统是逐行构建的。 OpenNL 有一个状态机,由 nlBegin()
、 nlEnd()
调用控制。看起来与 OpenGL 2.x 类似,但OpenNL构建稀疏矩阵而不是图形基元:
nlBegin(NL_SYSTEM);nlBegin(NL_MATRIX);nlBegin(NL_ROW);nlCoefficient(0, 1.0);nlCoefficient(1, 2.0);nlRightHandSide(5.0);nlEnd(NL_ROW);nlBegin(NL_ROW);nlCoefficient(0, 3.0);nlCoefficient(1, 4.0);nlRightHandSide(6.0);nlEnd(NL_ROW);nlEnd(NL_MATRIX);nlEnd(NL_SYSTEM);
接下来我们对系统进行求解:
nlSolve();x = nlGetVariable(0);y = nlGetVariable(1);
最后,我们删除 OpenNL 上下文:
nlDeleteContext(nlGetCurrent());
2、最小二乘回归
OpenNL 有一个特殊的最小二乘模式,可以组装正规方程(最小二乘)。 假设你有一个文件,其中每条线上都包含 X,Y 点坐标,并且想要找到最适合数据点的线方程 y=ax+b
。 和之前一样,我们创建一个 OpenNL 上下文并声明变量的数量。 此外,我们激活最小二乘模式:
nlNewContext();nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);nlSolverParameteri(NL_NB_VARIABLES, 2);
然后,我们读取文件并根据文件数据组装矩阵:
FILE* input = fopen("datapoints.dat", "r");double X,Y; // current datapointnlBegin(NL_SYSTEM);nlBegin(NL_MATRIX);while(!feof(input)) {fread(input, "%f %f", &X, &Y);nlBegin(NL_ROW);nlCoefficient(0, X);nlCoefficient(1, 1.0);nlRightHandSide(Y);nlEnd(NL_ROW);}nlEnd(NL_MATRIX);nlEnd(NL_SYSTEM);
就像前面的例子一样,我们现在可以求解系统:
nlSolve();a = nlGetVariable(0);b = nlGetVariable(1);
并且不要忘记关闭输入文件并删除 OpenNL 上下文:
fclose(input);nlDeleteContext(nlGetCurrent());
3、具有锁定变量的最小二乘回归
如前面的示例所示,我们假设有一个文件,其中每条线上都包含 X,Y 点坐标,并且我们仍然希望找到最适合数据点的线方程 y=ax+b
,但这一次我们有附加约束:直线的斜率 a 应等于 1。OpenNL 上下文的初始化与之前一样:
FILE* input = fopen("datapoints.dat", "r");double X,Y; nlNewContext();nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);nlSolverParameteri(NL_NB_VARIABLES, 2);
当我们构建系统时,我们锁定变量 0(对应于 a)并设置其值(1.0),如下所示:
nlBegin(NL_SYSTEM);nlLockVariable(0);nlSetVariable(0, 1.0);nlBegin(NL_MATRIX);while(!feof(input)) {fread(input, "%f %f", &X, &Y);nlBegin(NL_ROW);nlCoefficient(0, X);nlCoefficient(1, 1.0);nlRightHandSide(Y);nlEnd(NL_ROW);}nlEnd(NL_MATRIX);nlEnd(NL_SYSTEM);
然后剩下的就和以前一样了:
nlSolve();a = nlGetVariable(0);b = nlGetVariable(1);fclose(input);nlDeleteContext(nlGetCurrent());
原文链接:用OpenNL求解线性系统 - BimAnt
这篇关于OpenNL线性系统求解库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!