微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Math.Net错误“矩阵必须为正定”

如何解决Math.Net错误“矩阵必须为正定”

我尝试使用Cholesky分解解决最小二乘问题。

我遇到一个错误,“矩阵必须为正定”。 我已经确保矩阵A是列满秩。此外,我尝试输出此矩阵,发现它可以由numpy计算。

我不知道问题出在哪里。

C#代码

var X = A.TransposeThisAndMultiply(A).Cholesky();

矩阵A可以下载here

解决方法

我已经反编译了他们的dll和异常

throw new ArgumentException("Matrix must be positive definite.");

当对角线上的任何因子小于0.0时,会抛出

for (int index = 0; index < factor.RowCount; ++index)
            {
                double d = factor.At(index,index);
                if (d <= 0.0)
                    throw new ArgumentException("Matrix must be positive definite.");

例如-给定以下定义

        Matrix<double> m = Matrix<double>.Build.Random(3,3);

        m[0,0] = 1;
        m[0,1] = 12;
        m[0,2] = 0;

        m[1,0] = 2;
        m[1,1] = 37;
        m[1,2] = -43;

        m[2,0] = 3;
        m[2,1] = -43;
        m[2,2] = 98;

[0,0]和[1,1]和[2,2]处的因子-它们都必须为正-否则您将遇到该异常

编辑

我设法使其按预期工作。我认为问题在于您如何构建矩阵-可能不正确。

这是我的实现方式

    {
        FileStream stream = File.Open(@"YOUR_PATH_HERE\A.xlsx",FileMode.Open,FileAccess.Read);
        IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        Matrix<double> m = Matrix<double>.Build.Dense(352,252);
        int row = 0;
        using (var reader = ExcelReaderFactory.CreateReader(stream))
        {
            do
            {
                while (reader.Read())
                {
                    for (int column = 0; column < 252; column++)
                    {
                        var value = reader.GetDouble(column);
                        m[row,column] = value;
                    }
                    row++;
                }
            } while (reader.NextResult());
        }

        excelReader.Close();

        Matrix<double> transpose = m.TransposeThisAndMultiply(m);
        Cholesky<double> p = transpose.Cholesky();
    }

enter image description here

编辑2

为了使用稀疏矩阵,我们可以强制值仅进入对角线

例如:

        using (var reader = ExcelReaderFactory.CreateReader(stream))
        {
            do
            {
                while (reader.Read())
                {
                    for (int column = 0; column < 252; column++)
                    {
                        //var value = reader.GetDouble(column);
                        //m[row,column] = value;

                        if (column == row)
                        {
                            var value = reader.GetDouble(column);
                            m[row,column] = value;
                        }
                    }
                    row++;
                }
            } while (reader.NextResult());
        }

具有以下输出:

enter image description here

请注意,由于原始的稀疏矩阵不是方形的,因此此处可能会丢失一些数据。

,

我以略微的差异实施了上面的程序,这可能会影响舍入并导致行列式= 4.9714636E-19。可能没什么大不了的,但是它表明结果有点不稳定。考虑到所涉及的算术数量不足为奇。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。