【原創】Matlab.NET混合程式設計技巧之找出Matlab內建函式

資料之巔發表於2013-09-02

              本部落格所有文章分類的總目錄:【總目錄】本部落格博文總目錄-實時更新

      Matlab和C#混合程式設計文章目錄 :【目錄】Matlab和C#混合程式設計文章目錄

  Matlab與.NET的混合程式設計,掌握了基本過程,加上一定的開發經驗和演算法基礎,肯定不難。反之,有時候一個小錯誤,可能抓破腦袋,加班幾個晚上,除錯才能解決。同樣,由於Matlab.NET混編的特殊性,加上MathWorks的原因,英文文件和沒有披露一些詳細的細節(甚至不允許反編譯MWArray.dll,呵呵,它不允許,不代表你不會哦)。經過很多專案,和大量的實驗,也發現了一些小技巧和小祕密,今天就分享其中一個,先做一個簡單的鋪墊,下一篇將寫一個實際例子。

1.Matlab.NET混編小技巧

常規混編時,比如我們要呼叫plot函式進行繪圖,肯定是先自己寫一個m函式,把plot封裝一下,根據自己的需要,傳遞資料和引數。實際上,對於Matlab的內建函式,是不需要這麼做的。也就是說,對於Matlab的內建函式,是可以直接在C#中進行呼叫的,只要傳遞的引數符合要求,就可以得到結果。

2.什麼是Matlab的內建函式

本文所說的Matlab內建函式,就是Matlab所謂的"built-in MATLAB function"。

在Matlab中,可以使用exist返回一個名稱或者函式的狀態,比如是工作區的變數,搜尋路徑的m函式,dll檔案或者內建函式。

比如,我們可以使用exist 來檢視plot函式的資訊:

1 >> exist plot
2 
3 ans =
4 
5      5

可以看到,值為5,返回5說明就是"built-in MATLAB function"。從Matlab的組成來看,這些built-in MATLAB function應該都是matlab的核心函式,因此,也應該都包含在MCR中,因此這是一個直接可以呼叫的理由吧。

 3.Matlab有哪些內建函式

在發現上述小技巧之後,本人親自對其中幾個內建函式進行了測試,證明其是可以在C#中直接呼叫,然後,我就想,到底有Matlab有多少個內建函式,函式名稱有是什麼?在把Matlab Help翻了很久之後,依舊沒有結果。只是猜測,可能太多了,Matlab也沒有特別說明吧。那怎麼辦,只能自己動手了(自己動手豐衣足食)。

說說找出內建函式集合的過程吧。

1.首先內建函式應該在核心的計算引擎中,外部工具箱的函式應該不屬於(不排除其他工具箱中有部分函式也是內建函式)。

2.使用Matlab Help瀏覽器,開啟核心元件Matlab的Functions節點,可以看到下面這些函式分類:

  

3.手動將這些大類中的函式手動複製到一個txt文字中,當然格式可能有點亂,不用管。

4.使用C#編寫一個簡單的函式,將上述txt文字進行處理,把函式名都擷取出來,放到一個新的result.txt中。程式碼如下:

 1 using System;
 2 using System.Text ;
 3 using System.IO ;
 4 
 5 namespace FunctionNameProcess
 6 {
 7     class Program
 8     {
 9         public static void Main(string[] args)
10         {
11             string fileName = @"funcname.txt" ;
12             string saveName = @"result.txt";
13             TextWriter tw = new StreamWriter (saveName ,false );
14             using (TextReader tr = new StreamReader (fileName ))
15             {
16                 string temp ;
17                 while ((temp = tr.ReadLine ())!=null )
18                 {
19                     tw.WriteLine (GetBulidInFunction (temp ));
20                 }                                
21             }            
22             tw.Close ();
23             Console.Write("Press any key to continue . . . ");
24             Console.ReadKey(true);
25         }
26         
27         public static string GetBulidInFunction(string name)
28         {
29             if (name !="") {
30                 string[] names = name.Split ('\t');
31                 if (names!=null && names [0]!= "") {
32                     return names [0];
33                 }
34             }    
35             return "";            
36         }
37     }
38 }

5.最後在matlab中編寫一個簡單的批處理程式碼,迴圈驗證result.txt中的函式名的資訊,是否屬於內建函式即可。matlab程式碼如下:

 1 %匯入資料後是cell型別的資料型別
 2 %要進行轉換為字串陣列然後呼叫exist函式進行計算
 3 %最終結果也應該是字串陣列,需要宣告,新增過程中型別不一樣會有錯誤
 4 clc;clear;
 5 newData = importdata('result.txt');
 6 vars = fieldnames(newData);
 7 for i = 1:length(vars)
 8     assignin('base', vars{i}, newData.(vars{i}));%在名稱空間宣告變數
 9 end
10 result = {};%宣告一個空的cell陣列型別
11 for i = 1:size(textdata,1)
12     temp =cell2mat(textdata(i,1));
13     resultNo = exist(temp);
14     if resultNo == 5 %返回5說明為內建函式
15         len = size(result,1);
16         result(len+1,1) = mat2cell(temp);
17     end
18 end

OK,可以在result中看到屬於內建函式的名稱了。剩下的怎麼辦看你的了,本來想把這些函式都一一翻譯出來,可惜太大了,有1000多個,最後放棄了,把這個技巧分享給大家,“授人以魚不如授人以漁”,大家掌握了方法,其實也不難了。

備註:上面也提到了,其實也有可能其他工具箱也有一些內建函式,但工作量太大,沒有全部測試,只是猜測一下,大家以後混編的時候,可以先用exist檢測一下即可。至於這些核心元件中的內建函式,我也只測試了其中幾個,理論上應該都是可以直接呼叫的,也不排除有些函式由於其他原因不能用啊,大家對症下藥吧。

下次將分享如何在C#中直接呼叫這些內建函式,而不需要封裝。

 

相關文章