MATLAB混合编程

MATLAB混合编程

java调用MATLAB

  1. 在MATLAB中新建脚本,编写需要函数,此处仅做示例(作图)
Magic.m
function f =Magic( input )
f=magic(input);
end
Eig.m
function [v,d]=Eig(input)
format long
[v,d]=eig(input);
end
Plot.m
function Plot(x,y )
p=polyfit(x,y,3);
t=min(x):max(x)/100:max(x);
s=polyval(p,t);
plot(x,y,'*',t,s);
title('数据拟合结果');
xlabel('x');
ylabel('y');
end



  1. 在控制台输入 deploytool ,会打开一个Compiler窗口,选择第3个,Library Compiler,进入页面后左上角有个可以选着打包类型的,这里选java package,然后在右边选项框有个选择函数的+,点击左边那个加号可以添加函数,最后要注意的是最下面的有个class name ,这个名字是到时候你在java那边使用这个函数的类名,可以重命类名,这里直接使用默认的Class1 。最后点击Package就可。

在这里插入图片描述

在这里插入图片描述

1.选择java Package;
2.选择我们事先写好的脚本;
3.如果jar运行在安装matlab的电脑上打上第一个勾即可,若安装在无matlab的电脑上选上第二行的勾。
4.打包运行
5.类名和方法名

6.如果你要在没有安装matlab的机器上用java调用这些jar包,答案也是可以的,不过你要先在电脑上安装matlab提供的MATLAB Compiler Runtime (MCR) ,它的安装文件在D:\MATLAB\matlab\toolbox\compiler\deploy\win64下(你的安装目录下)文件名InstallAgent.zip里面。

在这里插入图片描述

  1. 然后就出错了,

在这里插入图片描述

问题一:
在这里插入图片描述

这个问题很重要,百度查到大多是这个问题,运行机器上必须装有JRE 并且版本要和MatLab自带的jre 大版本保持一致(位数也要保持一致)

  1. 查询MATLAB自带jre, 装的是MATLAB2016a,在MatLab中命令行窗口中输入 【version -java】 命令查看。如图所示:

在这里插入图片描述

  1. 验证系统jdk jre。 验证jdk,jre版本位数。打开cmd 输入命令 【java -version】

    和 【javac -version】分别验证编译和运行版本。

在这里插入图片描述

可以发现MATLAB和机器上的版本并不一致,解决方法重装jdk,注意保持版本一致

  1. 打包完成之后如图,

在这里插入图片描述

在这里插入图片描述

我们需要的导入进MyEclipse中的jar包是在第二个文件中。然后要回到Java中实现它了。首先我们要在MATLAB的安装目录下找到javabuilder.jar,它是在你安装目录下的toolbox文件夹下javabuilder目录下的jar文件夹里,比如我这个jar包的路径就是D:\MATLAB\matlab\toolbox\javabuilder\jar,在我们接下来要测试这个jar包的工程中导入这个jar包和我们之前生成的jar包。

JAVA调用matlab程序

1.使用java调用Maltab函数的基本方法是:通过Java Builder实现Java调用Matlab。在Java环境中直接调用Matlab所生成的Jar包。

下面以在Java中产生任意维数的魔方矩阵,计算任意矩阵的特征向量和特征值,对两组数据进行拟合并绘制拟合曲线三个实例来说明通过Java Builder实现Java调用Matlab的过程。传统的纯Java编程实现上述实例非常复杂,甚至很难完成。这一问题在Matlab中只需要调用几个函数即可完成。

1. 函数调用

在打包中会看for_testing文件下这个类的java文件了,打开我们可以看到如下的信息:

 /**
     * Provides the standard interface for calling the <code>Magic</code> MATLAB function with 
     * 1 input argument.
     * Input arguments may be passed as sub-classes of
     * <code>com.mathworks.toolbox.javabuilder.MWArray</code>, or as arrays of
     * any supported Java type. Arguments passed as Java types are converted to
     * MATLAB arrays according to default conversion rules.
     *
     * @param nargout Number of outputs to return.
     * @param rhs The inputs to the MATLAB function.
     * @return Array of length nargout containing the function outputs. Outputs
     * are returned as sub-classes of
     * <code>com.mathworks.toolbox.javabuilder.MWArray</code>. Each output array
     * should be freed by calling its <code>dispose()</code> method.
     * @throws MWException An error has occurred during the function call.
     */
   public Object[] Magic(int nargout, Object... rhs) throws MWException
    {
        Object[] lhs = new Object[nargout];
        fMCR.invoke(Arrays.asList(lhs), 
                    MWMCR.getRhsCompat(rhs, sMagicSignature), 
                    sMagicSignature);
        return lhs;
    }


