Math 解线性方程 我需要用程序来解决C、Objic C、或(如果需要的话)C++中的线性方程组。
下面是方程式的一个示例:Math 解线性方程 我需要用程序来解决C、Objic C、或(如果需要的话)C++中的线性方程组。,math,linear-algebra,system,linear-equation,Math,Linear Algebra,System,Linear Equation,下面是方程式的一个示例: -44.3940 = a * 50.0 + b * 37.0 + tx -45.3049 = a * 43.0 + b * 39.0 + tx -44.9594 = a * 52.0 + b * 41.0 + tx 从这里,我想得到a、b和tx的最佳近似值。您是在寻找一个软件包来完成这项工作,还是实际执行矩阵运算等等,并完成每一步 第一,我的一个同事刚刚用过。它只是一个包装器,但它删除了很多设置步骤。不过,看起来您必须坚持使用C语言中的GLPK。对于后者,感谢deli
-44.3940 = a * 50.0 + b * 37.0 + tx
-45.3049 = a * 43.0 + b * 39.0 + tx
-44.9594 = a * 52.0 + b * 41.0 + tx
从这里,我想得到
a
、b
和tx
的最佳近似值。您是在寻找一个软件包来完成这项工作,还是实际执行矩阵运算等等,并完成每一步
第一,我的一个同事刚刚用过。它只是一个包装器,但它删除了很多设置步骤。不过,看起来您必须坚持使用C语言中的GLPK。对于后者,感谢delicious保存了一篇我不久前学习LP的旧文章。如果您需要进一步的具体帮助,请让我们知道,我确信,我或其他人会回来帮助您,但是,我认为从这里开始就相当直接了。祝你好运
和
是两种良好的通用算法(另请参见)。如果您正在寻找代码,请签出,然后(当然,这取决于您的许可要求)
编辑:我知道你在C语言中工作,但我也必须为(Python中的计算机代数系统)说一句好话。你可以从它的算法中学到很多东西(如果你能读一点python的话)。另外,它是在新的BSD许可下,而大多数免费数学软件包都是GPL。对于3x3线性方程组,我想可以推出自己的算法
然而,您可能不得不担心精度、被零除或非常小的数字,以及如何处理无穷多个解。我的建议是使用一个标准的数值线性代数包,比如 就我个人而言,我偏爱计算机的算法。(我喜欢C++版) 这本书将教你为什么这些算法有效,并向你展示一些经过良好调试的算法实现 当然,你可以盲目地使用(我已经非常成功地使用了它),但我会直接输入一个高斯消去算法,至少对使这些算法稳定所做的工作有一个模糊的概念 稍后,如果你正在做更有趣的线性代数,环顾一下的源代码将回答许多问题。NIST有这样做的工具 其中一个更可靠的方法是使用 下面是一个包装器的示例,这样我就可以在代码中调用“GetInverse(a,InvA)”,它将把这个反向放入InvA中
void GetInverse(const Array2D<double>& A, Array2D<double>& invA)
{
QR<double> qr(A);
invA = qr.solve(I);
}
void GetInverse(常量数组2d&A、数组2d&invA)
{
QR(A);
invA=qr.solve(I);
}
Array2D是在库中定义的 从你问题的措辞来看,你似乎有更多的方程式而不是未知数,你想尽量减少不一致。这通常是通过线性回归实现的,线性回归使不一致的平方和最小化。根据数据的大小,您可以在电子表格或统计数据包中执行此操作。R是一个高质量的免费软件包,它可以进行线性回归,还有很多其他功能。线性回归有很多方法(还有很多方法),但对于简单的情况,这是很简单的。下面是一个使用您的数据的R示例。请注意,“tx”是模型的截距
> y <- c(-44.394, -45.3049, -44.9594)
> a <- c(50.0, 43.0, 52.0)
> b <- c(37.0, 39.0, 41.0)
> regression = lm(y ~ a + b)
> regression
Call:
lm(formula = y ~ a + b)
Coefficients:
(Intercept) a b
-41.63759 0.07852 -0.18061
>y a b回归=lm(y~a+b)
>回归
电话:
lm(公式=y~a+b)
系数:
(截取)a b
-41.63759 0.07852 -0.18061
在运行时效率方面,其他人的回答比我好。如果你总是拥有与变量数量相同的方程,我喜欢它,因为它易于实现。只需编写一个函数来计算一个矩阵的行列式(或者使用一个已经编写好的函数,我相信你可以在那里找到一个),然后将两个矩阵的行列式进行除法。你可以用一个程序来解决这个问题,就像你手工解决它一样(用乘法和减法,然后将结果反馈到方程中)。这是相当标准的中学数学
-44.3940 = 50a + 37b + c (A)
-45.3049 = 43a + 39b + c (B)
-44.9594 = 52a + 41b + c (C)
(A-B): 0.9109 = 7a - 2b (D)
(B-C): 0.3455 = -9a - 2b (E)
(D-E): 1.2564 = 16a (F)
(F/16): a = 0.078525 (G)
Feed G into D:
0.9109 = 7a - 2b
=> 0.9109 = 0.549675 - 2b (substitute a)
=> 0.361225 = -2b (subtract 0.549675 from both sides)
=> -0.1806125 = b (divide both sides by -2) (H)
Feed H/G into A:
-44.3940 = 50a + 37b + c
=> -44.3940 = 3.92625 - 6.6826625 + c (substitute a/b)
=> -41.6375875 = c (subtract 3.92625 - 6.6826625 from both sides)
因此,你最终会:
a = 0.0785250
b = -0.1806125
c = -41.6375875
如果你把这些值插回A、B和C中,你会发现它们是正确的
诀窍是使用一个简单的4x3矩阵,它依次减少为3x2矩阵,然后是一个2x1,即“a=n”,n是一个实际数字。一旦你有了它,你把它输入下一个矩阵,得到另一个值,然后这两个值进入下一个矩阵,直到你解出所有变量
如果你有N个不同的方程,你总是可以解N个变量。我之所以说这两个是不同的,是因为这两个不是:
7a + 2b = 50
14a + 4b = 100
它们是同一个方程乘以2,所以你无法从中得到一个解——将第一个方程乘以2,然后减去,你会得到一个正确但无用的结论:
0 = 0 + 0
举个例子,这里有一些C代码,可以计算出你在问题中的联立方程。首先是一些必要的类型、变量、用于打印公式的支持函数,以及
main
的开头:
#include <stdio.h>
typedef struct { double r, a, b, c; } tEquation;
tEquation equ1[] = {
{ -44.3940, 50, 37, 1 }, // -44.3940 = 50a + 37b + c (A)
{ -45.3049, 43, 39, 1 }, // -45.3049 = 43a + 39b + c (B)
{ -44.9594, 52, 41, 1 }, // -44.9594 = 52a + 41b + c (C)
};
tEquation equ2[2], equ3[1];
static void dumpEqu (char *desc, tEquation *e, char *post) {
printf ("%10s: %12.8lf = %12.8lfa + %12.8lfb + %12.8lfc (%s)\n",
desc, e->r, e->a, e->b, e->c, post);
}
int main (void) {
double a, b, c;
接下来,将两个具有两个未知数的方程简化为一个具有一个未知数的方程:
// Next step, populate equ3 based on removing b from equ2.
// D - E
equ3[0].r = equ2[0].r * equ2[1].b - equ2[1].r * equ2[0].b;
equ3[0].a = equ2[0].a * equ2[1].b - equ2[1].a * equ2[0].b;
equ3[0].b = 0;
equ3[0].c = 0;
dumpEqu ("D-E", &(equ3[0]), "F");
puts ("");
现在我们有了一个类型为number1=unknown*number2
的公式,我们可以简单地用unknown计算出未知值,看看下面的公式
使用它,您可以编写如下代码:
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
Decision a = new Decision(Domain.Real, "a");
Decision b = new Decision(Domain.Real, "b");
Decision c = new Decision(Domain.Real, "c");
model.AddDecisions(a,b,c);
model.AddConstraint("eqA", -44.3940 == 50*a + 37*b + c);
model.AddConstraint("eqB", -45.3049 == 43*a + 39*b + c);
model.AddConstraint("eqC", -44.9594 == 52*a + 41*b + c);
Solution solution = context.Solve();
string results = solution.GetReport().ToString();
Console.WriteLine(results);
以下是输出:
===求解器基础服务报告==< BR/>
日期时间:04/20/2009 23:29:55
型号名称:默认值
要求的能力:LP
求解时间(毫秒):1027
总时间(毫秒):1414
解决完成状态:最佳
所选解算器:Microsoft.SolverFoundation.Solvers.SimplexSolver
指令:
Microsoft.SolverFoundation.Services.Directive
算法:原始
算术:混合
定价(精确):默认值
定价(双倍):陡坡
基础:松弛
枢轴计数:3
===解决方案详细信息===
目标:
决断
// Finally, substitute values back into equations.
a = equ3[0].r / equ3[0].a;
printf ("From (F ), a = %12.8lf (G)\n", a);
b = (equ2[0].r - equ2[0].a * a) / equ2[0].b;
printf ("From (D,G ), b = %12.8lf (H)\n", b);
c = (equ1[0].r - equ1[0].a * a - equ1[0].b * b) / equ1[0].c;
printf ("From (A,G,H), c = %12.8lf (I)\n", c);
return 0;
}
>: -44.39400000 = 50.00000000a + 37.00000000b + 1.00000000c (A)
>: -45.30490000 = 43.00000000a + 39.00000000b + 1.00000000c (B)
>: -44.95940000 = 52.00000000a + 41.00000000b + 1.00000000c (C)
A-B: 0.91090000 = 7.00000000a + -2.00000000b + 0.00000000c (D)
B-C: -0.34550000 = -9.00000000a + -2.00000000b + 0.00000000c (E)
D-E: -2.51280000 = -32.00000000a + 0.00000000b + 0.00000000c (F)
From (F ), a = 0.07852500 (G)
From (D,G ), b = -0.18061250 (H)
From (A,G,H), c = -41.63758750 (I)
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
Decision a = new Decision(Domain.Real, "a");
Decision b = new Decision(Domain.Real, "b");
Decision c = new Decision(Domain.Real, "c");
model.AddDecisions(a,b,c);
model.AddConstraint("eqA", -44.3940 == 50*a + 37*b + c);
model.AddConstraint("eqB", -45.3049 == 43*a + 39*b + c);
model.AddConstraint("eqC", -44.9594 == 52*a + 41*b + c);
Solution solution = context.Solve();
string results = solution.GetReport().ToString();
Console.WriteLine(results);
function x = LinSolve(A,y)
%
% Recursive Solution of Linear System Ax=y
% matlab equivalent: x = A\y
% x = n x 1
% A = n x n
% y = n x 1
% Uses stack space extensively. Not efficient.
% C allows recursion, so convert it into C.
% ----------------------------------------------
n=length(y);
x=zeros(n,1);
if(n>1)
x(1:n-1,1) = LinSolve( A(1:n-1,1:n-1) - (A(1:n-1,n)*A(n,1:n-1))./A(n,n) , ...
y(1:n-1,1) - A(1:n-1,n).*(y(n,1)/A(n,n)));
x(n,1) = (y(n,1) - A(n,1:n-1)*x(1:n-1,1))./A(n,n);
else
x = y(1,1) / A(1,1);
end