1. 程式人生 > >java呼叫matlab:一、生成檔案,本機呼叫

java呼叫matlab:一、生成檔案,本機呼叫

Java程式碼實現的計算難免會顯得不夠高效。而利用MATLAB寫好相應的計算函式,然後打包成jar包供Java呼叫,在某些情況下會更加方便。或者有些時候會涉及到使用Java呼叫MatLab展現一些二維三維圖。因此用到Java呼叫MatLab。

我的需求是要在獲取一維曲線任一點的插值,計劃在服務端呼叫matlab function獲取返回值。

文章分為兩部分:

一、生成檔案,本機呼叫成功

二、在伺服器搭建執行環境

本篇是第一部分,一、生成檔案,本機呼叫

參考:https://www.cnblogs.com/welhzh/p/5782912.html

按照步驟操作,由於本機已經安裝了matlab,能跑命令,程式跑起來也基本沒問題。

非本機呼叫環境搭建遇到問題很多,第二篇講。

一:注意事項

1: MatLab的版本必須是2006b+(包括2006b或更高版本),因為只有在這些版本中才有MATLAB Builder for Java(也叫Java Builder)。

2: 執行機器上必須裝有JRE 並且版本要和MatLab自帶的jre 大版本保持一致(位數也要保持一致)(大版本一致既可,比如同是1.6,或者1.7既可)

   檢視MatLab 自帶JRE版本位數方法:在MatLab中Command Windows中輸入 【version -java】 命令檢視。如圖所示:

這裡是 1.6.0_17-b04 版本的JRE 並且為64位的。(注意:這裡之所以是64位的,取決於您當初下載的MatLab安裝包的位數。

3:驗證系統jdk jre,系統首先裝有Java環境(不在敘述)。 驗證jdk,jre版本位數。開啟cmd 輸入命令 【java -version】 

和 【javac -version】分別驗證編譯和執行版本。也許有讀者會想,兩個命令檢視的結果肯定版本都一樣,但是有些情況java和javac

的版本還真不一樣,比如安裝了多個版本的jdk或者不同位數的jdk,如果是以安裝的方式安裝,那麼java版本和位數是以最後一次安裝

保持一致,因為安裝時,會把java.exe拷貝到系統目錄一份(例如:win8中的c:/windows/system32)。雖然配置了java環境變數,但是

如果java環境變數配置在了path變數值得最後方,由於系統目錄配置在了最前方,以前方為準。因此會出現配置無效。照成了以上所說的

情況,這種情況解決方法有兩種(1:刪除系統目錄下的相關java檔案,2:把java環境變數配置到Path的最前面)。

無法正常顯示。如果讀者發生這種情況,可以試著用這種方式解決。

如 果你用的是AMD的處理器,不是intel的處理器,安裝matlab後,可能不能執行,具體表現是,一開啟就關閉了。解決辦法其實也很簡單,就是給你的 機器新建立一個系統變數,變數名是BLAS_VERSION,變數值是D://MATLAB7//bin//win32 //atlas_Athlon.dll(你的matlab安裝地址)。

6:如果你要在沒有安裝matlab的機器上用java呼叫這些jar包,怎麼辦?也是可以的,不過,不過你要先在機器上安裝matlab提供的MATLAB Compiler Runtime (MCR) ,它的安裝檔案在D:\program files\study\MATLAB\R2007b\toolbox\compiler\deploy\win32下(你的安裝目錄下)檔名MCRInstaller.exe。

二:呼叫基本步驟

1:開啟MatLab,HOME -》 新建指令碼 開啟Editor視窗。指令碼內容如下:

複製程式碼
%畫圖 自定義函式drawplot 引數 x y  
function drawplot(x, y)    
plot(x, y); %%使用matlab函式plot()作圖    
grid on %網格顯示  
xlabel('X軸值')  
ylabel('Y軸值')  
title('Java呼叫MatLab作圖例子') 
複製程式碼

2:在計算機某個目錄建個存放MatLab指令碼及其後期編譯出的java檔案。例如:桌面\mjTest。儲存指令碼到此資料夾下。儲存後,

在mjTest資料夾下多了一個drawplot.m檔案。

3:在MatLab下Command Window下輸入 【deploytool】 命令,開啟部署工具Deployment Tool。新建一個工程demo.prj,設定路徑為mjTest

既可,型別選擇Java Package 點選確定。這時MatLab右側自動打開了java部署視窗。

4:在Build選項卡下點選 Add classes 新增一個名稱為plotter的Class(java類,在後邊java程式碼中會呼叫到)。

5:在plotter底下點選Add files,新增剛才mjTest下的drawplot.m檔案。點選上圖右上方位置的編譯按鈕(兩個向下箭頭的那個按鈕)。

編譯時間稍微有些長,耐心等待即可。

6:編譯完成後,我們會在mjTest目錄下看到了demo資料夾生成了。進入demo/distrib目錄。如發現demo.jar。則可以進行下一步操作了。

7:開啟Myeclipse或者eclipse等IDE工具

      新建JavaProject mjTest(專案名稱隨意),並且引用以下兩個jar包

E:\Program Files\MATLAB\R2013a\toolbox\javabuilder\jar\javabuilder.jar(MatLab安裝目錄下)如果是64位,選擇E:\Program Files\MATLAB\R2013a\toolbox\javabuilder\jar\win64\javabuilder.jar

以及剛剛生成的demo\distrib\demo.jar

新建ConnectMatLabTest.java:

複製程式碼
    package com.xiami.test;  
      
    import com.mathworks.toolbox.javabuilder.MWArray;  
    import com.mathworks.toolbox.javabuilder.MWClassID;  
    import com.mathworks.toolbox.javabuilder.MWComplexity;  
    import com.mathworks.toolbox.javabuilder.MWNumericArray;  
      
    import demo.plotter;  
      
    public class ConnectMatLabTest {  
      
        /**  
         * @param args  
         */  
        public static void main(String[] args) {  
            // TODO Auto-generated method stub  
            MWNumericArray x = null; // 存放x值的陣列  
            MWNumericArray y = null; // 存放y值的陣列  
            plotter thePlot = null; // plotter類的例項(在MatLab編譯時,新建的類)  
            int n = 20; // 作圖點數  
      
            try {  
                // 分配x、y的值  
                int[] dims = { 1, n };  
                x = MWNumericArray.newInstance(dims, MWClassID.DOUBLE,  
                        MWComplexity.REAL);  
                y = MWNumericArray.newInstance(dims, MWClassID.DOUBLE,  
                        MWComplexity.REAL);  
      
                // 定義 y = x^2  
                for (int i = 1; i <= n; i++) {  
                    x.set(i, i);  
                    y.set(i, i * i);  
                }  
      
                // 初始化plotter的物件  
                thePlot = new plotter();  
      
                // 作圖  
                thePlot.drawplot(x, y);  
                thePlot.waitForFigures();  
            }  
      
            catch (Exception e) {  
                System.out.println("Exception: " + e.toString());  
            }  
      
            finally {  
                // 釋放本地資源  
                MWArray.disposeArray(x);  
                MWArray.disposeArray(y);  
                if (thePlot != null)  
                    thePlot.dispose();  
            }  
        }  
      
    }  
複製程式碼

執行此類既可看到效果(Run -》 javaapplication),如下圖所示:

三:呼叫matlab函式並返回計算結果

如下:

考慮到計算的各種情況,有些用Java程式碼實現的計算難免會顯得不夠高效。而利用MATLAB寫好相應的計算函式,然後打包成jar包供Java呼叫,在某些情況下會更加方便。現在就來說一下如何實現這一過程:

  1.確定配置好了相應的環境

    首先,要確定你電腦上裝好了MATLAB並且配置好了Java的執行環境,注意,MATLAB的版本必須是2006b+(包括2006b或更高版本),因為只有在這些版本中才有MATLAB Builder for Java(也叫Java Builder)。

  2.打包步驟

    a)開啟MATLAB(筆者用的是MATLAB 2012b,版本的一些差異我會在後面註明),在Command Window框中輸入deploytool,會跳出如下介面:

