Pull to refresh

Интегрируем MATLAB в С#.NET

Reading time 4 min
Views 53K

Вступление


В этой статье я постараюсь максимально полно и пошагово рассказать, как связать MATLAB с С#.NET и сделать приложение с интерфейсом на примере построения 3D-плоскости.

Зачем это нужно?


Очень часто перед программистом встает задача вычисления сложной математики. MATLAB в свою очередь является отличным средством для решения, но слаб в создании полноценного пользовательского приложения (можно воспользоваться инструментами GUI MATLAB'a, но это меня не устроило).

Инструменты


  1. Microsoft Visual Studio 2008 SP1
  2. MATLAB 2010a
  3. MATLAB Component Runtime


Шаг 1. Настройка линкера


Чтобы собрать dll-библиотеку MATLAB'а для интеграции в C#.NET, нужно настроить линкер, т.е. какой средой мы будем собирать проект. Для начала нужно установить среду выполнения MCR (MATLAB Component Runtime). Это набор dll-библиотек для полной поддержки языка MATLAB. Установочный файл можно найти: ...\MATLAB\R2011b\toolbox\compiler\deploy\win32\MCRInstaller. Установка типовая, жмем next.
Для настройки линкера в командном окне MATLAB'а набираем mbuild -setup. Со всем соглашаемся и выбираем нужную нам среду, в нашем случае это MVS 2008 SP1. Получаем что-то похожее:

Please choose your compiler for building standalone MATLAB applications:

Would you like mbuild to locate installed compilers [y]/n? y

Select a compiler:
[1] Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010a\sys\lcc
[2] Microsoft Visual C++ 2008 SP1 in C:\Program Files\Microsoft Visual Studio 9.0

[0] None

Compiler: 2

Please verify your choices:

Compiler: Microsoft Visual C++ 2008 SP1
Location: C:\Program Files\Microsoft Visual Studio 9.0

Are these correct [y]/n? y


Получаем радостное Done. Все — линкер настроен.

Шаг 2. Пишем m-функцию


Напишем функцию построения 3D-плоскости в заданных граничных условиях, для большего интереса вернем дескриптор функции.

function res=plane(strfunc,vx0,vx1,vy0,vy1,h)
vx=vx0:h:vx1;
vy=vy0:h:vy1;
figure(1)
res=ezsurfc(strfunc,vx,vy);
end


Как видно функция состоит из шести строчек кода, однако выполняет все вышеуказанные действия: в качестве входных параметров принимает символьную функцию (strfunc), начальные и конечные значения векторов границ плоскости (vx0,vx1,vy0,vy1), шаг сетки (h) и возвращает дескриптор (res).
Сохраняем данный код как plane.m.

Важно: компилятор MATLAB'а понимает только функции т.е., каждый сценарий должен начинаться с function (желательно заканчиваться end) и быть отдельным m-файлом.

Шаг 3. Получаем динамическую библиотеку


Набираем в командном окне MATLAB'a deploytool. Создаем новый .NET Assembly проект MATLABplane, указываем размещение.

image

Далее создаем класс planeClass, добавляем в него plane.m и нажимаем кнопку build

image

После успешной компиляции создается интересующая нас библиотека MATLABplane.dll, находиться она будет здесь: ...MATLABplane\distrib\MATLABplane.dll.

Шаг 4. Создаем приложение C#.NET


В MVS 2008 SP1 создаем приложение Windows Forms на С#.

Добавляем ссылки на библиотеки

Перед использованием методов проекта, необходимо добавить ссылки на скомпилированную библиотеку MATLABplane.dll и на библиотеку MWArray.dll, найти ее можно по адресу ...\MATLAB\R2010a\toolbox\dotnetbuilder\bin\win32\v2.0. После добавления должно получиться:

image

Для использования библиотек в проекте необходимо добавить описание пространства имен:

using MathWorks.MATLAB.NET.Utility;
using MathWorks.MATLAB.NET.Arrays;
using MATLABplane;

Создаем форму

С помощью панели инструментов в конструкторе создаем форму будущего приложения.

image

Для создания формы были использованы следующие блоки: Label, TextBox, RichBox, Button.

Пишем код

Для взаимодействия языков программирования C# и MATLAB создан соответствующий типу MATLAB тип данных MWArray C#. MWArray — это массив массивов, он может состоять из переменных, скаляров, векторов, матриц, строк, структур, объектов и т.д. Для получения каких-либо значений из MWArray нужно использовать приведение типов.
Алгоритм работы приложения должен быть следующим:
  1. Получение функции в символьном виде и значений с текстовых полей
  2. Вызов метода plane из класса planeClass
  3. Получение выходного массива descriptor (тип MWNumericArray)
  4. Вывод массива descriptor в RichBox

Ниже представлен полный код с комментариями:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MathWorks.MATLAB.NET.Utility;
using MathWorks.MATLAB.NET.Arrays;
using MATLABplane;

namespace planeApp
{
  public partial class Form1 : Form
  {
      public Form1()
      {
          InitializeComponent();
          button1.Click += new EventHandler(button1_Click);//инициализация событий
          button2.Click += new EventHandler(button2_Click);
      }

      double x0, x1, y0, y1, h; //объявление переменых
      string func, s_x0, s_x1, s_y0, s_y1, s_h;

      MWArray[] res = null; //выходной массив метода plane
      MWNumericArray descriptor = null; //массив возвращаемого параметра 

      private void button1_Click(object sender, EventArgs e)//событие
      {
          try
          {
              func = textBox1.Text; //считывание с TextBox
              s_x0 = textBox2.Text;
              s_x1 = textBox3.Text;
              s_y0 = textBox4.Text;
              s_y1 = textBox5.Text;
              s_h = textBox6.Text;

              MWCharArray mw_func = new MWCharArray(func);//преобразование строки функции в тип MWCharArray
              x0 = Convert.ToDouble(s_x0); //преобразоване string в double
              x1 = Convert.ToDouble(s_x1);
              y0 = Convert.ToDouble(s_y0);
              y1 = Convert.ToDouble(s_y1);
              h = Convert.ToDouble(s_h);

              planeClass obj_plane = new planeClass(); //экземпляр класса компонента               
              res = obj_plane.plane(1, mw_func, x0, x1, y0, y1, h);//обращение к методу plane, первый параметр - это кол-во возвращаемых аргументов

              descriptor = (MWNumericArray)res[0]; //выбор первого элемента из массива MWArray и преобразование в числовой тип MWNumericArray
              double[,] d_descriptor = (double[,])descriptor.ToArray(MWArrayComponent.Real);//преобразование массива MWNUmericArray  к масииву типа double  

              for (int i = 0; i < d_descriptor.Length; i++)//вывод массива d_descriptor в RichBox
              {
                  richTextBox1.Text += i.ToString() + '\t';
                  richTextBox1.Text += d_descriptor[i, 0].ToString("0.000") + '\n';//преобразование элеметна массива double в string
              }
          }
          catch (Exception ex)//обработка исключения 
          {
              System.Windows.Forms.MessageBox.Show(ex.Message);
          }
      }

      private void button2_Click(object sender, EventArgs e)
      {
          richTextBox1.Text = string.Empty;//очистка RichBox
          res = null;//обнуление массивов
          descriptor = null;
      }
  }
}


Как видим, активно используется приведение типов, по схеме MWArray->MWNUmericArray->тип C#.
Компилируем проект и видим результат:

image

Литература


  1. MATLAB. Программирование на Visual С#, Borland JBuilder, VBA — Н. К. Смоленцев
  2. С# и платформа .NET — Э. Троелсен
Tags:
Hubs:
+34
Comments 20
Comments Comments 20

Articles