Reading a single element from HDF5 file - c#

Could you please provide me with an example of reading a single element from HDF5 file using HDF5DotNet library. I know how to read the full array into the memory and select the necessary element by index. The problem that I don't want to read the full array and would like to use the H5S.selectElements method (http://hdf5.net/api/M_HDF5DotNet_H5S_selectElements_4_9e6f2387.aspx).
So far I've created the following:
H5.Open();
H5FileId fileId = H5F.open(this.filePath, H5F.OpenMode.ACC_RDONLY);
var dSet = H5D.open(fileId, "/Link");
var dSpace = H5D.getSpace(dSet);
var dDims = H5S.getSimpleExtentDims(dSpace);
var dType = H5D.getType(dSet);
H5S.selectElements(dSpace, H5S.SelectOperator.SET, InpPtr numElements,long [] coord);
I can not figure out how to define the numElements parameter and coord of the element (I have 3 dimensional array).

Using the HDF5 support doc
Assuming your DataSet is As Follows: (2D for simplicity explaining how the parameters work)
1 2 3
4 5 6
7 8 9
And you wanted to select the 6 and only the 6.
That means that you want one element located in the second row and the third column. (One Indexed).
That means that you will need a 1 by 2 array of points in the selection array. (Zero Indexed).
1 2
If you wanted to select the 7 also, then the selection array would look like this. (Zero Indexed).
1 2 2 0
The related calls would be:
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 1, new long [] { 1, 2 });
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 2, new long [] { 1, 2, 2, 0 });
Translating to a 3D dataspace, we just add an extra value to the selection array.
That is:
1 2 0
Will select the point (2,3,1)
If you wanted to select a second value, then the selection array would look like this. (Zero Indexed).
1 2 0 1 2 1
Will select the points (2,3,1), (2,3,2).
The related calls would be:
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 1, new long [] { 1, 2, 0 });
H5S.selectElements(dSpace, H5S.SelectOperator.SET, 2, new long [] { 1, 2, 0, 1, 2, 1 });
Note: That I have never used HDF5, describing call based on documentation, so there may be errors.

Using HDFql in C#, reading one particular element of a three dimensional dataset can be done as follows (assume that the dataset is called my_dataset and the element to read is at position 2, 3 and 5 in the first, second and third dimension respectively):
HDFql.Execute("SELECT FROM my_dataset(2, 3, 5)");
From there, you can retrieve the element by doing the following (assume that my_dataset is of datatype integer):
HDFql.CursorFirst();
System.Console.WriteLine("Element is " + HDFql.CursorGetInt());

I've found another approach to solve the problem - using H5S.selectHyperslab method. Maybe it's not so elegant but it seems to work fine.
H5.Open();
H5FileId fileId = H5F.open(this.filePath, H5F.OpenMode.ACC_RDONLY);
var dSet = H5D.open(fileId, "/Link");
var dSpace = H5D.getSpace(dSet);
var dDims = H5S.getSimpleExtentDims(dSpace);
var dType = H5D.getType(dSet);
//E.g. to extract the value with coordinates [0,1,0]:
H5DataSpaceId memspaceid = H5S.create_simple(1, new long[] { 1, 1, 1 });
H5S.selectHyperslab(memspaceid, H5S.SelectOperator.SET, new long[] { 0, 1, 0 }, new long[] { 1, 1, 1 });
H5S.selectHyperslab(dSpace, H5S.SelectOperator.SET, new long[] { 0, 1, 0 }, new long[] { 1, 1, 1 });
//array to read data
double[] readDataBank = new double[1];
H5DataTypeId typeId = new H5DataTypeId(H5T.H5Type.NATIVE_DOUBLE);
H5D.read(dSet, dType, memspaceid, dSpace,new H5PropertyListId(new H5P.Template()), new H5Array<double>(readDataBank));

Related

How the first array entry differs from the second

