I am trying to import a function from MATLAB to C#, however I am having troubles in dealing with an array 1xN as input in C.
I saw that it is common to use emxArray_real_T functions to deal with unbounded arrays but for some reasons it works for me as an output but not as an input.
Any thoughts? And many thanks in advance!
Here is my function:
class Program
{
[DllImport(#"./myFunc.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void sinus_FFT(ref emxArray_real_T input, double fs,
ref emxArray_real_T output);
static void Main(string[] args)
{
double[] Input = new double[] {1, 2, 3};
double fs = 100;
double[] Output = new double[A.Length];
emxArray_real_T_Wrapper wI = new emxArray_real_T_Wrapper(Input);
emxArray_real_T_Wrapper wO = new emxArray_real_T_Wrapper(Output);
sinus_FFT(ref wI.Value, fs, ref wO.Value);
Output = wO.Data;
}
public struct emxArray_real_T
{
public IntPtr data;
public IntPtr size;
public int allocatedSize;
public int numDimensions;
public bool canFreeData;
}
public class emxArray_real_T_Wrapper : IDisposable
{
private emxArray_real_T value;
private GCHandle dataHandle;
private GCHandle sizeHandle;
public ref emxArray_real_T Value
{
get { return ref value; }
}
public double[] Data
{
get
{
double[] data = new double[value.allocatedSize];
Marshal.Copy(value.data, data, 0, value.allocatedSize);
return data;
}
}
public emxArray_real_T_Wrapper(double aData)
{
double[] data = { aData };
dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
value.data = dataHandle.AddrOfPinnedObject();
sizeHandle = GCHandle.Alloc(new int[] { 1, data.Length }, GCHandleType.Pinned);
value.size = sizeHandle.AddrOfPinnedObject();
value.allocatedSize = data.Length;
value.numDimensions = 1;
value.canFreeData = false;
}
public emxArray_real_T_Wrapper(double[] data)
{
dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
value.data = dataHandle.AddrOfPinnedObject();
sizeHandle = GCHandle.Alloc(new int[] { 1, data.Length }, GCHandleType.Pinned);
value.size = sizeHandle.AddrOfPinnedObject();
value.allocatedSize = data.Length;
value.numDimensions = 1;
value.canFreeData = false;
}
public emxArray_real_T_Wrapper(double[,] data)
{
int nRow = data.GetLength(0);
int nCol = data.GetLength(1);
double[] flattenedData = new double[nCol * nRow];
int index = 0;
for (int col = 0; col < nCol; col++)
{
for (int row = 0; row < nRow; row++)
{
flattenedData[index] = data[row, col];
index++;
}
}
dataHandle = GCHandle.Alloc(flattenedData, GCHandleType.Pinned);
value.data = dataHandle.AddrOfPinnedObject();
sizeHandle = GCHandle.Alloc(new int[] { nRow, nCol }, GCHandleType.Pinned);
value.size = sizeHandle.AddrOfPinnedObject();
value.allocatedSize = flattenedData.Length;
value.numDimensions = 2;
value.canFreeData = false;
}
public void Dispose()
{
dataHandle.Free();
sizeHandle.Free();
GC.SuppressFinalize(this);
}
~emxArray_real_T_Wrapper()
{
Dispose();
}
}
}
Related
I have a class, all the parameters of the class -except one that is detect value- have 2 values that is controlled by the detect value. See the implementation below.
I have a detect value that is controlled by external sources. With this value get are set methods map to 2 variables.
I realized this as array of length 2, but I am curious about other ways. Any recommendations and improvements to the question is appreciated.
I am a new developer in this project. I thought that using singleton like extension like doubleton may be OK, but I am a bit reluctant to change the structure of the project. If I am more confident about better ways, I will be more courageous to request change in the structure of the project.
My first aim to find if there are better ways to do this 2 same variables in a class better than using arrays.
class Fun
{
int detect;
int a[2], b[2], c[2];
void Apply(byte[] ar)
{
detect = ar[0];
if(detect == 1)
{
a[0] = ar[1];
b[0] = ar[2];
c[0] = ar[3];
}
if(detect == 2)
{
a[1] = ar[1];
b[1] = ar[2];
c[1] = ar[3];
}
}
byte [] GetAll(int detect)
{
int [] ar = new int [3];
if(detect = 1)
{
ar[0] = a[0];
ar[1] = b[0];
ar[2] = c[0];
}
if(detect = 2)
{
ar[0] = a[1];
ar[1] = b[1];
ar[2] = c[1];
}
}
GetA(int detect)
{
if(detect == 1)
{
return a[0];
}
if(detect == 2)
{
return a[1];
}
}
SetA(int detect, int val)
{
if(detect == 1)
{
a[0] = val;
}
if(detect == 2)
{
a[1] = val;
}
}
// GetB, GetC, SetB, SetC are similar
}
You can use a 2 dimensional array and your methods can be much simpler:
class Fun
{
int detect;
int a[2][3];
void Apply(byte[] ar)
{
detect = ar[0];
for (int i = 0; i < 3; i++)
a[detect - 1][i] = ar[i];
}
public int[] GetAll(int detect)
{
int[] ar = new int[3];
for (int i = 0; i < 3; i++)
ar[i] = a[detect - 1][i];
return ar;
}
GetA(int detect)
{
return a[detect - 1][0];
}
SetA(int detect, int val)
{
a[detect - 1][0] = val;
}
GetB(int detect)
{
return a[detect - 1][1];
}
SetB(int detect, int val)
{
a[detect - 1][1] = val;
}
GetC(int detect)
{
return a[detect - 1][2];
}
SetC(int detect, int val)
{
a[detect - 1][2] = val;
}
}
Note: if you provide a value other than 1 or 2 for detect you can expect an exception to be thrown.
A different and probably more sensible approach would be to have two instances of a simpler class:
public class Fun
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public void Apply(byte[] ar)
{
A = ar[0];
B = ar[1];
C = ar[2];
}
public byte[] GetAll()
{
byte[] ar = new byte[3];
ar[0] = A;
ar[1] = B;
ar[2] = C;
}
}
public class NotFun
{
Fun fun1 = new Fun();
Fun fun2 = new Fun();
void Something()
{
fun1.Apply(new byte[3] { 1, 2, 3 });
int a = fun1.A;
}
}
Protobuf doesn't support multi-dim arrays so I decided to use this implementation to make a 1D array out of a 2D one.
I get a Cannot cast from source type to destination type in the ToProtoArray method when I call the MultiLoop function. Any ideas on how to fix this?
public static ProtoArray<T> ToProtoArray<T>(this System.Array array)
{
// Copy dimensions (to be used for reconstruction).
var dims = new int[array.Rank];
for (int i = 0; i < array.Rank; i++) dims[i] = array.GetLength(i);
// Copy the underlying data.
var data = new T[array.Length];
var k = 0;
array.MultiLoop(indices => data[k++] = (T)array.GetValue(indices));
// ^^^^^^^^^^ cannot cast from source type to destination type
return new ProtoArray<T> { Dimensions = dims, Data = data };
}
public static System.Array ToArray<T>(this ProtoArray<T> protoArray)
{
// Initialize array dynamically.
var result = System.Array.CreateInstance(typeof(T), protoArray.Dimensions);
// Copy the underlying data.
var k = 0;
result.MultiLoop(indices => result.SetValue(protoArray.Data[k++], indices));
return result;
}
public static void MultiLoop(this System.Array array, System.Action<int[]> action)
{
array.RecursiveLoop(0, new int[array.Rank], action);
}
private static void RecursiveLoop(this System.Array array, int level, int[] indices, System.Action<int[]> action)
{
if (level == array.Rank)
{
action(indices);
}
else
{
for (indices[level] = 0; indices[level] < array.GetLength(level); indices[level]++)
{
RecursiveLoop(array, level + 1, indices, action);
}
}
}
[ProtoContract]
public class ProtoArray<T>
{
[ProtoMember(1)]
public int[] Dimensions { get; set; }
[ProtoMember(2)]
public T[] Data { get; set; }
}
Here's how I use this to serialize a 2D array:
[ProtoContract]
public class Tile
{
[ProtoMember(1)]
public int x;
[ProtoMember(2)]
public int y;
// ...
}
Tile[,] map; // meanwhile I assign the data to the array
map1d = Extensions.ToProtoArray<Tile[,]>(map);
using (var file = File.Create(path))
{
Serializer.Serialize(file, map1d);
}
I think this is what you need:
public class ProtoArray<T>
{
public ProtoArray(T[] array)
{
this.Data=array;
this.Dimensions=new int[array.Length];
}
public ProtoArray(T[,] array)
{
int n = array.GetLength(0);
int m = array.GetLength(1);
this.Data=new T[n*m];
for(int i = 0; i<n; i++)
{
for(int j = 0; j<m; j++)
{
// Row Major
Data[i*m+j]=array[i, j];
// For Column Major use Data[i+j*n]=array[i, j];
}
}
this.Dimensions=new[] { n, m };
}
public int[] Dimensions { get; set; }
public T[] Data { get; set; }
public T[] ToArray()
{
if(Dimensions.Length==1)
{
return Data.Clone() as T[];
}
else
{
throw new NotSupportedException();
}
}
public T[,] ToArray2()
{
if(Dimensions.Length==2)
{
int n = Dimensions[0], m = Dimensions[1];
T[,] array = new T[n, m];
for(int i = 0; i<n; i++)
{
for(int j = 0; j<m; j++)
{
array[i, j]=Data[i*m+j];
}
}
return array;
}
else
{
throw new NotSupportedException();
}
}
}
public class Tile
{
public int x;
public int y;
// ...
}
class Program
{
static void Main(string[] args)
{
Tile[,] map = new Tile[16, 4];
ProtoArray<Tile> array = new ProtoArray<Tile>(map);
//serialize array
//
// de-serialize array
Tile[,] serialized_map = array.ToArray2();
}
}
I am trying to write a List<double[]> into a csv file. Based on my experiments it is not possible using WriteRecords() directly, so I am looking for alternatives.
I cannot create a class to map this data because the number of elements in the arrays varies from execution to execution, and ranges from 1 to 75.
I have tried to go through each element of the array manually with WriteField() but it is really slow., and I have thousands of elements.
Is there anyway to accomplish this fast enough?
Thanks.
Edit:
Code
class ExportData
{
private Dictionary<int, Dictionary<SensorT, ListIndex>> _dict_sensorN;
private List<double[]> _values_list;
private int _current_max_Count=-1;
private static int _max_Count = 3000;
int n_columns = 0;
private CsvWriter csv;
public ExportData(List<SensorControl> sensorsUC)
{
//We create a dictionary with two keys that will store all the info from the sensors
_dict_sensorN = new Dictionary<int, Dictionary<SensorT, ListIndex>>();
foreach (SensorControl SensorC in sensorsUC)
{
Dictionary<SensorT, ListIndex> dict_sensorM = new Dictionary<SensorT, ListIndex>();
if (SensorC.emg)
{
ListIndex Index = new ListIndex();
Index.Column = n_columns;
Index.Row = 0;
dict_sensorM.Add(SensorT.EMG, Index);
n_columns++;
}
if (SensorC.triggers)
{
ListIndex Index = new ListIndex();
Index.Column = n_columns;
Index.Row = 0;
dict_sensorM.Add(SensorT.Trigger1, Index);
n_columns++;
Index.Column = n_columns;
Index.Row = 0;
dict_sensorM.Add(SensorT.Trigger2, Index);
n_columns++;
}
if (SensorC.acc)
{
ListIndex Index = new ListIndex();
Index.Column = n_columns;
Index.Row = 0;
dict_sensorM.Add(SensorT.ACC, Index);
n_columns++;
}
_dict_sensorN.Add(SensorC.sensorNumber, dict_sensorM);
}
//Initialize the array
_values_list = new List<double[]>();
//Initialize the document
DateTime currentDate = DateTime.Now;
string fileName = "exp_" + currentDate.ToString("yyyy-dd-M--HH-mm-ss") + ".csv";
try
{
var textWriter = new StreamWriter(fileName);
csv = new CsvWriter(textWriter);
}
catch (IOException e)
{
Console.WriteLine(e.Message + "\n Cannot create file.");
return;
}
}
public void AddToBuffer(SensorPoint sp)
{
Dictionary<SensorT, ListIndex> dict_sensorM = new Dictionary<SensorT, ListIndex>();
ListIndex Index = new ListIndex();
if (_dict_sensorN.TryGetValue(sp.ID, out dict_sensorM))
{
SensorT type = ToSensorT(sp.SensorType, sp.Battery);
if(type == SensorT.Trigger1) {
if (dict_sensorM.TryGetValue(type, out Index))
{
if (_current_max_Count < Index.Row)
{
_current_max_Count = Index.Row + 1;
_values_list[Index.Row] = new double[n_columns];
}
_values_list[Index.Row][Index.Column] =sp.Trigger1_int;
Index.Row++;
}
if (dict_sensorM.TryGetValue(SensorT.Trigger2, out Index))
{
if (_current_max_Count < Index.Row)
{
_current_max_Count = Index.Row + 1;
_values_list[Index.Row] = new double[n_columns];
}
_values_list[Index.Row][Index.Column] = sp.Trigger2_int_pos;
Index.Row++;
}
}
else {
if (dict_sensorM.TryGetValue(type, out Index))
{
if (_current_max_Count < Index.Row)
{
_current_max_Count = Index.Row;
_values_list.Add(new double[n_columns]);
}
_values_list[Index.Row][Index.Column] = sp.YPoint;
Index.Row++;
}
}
}
if (_current_max_Count > _max_Count) AddToFile();
}
private void AddToFile() {
csv.WriteRecords(_values_list);
}
private SensorT ToSensorT(SensorType stype, int battery)
{
if (stype == SensorType.EMG)
{
return SensorT.EMG;
}
else if (stype == SensorType.EMG_Trigger )
{
if (battery < 0) return SensorT.Trigger1;
else return SensorT.EMG;
}
else if (stype == SensorType.ACC)
{
return SensorT.ACC;
}
else {
return SensorT.Unknown;
}
}
}
/// <summary>
/// In order to create a multivalue dictionary it is necessary another class
/// </summary>
class ListIndex {
public int Column { get; set; }
public int Row { get; set; }
}
}
i need to call variables that are defined in a class
class testclasss
{
public testclass(double[,] values)
{
double[][] rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] }; // if data won't fit into memory, stream through external storage
}
int num = 3;
int max = 30;
}
public int[] checkvalue(double[][] rawData, int num, int maxCount)
{
............
}
}
I have called constructor using
testclass newk = new testclass(values);
now how can i call the function checkvalues(). i tried using newk.num,newk.maxcount but those variables were not recognized.
Just as your class constructor and checkvalues function are public, so too must the properties you wish to access from outside the class. Put these at the top of your class declaration:
public int num {get; set;}
public int max {get; set;}
Then you can access them via newk.num and newk.max.
EDIT: In response to your second comment, I think you might be a bit confused about how functions and properties interact within the same class. This might help:
class TestClass {
private int _num;
private int _max;
private double[][] _rawData;
public TestClass(double[,] values, int num, int max)
{
_num = num;
_max = max;
_rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
_rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] };
}
}
public int[] CheckValues()
{
//Because _num _max and _rawData exist in TestClass, CheckValues() can access them.
//There's no need to pass them into the function - it already knows about them.
//Do some calculations on _num, _max, _rawData.
return Something;
}
}
Then, do this (for example, I don't know what numbers you're actually using):
double[,] values = new double[10,10];
int num = 3;
int max = 30;
Testclass foo = new Testclass(values, num, max);
int[] results = foo.CheckValues();
I believe this is what you're looking for:
class TestClass {
public int num { get; set; }
public int max { get; set; }
public double[][] rawData;
public TestClass(double[,] values)
{
rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] }; // if data won't fit into memory, stream through external storage
}
this.num = 3;
this.max = 30;
}
public int[] CheckValue()
{............}
}
You'll need a property with a get accessor.
Here is a simplified example based on your code:
class testclass
{
private int _num = 0;
private int _max = 0;
public int Num
{
set { _num = value; }
get { return _num; }
}
public int Max
{
set { _max = value; }
get { return _max; }
}
public testclass()
{
Num = 3;
Max = 30;
}
}
//To access Num or Max from a different class:
testclass test = new testclass(null);
Console.WriteLine(test.Num);
Hope that helps.
Using your exact same code, except for public testclass(double[,] values), which I changed to public testfunction(double[,] values)
class testclass
{
public testfunction(double[,] values)
{
double[][] rawData = new double[10][];
for (int i = 0; i < 10; i++)
{
rawData[i] = new double[] { values[i, 2], stockvalues[i, 0] }; // if data won't fit into memory, stream through external storage
}
int num = 3;
int max = 30;
}
public int[] checkvalue(double[][] rawData, int num, int maxCount)
{
............
}
}
Have you tried calling checkvalues() function like this?
testclass.checkvalue();
I am attempting to create a function that will create a set of cards
that can be randomly input into a list, but despite researching the solution
I can not figure out what I need to place in the parentheses when I called my
function, and when I return its variable.
using System;
using System.Collections.Generic;
using System.Text;
namespace BlackJackGameX
{
public class Deck
{
Random rNumber = new Random();
List<Card> Cards;
List<Card> ShuffledDeck;
public int iValue1 = 11;
public int iValue2 = 2;
public int iValue3 = 3;
public int iValue4 = 4;
public int iValue5 = 5;
public int iValue6 = 6;
public int iValue7 = 7;
public int iValue8 = 8;
public int iValue9 = 9;
public int iValue10 = 10;
public int iValue11 = 10;
public int iValue12 = 10;
public int iValue13 = 10;
I can not figure out what I need to put in the NewDeck parentheses.
public Deck()
{
Cards = NewDeck();
}
public void Shuffle()
{
for (int i = 0; i <= 51; ++i)
{
int c = rNumber.Next (1, 53);
ShuffledDeck.Add(Cards[c]);
}
}
private List<Card> NewDeck(Suit CardSuit, FaceValue CardValue, int iValue)
{
var AllSuits = new Suit[]
{
Suit.Spades,
Suit.Hearts,
Suit.Clubs,
Suit.Diamonds
};
var AllFaces = new FaceValue[]
{
FaceValue.Ace,
FaceValue.Two,
FaceValue.Three,
FaceValue.Four,
FaceValue.Five,
FaceValue.Six,
FaceValue.Seven,
FaceValue.Eight,
FaceValue.Nine,
FaceValue.Ten,
FaceValue.Jack,
FaceValue.Queen,
FaceValue.King
};
var AllValues = new int[]
{
iValue1,
iValue2,
iValue3,
iValue4,
iValue5,
iValue6,
iValue7,
iValue8,
iValue9,
iValue10,
iValue11,
iValue12,
iValue13
};
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 12; j++)
{
Card newCard = new Card(AllSuits[i], AllFaces[j], AllValues[j]);
}
}
I can not figure out what I need to put in the NewDeck parentheses
return NewDeck ();
}
public void Print()
{
Console.WriteLine(ShuffledDeck[1].CardValue);
Console.ReadLine();
}
}
}
As the signature of the method in question is:
private List<Card> NewDeck(Suit CardSuit, FaceValue CardValue, int iValue)
you will need to pass in values like the following:
return NewDeck(Suit.Spades, FaceValue.Ace, iValue1);
As Oren has said, inside the NewDeck method you do not use these values. Having the signature like this should also be OK:
private List<Card> NewDeck()