У меня есть приложение C # (Unity / Mono на MacOS), где мне нужно решить типичную задачу оптимизации матрицы Ax = b с размерами 3xN. Подробнее здесь . Я обнаружил, что основной метод для этого называется неотрицательными наименьшими квадратами (NNLS) и искал чистую реализацию C # (или аналогичную), но безуспешно.
Любые решения приветствуются, но самое близкое, что я пришел, это реализация Fortran , используемая функцией SciPy nnls () с заголовком fortran:
SUBROUTINE NNLS (A,MDA,M,N,B,X,RNORM,W,ZZ,INDEX,MODE)
C ------------------------------------------------------------------
! Don't leave the calling convention to chance.
!GCC$ ATTRIBUTES CDECL :: NNLS
!DIR$ ATTRIBUTES DLLEXPORT :: NNLS
!DIR$ ATTRIBUTES ALIAS: 'NNLS' :: NNLS
integer I, II, IP, ITER, ITMAX, IZ, IZ1, IZ2, IZMAX, J, JJ, JZ, L
integer M, MDA, MODE,N, NPP1, NSETP, RTNKEY
c integer INDEX(N)
c double precision A(MDA,N), B(M), W(N), X(N), ZZ(M)
integer INDEX(*)
double precision A(MDA,*), B(*), W(*), X(*), ZZ(*)
double precision ALPHA, ASAVE, CC, DIFF, DUMMY, FACTOR, RNORM
double precision SM, SS, T, TEMP, TWO, UNORM, UP, WMAX
double precision ZERO, ZTEST
parameter(FACTOR = 0.01d0)
parameter(TWO = 2.0d0, ZERO = 0.0d0)
C ------------------------------------------------------------------
....
Следуя нескольким руководствам, я успешно скомпилировал это с помощью gfortran (с несколькими предупреждениями) для библиотеки .so (эквивалент Mac DLL) и пытался загрузить ее в C # для вызова.
// C# alias function
[DllImport("Fortran/NNLS.so", CallingConvention = CallingConvention.Cdecl)]
public static extern int NNLS(ref float[,] A, ref int MDA, ref int M, ref int N, ref float[] B, out float[] X, out float RNORM, ref float[] W, ref float[] ZZ, ref int[] INDEX, out int MODE);
// C# call
NNLS(ref A, ref mda, ref m, ref n, ref b, out x, out rnorm, ref w, ref zz, ref index, out mode);
Импорт DLL работает нормально, но выдает EntryPointNotFoundException: NNLS. Я перепробовал ряд изменений в именах, связывании, соглашениях о вызовах и т. Д. Что я делаю не так?
Единственное, о чем я могу думать, это то, что в настоящее время в верхней части файла fortran нет объявления модуля / интерфейса, так как это приводит к сбою компилятора, хотя и не знаю, как это решить.