C# 齐次线性方程组的基本解:Ax=0,Det(A)=0,MathNet
我试图解一个齐次线性方程组,比如C# 齐次线性方程组的基本解:Ax=0,Det(A)=0,MathNet,c#,linear-algebra,math.net,C#,Linear Algebra,Math.net,我试图解一个齐次线性方程组,比如Ax=0。 以下是一个为简单起见已简化的示例矩阵: 1 2 | 0 3 6 | 0 我希望得到的解决方案至少是[2,-1]。但基本解决方案是[2C;-1C]。您可以看到Det(A)=0和Rank(A)=1。当然,您知道这样的系统有一个简单的解决方案[0,0] 我正在努力: Matrix<double> A = Matrix<double>.Build.DenseOfArray(new double[,] { { 1, 2 },
Ax=0
。
以下是一个为简单起见已简化的示例矩阵:
1 2 | 0
3 6 | 0
我希望得到的解决方案至少是[2,-1]
。但基本解决方案是[2C;-1C]
。您可以看到Det(A)=0
和Rank(A)=1
。当然,您知道这样的系统有一个简单的解决方案[0,0]
我正在努力:
Matrix<double> A = Matrix<double>.Build.DenseOfArray(new double[,]
{
{ 1, 2 },
{ 3, 6 }
});
Vector<double> B = Vector<double>.Build.Dense(new double[] { 0, 0 });
var result = A.Solve(B); //result = Nan, Nan.
Matrix A=Matrix.Build.DenseOfArray(新双[,]
{
{ 1, 2 },
{ 3, 6 }
});
向量B=Vector.Build.Dense(新的双精度[]{0,0});
var结果=A.解算(B)//结果=Nan,Nan。
不适用于我的情况(B=0,Det(A)=0)。要解线性方程组,您可以尝试
Matrix.SolveIterative(向量输入,IIterativeSolver解算器,迭代器迭代器=null,IPreconditioner预条件器=null)
要获取可用的解算器,请执行以下操作:
var solvers = Assembly.GetAssembly(typeof(Matrix<double>))
.GetTypes()
.Where(t => t.GetInterfaces().Contains(typeof(IIterativeSolver<double>)) &&
t.GetConstructors().Any(ctor => ctor.GetParameters().Count() == 0))
.Select(t => Activator.CreateInstance(t))
.Cast<IIterativeSolver<double>>();
使用您的数据尝试所有这些方法:
Matrix<double> A = Matrix<double>.Build.DenseOfArray(new double[,]
{
{ 1, 2 },
{ 3, 6 }
});
Vector<double> B = Vector<double>.Build.Dense(new double[] { 0, 0 });
对你来说,这不是运气。结果是:
MathNet.Numerics.LinearAlgebra.Double.Solvers.BiCgStab
Algorithm experience a numerical break down
MathNet.Numerics.LinearAlgebra.Double.Solvers.GpBiCg
DenseVector 2-Double
NaN
NaN
MathNet.Numerics.LinearAlgebra.Double.Solvers.MlkBiCgStab
Algorithm experience a numerical break down
MathNet.Numerics.LinearAlgebra.Double.Solvers.TFQMR
DenseVector 2-Double
0
0
虽然它可以像这样工作
无论如何MathNet
非常好,可以轻松构建解决方案。
使用学院的线性代数和图书馆功能:
static class MatrixExtension
{
public static Vector<double>[] SolveDegenerate(this Matrix<double> matrix, Vector<double> input)
{
var augmentedMatrix =
Matrix<double>.Build.DenseOfColumnVectors(matrix.EnumerateColumns().Append(input));
if (augmentedMatrix.Rank() != matrix.Rank())
throw new ArgumentException("Augmented matrix rank does not match coefficient matrix rank.");
return augmentedMatrix.SolveAugmented();
}
private static Vector<double>[] SolveAugmented(this Matrix<double> matrix)
{
var rank = matrix.Rank();
var cut = matrix.CutByRank(rank);
// [A|R]x[X] = [B]
var A = Matrix<double>.Build.DenseOfColumnVectors(cut.EnumerateColumns().Take(rank));
var R = Matrix<double>.Build.DenseOfColumnVectors(cut.EnumerateColumns().Skip(rank).Take(cut.ColumnCount - rank - 1));
var B = cut.EnumerateColumns().Last();
var vectors = Matrix<double>.Build.DenseDiagonal(R.ColumnCount, 1)
.EnumerateColumns().ToArray();
return vectors.Select(v => A.Solve(B - R * v))
.Zip(vectors, (x, v) => Vector<double>.Build.DenseOfEnumerable(x.Concat(v)))
.ToArray();
}
private static Matrix<double> CutByRank(this Matrix<double> matrix, int rank)
{
var result = Matrix<double>.Build.DenseOfMatrix(matrix);
while (result.Rank() < result.RowCount)
result = result.EnumerateRows()
.Select((r, index) => result.RemoveRow(index))
.FirstOrDefault(m => m.Rank() == rank);
return result;
}
}
给出:
DenseVector 2-Double
-2
1
DenseVector 3-Double
-2
1
0
DenseVector 3-Double
-1
0
1
另一个例子:
Matrix<double> A = Matrix<double>.Build.DenseOfArray(new double[,]
{
{ 1, 2, 1 },
{ 3, 6, 3 },
{ 4, 8, 4 }
});
Vector<double> B = Vector<double>.Build.Dense(new double[3]);
foreach (var x in A.SolveDegenerate(B))
Console.WriteLine(x);
我投票结束这个问题,因为它属于所有系数
integer
?@stealthynija,因为我知道你建议我参加数学论坛。但我的任务很琐碎,我只想在C#中找到MathNet代码来求解this@DmitryBychenko不幸的是没有!在实际任务中,它是双重或浮动的!但整数的解决方案也可能对我感兴趣
DenseVector 2-Double
-2
1
Matrix<double> A = Matrix<double>.Build.DenseOfArray(new double[,]
{
{ 1, 2, 1 },
{ 3, 6, 3 },
{ 4, 8, 4 }
});
Vector<double> B = Vector<double>.Build.Dense(new double[3]);
foreach (var x in A.SolveDegenerate(B))
Console.WriteLine(x);
DenseVector 3-Double
-2
1
0
DenseVector 3-Double
-1
0
1