MATLAB与.NET混合编程实例(C#)

我们为什么要应用MATLAB接口技术进行混合编程?
       MATLAB使用一种脚本语言,它的执行是逐行解释执行的,也就是边解释边执行,程序中所有的变量都是MxArray来实现的,所以为了保证通用性,他的执行效率非常低,这就是我们常常看到的在开发一些复杂算法时,通常会发现程序执行的特别慢,虽然Mathworks公司已经在竭力提高M脚本文件的运算速度,但目前为止,效果仍然不能和同样功能的可执行程序相比 。而且,M文件不能脱离MATLAB这个应用程序环境,这就大大制约了程序的可移植性和通用性,因此,MATLAB不适合作为通用的编程平台。那么实现MATLAB与其他语言的混合编程就十分重要了,这有助于发挥MATLAB和其他编程语言各自的优势,降低开发难度,缩短编程时间,提高执行效率。

MATLAB的接口技术有什么?
      主要有9种:MATLAB Compiler, MATLAB引擎, MAT数据文件共享数据, 通过ActiveX, Mideva/Matcom, MATLAB<LIB>数学库, MATLAB COM Builder, Excel Link, MATLAB Builder for Excel等。

ps: 上面的内容参考的一本书。

      本文主要说明一下MATLAB与.NET是怎样进行混合编程的,以C#为例,通过com组件的形式。

我的机器的软件环境:
Windows 7 操作系统;MATLAB r2010a;visual studio 2010

       通过com组建的形式进行混合编程,如果机器上没有安装MATLAB,编译生成的软件照样可以使用,但是需要安装MATLAB提供的MATLAB Compiler Runtime ,这个软件在MATLAB的安装目录下:X:\MATLAB\R2010a\toolbox\compiler\deploy\win32 \MCRInstaller.exe(X是MATLAB安装的盘符),如果你的电脑上安装了MATLAB,则不需要在重新安装这个软件。另外,不同的 MATLAB版本提供的MATLAB Compiler Runtime可能会不同,如果在另一台电脑上自己编写的软件运行有问题,可能是编译器的版本不同引起的。

这个例子是平时上课的时候一个作业,我只公布关于混合编程部分的源代码。

首先来几张关于这个小软件的图片:

主界面
1.JPG
模拟计算的界面
2.JPG

绘图的界面
3.JPG
这里只有tabcontrol这个控件的作图用到了混合编程,其它三个picturebox里的图形使用GDI作出来的。
来一张混合编程作出来的图片:
混合编程
4.JPG

怎么样,很像是有个驱替前缘吧?事实就是如此。

使用混合编程,首先把MATLAB提供的MWARRAY类库添加进去 。在visual studio 2010中,新建好项目以后,在解决方案资源管理器中,右键单击“引用”-“添加引用”-“浏览”,MWARRAY.dll在X:\MATLAB \R2010a\toolbox\dotnetbuilder\bin\win32\v2.0中,浏览的时候找到这个组件,添加进去即可。它的作用是把 C#中的数组转化为MATLAB中的数组。并且需要在程序开始部分添加下面这句话:
using MathWorks.MATLAB.NET.Arrays;

本例中主要用MATLAB作图,因此还需要把作图组件添加到引用中,这就需要先写好程序,然后在MATLAB中进行编译,编译成.dll文件,和添加MWARRAY一样,添加到引用之中。

我们给画图的com组件起个名,叫DrawAss,下面主要讲 DrawAss组件的生成
首先把在C#中要实现的MATLAB的功能的函数写好,这里必须是函数文件,一般的M文件不可以。
我们以作压力分布曲面为例,其他类似。在MATLAB中编写程序如下:

function DrawP3D(P)
%绘制压力变换的3D图像

[m n]=size(P);
x=1:m;
t=1:n;
[x t]=meshgrid(x,t);
P=P';
meshc(x,t,P);
title('一维油水两相数值模拟压力变化');
xlabel('网格标号')
ylabel('时间步数')
zlabel('压力')

这段程序非常简单,没啥好说的。
然后再编写作含水饱和度及含油饱和度分布图像的函数,见下图:

5.JPG
一看函数的名字就知道是干啥的了。

下面就进行编译了。
       单击MATLAB界面左下角的start-MATLAB-MATLAB Builder NE-Deployment tool,或者是直接在命令窗口直接输入deploytool,新建一个工程,名为DrawAss,target选择.Net Assembly即可。这样MATLAB会弹出一个窗口,在窗口上部,点击classes,新建一个类,默认的类名是class1,改为MWDraw,然后点击add files,把上图中的函数文件添加进去,点击build按钮(一个框,上面三个向下的箭头)编译即可。如果第一次进行编译,会出错,首先在命令窗口中输入mbuild -setup(注意有空格),然后选择1即可。
      这样就会得到一个文件夹DrawAss,我们需要的组件DrawAss.dll就在DrawAss\distrib中,按照添加MWARRAY的方法添加到引用中,当然也需要在程序开始部分添加下面一句话:
using DrawAss;

C#中的代码
下面的代码就是C#中进行调用这两个组件的代码:
代码不难,仔细斟酌一下就会明白了。我只在第一个上加上几句注释,其他的都一样

private void bntP_Click(object sender, EventArgs e)
              {
                    int t = cbxP.SelectedIndex;
                    if (t == -1)
                    {
                          MessageBox.Show("没有选择时间!", "提示",
                                  MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                    {
                          double[] p = new double[m];
                          for (int i = 0; i < m; i++)
                          {
                                  p[\i] = result[i, 2 * t];
                                  //p[\i]这里本没有这个斜杠,但是和萃园的代码冲突,就加上了个斜杠
                                  //后面的一样
                          }
                          t = t + 1;
                          MWDraw myDraw = new MWDraw();//声明类的实例,了解C#朋友都明白
                          myDraw.DrawPCurve((MWNumericArray)p, (MWNumericArray)t);
                          //调用myDraw中的方法DrawPCurve作图,(MWNumericArray)p把C#中的数组p转
                          //化为MATLAB中的数组
                    }
              }

              private void bntSw_Click(object sender, EventArgs e)
              {
                    int t = cbxSw.SelectedIndex;
                    if (t == -1)
                    {
                          MessageBox.Show("没有选择时间!", "提示",
                                  MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                    {
                          double[] Sw = new double[m];
                          for (int i = 0; i < m; i++)
                          {
                                  Sw[\i] = result[i, 2 * t + 1];
                          }
                          t = t + 1;
                          MWDraw myDraw = new MWDraw();
                          myDraw.DrawSwCurve((MWNumericArray)Sw, (MWNumericArray)t);
                    }
              }

              private void bntSo_Click(object sender, EventArgs e)
              {
                    int t = cbxSo.SelectedIndex;
                    if (t == -1)
                    {
                          MessageBox.Show("没有选择时间!", "提示",
                                  MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                                          
                          double[] So = new double[m];
                          for (int i = 0; i < m; i++)
                          {
                                  So[\i] = 1 - result[i, 2 * t + 1];                                 
                          }
                          t = t + 1;
                          MWDraw myDraw = new MWDraw();
                          myDraw.DrawSoCurve((MWNumericArray)So, (MWNumericArray)t);
                    }
              }

              private void bnd3D_Click(object sender, EventArgs e)
              {
                    int DMode = listBox1.SelectedIndex;
                    MWDraw myDraw = new MWDraw();
                    if(DMode==0)
                    {
                          double[,] P = new double[m, n / 2];
                          for (int i = 0; i < m; i++)
                          {
                                  for (int j = 0; j < n / 2; j++)
                                  {
                                        P[i, j] = result[i, 2 * j];
                                  }
                          }
                          myDraw.DrawP3D((MWNumericArray)P);
                    }
                    else if(DMode==1)
                    {
                          double[,] Sw = new double[m, n/2];
                          for (int i = 0; i < m; i++)
                          {
                                  for (int j = 0; j < n / 2; j++)
                                  {
                                              Sw[i, j] = result[i, 2 * j + 1];
                                  }
                          }
                          myDraw.DrawSw3D((MWNumericArray)Sw);
                    }
                    else
                    {
                          double[,] So = new double[m, n / 2];
                          for (int i = 0; i < m; i++)
                          {
                                  for (int j = 0; j < n / 2; j++)
                                  {
                                        So[i, j] = 1 - result[i, 2 * j + 1];
                                  }
                          }
                          myDraw.DrawSo3D((MWNumericArray)So);
                    }

        }
该文引用:http://blog.sina.com.cn/s/blog_6bf019790100yh7h.html

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值