这正是我们在matlab写的程序调用它的方法,返回的类型是Obeject[] 也正是写的那个 Object[] result,那后面传参, int nargout可以看到注释的解释,指的就是MATLAB函数中对应的输出参数个数,所以输出的一个不定大小的二维矩阵这个参数也是1,而且nargout在印象里好像也是MATLAB里面的输出量。后面开始就是你对应MATLAB函数的传入参数了

a. 传入函数的JAVA变量先转换为运行时环境里的对象
例如:JAVA double对象转 matlab double对象(传入函数的实际是运行时环境提供的中间类型)

//把值先变成matlab能理解的double类型
a = new MWNumericArray(Double.valueOf(args1[0]), MWClassID.DOUBLE);
b = new MWNumericArray(Double.valueOf(args1[1]), MWClassID.DOUBLE);
a = new MWNumericArray(array, MWClassID.DOUBLE);


b. 函数调用

调用格式:

Object[] result = null; 

// 用于保存计算结果。 

//当返回矩阵有n个,则result[0]...result[n-1]分别是这些返回矩阵。 

result = c1.myFunction(1, intput); 

//调用matlab函数,第一个数表示输出多少个矩阵,输入1表示输出一个矩阵。 //输入2表示有两个输出矩阵,以此类推。输出多少个矩阵根据原先m文件的定义。 //input表示输入的矩阵,当需要多个输入矩阵时,可以input1,input2…

常规的输入矩阵:

MWNumericArray input = null; // 用于保存输入矩阵

在Java中调用Matlab的方法时,有三种方式。大致都有2个参数,第一个参数是定义输出结果,第二个参数为输入参数。

方式一:

input = MWNumbericArray.newInstance(int,int[],MWClassID.DOUBLE,MWComplexity.REAL);

//参数1表示矩阵的维数,参数2表示各维的大小即几行几列,参数三表示数据类型,参数四表示实数或复数

方式二:

double array[] = { 3, 2, 4, 5 };//要计算的数 

//int array[]={3,2,4,5};也是可以的。 

input = new MWNumericArray(array, MWClassID.DOUBLE); 

result = c1.myFunction(1, intput);

输入二维矩阵:

double array[][] = { {3,2,4,5},{2,4,4,5} };//要计算的数,两行四列 

//int array[][] = { {3,2,4,5},{2,4,4,5} };也是可以的。 

//输入三维等多维矩阵同理。 

input = new MWNumericArray(array, MWClassID.DOUBLE); 

result = c1.myFunction(1, intput);  //1代表返回值的个数为1

输出的Object[]处理

Object数组有多少元素由输出矩阵数决定

Object转换成MWNumericArray

例如:

 MWNumericArray output = null; // 用于保存输出矩阵 

output=(MWNumericArray) result[0];//将结果object转换成MWNumericArray 

double res = output.getDouble(1);//从MWNumericArray对象中读取数据 

后期处理,释放本地资源

MWArray.disposeArray(input);//建立的矩阵用这句 

MWArray.disposeArray(output);// 建立的矩阵用这句 

MWArray.disposeArray(result);//建立的Object数组用这句 

c1.dispose();//建立的matlab类对象用这句 

以上释放时,必须保证其不为null。

方式一最常用,

方式一:functionName(int arg0, Object… agr1): Object[]

  Object[] result = null; // 用于保存计算结果,定义输出结果
 GetEig getEig = null;
 getMagic = new GetMagic();
result = getMagic.Magic(1,a);//2个参数,第一个参数1是定义输出结果为1个,第二个参数为输入参数是a。
  System.out.println(result[0]); //输出返回内容

MATLAB封装dll

  1. 在控制台输入 deploytool ,会打开一个Compiler窗口,选择第3个库编译器Library Compiler,进入页面后左上角有个可以选着打包类型。

在这里插入图片描述

  1. 选择.NetAssembly,

  2. 那里点“+”好选择你要封装的m文件,

  3. 是封装后生成的dll的名字,

  4. 是在C#里你要调用MATLAB时需要创建的对象的类名,

  5. 是要调用的函数。

  6. 点击右上角封装打包

  7. 需要把这dll拷贝到C#的工程目录下,同时还要拷贝一份MWArray的dll,这个是C#专门针对调用MATLAB语言所设计的数据类型,如果不添加这个dll,那么在C#是无法调用MATLAB的。

在这里插入图片描述

另外,MWArray.dll 在matlab安装目录中,参考路径:D:\MATLAB\matlab\toolbox\dotnetbuilder\bin\win64\v4.0

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值