6

C#に2次元配列がある場合、この配列の内容を2次元グラフとしてMatlabにプロットするにはどうすればよいですか?私は拡張メソッドを求めています。

my2DArray.PlotInMatlab();
4

1 に答える 1

9

最終的にこれはうまく機能しました。以下は、Matlab.mファイルを呼び出す.NET4.0 C#コンソールアプリによって生成されたサンプルグラフです。

ここに画像の説明を入力してください

良い点は、わずか数行の.NETで、Matlabのすべての機能を使用してグラフを描画できることです。

.NETでこれを行う方法:

  1. Visual Studio 2010でC#用の新しい.NETコンソールアプリを作成し、それを.NET 4.0に変更します(プロジェクトを右クリックし、[プロパティ]を選択します)。

    1. .NET Main():

      using System;
      using System.Diagnostics;
      
      namespace MyPlotGraphUsingMatlabRuntimes
      {
          /// <summary>
          /// Display a graph in Matlab, from a .NET console app.
          /// </summary>
          class Program
          {
              static void Main(string[] args)
              {
                  var x = new double[100];
                  var y = new double[100];
                  for (int i = 0; i < 100; i++) {
                      x[i] = i;
                      y[i] = 2 ^ i;
                  }
                  MyHelper.MyMatlab.MyGraph2D(x,y);
                  Console.Write("[any key to exit]");
                  Console.ReadKey();
              }
          }
      }
      
    2. Matlabへの相互運用を行うための拡張メソッドを提供する.NETクラス(ファイルに名前を付けますMyMatlab.cs)。

      using System;
      using System.Collections.Generic;
      using MathWorks.MATLAB.NET.Arrays;
      namespace MyHelper
      {
          /// <summary>
          /// Collection of chained classes to make Matlab access easier.
          /// </summary>
          public static class MyMatlab
          {
              /// <summary>
              /// Returns a double in a format that can be passed into Matlab.
              /// </summary>
              /// <param name="toMatlab">Double to convert into a form we can pass into Matlab.</param>
              /// <returns>A double in Matlab format.</returns>
              public static MWNumericArray MyToMatlab(this double toMatlab)
              {
                  return new MWNumericArray(toMatlab);
              }
              /// <summary>
              /// Converts an array that contains a single Matlab return parameter back into a .NET double.
              /// </summary>
              /// <param name="toDouble">MWArray variable, returned from Matlab code.</param>
              /// <returns>.NET double.</returns>
              public static double MyToDouble(this MWArray toDouble)
              {
                  var matNumericArray = (MWNumericArray)toDouble;
                  return matNumericArray.ToScalarDouble();
              }
              /// <summary>
              /// Converts an array that contains multiple Matlab return parameters back into a list of .NET doubles.
              /// </summary>
              /// <param name="toList">MWArray variable, returned from Matlab code.</param>
              /// <returns>List of .NET doubles.</returns>
              public static List<double> MyToDoubleList(this MWArray toList)
              {
                  var matNumericArray = toList;
                  var netArray = (MWNumericArray)matNumericArray.ToArray();
      
                  var result = new List<double>();
                  // Console.Write("{0}", netArray[1]);
                  for (int i = 1; i <= netArray.NumberOfElements; i++) // Matlab arrays are 1-based, thus the odd indexing.
                  {
                      result.Add(netArray[i].ToScalarDouble());
                  }
                  return result;
              }
              /// <summary>
              /// Converts an array that contains multiple Matlab return parameters back into a list of .NET ints.
              /// </summary>
              /// <param name="toList">MWArray variable, returned from Matlab code.</param>
              /// <returns>List of .NET ints.</returns>
              public static List<int> MyToMWNumericArray(this MWArray toList)
              {
                  var matNumericArray = toList;
                  var netArray = (MWNumericArray)matNumericArray.ToArray();
      
                  var result = new List<int>();
                  // Console.Write("{0}", netArray[1]);
                  for (int i = 1; i <= netArray.NumberOfElements; i++) // Matlab arrays are 1-based, thus the odd indexing.
                  {
                      result.Add(netArray[i].ToScalarInteger());
                  }
                  return result;
              }
              /// <summary>
              /// Converts an int[] array into a Matlab parameters.
              /// </summary>
              /// <param name="intArray">MWArray variable, returned from Matlab code.</param>
              /// <returns>List of .NET ints.</returns>
              public static MWNumericArray MyToMWNumericArray(this int[] intArray)
              {
                  return new MWNumericArray(1, intArray.Length, intArray); // rows, columns int[] realData
              }
              /// <summary>
              /// Converts an double[] array into parameter for a Matlab call.
              /// </summary>
              /// <param name="arrayOfDoubles">Array of doubles.</param>
              /// <returns>MWNumericArray suitable for passing into a Matlab call.</returns>
              public static MWNumericArray MyToMWNumericArray(this double[] arrayOfDoubles)
              {
                  return new MWNumericArray(1, arrayOfDoubles.Length, arrayOfDoubles); // rows, columns int[] realData
              }
              /// <summary>
              /// Converts an List of doubles into a parameter for a Matlab call.
              /// </summary>
              /// <param name="listOfDoubles">List of doubles.</param>
              /// <returns>MWNumericArray suitable for passing into a Matlab call.</returns>
              public static MWNumericArray MyToMWNumericArray(this List<double> listOfDoubles)
              {
                  return new MWNumericArray(1, listOfDoubles.Count, listOfDoubles.ToArray()); // rows, columns int[] realData
              }
              /// <summary>
              /// Converts a list of some type into an array of the same type.
              /// </summary>
              /// <param name="toArray">List of some type.</param>
              /// <returns>Array of some type.</returns>
              public static T[] MyToArray<T>(this List<T> toArray)
              {
                  var copy = new T[toArray.Count];
                  for (int i = 0; i < toArray.Count; i++) {
                      copy[i] = toArray[i];
                  }
                  return copy;
              }
              static private readonly MatlabGraph.Graph MatlabInstance = new MatlabGraph.Graph();
              /// <summary>
              /// Plot a 2D graph.
              /// </summary>
              /// <param name="x">Array of doubles, x axis.</param>
              /// <param name="y">Array of doubles, y axis.</param>
              /// <param name="title">Title of plot.</param>
              /// <param name="xaxis">X axis label.</param>
              /// <param name="yaxis">Y axis label.</param>
              static public void MyGraph2D(List<double> x, List<double> y, string title = "title", string xaxis = "xaxis", string yaxis = "yaxis")
              {
                  MatlabInstance.Graph2D(x.MyToMWNumericArray(), y.MyToMWNumericArray(), title, xaxis, yaxis);
              }
              /// <summary>
              /// Plot a 2D graph.
              /// </summary>
              /// <param name="x">Array of doubles, x axis.</param>
              /// <param name="y">Array of doubles, y axis.</param>
              /// <param name="title">Title of plot.</param>
              /// <param name="xaxis">X axis label.</param>
              /// <param name="yaxis">Y axis label.</param>
              static public void MyGraph2D(double[] x, double[] y, string title = "title", string xaxis = "xaxis", string yaxis = "yaxis")
              {
                  MatlabInstance.Graph2D(x.MyToMWNumericArray(), y.MyToMWNumericArray(), title, xaxis, yaxis);
              }
              /// <summary>
              /// Unit test for this class. Displays a graph using Matlab.
              /// </summary>
              static public void Unit()
              {
                  {
                      var x = new double[100];
                      var y = new double[100];
                      for (int i = 0; i < 100; i++) {
                          x[i] = i;
                          y[i] = Math.Sin(i);
                      }
                      MyGraph2D(x, y);                
                  }
      
                  {
                      var x = new double[100];
                      var y = new double[100];
                      for (int i = 0; i < 100; i++) {
                          x[i] = i;
                          y[i] = 2 ^ i;
                      }
                      MyGraph2D(x, y);
                  }
              }
          }
      }
      
  2. 次に、.mファイルを.NETアセンブリにエクスポートします。Matlab 2010aを使用しました(これは2010bでも機能します)。Matlab、32ビットバージョンを使用します(Matlabの起動時に32ビットまたは64ビットがスプラッシュ画面に表示されます)。

    1. 次のMatlabコードはグラフを表示します。として保存します Graph2D.m

      function Graph2D (x,y, titleTop, labelX, labelY)
      
      % Create figure
      myNewFigure = figure;
      
      plot(x,y)
      
      title({titleTop});
      xlabel({labelX});
      ylabel({labelY});
      
    2. コンソールで次のように入力して、Matlab内でこれをテストします( Current Folder Matlabツールバーでと同じディレクトリに変更していることを確認してくださいGraph2D.m)。

      x = 0:.2:20;
      y = sin(x)./sqrt(x+1);
      Graph2D(x,y,'myTitle', 'my x-axis', 'my y-axis')
      
    3. Matlabデプロイメントツールで、クラス Graphを追加し、ファイルを追加して Graph2D.mから、パッケージ化し ますMatlabGraph.dll (設定でコンポーネント名を MatlabGraph に変更します。これにより、生成される.dllの名前が決まります)。

    4. .NETプロジェクトで、 MatlabGraph.dll ((コンパイル元の.NET .dll )への参照を追加しますGraph2D.m。これは 、Matlab32-bit のリリースでコンパイルされた場合に なります。32-bit

    5. .NETプロジェクトで、32ビットバージョンの。への参照を追加しますMWArray.dll。これは、Matlabのインストールディレクトリを検索することで見つけることができます。
    6. 繰り返しますが、すべてが一貫して 32-bit、または一貫 してであることを確認して64-bitください。
      1. を選択した場合 32-bitは、.NETアプリをコンパイルし x3232-bit Matlabのバージョン(スプラッシュ画面に 表示されます)を使用して.NET .dllをエクスポートし、の バージョンを .NETプロジェクトに32-bit インポートする必要があり ます。32-bitMWArray.dll
      2. を選択した場合は 64-bit、.NETアプリをにコンパイルし 、 Matlab All CPUの バージョン(スプラッシュ画面に表示されます)を使用して.NET .dllをエクスポートし、の バージョンを .NETプロジェクトに インポートする必要があり ます。64-bit64-bit64-bitMWArray.dll
    7. .NETアプリを実行すると、Matlabランタイムを呼び出すことにより、上のグラフが表示されます。
  3. これを新しいPCに展開する場合は、このPCに.NETランタイムをインストールする必要があります(これらはロイヤリティフリーです)。
  4. これの良いところは、Matlabのすべての機能を使用して、Matlabのグラフを心のコンテンツに合わせてカスタマイズできることです。3Dグラフを作成できます。を使用してMatlabで新しい図を作成し、を使用して File..New..Figureカスタマイズして Insertから、を使用して.mコードを生成し File..Generate M fileます。新しく生成された.mファイルの行が何をするかはかなり明白です。それらを元の Graph2D.m ファイルにコピーしてから、を再生成できます MatlabGraph.dll。たとえば、図にタイトルを追加するtitle({'My new title});と、自動生成された.mファイルに行が追加されます。
  5. 興味があれば、.NETで完全なC#サンプルプロジェクトを提供できます。
于 2011-10-08T14:51:31.657 に答える