math - variable - sistema de ecuaciones lineales




Resolviendo una ecuación lineal (7)

Necesito resolver mediante programación un sistema de ecuaciones lineales en C, Objetivo C o (si es necesario) C ++.

Aquí hay un ejemplo de las ecuaciones:

-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 partir de esto, me gustaría obtener la mejor aproximación para a , b tx .


¿Está buscando un paquete de software que haga el trabajo o realmente haga las operaciones de la matriz y tal y haga cada paso?

El primero, un compañero de trabajo mío acaba de usar Ocaml GLPK . Es solo una envoltura para el GLPK , pero elimina muchos de los pasos para configurar las cosas. Parece que vas a tener que seguir con el GLPK, en C, sin embargo. Para este último, gracias a delicious por guardar un artículo antiguo que solía aprender LP hace un tiempo, PDF . Si necesita ayuda específica para la configuración adicional, avísenos y estoy seguro de que alguien o yo volveremos y ayudaremos, pero creo que es bastante sencillo desde aquí. ¡Buena suerte!


Eche un vistazo a la Microsoft Solver Foundation .

Con él podrías escribir código como este:

  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); 

Aquí está la salida:
=== Informe del servicio de la Fundación Solver ===
Fecha y hora: 20/04/2009 23:29:55
Nombre del modelo: Predeterminado
Capacidades solicitadas: LP
Tiempo de resolución (ms): 1027
Tiempo total (ms): 1414
Resolver estado de finalización: óptimo
Solucionador seleccionado: Microsoft.SolverFoundation.Solvers.SimplexSolver
Directivas:
Microsoft.SolverFoundation.Services.Directive
Algoritmo: Primal
Aritmética: Híbrida
Precio (exacto): Predeterminado
Precio (doble): SteepestEdge
Base: holgura
Conteo de pivotes: 3
=== Detalles de la solución ===
Metas:

Decisiones:
a: 0.0785250000000004
b: -0.180612500000001
c: -41.6375875


Para un sistema 3x3 de ecuaciones lineales, supongo que estaría bien implementar sus propios algoritmos.

Sin embargo, es posible que deba preocuparse por la precisión, la división por cero o números realmente pequeños y qué hacer con infinitas soluciones. Mi sugerencia es ir con un paquete estándar de álgebra lineal numérica como LAPACK .


Personalmente, soy parcial a los algoritmos de recetas numéricas . (Soy aficionado a la edición C ++).

Este libro le enseñará por qué funcionan los algoritmos, y le mostrará algunas implementaciones depuradas bastante bien de esos algoritmos.

Por supuesto, podría usar CLAPACK ciegas (lo he usado con gran éxito), pero primero escribiría a mano un algoritmo de eliminación gaussiana para al menos tener una idea tenue del tipo de trabajo que se ha dedicado a hacer estos algoritmos estable.

Más tarde, si está haciendo un álgebra lineal más interesante, mirar alrededor del código fuente de Octave responderá muchas preguntas.


Según la redacción de su pregunta, parece que tiene más ecuaciones que incógnitas y desea minimizar las inconsistencias. Esto se hace típicamente con regresión lineal, que minimiza la suma de los cuadrados de las inconsistencias. Dependiendo del tamaño de los datos, puede hacerlo en una hoja de cálculo o en un paquete estadístico. R es un paquete gratuito de alta calidad que hace regresión lineal, entre muchas otras cosas. Hay mucho en la regresión lineal (y muchos problemas), pero como es fácil de hacer para casos simples. Aquí hay un ejemplo de R con sus datos. Tenga en cuenta que el "tx" es la intercepción de su modelo.

> 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  

La regla de Cramer y la eliminación gaussiana son dos buenos algoritmos de propósito general (también vea Ecuaciones lineales simultáneas ). Si está buscando código, consulte GiNaC , Maxima y SymbolicC++ (dependiendo de sus requisitos de licencia, por supuesto).

EDITAR: Sé que estás trabajando en C land, pero también tengo que poner una buena palabra para SymPy (un sistema de álgebra de computadora en Python). Puedes aprender mucho de sus algoritmos (si puedes leer un poco de Python). Además, está bajo la nueva licencia BSD, mientras que la mayoría de los paquetes matemáticos gratuitos son GPL.


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




linear-equation