using System;
namespace Zhou.CSharp.Algorithm
{ /// <summary> /// Class LEquations for solving linear equations /// Original Zhou Changfa /// Adapted to deep confusion /// </summary> public static partial class LEquations {
/// <summary>
/// Hausholder transformation method for solving linear least squares problem
/// </summary>
/// <param name="mtxLECoef">specified coefficient matrix</param>
/ // <param name="mtxLEConst">Specified constant matrix</param>
/// <param name="mtxResult">Matrix object, returns the solution matrix of the equation system</param>
/// <param name="mtxQ ">Matrix object, returns the Q matrix of the Hausholde transformation</param>
/// <param name="mtxR">Matrix object, returns the R matrix of the Hausholde transformation</param>
/// <return>bool type, whether the equation system is solved successfully</return>
public static bool GetRootsetMqr(Matrix mtxLECoef, Matrix mtxLEConst, Matrix mtxResult, Matrix mtxQ,Matrix mtxR)
{ // The number of equations and unknowns in the equation system int m = mtxLECoef.GetNumRows(); int n = mtxLECoef.GetNumColumns();
// singular equations
if (m < n)
{ return false; }
// Initialize the solution vector as a constant vector
mtxResult.SetValue(mtxLEConst);
double[] pDataConst = mtxResult.GetData();
// Construct a temporary matrix for QR decomposition
mtxR.SetValue(mtxLECoef);
double[] pDataCoef = mtxR.GetData();
// QR decomposition
if (!Matrix.SplitQR(mtxR, mtxQ))
{ return false; }
// temporary buffer
double[] c = new double[n];
double[] q = mtxQ.GetData();
// 求解
for (int i = 0; i <= n - 1; i++)
{
double d = 0.0;
for (int j = 0; j <= m - 1; j++)
{
d = d + q[j * m + i] * pDataConst[j];
}
c[i] = d;
}
pDataConst[n - 1] = c[n - 1] / pDataCoef[n * n - 1];
for (int i = n - 2; i >= 0; i--)
{
double d = 0.0;
for (int j = i + 1; j <= n - 1; j++)
{
d = d + pDataCoef[i * n + j] * pDataConst[j];
}
pDataConst[i] = (c[i] - d) / pDataCoef[i * n + i];
}
return true;
}
}
}