double[] -> double[,] - c#

Just curious is there a quicker/neater way to achieve this:
double[] source = ... // some initialisation
var target = new double[1, source.Length];
for (var c = 0; c < source.Length; c++)
{
target[0, c] = source[c];
}

Initialiaze the array like this:
double[,] target = { { /* your list of values */ } };
Then you have a two dimentional array with only one row.

Since you are mentioning this is for P/Invoke, BlockCopy is probably reasonable to use:
double[] source = new double [] {1,2,3,4,7,8,9,0};// some initialisation
double[,] target = new double[1, source.Length];
Buffer.BlockCopy(source, 0, target, 0, source.Length * sizeof(double));

Related

<Module> class in C#

I was migrating a function from a dll to C# and I found a line of code that I don't understand:
< Module >.lm_minimize(((Vector<CalPoint>)calPoints).Size, n_par1, par, (ILMCallbacks)callbacks, (lm_data_type)data, control);
When I try to enter the class there is code in hexadecimal (I guess it's auto generated code) that I can't copy.
This is the code:
internal static void lm_minimize(
int m_dat,
int n_par,
double[] par,
ILMCallbacks callbacks,
lm_data_type data,
lm_control_type control)
{
double[] numArray = new double[m_dat];
double[] diag = new double[n_par];
double[] qtf = new double[n_par];
double[] fjac = new double[m_dat * n_par];
double[] wa1 = new double[n_par];
double[] wa2 = new double[n_par];
double[] wa3 = new double[n_par];
double[] wa4 = new double[m_dat];
int[] ipvt = new int[n_par];
control.info = 0;
control.nfev = 0;
\u003CModule\u003E.lm_lmdif(m_dat, n_par, par, numArray, control.ftol, control.xtol, control.gtol, control.maxcall * (n_par + 1), control.epsilon, diag, 1, control.stepbound, ref control.info, ref control.nfev, fjac, ipvt, qtf, wa1, wa2, wa3, wa4, callbacks, data);
callbacks.lm_printout(n_par, par, m_dat, numArray, data, -1, 0, control.nfev);
control.fnorm = \u003CModule\u003E.\u003FA0x6d25334e\u002Elm_enorm(m_dat, 0, numArray);
if (control.info >= 0)
return;
control.info = 10;
}
And this code calls the function lm_mdif. Part of the code is like this:
\u003CModule\u003E.\u003FA0x6d25334e\u002E\u003F\u0024S1\u0040\u003F1\u003F\u003Flm_lmdif\u0040\u0040YMXHHP\u002401AN0NNNHN0HNA\u0024CAH10P\u002401AH00000A\u0024AAUILMCallbacks\u0040\u0040P\u0024AAVlm_data_type\u0040\u0040\u0040Z\u0040\u0024\u0024Q4IA |= 1U;
// ISSUE: fault handler
I wanted to know if anyone knows what the LM_MINIMIZE function is for, I can't find what it is for..
Thanks
I tried migrate the library code to C#.

Truncate cube of double

I would like to truncate a cube.
If I have a 1d array I can do this:
var oldarray = new double[n];
var newarray = new double[m];
Array.Copy(oldarray, newarray, m);
for m smaller n, obviously oldarray would store some data...
I would like to do the same on a cube, like:
var oldarray = new double[n,n,n];
var newarray = new double[m,m,m];
Array.Copy(oldarray, newarray, m);
Whats the fastest (most performant) way please? (apart from using a triple for loop) thanks.
You could still use Array.Copy, but then the multi-dimensional one:
for (int i = 0 ; i < m ; i++)
{
Array.Copy(oldarray, i, newarray, i, oldarray.GetLength(i));
}

Acess violation exception emguCV cvQueryHistValue

I got stuck with Access violation exception in managed code. Histogram pointer is not null and everything seems ok. Got example of creating IntPtr's from http://www.emgu.com/forum/viewtopic.php?f=8&t=59
// initializing data
var random = new Random();
var array = new double[1000];
for (int i = 0; i < 1000; i++)
{
array[i] = random.NextDouble();
}
var arrayPtr = GetDataPtr(array);
//initializing ranges array
double[] rangesArray = { 0, 1 };
var rangesArrayPtr = GetRangesArrayPtr(rangesArray);
//creating and querying histogram
var histogramStructure = CvInvoke.cvCreateHist(1, new[] {20}, HIST_TYPE.CV_HIST_ARRAY, rangesArrayPtr, true);
var histogram = CvInvoke.cvMakeHistHeaderForArray(1, new[] { 20 }, histogramStructure, arrayPtr, rangesArrayPtr, 1);
CvInvoke.cvNormalizeHist(histogram, 1.0);
CvInvoke.cvQueryHistValue_1D(histogram, 0); // getting exception here
help methods
private static IntPtr[] GetRangesArrayPtr(double[] array)
{
var ranges = new IntPtr[1];
ranges[0] = Marshal.AllocHGlobal(array.Length * sizeof(double));
Marshal.Copy(array, 0, ranges[0], array.Length);
return ranges;
}
private static IntPtr GetDataPtr(double[] array)
{
var ranges = new IntPtr();
ranges = Marshal.AllocHGlobal(array.Length * sizeof(double));
Marshal.Copy(array, 0, ranges,array.Length);
return ranges;
}
I had the same problem in a recent project and solved it by copying the histogram values into a new array.
Double[] histtemp = new double[255];
Histogram.MatND.ManagedArray.CopyTo(histtemp,0);
Now you can access the histogram values in histtemp. I hope it will help future viewers.

How to convert List<Double> to Byte[] in C#

Convertion from Double[] src to Byte[] dst
can be efficiently done in C# by fixed pointers:
fixed( Double* pSrc = src)
{
fixed( Byte* pDst = dst)
{
Byte* ps = (Byte*)pSrc;
for (int i=0; i < dstLength; i++)
{
*(pDst + i) = *(ps +i);
}
}
}
How can I do the same for List src ?
I.e. how can I get fixed pointer to array Double[]
included in List ?
Thanks.
I have used these helper methods before:
byte[] GetBytesBlock(double[] values)
{
var result = new byte[values.Length * sizeof(double)];
Buffer.BlockCopy(values, 0, result, 0, result.Length);
return result;
}
double[] GetDoublesBlock(byte[] bytes)
{
var result = new double[bytes.Length / sizeof(double)];
Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length);
return result;
}
An example:
List<double> myList = new List<double>(){ 1.0, 2.0, 3.0};
//to byte[]
var byteResult = GetBytesBlock(myList.ToArray());
//back to List<double>
var doubleResult = GetDoublesBlock(byteResult).ToList();
not sure what you are intending, but I think ... you want
System.Runtime.Interopservices.Marshal.StructToPtr.
You can always use the ToArray() method on the List<Double> object to get a Double[].
You can use reflection to get the reference to the private T[] _items field, in the List instance.
Warning: In your code snippet, you need to make sure dstLength is the minimum of dst and src lengths in bytes, so that you don't try to copy more bytes than what are available. Probably you do so by creating dst with exactly the needed size to match the src, but your snippet doesn't make it clear.
Use the List<T>.ToArray() method and operate on the resulting array.
This might work, but you will have a data loss- content of the array will be 3 and 34 .
List<double> list = new List<double>();
list.Add(Math.PI);
list.Add(34.22);
byte[] arr = (from l in list
select (byte)l).ToArray<byte>();
Why don't you just access the list as usual?
List<double> list = new List<double>();
list.Add(Math.PI);
list.Add(34.22);
byte[] res = new byte[list.Count * sizeof(double)];
unsafe
{
fixed (byte* pres = res)
{
for (int i = 0; i < list.Count; i++)
{
*(((double*)pres) + i) = list[i];
}
}
}
I haven't tested it thoroughly and i seldomly need unsafe code, but it seems to work fine.
Edit: here is another (imo preferable) solution, without unsafe code:
int offset = 0;
for (int i = 0; i < list.Count; i++)
{
long num = BitConverter.DoubleToInt64Bits(list[i]);
for (int j = 0; j < 8; j++)
{
res[offset++] = (byte)num;
num >>= 8;
}
}

Array concatenation in C#

How do I smartly initialize an Array with two (or more) other arrays in C#?
double[] d1 = new double[5];
double[] d2 = new double[3];
double[] dTotal = new double[8]; // I need this to be {d1 then d2}
Another question: How do I concatenate C# arrays efficiently?
You could use CopyTo:
double[] d1 = new double[5];
double[] d2 = new double[3];
double[] dTotal = new double[d1.Length + d2.Length];
d1.CopyTo(dTotal, 0);
d2.CopyTo(dTotal, d1.Length);
var dTotal = d1.Concat(d2).ToArray();
You could probably make it 'better' by creating dTotal first, and then just copying both inputs with Array.Copy.
You need to call Array.Copy, like this:
double[] d1 = new double[5];
double[] d2 = new double[3];
double[] dTotal = new double[d1.length + d2.length];
Array.Copy(d1, 0, dTotal, 0, d1.Length);
Array.Copy(d2, 0, dTotal, d1.Length, d2.Length);
using System.Linq;
int[] array1 = { 1, 3, 5 };
int[] array2 = { 0, 2, 4 };
// Concat array1 and array2.
var result1 = array1.Concat(array2).ToArray();

Categories