I can not understand the difference between the declaration with array initialization in the first case and the second
int[] array = new int[3] { 1, 2, 3 };
int[] secondArray = { 1, 2, 3 };
They seem to do the same thing, maybe they work differently?
The is no difference in the result between the two show lines shown:
int[] array = new int[3] { 1, 2, 3 };
int[] secondArray = { 1, 2, 3 };
However, there are practical differences between new int[n] {...} syntax and {...}:
Implicit type is not available for the alternative array initialiser:
var a1 = new int[3] { 1, 2, 3 }; // OK
var a2 = { 1, 2, 3 }; // Error: Cannot initialize an implicitly-typed variable with an array initializer
// BTW. You can omit the size
var a3 = new int[] { 1, 2, 3 }; // OK
With the alternative syntax you cannot specify the size, it's always inferred.
var a1 = new int[100]; // Array with 100 elements (all 0)
int[] a2 = { }; // Array with no elements
There is no difference in the compiled code between the two lines.
The second one is just a shortcut. Both statements have the same result. The shorter variant just wasn't available in early versions of C#.
The first one uses 3 as a array size explictly, the 2nd one size is inferred.
This might be work if you dont want to initialize the values.
There is no difference between this two array initialization syntaxes in terms how they will be translated by the compiler into IL (you can play with it at sharplab.io) and it is the same as the following one:
int[] thirdArray = new int[] { 1, 2, 3 };
The only difference comes when you are using those with already declared variable, i.e. you can use 1st and 3rd to assign new value to existing array variable but not the second one:
int[] arr;
arr = new int[3] { 1, 2, 3 }; // works
// arr = { 1, 2, 3 }; // won't compile
arr = new int[] { 1, 2, 3 }; // works

Multi Label Support Vector Machine in Accord.NET

I am trying to make a Multi Label Support Vector Machine using Accord.NET framework (MultilabelSupportVectorMachine Class) but based on the example it's difficult to understand the encoding e.g.:
// Sample input data
double[][] inputs =
{
new double[] { 0 },
new double[] { 3 },
new double[] { 1 },
new double[] { 2 },
};
// Outputs for each of the inputs
int[][] outputs =
{
new[] { -1, 1, -1 },
new[] { -1, -1, 1 },
new[] { 1, 1, -1 },
new[] { -1, -1, -1 },
};
What if my output is a matrix which contains integer values not within the -1 and +1 range, what encoding should we use to convert the data into this format?
This is the format of the output the MultiLabelSupportVectorMachine would return if you compute something with it. MultiClassSupportVectorMachine returns a single int because it is used when you are sure that an example matches only a single class whereas MultiLabelSupportVectorMachine returns an array which shows which classes does the example match and is used when an example can match more classes.
It works like this:
The output array length is between 0(inclusive) and the number of classes. So if you have 4 classes you'll have an output array like this:
{ -1, -1, 1, -1 }
This means that the output class is 2, because the index of 1 is 2.
I hope that now you know how the output of this class works and that this gives you directions how to format your example output.
Additional info: If you want to use MultiLabelSupportVectorMachine, but you want to get only one output class you can just take the first index of 1 in the output array. I recommend this only if you are certain that One-Vs-All serves you better than One-Vs-One.

Retrieving values from multidimensional arrays

I have an array something like this:
int[,] multiDimensionalArray2 = { { 1, 2 }, { 4, 5 } };
if I want to retrieve 1 and 2 and feed them into this:
int a;
int b;
How do I do it?
Is it something like this:
multiDimensionalArray2[0,0]
What if I wanted to put more numbers in the same form e.g. { { 2, 1 }, { 4, 1 } };, in the same form as above. Would it be something like this:
int[,] multiDimensionalArray2 = { { 1, 2 }, { 4, 5 } },{ { 2, 1 }, { 4, 1 } };
To retrieve the second set would I do this, multiDimensionalArray2[1,1]
You´re close, to retrieve the first numbers try this
var a = multiDimensionalArray2[0, 0]; // x == 1
var b = multiDimensionalArray2[0, 1]; // x == 2
Did you give it a try and it didn´t work? You´ll notice that SO users will encourage you to try-and-error first. Come back when you hit a wall :)
Double dimention arrays are stored like this (picture it in your mind) as per your example
Row0 Row1
1 2
4 5
2 1
4 1
Now follow what Dominik suggested.
If you have a multi dimensional array like the one you gave,
int[,] multiDimensionalArray2 = { { 1, 2 }, { 4, 5 }, { 2, 1 }, { 4, 1 } };
We want to get the index of the number 5. To do this we need two indexes, [a,b]
Index a is the index of the "group of numbers" that you want to get.
First look at which group it is in. The first group (index 0) contains 1 and 2, the second group (index 1) contains 4 and 5.
Therefore a = 1.
Index b is the index of the "position within the group" that you want to get.
In the group {4, 5}, the number 5 is the first item (index 0). Therfore b = 0.
This means that the number 5 can be found at multiDimensionalArray2[1,0]
Chao, I search documents in MSDN site for you, you should give it a try if you want.
Here is how I see on MSDN
List< > >
Dictionary<>
I guess it works for your problem too, it can dynamically grow longer or shorter. they say using generic classes might be better, I am not sure about whether it ought to be faster or not though.

