creating 4D lookup table - c

I need to create fast 4D lookup table according to the following:
1- it will receive 4 input variables (u,v,i,j) each one range from 0 to 15
2- the lookup table returns a precalculated value of 8 bit
how can I implement this 4D lookup table in very fast code in C Language

Just make a 4-dimensional array on the stack. 16^4 bytes is a size that should fit on the stack on most platforms, otherwise make it static or global. It gives the compiler full knowledge about the layout, it is a well known and commonly used language construct, it should optimize well:
uint8_t lookup[16][16][16][16]; // global table about 64KB
int main(int, char **)
{
...
Of course you can make one dimensional array uint8_t lookup[16*16*16*16] and multiply your values lookup[u*16*16*16 + v*16*16 + i*16 + j] but I massively doubt that you will be able to make this more performant than the 4-dim array (where the compiler does this kind of multiplication internally anyway)
Since you are asking about the initialization, here is an example of how to init a 4-dim array. for simplicity it is just [4][4][4][4], so you have to increase that to 16 (16 blocks of 16 rows, of 16 series of 16 numbers.
uint8_t test[4][4][4][4]= {
{ // [0][x][y][z]
{ 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 },
{ 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 },
{ 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 },
{ 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 } },
{ // [1][x][y][z]
{ 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 },
{ 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 },
{ 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 },
{ 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 } },
{ // [2][x][y][z]
{ 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 },
{ 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 },
{ 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 },
{ 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 }, { 3, 3, 3, 3 } },
{ // [3][x][y][z]
{ 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 },
{ 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 },
{ 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 },
{ 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 }, { 4, 4, 4, 4 } }
};

Related

MongoDB - aggregation - How to group, concatenate arrays, sum integer field in a single step

I have a collection called 'session_list' with the following rows.
{"user_id":"test#gmail.com","focus_score":[1, 2, 3, 4],"active_score":[3, 4, 1], "score" : 10}
{"user_id":"abcd#gmail.com","focus_score":[3, 4],"active_score":[3, 4, 1, 7, 7], "score" : 3}
{"user_id":"test#gmail.com","focus_score":[1, 2, 3, 4, 7],"active_score":[3, 9, 2], "score" : 7}
{"user_id":"abcd#gmail.com","focus_score":[5, 7, 8],"active_score":[1, 3, 7], "score" : 4}
How do I group by user_id and consolidate the focus_score array and then active_score array (without having any for loops) ?
Expected result:
{"user_id":"test#gmail.com","focus_score":[1, 2, 3, 4, 1, 2, 3, 4, 7], "active_score":[3, 4, 1, 3, 9, 2], "score_sum" : 17}
{"user_id":"abcd#gmail.com","focus_score":[3, 4, 5, 7, 8], "active_score":[3, 4, 1, 7, 7, 1, 3, 7], "score_sum" : 7}
My code:
db.session_list.aggregate([
{
$group: {
_id:{user_id:'$user_id'},
focus_score:{$push:'$focus_score'}
active_score:{$push:'$active_score'}
score_sum:{$sum:'$score_sum'}
}
}
])
But this does not provide the expected result.
db.collection.aggregate([
{
$group: {
_id: "$user_id",
focus_score: { $push: "$focus_score" },
active_score: { $push: "$active_score" },
score_sum: { $sum: "$score" }
}
},
{
$project: {
_id: 0,
score_sum: 1,
user_id: "$_id",
focus_score: {
$reduce: {
input: "$focus_score",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
},
active_score: {
$reduce: {
input: "$active_score",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
}
}
}
])
mongoplayground

Identify rows of one numpy array that gave rise to another numpy array

I think I'm missing something obvious. Consider the following code:
import numpy as np
a = np.array([[ 0, 2, 0, 5, 4, 6, 2, 4],
[ 3, 4, 0, 1, 0, 7, 4, 6],
[ 2, 6, 3, 5, 2, 5, 5, 8],
[ 0, 1, 0, 8, 0, 5, 8, 10],
[ 7, 9, 2, 7, 0, 6, 7, 2],
[ 0, 1, 4, 9, 0, 7, 9, 9],
[ 0, 6, 7, 5, 6, 2, 4, 13],
[ 0, 1, 1, 4, 1, 3, 2, 3]]
# isolate columns 2,3,6,7
mask = [False,False, True, True,False,False, True, True]
b = a[:,mask]
# determine rows of b having unique elements
s = np.sort(b, axis=1)
c = b[~(s[:,:-1] == s[:,1:]).any(1)]
c looks like:
c = [[ 0, 5, 2, 4],
[ 0, 1, 4, 6],
[ 7, 5, 4, 13],
[ 1, 4, 2, 3]]
QUESTION: How do I 'recover' the rows of a that gave rise to the rows of c?
The output should be like:
d = [[ 0, 2, 0, 5, 4, 6, 2, 4],
[ 3, 4, 0, 1, 0, 7, 4, 6],
[ 0, 6, 7, 5, 6, 2, 4, 13],
[ 0, 1, 1, 4, 1, 3, 2, 3]]

How to get depth of tree of arrays given total num items and max array size?

Given this divide algorithm and sample data:
const data = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 0
]
function divide(data, size) {
const result = []
for (let i = 0; i < data.length; i += size) {
const chunk = data.slice(i, i + size);
result.push(chunk)
}
if (result.length > size) {
return divide(result, size)
}
return result;
}
const result = divide(data, 5);
console.log(result)
How do you calculate the number of levels in the resulting tree? In this case of block size 5, I think there are 3 are 4 levels about, but what is the equation to use so you don't have to compute the actual tree? Basically getDepth(numItems, blockSize)?
Every recursive call reduces the input size by a factor of blocksize.
Starting with your example of 100 items. This is grouped into 20, these 20 are grouped into 4 and the algorithm ends.
The expression that capture this is log with a base of blocksize.
f(n,m) = ceil(log_base_m(n))
The depth of the example tree is
        ceil(log5(99))
In general:
        ceil(logchunksize(datasize-1))

How to get every permutation of elements in an array of arrays

I have an array of arrays in TypeScript. I would like to take action on every permutation of elements between the inner arrays.
Here is an example:
const arrOfArrays = [
[1],
[2, 3, 4],
[5, 6],
[7, 8]
];
recursePermutations(arrOfArrays, permutation => {
console.log(permutation);
});
And when I run this, I would like to have the following output:
[ 1, 2, 5, 7 ]
[ 1, 2, 5, 8 ]
[ 1, 2, 6, 7 ]
[ 1, 2, 6, 8 ]
[ 1, 3, 5, 7 ]
[ 1, 3, 5, 8 ]
[ 1, 3, 6, 7 ]
[ 1, 3, 6, 8 ]
[ 1, 4, 5, 7 ]
[ 1, 4, 5, 8 ]
[ 1, 4, 6, 7 ]
[ 1, 4, 6, 8 ]
It should call the permutation callback with the number of elements as there are non-empty inner arrays.
I see questions regarding how to find all permutations of elements in a fixed number of arrays. But in this case, I don't know how many inner arrays are present.
As I hinted in the question, here is a solution that uses recursion and generics:
function recursePermutations<T>(arrOfArrays: T[][], callback: (permutation: T[]) => void, i: number = 0, previousElements: T[] = []) {
if (i < arrOfArrays.length) {
const currentElements = arrOfArrays[i];
for (var element of currentElements) {
recursePermutations(arrOfArrays, callback, i + 1, previousElements.concat(element));
}
if (currentElements.length < 1) {
recursePermutations(arrOfArrays, callback, i + 1, Array.from(previousElements));
}
}
else if (previousElements.length > 0) {
callback(previousElements);
}
}
It handles the case of the outer array not having any inner arrays by not calling the callback.
It also handles the case of one or more of the inner arrays having zero elements. In that case, it calls the permutation callback with only the number of elements as there are non-empty inner arrays.

How to send midi pitch bend messages correctly in c?

I'm trying to make a custom midi player, to do so I'm using an array that has already memorized correctly the midi messages data like this:
int array[3000][4]={{time,status,data1,data2},{...},...}
when I want my program to send the midi message (so that it can be played) I call this array and do the needed distinctions between noteon/off, pitch-bend and such. At first I thought I was doing the division in two 7 bits variables wrong, because I never worked with this procedure and I just copied the code from another question on stackoverflow, I posted my own question about it (here) and as it turns out the copied code works just fine. And yet the sound output isn't the right one, it barely has any change in pitch and when it has, it is so small I'm not even sure I'm hearing it (it should sound like a half tone bend with a vibrato in the end). So here's the code:
union { unsigned long word; unsigned char data[4]; } message;
int main(int argc, char** argv) {
int midiport; // select which MIDI output port to open
uint16_t bend;
int flag,u; // monitor the status of returning functions
uint16_t mask = 0x007F;
HMIDIOUT device; // MIDI device interface for sending MIDI output
message.data[0] = 0x90;
message.data[1] = 60;
message.data[2] = 100;
message.data[3] = 0; // Unused parameter
// Assign the MIDI output port number (from input or default to 0)
if (!midiOutGetNumDevs()){
printf("non ci sono devices");
}
if (argc < 2) {
midiport = 0;
}
else {
midiport = 0;
}
printf("MIDI output port set to %d.\n", midiport);
// Open the MIDI output port
flag = midiOutOpen(&device, midiport, 0, 0, CALLBACK_NULL);
if (flag != MMSYSERR_NOERROR) {
printf("Error opening MIDI Output.\n");
return 1;
}i = 0;
message.data[0] = 0xC0;
message.data[1] = 25;
message.data[2] = 0;
flag = midiOutShortMsg(device, message.word); //program change to steel guitar
if (flag != MMSYSERR_NOERROR) {
printf("Warning: MIDI Output is not open.\n");
}
while (1){
if (array[i][1] == 1) { //note on
this_works();i++;
}
else if (array[i][1] == 0){//note off
this_also_works();i++;
}
else if (array[i][1] == 2){//pitch bend
while (array[i][1] == 2){
Sleep(10);
message.data[0] = 0xE0;
bend = (uint16_t) array[i][2];
message.data[1] = bend & mask;
message.data[2] = (bend & (mask << 7)) >> 7;
printf("bending %d, %d\n", message.data[1],message.data[2]);
flag = midiOutShortMsg(device, message.word);
if (flag != MMSYSERR_NOERROR) {
printf("Warning: MIDI Output is not open.\n");
}i++;
}
}
}}
here's the pitch-bend array[][] values for a half tone bend with vibrato:
{ 6560, 2, 8192 },
{ 6576, 2, 8320 },
{ 6592, 2, 8448 },
{ 6608, 2, 8704 },
{ 6624, 2, 8832 },
{ 6720, 2, 8832 },
{ 6729, 2, 8832 },
{ 6739, 2, 8832 },
{ 6748, 2, 8832 },
{ 6757, 2, 8832 },
{ 6766, 2, 8832 },
{ 6776, 2, 8704 },
{ 6785, 2, 8704 },
{ 6794, 2, 8704 },
{ 6804, 2, 8704 },
{ 6813, 2, 8704 },
{ 6822, 2, 8832 },
{ 6831, 2, 8832 },
{ 6841, 2, 8832 },
{ 6850, 2, 8832 },
{ 6859, 2, 8832 },
{ 6868, 2, 8832 },
{ 6878, 2, 8832 },
{ 6887, 2, 8832 },
{ 6896, 2, 8832 },
{ 6906, 2, 8832 },
{ 6915, 2, 8832 },
{ 6924, 2, 8960 },
{ 6933, 2, 8960 },
{ 6943, 2, 8960 },
{ 6952, 2, 8960 },
{ 6961, 2, 8960 },
{ 6971, 2, 8832 },
{ 6980, 2, 8832 },
{ 6989, 2, 8832 },
{ 6998, 2, 8832 },
{ 7008, 2, 8832 },
{ 7017, 2, 8832 },
{ 7026, 2, 8832 },
{ 7036, 2, 8960 },
{ 7045, 2, 8960 },
{ 7054, 2, 8960 },
{ 7063, 2, 8960 },
{ 7073, 2, 8960 },
{ 7082, 2, 8960 },
{ 7091, 2, 8960 },
{ 7101, 2, 8960 },
{ 7110, 2, 8960 },
{ 7119, 2, 8960 },
{ 7128, 2, 8960 },
{ 7138, 2, 8960 },
{ 7147, 2, 8960 },
{ 7156, 2, 8832 },
{ 7165, 2, 8832 },
{ 7175, 2, 8832 },
{ 7184, 2, 8704 },
{ 7193, 2, 8704 },
{ 7203, 2, 8704 },
{ 7212, 2, 8704 },
{ 7221, 2, 8704 },
{ 7230, 2, 8704 },
{ 7240, 2, 8704 },
{ 7249, 2, 8704 },
{ 7258, 2, 8704 },
{ 7268, 2, 8704 },
{ 7277, 2, 8704 },
{ 7286, 2, 8704 },
{ 7295, 2, 8704 },
{ 7305, 2, 8832 },
{ 7314, 2, 8832 },
{ 7323, 2, 8832 },
{ 7333, 2, 8960 },
{ 7342, 2, 8960 },
{ 7351, 2, 9088 },
{ 7360, 2, 9088 },
{ 7370, 2, 9088 },
{ 7379, 2, 9088 },
{ 7388, 2, 9088 },
{ 7398, 2, 9088 },
{ 7407, 2, 9088 },
{ 7416, 2, 9088 },
{ 7425, 2, 9088 },
{ 7435, 2, 8960 },
{ 7444, 2, 8960 },
{ 7453, 2, 8832 },
{ 7462, 2, 8832 },
{ 7472, 2, 8832 },
{ 7481, 2, 8704 },
{ 7490, 2, 8704 },
{ 7500, 2, 8576 },
{ 7509, 2, 8576 },
{ 7518, 2, 8576 },
{ 7527, 2, 8576 },
{ 7537, 2, 8576 },
{ 7546, 2, 8576 },
{ 7555, 2, 8576 },
{ 7565, 2, 8576 },
{ 7574, 2, 8576 },
{ 7583, 2, 8704 },
{ 7592, 2, 8704 },
{ 7602, 2, 8832 },
{ 7611, 2, 8832 },
{ 7620, 2, 8832 },
{ 7630, 2, 8832 },
{ 7639, 2, 8832 },
{ 7648, 2, 8832 },
{ 7657, 2, 8832 },
{ 7667, 2, 8832 },
{ 7676, 2, 8832 },
and here's the printf output:
I really don't know what I'm doing wrong, any help will be appreciated.
The message.data[] values are correctly computed; the code does nothing wrong.
The problem is that the bend values do not correspond to a half tone.
The default pitch bend range maps the 0..16383 control values to ±2 halftones; to get a half tone up, the values would have to go up to 12288.

Resources