65.9K
CodeProject 正在变化。 阅读更多。
Home

OctaveSharp - 使用 C# 运行 GNU Octave

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (15投票s)

2012 年 3 月 7 日

CPOL

2分钟阅读

viewsIcon

92893

downloadIcon

2161

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

© . All rights reserved.