neděle 16. listopadu 2008

Scilab and C#

I was searching for usefull example inlustrating Scilab and C# interaction. There are few articles about this issue, but none of them is complete and you always have to search some additional information. So I decided to sumarize my experiences from one project that is based on .net desktop application and Scilab interaction.

First you need to imprort Scilab dll functions:

[DllImport(@"C:\Program Files\scilab-5.0.1\bin\LibScilab.dll", EntryPoint = "StartScilab", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)]
public static extern int StartScilab(StringBuilder SCIpath, StringBuilder ScilabStartup, int Stacksize);

[DllImport(@"C:\Program Files\scilab-5.0.1\bin\LibScilab.dll", EntryPoint = "SendScilabJob", ExactSpelling = false,
CallingConvention = CallingConvention.Cdecl)]

public static extern int SendScilabJob(string job);

Note that you have to change the path according to your Scilab directory.

Now after calling

StartScilab(null, null, 0);

you can call any Scilab funtions using SendScilabJob.

The aim of my project was to push data into scilab, run the scirpt and get out the results. It is done by this code:

TextWriter tw = File.CreateText("temp.sci");
SaveToScilabMatrix2("data_in.dat");
tw.WriteLine("load('{0}\\data_in.dat');", System.IO.Directory.GetCurrentDirectory());
tw.WriteLine(myScript);
tw.WriteLine("save('{0}\\data_out.dat', {1});", System.IO.Directory.GetCurrentDirectory(), tbVariables2Save.Text);
tw.Close();
if (SendScilabJob(string.Format(@"exec('{0}\temp.sci');", System.IO.Directory.GetCurrentDirectory())) != 0)
{
MessageBox.Show("Error in the script");
}


where SaveToScilabMatrix2 is as follows:


private void SaveToScilabMatrix2(string fileName)
{
if (GetAllActiveTrends().Count == 0) return;

FileStream BinaryFile = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
using (BinaryWriter writer = new BinaryWriter(BinaryFile))
{
List trends = GetAllActiveTrends();
foreach (TrendData td in trends)
{
//name
writer.Write(Str2Code(td.Name, true));
// type
writer.Write((int)1);
// rows
writer.Write((int)td.DataBuffer.Count);
// cols
writer.Write((int)1);
// real numbers are used
writer.Write((int)0);

foreach (double d in td.DataBuffer.Values)
{
writer.Write((double)d);
}
}
}

BinaryFile.Close();
}


For additional infromatios see the following links:

http://www.mathkb.com/Uwe/Forum.aspx/scilab/1808/Help-interfacing-Scilab-with-C
http://www.mathkb.com/Uwe/Forum.aspx/scilab/2111/Some-questions-about-Scilab-s-application-in-engineering-area
http://www.mathkb.com/Uwe/Forum.aspx/scilab/2132/Fortran-and-recompiling-V4
http://pages.cs.aueb.gr/users/yiannisk/aps-06/sci-bot-1.5-html/sci-bot/x8655.html