why does Enumerable.Except returns DISTINCT items?

Having just spent over an hour debugging a bug in our code which in the end turned out to be something about the Enumerable.Except method which we didn't know about:
var ilist = new[] { 1, 1, 1, 1 };
var ilist2 = Enumerable.Empty<int>();
ilist.Except(ilist2); // returns { 1 } as opposed to { 1, 1, 1, 1 }
or more generally:
var ilist3 = new[] { 1 };
var ilist4 = new[] { 1, 1, 2, 2, 3 };
ilist4.Except(ilist3); // returns { 2, 3 } as opposed to { 2, 2, 3 }
Looking at the MSDN page:
This method returns those elements in
first that do not appear in second. It
does not also return those elements in
second that do not appear in first.
I get it that in cases like this:
var ilist = new[] { 1, 1, 1, 1 };
var ilist2 = new[] { 1 };
ilist.Except(ilist2); // returns an empty array
you get the empty array because every element in the first array 'appears' in the second and therefore should be removed.
But why do we only get distinct instances of all other items that do not appear in the second array? What's the rationale behind this behaviour?
I certainly cannot say for sure why they decided to do it that way. However, I'll give it a shot.
MSDN describes Except as this:
Produces the set difference of two
sequences by using the default
equality comparer to compare values.
A Set is described as this:
A set is a collection of distinct
objects, considered as an object in
its own right

C# Calculate items in List<int> values vertically

I have a list of int values some thing like below (upper bound and lower bounds are dynamic)
1, 2, 3
4, 6, 0
5, 7, 1
I want to calculate the column values in vertical wise like
1 + 4 + 5 = 10
2 + 6 + 7 = 15
3 + 0 + 1 = 4
Expected Result = 10,15,4
Any help would be appreciated
Thanks
Deepu
Here's the input data using array literals, but the subsequent code works exactly the same on arrays or lists.
var grid = new []
{
new [] {1, 2, 3},
new [] {4, 6, 0},
new [] {5, 7, 1},
};
Now produce a sequence with one item for each column (take the number of elements in the shortest row), in which the value of the item is the sum of the row[column] value:
var totals = Enumerable.Range(0, grid.Min(row => row.Count()))
.Select(column => grid.Sum(row => row[column]));
Print that:
foreach (var total in totals)
Console.WriteLine(total);
If you use a 2D array you can just sum the first, second,... column of each row.
If you use a 1D array you can simply use a modulo:
int[] results = new results[colCount];
for(int i=0, i<list.Count; list++)
{
results[i%colCount] += list[i];
}
Do you have to use a "List"-object? Elseway, I would use a twodimensional array.
Otherwise, you simply could try, how to reach rows and columns separatly, so you can add the numbers within a simply for-loop. It depends on the methods of the List-object.
Quite inflexible based on the question, but how about:
int ans = 0;
for(int i = 0; i < list.length; i+=3)
{
ans+= list[i];
}
You could either run the same thing 3 times with a different initial iterator value, or put the whole thing in another loop with startValue as an interator that runs 3 times.
Having said this, you may want to a) look at a different way of storing your data if, indeed they are in a single list b) look at more flexible ways to to this or wrap in to a function which allows you to take in to account different column numbers etc...
Cheers,
Adam

Categories