可能在有些版本中選擇Type時顯示的是Matlab Builder for Java,並且在Deployment Tool面板中還有Generate Verbose Output選項框,勾選上它,針對不同的版本時可能有一些出入,大家多留心一些,自己多嘗試嘗試。

  c)在MATALAB的Editor中新建一個m檔案,這裡編輯一個簡單的加法函式add並儲存:

d)在MATLAB中找到Java Package視窗,新增class檔案,命名這個class檔案的時候要注意了,因為這個檔案就是以後匯入到Java中要作為一個物件的名字,也就是說它就是放在new後面作為建構函式的類名。這裡命名為matlabAdd:

e)然後點類名下的Add files,將剛才編輯好的m檔案add.m加到matlabAdd當中。

f)接著就可以打包了,還是在Java Package視窗找到在Java中呼叫matlab函式,點選就可以打包了。等打包好,就可以呼叫了。

  3.呼叫打包好的matlab函式

    a)在MATLAB安裝的目錄中找到"...\toolbox\javabuilder\jar\javabuilder.jar"的檔案,並在你剛才打包的資料夾中找到對應的包,本例中是firstOne.jar,然後將這兩個jar包匯入到你的Java專案當中。

b)新建JAVA類檔案MJBuilderTest.java,示例程式碼如下:

複製程式碼
import com.mathworks.toolbox.javabuilder.*;
import myadd.*;

class MJBuilderTest
{
     public static void main(String[] args)
     {
         MWNumericArray a = null;   
         MWNumericArray b = null;   
         Object[] result = null;    
         Myadd myAdd = null;     
         try
         {
            
             if (args.length != 2)
             {
                 System.out.println("Error: must input 2 numbers!");
                 return;
             }
           
            
             a = new MWNumericArray(Double.valueOf(args[0]),MWClassID.DOUBLE);
             b = new MWNumericArray(Double.valueOf(args[1]),MWClassID.DOUBLE);
            
             myAdd = new Myadd();
           
            
             result = myAdd.myadd(1, a, b);
             System.out.print("/nThe sum of " + a.toString() + " and " + b.toString() + " is: ");
             System.out.println(result[0]);
         }
         catch (Exception e)
         {
             System.out.println("Exception: " + e.toString());
         }
       
         finally
         {
            
             MWArray.disposeArray(a);
             MWArray.disposeArray(b);
             MWArray.disposeArray(result);
             if (myAdd != null)
                 myAdd.dispose();
         }
     }
}
複製程式碼

c)在Eclipse中設定好輸入引數輸入視窗:Run as- Run configations-Arguments 選擇 要輸入的資料型別,這裡選擇的是“string_prompt”,點選應用。

d)編譯執行MJBuilderTest.java,輸入引數(2個引數用空格隔開),例如:1 2 ,如果配置正確,結果會顯示

“The sum of 1 and 2 is: 3”