项目需要在C#中使用MATLAB函数,根据网上老哥提供的方案查阅资料并记录以下(有部分可能存在认知错误,后面遇到再改)
ArrayFire/ Armadillo
未尝试
C++库,对MATLAB函数进行逐句翻译,直接编译成dll。 效率最高(需要硬件支持)
ArrayFire
ArrayFire是一个通用的GPU计算库,旨在简化并行架构(如CPU、GPU和其他硬件加速设备)上的软件开发过程。该项目主要使用C++编写,但也提供了其他语言的API,如C、Python和Fortran,以满足不同开发者的需求。 官方网站
Octave/Python
转Octave或者Python。 工作量最小,效率还行
Octave
mkoctfile
未尝试
入参是 矩阵/张量,使用mkoctfile编译dll方便点
mkoctfile --link-stand-alone
Octave.NET
.NET拓展包。 仓库地址
Basics
基础使用:
//指定octave-cli.exe路径(可选)
OctaveContext.OctaveSettings = new OctaveSettings() { OctaveCliPath = @"D:\GNU Octave\Octave-9.4.0\mingw64\bin\octave-cli.exe" };
using (var octave = new OctaveContext())
{
// Please note that there is no ";" at the end. This is important if we want to capture the output.
var scalarResult = octave
.Execute("2 + 2")
.AsScalar();
var vectorResult = octave
.Execute("[1 2 3 4 5]")
.AsVector();
var matrixResult = octave
.Execute("[1 2 3 4 5; 5 4 3 2 1]")
.AsMatrix();
var vec = new double[] { 1, 2, 3, 4, 5 };
var anotherVector = octave.Execute(vec.ToOctave()); // [1 2 3 4 5]
var mat = new[]
{
new double[] { 1, 2, 3, 4, 5 },
new double[] { 1, 2, 3, 4, 5 }
};
var anotherMatrix = octave.Execute(mat.ToOctave());// [1 2 3 4 5;1 2 3 4 5]
}
DisplayPlot
显示图表:
using (var octave = new OctaveContext())
{
// Note: your octave-cli must support some plot backend, in case of problems investigate manually in octave-cli
var script = @"
x = -10:0.1:10;
y = sin (x);
handle = plot (x, y);
title (""Hello from C#"");
xlabel (""x"");
ylabel (""sin (x)"");
waitfor(handle); # <- without that plot window would not show
";
octave.Execute(script, int.MaxValue);
}
Packages
加载包:
using (var octave = new OctaveContext())
{
octave.Execute("pkg load fuzzy-logic-toolkit;");
double result = octave
.Execute("algebraic_product(5,2)")
.AsScalar(); // 10
}
引用外部.m
文件
需要注意的是调用函数时结尾不要加分号
octave.Execute("t1(6, 7)")
否则就抑制输出了,得用disp()
显示
addpath
指定工作区:
//指定octave-cli.exe路径(可选)
OctaveContext.OctaveSettings = new OctaveSettings() { OctaveCliPath = @"D:\GNU Octave\Octave-9.4.0\mingw64\bin\octave-cli.exe" };
using (var octave = new OctaveContext())
{
string script = @"addpath('C:/Users/admin/Desktop/test');t1(6, 7)";
// 调用 Octave 函数
var sumResult = octave.Execute(script);
}
直接运算
在C#中运行Octave
代码:
//指定octave-cli.exe路径(可选)
OctaveContext.OctaveSettings = new OctaveSettings() { OctaveCliPath = @"D:\GNU Octave\Octave-9.4.0\mingw64\bin\octave-cli.exe" };
using (var octave = new OctaveContext())
{
string funcDef = @" wt=[0.123456 1.234567 0.345678]; ...
i = 1; ...
outputs = {}; ...
predict = zeros(1, 3); ...
for k = 1:length(wt) ...
outputs{i, k} = round(wt(k)); ...
predict(i, k) = round(wt(k)); ...
end ...
";
octave.Execute(funcDef);
var r1 = octave.Execute("disp(cell2mat(outputs))");
var r2 = octave.Execute("disp(predict)");
var result1 = r1.AsMatrix();
var result2 = r2.AsVector();
}
MATLAB Compiler
直接编译为dll或者exe,需要依赖MCR(MATLAB Compiler Runtime)
且调用dll之前要启动一个ngine 之类的东西。影响效率
.NET Assembly
打包 MATLAB函数
MATLAB中选APP菜单
找到库编译器 Library Compiler
:
Type:选择目标类型 (这里选
.NET Assembly
)Exported Functions:添加需要打包的函数文件
Library information:重命名库名称,重命名类名称,或者添加类,分配函数所属类
Package:打包
C#调用
打包好的dll在
for_redistribution_files_only
目录下,里面两个dll都可以使用
除了需要引用打包好的dll,还需要引用 MWArray.dll
。该文件在Matlab安装目录中,参考路径: 安装路径\MATLAB\R2023a\toolbox\dotnetbuilder\bin\win64\v4.0\
。
直接实例打包时设置的类名即可:
//添加引用
using System;
using TESTNative;
using MathWorks.MATLAB.NET.Arrays;
//触发代码
private void TEST_Click(object sender, EventArgs e)
{
int[,] list = { { 1 }, { 2 }, { 3 }, { 4 } }; //列向量
MWArray array = new MWNumericArray(list); //转换list格式
TESTNative.Cal ts = new Cal();//定义目标类
object resultObj = ts.TEST(1, array);// 1表示返回的结果数量,要小于等于Matlab对应函数实际的返回值数量
//转换返回值
object[] resultObjs = (object[])resultObj;
double[,] calcResult = (double[,])resultObjs[0];
}