I was playing with integer array hashing and the different ways to go from a representation to the other. I ended up with the following:
void main(string[] args) {
import std.algorithm, std.array, std.conv, std.stdio, std.digest.md;
union hashU {
ubyte[] hashA;
int[] hashN;
};
hashU a;
auto md5 = new MD5Digest();
a.hashN = [1, 2, 3, 4, 5];
/* Using an union, no actual data conversion */
md5.put( a.hashA );
auto hash = md5.finish();
writeln(hash);
// [253, 255, 63, 4, 193, 99, 182, 232, 28, 231, 57, 107, 18, 254, 75, 175]
/* Using a cast... Doesn't match any of the other representations */
md5.put( cast(ubyte[])(a.hashN) );
hash = md5.finish();
writeln(hash);
// [254, 5, 74, 210, 231, 185, 139, 238, 103, 63, 159, 242, 45, 80, 240, 12]
/* Using .to! to convert from array to array */
md5.put( a.hashN.to!(ubyte[]) );
hash = md5.finish();
writeln(hash);
// [124, 253, 208, 120, 137, 179, 41, 93, 106, 85, 9, 20, 171, 53, 224, 104]
/* This matches the previous transformation */
md5.put( a.hashN.map!(x => x.to!ubyte).array );
hash = md5.finish();
writeln(hash);
// [124, 253, 208, 120, 137, 179, 41, 93, 106, 85, 9, 20, 171, 53, 224, 104]
}
My question is the following: what does the cast do? I'd have expected it to do either the same as .to! or the union trick, but it doesn't seem so.
I think Colin Grogan has it right, but his wording is a little confusing.
Using the union, the array is simply reinterpreted, no calculation/computation happens at all. The pointer and length of the int[] are reinterpreted to refer to ubyte elements. Before: 5 ints, after: 5 ubytes.
The cast is a little smarter than that: It adjusts the length of the array so that it refers to the same memory as before. Before: 5 ints, after: 20 ubytes (5*int.sizeof/ubyte.sizeof = 5*4/1 = 20).
Both the union and the cast reinterpret the bytes of the ints as ubytes. That is, an int value 1 will result in 4 ubytes: 0,0,0,1, or 1,0,0,0 depending on endianess.
The to variants convert every single element to the new element type. Before: 5 ints, after: 5 ubytes with the same values as the ints. If one of the ints couldn't be converted to a ubyte, to would throw an exception.
Printing the elements after the various conversions might help clarifying what happens where:
void main()
{
import std.algorithm, std.array, std.conv, std.stdio;
union hashU
{
ubyte[] hashA;
int[] hashN;
}
hashU a;
a.hashN = [1, 2, 3, 4, 5];
writeln( a.hashA ); /* union -> [1, 0, 0, 0, 2] (depends on endianess) */
writeln( cast(ubyte[])(a.hashN) );
/* cast -> [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0]
(depends on endianess) */
writeln( a.hashN.to!(ubyte[]) ); /* `to` -> [1, 2, 3, 4, 5] */
}
As far as I know, cast simply tells the compiler to start talking to the chunk of memory that you've cast as the type you've cast it to.
The last two options in your example actually convert the numbers to the new type, and so do some actual work. Which is why they end up being the same values.
The issue in your first two examples is that the int[] is larger in memory than the ubyte[]. (4 bytes per element vs 1 byte per element)
I've edited your first two methods:
/* Using an union, no actual data conversion */
md5.put( a.hashA );
auto hash = md5.finish();
writefln("Hash of: %s -> %s", a.hashA, hash);
// Hash of: [1, 0, 0, 0, 2] -> [253, 255, 63, 4, 193, 99, 182, 232, 28, 231, 57, 107, 18, 254, 75, 175]
// notice 5 bytes in first array
/* Using a cast... Doesn't match any of the other representations */
md5.put( cast(ubyte[])(a.hashN) );
hash = md5.finish();
writefln("Hash of: %s -> %s", cast(ubyte[])(a.hashN), hash);
// Hash of: [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0] -> [254, 5, 74, 210, 231, 185, 139, 238, 103, 63, 159, 242, 45, 80, 240, 12]
// notice 20 bytes (4 x 5 bytes) in first array
So in the first, you're reading the length of ubyte[]'s bytes. In the second your casting the length of int[]'s length to ubyte[].
Edit: Prob wasn't clear. A union is pretty dumb, it simply stores all the values in the same memory. When you go to read any of them out, it will only read X bits of that memory, depending on the length of the type you're reading.
So because you're reading the int[] THEN casting it, it reads all 20 of the bytes and casts them to a ubyte[]. Which is of course different than just reading the 5 bytes of the ubyte[] variable.
I think I made sense there :)
cast is a D operator used when developer needs to perform an explicit type conversion.
Related
I am trying to get the x and y values out of a PointCloud2 data. This data is stored in an array in bytes of float32's. My question is, how can I get only the x and y data?
I will add a snippet of what the PointCloud2 data looks like, but for now I'd like to just be able to get the x - data. So for every 16 values, I only want the first 4 (I want the first 4 as this is how it is ordered and because the float32's are decomposed into 4 bytes each).
My original thought process was just to use a loop, but I am worried this may be too slow. This is as my array has more than 2000 values and I am getting 15 of these arrays per second. Is there any other way of doing this?
seq: 296
stamp:
secs: 1553456947
nsecs: 421859979
frame_id: "cloud"
height: 1
width: 811
fields:
-
name: "x"
offset: 0
datatype: 7
count: 1
-
name: "y"
offset: 4
datatype: 7
count: 1
-
name: "z"
offset: 8
datatype: 7
count: 1
-
name: "intensity"
offset: 12
datatype: 7
count: 1
is_bigendian: False
point_step: 16
row_step: 12976
data: [108, 171, 8, 191, 107, 171, 8, 191, 0, 0, 0, 0, 0, 0, 113, 70, 167,
197, 8, 191, 103, 95, 10, 191, 0, 0, 0, 0, 0, 240, 115, 70, 99, 101, 9, 191,
127, 161, 12, 191, 0, 0, 0, 0, 0, 200, 106, 70, 99, 50, 5, 191, 202, 237, 9,
191, 0, 0, 0, 0, 0, 76, 82, 70, 200, 22, 235, 190, 200, 74, 246, 190, 0, 0,
0, 0, 0, 132, 52, 70, 186, 111, 255, 190, 99, 95, 7, 191, 0, 0, 0, 0, 0, 24,
60, 70, 227, 1, 8, 191, 89, 217, 17, 191, 0, 0, 0, 0, 0, 64, 93, 70, 216,
183, 8, 191, 245, 84, 20, 191, 0, 0, 0, 0, 0, 236, 112, 70, 195, 94, 8, 191,
64, 177, 21, 191, 0, 0, 0, 0 ...
I would also like to add that I am a beginner at this sort of thing. I spoke with my friend and he said using mutex threading for this, but that seems way over my head.
Thanks!
I suspect that you'll be surprised how fast modern hardware can loop through 30000 points.
You should start off with your loop and some basic considerations. For example, for storage of our X/Y coordinates in a vector, reserve the required space in the vector before you enter your loop to avoid extra memory allocations. Once you have your loop working, evaluate the performance and maybe post another question if you think that your code is too slow.
A helpful quote by Donald E. Knuth that may apply:
Premature optimization is the root of all evil.
Edit; to provide some context: We had an application running on a low end i5 processor collecting 76,800 3D points at 15 fps via the Kinect SDK or via OpenNI (different sensor). We'd loop through the points and apply a basic transformation before storing each point into a pcl::PointCloud. We'd then loop through the point cloud points again for some analysis. The analysis portion far outweighed the cost of any basic loop. You will probably end up worrying about optimizing whatever evaluation logic you want apply to your data rather than basic things such as looping over the points.
I have two vectors: one populated with a stride of 5, so it's size can be 5, 10, 15, 20, 25, 30 ... 5n.
And the other is populated with a stride of 6, so it's size is 6, 12, 18, 24, 30, 36 ... 6n
I'd like to subtract these two vectors as they were the same size. Since they both hold coordinates of a curve I thought I might subtract the middle two elements in the second vector so something like this:
// The numbers are indexes
(0, 1, 2, 3, 4, 5) =
(0, 1, 3 - 2, 4, 5)
The new size is 5. But it's not as easy on a general case when using a for loop to maintain and compare them both. The comparison should be something like this:
// The numbers are indexes
vector<int> v1 = (0, 1, 2, 3, 4, 5);
vector<int> v2 = (0, 1, 3 - 2, 4, 5);
vector<int> v3 = v1 - v2
Example:
// Actual numbers
vector<int> v1 = (110, 210, 310, 410, 510, 610, 710, 810, 910, 1010);
vector<int> v2 = (120, 220, 320, 420, 520, 620, 720, 820, 920, 1020, 1120, 1220);
vector<int> v3 = v1 - v2; // error - vectors different size
// so we try to fix it
v2 = (120, 220, (420 - 320), 520, 620, 720, 820, (920 - 1020), 1120, 1220);
v2 = (220, 100, 520, 620, 720, 820, 100, 1120, 1220); // resized vector in the desired fasion
v3 = v1 - v2; // still not ok - the vector is of the size 9.
Works just fine for the example of 1n but goes per shape when n > 1. How to do it, the same way, when the size of both vectors changes but they are always going to be populated the same number of times n? These vectors represent lines. I want to know the distances between each individual points in both vectors: so how far is the point v1[0] from the point v2[0] ect.
I have just started my journey with Wolfram Mathematica and I want to implement a simple genetic algorithm. The construction of the data is given and I have to start with such rows/columns.
Here is what I have:
chromosome := RandomSample[CharacterRange["A", "G"], 7]
chromosomeList = Table[chromosome, 7] // MatrixForm
This gives me a matrix, where every row represents a chromosome:
yPos = Flatten[Position[chromosomeList, #], 1] & /# {"A", "B", "C",
"D", "E", "F", "G"};
yPos = yPos[[All, 3 ;; 21 ;; 3]] // Transpose
Now every column represents a letter (From A to G) and every row it's index in every chromosome:
Here is a given efficiency matrix, where very row represents different letter (From A to G) and every column gives the value that should be applied on the particular position:
efficiencyMatrix = {
{34, 31, 20, 27, 24, 24, 18},
{14, 14, 22, 34, 26, 19, 22},
{22, 16, 21, 27, 35, 25, 30},
{17, 21, 24, 16, 31, 22, 20},
{17, 29, 22, 31, 18, 19, 26},
{26, 29, 37, 34, 37, 20, 21},
{30, 28, 37, 28, 29, 23, 19}}
What I want to do is to create a matrix with values that correspond to the letter and it's position. I have done it like that:
values = Transpose[{ efficiencyMatrix[[1, yPos[[1]]]],
efficiencyMatrix[[2, yPos[[2]]]],
efficiencyMatrix[[3, yPos[[3]]]],
efficiencyMatrix[[4, yPos[[4]]]],
efficiencyMatrix[[5, yPos[[5]]]],
efficiencyMatrix[[6, yPos[[6]]]],
efficiencyMatrix[[7, yPos[[7]]]]}]
How can I write it in more elegant way?
You can apply a list of functions to some variable using the function Through, which is helpful when applying Position multiple times. Because Position[patt][expr] == Position[expr, patt], we can do
Through[ (Position /# CharacterRange["A","C"])[{"B", "C", "A"}] ]
to get {3, 1, 2}.
Position can also operate on lists, so we can simplify finding ypos by doing
Transpose#Map[Last, Through[(Position /# characters)[chromosomeList]], {2}]
where characters is the relevant output of CharacterRange.
We can also simplify dealing with ranges of integers by mapping over the Range function, so in total we end up with
characters = CharacterRange["A","G"]
efficiencies = ...
chromosomes = ...
ypos = Transpose#Map[Last, Through[(Position /# characters)[chromosomes]], {2}];
efficiencies[[#, ypos[[#]]]]& /# Range[Length[characters]] //Transpose ]
Having a list as pbRecvBuffer=[112, 1, 0, 32, 225, 1, 0, 15, 55, 56, 52, 49, 57, 54, 57, 57, 56, 51, 55, 57, 56, 53, 49, 225, 2, 0, 9, 48, 54, 55, 51, 54, 50, 48, 54, 52, 0, 0, 0, 144, 0] in hexadecimal.
how can we copy the above items from index 8 to 0xf in to another list.
My work on the above question.
iDataTagLength = ( pbRecvBuffer[index + 2] << 8 ) | pbRecvBuffer[index + 3]
where index = 4
and the resulting "iDataTagLength" i get is 0xf which is 15 in decimal.
PublicData['IDNumber']= pbRecvBuffer[(index + 4 ): iDataTagLength]
copying the above to public data results till "pbRecvBuffer[0Xf]" rather than copying 0XF items.
any help is appreciated and thankful in advance
You need to iterate over the items to copy them to your desired variable. What you're getting here is a list reference. Printing the class will be helpful in future:
print (pbRecvBuffer[(index + 4 ): iDataTagLength]).__class__
This results in <type 'list'> as output.
Try iterating over the content of the list by using (pbRecvBuffer[(index + 4 ): iDataTagLength][x] where x is the index and populate the desired variable.
I am trying to assign values to the Arrival, BurstTime, and IOTime arrays. It worked fine when I didn't have Arrival[9]. However trying to pass multiple ints into the variable doesn't work. I get -86638*** numbers. I have been trying to find an answer for days, No luck.
This is my struct.
struct ReadyQueue
{
//static const int MAX_NUMBER = 10;
int ArrivalTime[10];
int BurstTime[10];
int IOTime[10];
std::string Name;
};
and my variables
P[0].ArrivalTime[10] = 0, 98, 221, 327, 423, 530, 628, 719, 788 ;
P[1].ArrivalTime[8] = 17, 116, 208, 320, 437, 554, 665, 754 ; // P2
P[2].ArrivalTime[7] = 27, 125, 238, 364, 468, 579, 680; // P3
P[3].ArrivalTime[8] = 45, 155, 276, 392, 515, 642, 739, 820 ; // P4
P[4].ArrivalTime[10] = 62, 186, 343, 489, 603, 715, 807, 887, 952, 997; // P5
P[5].ArrivalTime[7] = 67, 174, 262, 348, 446, 566, 654; // P6
P[6].ArrivalTime[9] = 77, 148, 216, 302, 359, 461, 546, 622, 697; // P7
P[7].ArrivalTime[8] = 83, 196, 306, 409, 499, 608, 702, 773 ; // P8
P[8].ArrivalTime[9] = 92, 192, 296, 386, 492, 599, 692, 734, 803; // P9
P[0].BurstTime[8] = 17 , 18, 17, 16, 14, 16, 14, 15, 15;
P[0].IOTime[8] = 24, 73, 31, 27, 33, 43, 64, 19 ;
P[1].BurstTime[8] = 10, 9, 8, 7, 9, 12, 15, 19 ;
P[1].IOTime[7] = 31, 35, 42, 43, 47, 43, 51 ;
P[2].IOTime[6] = 51, 53, 61, 31, 43, 31 ;
P[2].BurstTime[7] = 18, 23, 24, 22, 21, 20, 12 ;
P[3].BurstTime[8] = 17, 19, 20, 17, 15, 12, 15, 14 ;
P[3].IOTime[7] = 42, 55, 54, 52, 67, 72, 66 ;
P[4].BurstTime[10] = 5, 6, 5, 3, 5, 4, 3, 4, 3, 5 ;
P[4].IOTime[9] = 61, 82, 71, 61, 62, 51, 77, 61, 42 ;
P[5].BurstTime[7] = 10, 12, 14, 11, 15, 13, 11 ;
P[5].IOTime[6] = 35, 41, 33, 32, 41, 29 ;
P[6].BurstTime[7] = 6, 7, 5, 4, 5, 7, 8, 6, 5 ;
P[6].IOTime[8] = 18, 21, 19, 16, 29, 21, 22, 24 ;
P[7].BurstTime[8] = 9, 12, 14, 14, 16, 14, 13, 15 ;
P[7].IOTime[7] = 52, 42, 31, 21, 43, 31, 32 ;
P[8].BurstTime[9] = 6, 4, 6, 6, 7, 4, 5, 5, 4 ;
P[8].BurstTime[8] = 35, 41, 33, 32, 41, 29, 16, 22 ;
Thank you very much
I want to clarify what those assignments do, because I see some wrong answers.
Let's see it with an example:
P[0].ArrivalTime[10] = 0, 98, 221, 327, 423, 530, 628, 719, 788 ;
First, that statement is assigning 0 in the eleventh element of the ArrivalTime array and I don't think you wanted to do this due to ArrivalTime[9] is the last element.
Second, the comma operator evaluates the first operand, discard the result, and then evaluates the second operand and returns his value. In the example you could think this evaluation returns 788, but assign operator have more precedence than comma, so, the statement will evaluate like this:
((P[0].ArrivalTime[10] = 0), 98, 221, 327, 423, 530, 628, 719, 788 ;
Change this:
struct ReadyQueue
{
//static const int MAX_NUMBER = 10;
int ArrivalTime[10];
int BurstTime[10];
int IOTime[10];
std::string Name;
};
to this:
struct Item
{
int ArrivalTime;
int BurstTime;
int IOTime;
};
struct Ready_queue
{
string name;
queue<Item> items;
};
where queue is std::queue.
If that doesn't suit your higher level purpose, then something similar that does suit that (unexplained) purpose.
The main point is an inversion of the logical structure, putting related data together.
Do note that e.g. x = 6, 4, 6, 6, 7, 4, 5, 5, 4 ; is parsed as (x = 6), 4, 6, 6, 7, 4, 5, 5, 4 ; and thus is equivalent to just = 6;. The longwinded expression after the assignment is using the comma operator, which evaluates the expressions in ordinary reading order, producing the value of the last one. Due to the parsing also that final value is discarded.
Please note that my answer contained a mistake which I corrected it: equal operator has a higher priority than the comma operator (it might still contain traces of it)
This is not how you assign an array to a variable.
what you are doing is simply:
assign 788 0 to p[0].ArrivalTime[10] //the 11th element of p[0] which is outside the reserved space for the array
because the comma operator what it does is that it evaluates every one from left to right and return the last value: example:
int i=0,j;
j=i++,(i+=5),i; //j=0 and i=6 //because it is in fact (j=i++),(i+=5),i;
j=(i++,(i+=5),i); //j=6 and i=6
what you are trying to do is assign p[0].arrivalTime to an array of 10. You should do it this way:
P[0].ArrivalTime[0] = 0 ;
P[0].ArrivalTime[1] = 98 ;
...
P[0].ArrivalTime[9] = 788 ;
I don't know any method that assign an array to an array variable after declaration
You cannot do assignments to arrays like this in c/c++. You can use a similar syntax with {} for initializing arrays, but it won't work for what you want to do here. You could use memcpy to copy the arrays into the memory locations in the struct.
memcpy( p[0].ArrivalTime,
(const int[9]) {0, 98, 221, 327, 423, 530, 628, 719, 788},
sizeof(int [9])
);
Note that the comma is an operator which evaluates a list of expressions and returns the value of the last expression. This means that
P[0].ArrivalTime[10] = 0, 98, 221, 327, 423, 530, 628, 719, 788 ;
assigns 0 to the value at index 10 of the array named ArrivalTime and ignores the rest of the list.