OctaveSharp - 使用 C# 运行 GNU Octave






4.97/5 (15投票s)
OctaveSharp 包装器,用于在 C# 应用程序中使用 Octave
简介
“GNU Octave 是一种高级解释型语言,主要用于数值计算。它提供了求解线性及非线性问题的数值能力,以及执行其他数值实验的能力。它还提供了广泛的图形功能,用于数据可视化和操作。Octave 通常通过其交互式命令行界面使用,但也可以用于编写非交互式程序。Octave 语言与 Matlab 非常相似,因此大多数程序易于移植。”
Octave 根据 GNU 通用公共许可证 发布。
(以上文字和图片归属于 http://www.gnu.org/software/octave/)
最近,我需要在当前正在进行的一个 C# 项目中使用一些 Octave 脚本。在搜索解决方案后,我不得不自己实现一个 Octave 包装器。
基本思路是启动一个进程,并重定向标准输入、输出和错误流,以便使用 Octave 解释器执行随机命令。一个常见的问题是,在成功运行命令后,解释器会阻塞输出流,并且无法知道 Octave 何时完成其工作。对此问题的解决方案如下:鉴于进程执行的最后一行始终可用,您可以创建一个随机字符串,并让 Octave 每次运行另一个命令时都回显该字符串;在解析输出时,遇到您回显的字符串是先前命令已执行的指示。
实现
启动 octave 进程时,会生成一个新的随机回显字符串
private string StartOctave(string PathToOctaveBinaries, bool CreateWindow) {
this.OctaveEchoString = Guid.NewGuid().ToString();
OctaveProcess = new Process();
.
.
.
OctaveProcess.OutputDataReceived +=
new DataReceivedEventHandler(OctaveProcess_OutputDataReceived);
OctaveProcess.BeginOutputReadLine();
OctaveEntryText = ExecuteCommand(null);
}
执行随机命令时,当前线程会阻塞,直到触发 ManualResetEvent
public string ExecuteCommand(string command) {
if (OctaveProcess.HasExited)
OctaveProcess.Start();
SharedBuilder.Clear();
if (command != null) {
OctaveProcess.StandardInput.WriteLine(command);
}
//echo the random GUID string
OctaveProcess.StandardInput.WriteLine("\""+ OctaveEchoString + "\"");
OctaveDoneEvent.Reset();
OctaveDoneEvent.WaitOne();
return SharedBuilder.ToString();
}
并且接收到的异步输出数据会将所有数据放入 StringBuilder 中,直到遇到回显的字符串。
void OctaveProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) {
if (e.Data == null) {
SharedBuilder.Clear();
SharedBuilder.Append("Octave has exited with the following error message: \r\n" + OctaveProcess.StandardError.ReadToEnd());
OctaveDoneEvent.Set();
return;
}
if (e.Data.Trim() == "ans = " + OctaveEchoString)
OctaveDoneEvent.Set();
else
SharedBuilder.Append(e.Data + "\r\n");
}
使用代码
只需使用两个构造函数中的一个创建一个新的 Octave 类实例,并传递 Octave 安装的完整路径即可。
完成此操作后,您可以使用“ExecuteCommand
”方法访问 Octave 命令解释器。读取结果以标量(GetScalar
)、向量(GetVector
)和矩阵(GetMatrix
)的形式进行。
下面给出一个计算矩阵转置的简单脚本
octave = new Octave(@"D:\Download\Soft\Octave3.6.0_gcc4.6.2\bin", false);
octave.ExecuteCommand("a=[1,2;3,4];");
octave.ExecuteCommand("result=a';");
double[][] m = octave.GetMatrix("result");
希望这有帮助,如果您使用这项工作,请务必添加引用: Boros Tiberiu,OctaveSharp - 使用 C# 运行 GNU Octave,CodeProject,2012