Я хочу вычислить все собственные значения и все собственные векторы реальной симметричной матрицы, используя LAPACKE_dsyevd из Intel MKL (обновление 2019 года).
У меня следующий метод в C #:
public static class MKL
{
public static double[,] SymmetricEig(double[,] a, out double[] w)
{
int n1 = a.GetLength(0);
int n2 = a.GetLength(1);
if (n1 != n2) throw new System.Exception("Matrix must be square");
double[,] b = Copy(a);
int matrix_layout = 101; // row-major arrays
char jobz = 'V';
char uplo = 'U';
int n = n2;
int lda = n;
w = new double[n];
_mkl.LAPACKE_dsyevd(matrix_layout, jobz, uplo, n, b, lda, w);
return b;
}
}
с
class _mkl
{
[DllImport(DLLName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
internal static extern lapack_int LAPACKE_dsyevd(
int matrix_layout, char jobz, char uplo, lapack_int n, [In, Out] double[,] a, lapack_int lda, [In, Out] double[] w);
}
и следующим тестовым кодом:
int n = 32766; // 32767 or greater --> Not enough memory to allocate work array in LAPACKE_dsyevd
double[,] A = CreateRandomSymmetricMatrix(n);
double[] w = new double[n];
double[,] B = MKL.SymmetricEig(A, out w);
с
static double[,] CreateRandomSymmetricMatrix(int n1)
{
double[,] m = new double[n1, n1];
for (int i1 = 0; i1 < n1; i1++)
{
for (int i2 = 0; i2 <= i1; i2++)
{
m[i1, i2] = r.NextDouble();
m[i2, i1] = m[i1, i2];
}
}
return m;
}
Если n
большечем 32766, происходит сбой со следующим сообщением об ошибке:
Недостаточно памяти для выделения рабочего массива в LAPACKE_dsyevd
Мой компьютер имеет 128 ГБ ОЗУ, чего должно быть достаточно.Мне известно о <gcAllowVeryLargeObjects enabled="true" />
, и я установил его на true.Мне также известно о пределе 65535 ^ 2 для многомерного массива в C #, см. 2d-массив с более чем 65535 ^ 2 элементами -> Размеры массива превысили поддерживаемый диапазон .
Кстати, я могу вычислить разложение по собственным значениям, используя MATLAB для матриц с n = 40000 или больше.И я думаю, что MATLAB также использует Intel MKL в фоновом режиме для его вычисления.
Итак, как я могу вычислить разложение по собственным значениям очень больших матриц (n> 40000) в C # с использованием Intel MKL?