Get index of first "true" in vector - vector

How do I efficiently calculate the index of the first "true" value in an OpenCL vector:
float4 f = (float4)(1, 2, 3, 4);
int i = firstTrue(f > 2);
In the example I would like to get i=2 because 3 is the first value greater than 2.
I have looked at all functions in http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/ but have found nothing.
Is this such an uncommon operation?
How do I calculate this (on my own) without much branching/code duplication?

I'm not aware of a built-in function that does exactly what you want, but I have some ideas on how you could do it. There might be a simpler solution, but I've only had one cup of coffee so far. The idea is to leverage the "count leading zeros" function "clz". You just need to convert the results of your conditional into bit positions in an integer.
Create a boolean vector with true/false state set by the comparison
Do a dot product of that against an integer vector with pre-defined values that correspond to bit positions.
The first bit set will correspond to the index you're asking for. Use clz() or a bithack to find that bit index.
In code, something like this (untested and might need adjusting):
float4 f = (float4)(1, 2, 3, 4);
int4 greater = (f > 2);
int4 bits = (int4)(8, 4, 2, 1);
int sum = dot(greater, bits); // maybe this needs to use float
int index = clz(sum); // might need offset applied
You'll need to offset or invert the result from clz to get 0,1,2,3 but that's just addition or subtraction.
Working Code
int firstTrue(int4 v) {
return 4 - (clz(0) - clz((v.x & 8) | (v.y & 4) | (v.z & 2) | (v.w & 1));
}

Related

How to convert ints to strings in SML recursively?

I made a very small program which takes an int and converts it into string in SML:
fun int2str i =
if i < 0 then "~" ^ Int.toString (~i)
else Int.toString i;
int2str(~1234) --> "~1234"
int2str(1234) --> "1234"
I have been struggling immensely to accomplish this in a recursive way. Any help? Additionally, I had to take a string and convert it into an int which I finished through stackOverflow help in general, but the '~' screws everything up as well; however this was able to be finished recursively.
I'm not entirely sure why you need to do this recursively since calling Int.toString on any int will produce the desired result (even if it's negative) but you can also do:
fun helper 0 = "" | helper n = helper (Int.div(n, 10)) ^ Int.toString (Int.mod (n, 10));
fun int2str n = if n < 0 then "~" ^ helper(~n) else if n = 0 then "0" else helper(n);
Modding by 10 will get the last digit and integer dividing by 10 will cut off the last digit so this should get you your desired results in a recursive manner.

What does the C++ map() function do

I am currently looking at the following code (which can be found here)
void MPU6050::CalibrateAccel(uint8_t Loops,uint8_t OffsetSaveAddress) {
double kP = 0.15;
double kI = 8;
float x;
x = (100 - map(Loops, 1, 5, 20, 0)) * .01;
kP *= x;
kI *= x;
PID( 0x3B, OffsetSaveAddress, kP, kI, Loops);
}
Specifically I am struggling to understand what the line:
x = (100 - map(Loops, 1, 5, 20, 0)) * .01;
is doing?
The best matching function I can find for map() is here but it doesn't appear to match the integer parameters that are being passed into the function.
Obviously ideally I would run this code but unfortunately I am yet unable to get this to compile.
Have I correctly found the function being invoked and what is the behaviour of this function with the given parameters? I assume this is a map() function similar to any other typical map function in other languages/frameworks such as python, jquery etc.
Could anyone guide me in the right direction?
map defined in math, re-maps a number from one range to another. Syntax is map(value, fromLow, fromHigh, toLow, toHigh)
So, map(Loops, 1, 5, 20, 0)) means the value of variable Loops will be initially searched between (1,5) but result will be between 20 to 0 since it is remapped.

How to use predicate exactly in MiniZinc

New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:
predicate exactly(int: n, array[int] of var int: x, int: v)
"Requires exactly n variables in x to take the value v."
I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.
If i declare my array as
array[1..10,1..30] of var 0..3: s;
how can I use predicate exactly to populate it as I need? Thanks!
Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:
include "globals.mzn";
array[1..10,1..30] of var 0..3: s;
solve satisfy;
constraint
forall(j in 1..30) (
forall(c in 1..3) (
count([s[i,j] | i in 1..10],c) >= 1
)
)
;
output [
if j = 1 then "\n" else " " endif ++
show(s[i,j])
| i in 1..10, j in 1..30
];
You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.
Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .
If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.

How to make recursive nested loops which use loop variables inside?

I need to make a nested loop with an arbitrary depth. Recursive loops seem the right way, but I don't know how to use the loop variables in side the loop. For example, once I specify the depth to 3, it should work like
count = 1
for i=1, Nmax-2
for j=i+1, Nmax-1
for k=j+1,Nmax
function(i,j,k,0,0,0,0....) // a function having Nmax arguments
count += 1
end
end
end
I want to make a subroutine which takes the depth of the loops as an argument.
UPDATE:
I implemented the scheme proposed by Zoltan. I wrote it in python for simplicity.
count = 0;
def f(CurrentDepth, ArgSoFar, MaxDepth, Nmax):
global count;
if CurrentDepth > MaxDepth:
count += 1;
print count, ArgSoFar;
else:
if CurrentDepth == 1:
for i in range(1, Nmax + 2 - MaxDepth):
NewArgs = ArgSoFar;
NewArgs[1-1] = i;
f(2, NewArgs, MaxDepth, Nmax);
else:
for i in range(ArgSoFar[CurrentDepth-1-1] + 1, Nmax + CurrentDepth - MaxDepth +1):
NewArgs = ArgSoFar;
NewArgs[CurrentDepth-1] = i;
f(CurrentDepth + 1, NewArgs, MaxDepth, Nmax);
f(1,[0,0,0,0,0],3,5)
and the results are
1 [1, 2, 3, 0, 0]
2 [1, 2, 4, 0, 0]
3 [1, 2, 5, 0, 0]
4 [1, 3, 4, 0, 0]
5 [1, 3, 5, 0, 0]
6 [1, 4, 5, 0, 0]
7 [2, 3, 4, 0, 0]
8 [2, 3, 5, 0, 0]
9 [2, 4, 5, 0, 0]
10 [3, 4, 5, 0, 0]
There may be a better way to do this, but so far this one works fine. It seems easy to do this in fortran. Thank you so much for your help!!!
Here's one way you could do what you want. This is pseudo-code, I haven't written enough to compile and test it but you should get the picture.
Define a function, let's call it fun1 which takes inter alia an integer array argument, perhaps like this
<type> function fun1(indices, other_arguments)
integer, dimension(:), intent(in) :: indices
...
which you might call like this
fun1([4,5,6],...)
and the interpretation of this is that the function is to use a loop-nest 3 levels deep like this:
do ix = 1,4
do jx = 1,5
do kx = 1,6
...
Of course, you can't write a loop nest whose depth is determined at run-time (not in Fortran anyway) so you would flatten this into a single loop along the lines of
do ix = 1, product(indices)
If you need the values of the individual indices inside the loop you'll need to unflatten the linearised index. Note that all you are doing is writing the code to transform array indices from N-D into 1-D and vice versa; this is what the compiler does for you when you can specify the rank of an array at compile time. If the inner loops aren't to run over the whole range of the indices you'll have to do something more complicated, careful coding required but not difficult.
Depending on what you are actually trying to do this may or may not be either a good or even satisfactory approach. If you are trying to write a function to compute a value at each element in an array whose rank is not known when you write the function then the preceding suggestion is dead flat wrong, in this case you would want to write an elemental function. Update your question if you want further information.
you can define your function to have a List argument, which is initially empty
void f(int num,List argumentsSoFar){
// call f() for num+1..Nmax
for(i = num+1 ; i < Nmax ; i++){
List newArgs=argumentsSoFar.clone();
newArgs.add(i);
f(i,newArgs);
}
if (num+1==Nmax){
// do the work with your argument list...i think you wanted to arrive here ;)
}
}
caveat: the stack should be able to handle Nmax depth function calls
Yet another way to achieve what you desire is based on the answer by High Performance Mark, but can be made more general:
subroutine nestedLoop(indicesIn)
! Input indices, of arbitrary rank
integer,dimension(:),intent(in) :: indicesIn
! Internal indices, here set to length 5 for brevity, but set as many as you'd like
integer,dimension(5) :: indices = 0
integer :: i1,i2,i3,i4,i5
indices(1:size(indicesIn)) = indicesIn
do i1 = 0,indices(1)
do i2 = 0,indices(2)
do i3 = 0,indices(3)
do i4 = 0,indices(4)
do i5 = 0,indices(5)
! Do calculations here:
! myFunc(i1,i2,i3,i4,i5)
enddo
enddo
enddo
enddo
enddo
endsubroutine nestedLoop
You now have nested loops explicitly coded, but these are 1-trip loops unless otherwise desired. Note that if you intend to construct arrays of rank that depends on the nested loop depth, you can go up to rank of 7, or 15 if you have a compiler that supports it (Fortran 2008). You can now try:
call nestedLoop([1])
call nestedLoop([2,3])
call nestedLoop([1,2,3,2,1])
You can modify this routine to your liking and desired applicability, add exception handling etc.
From an OOP approach, each loop could be represented by a "Loop" object - this object would have the ability to be constructed while containing another instance of itself. You could then theoretically nest these as deep as you need to.
Loop1 would execute Loop2 would execute Loop3.. and onwards.

Extracting minimum of vector

I'm extracting the min from a vector.
Say vector = [0, inf, inf, inf];
ExtractSmallest(vector) = 0;
and then vector = [0, 1, inf, inf];
but now, we've already seen 0. Thus,
ExtractSmallest(vector) = 1;
I represent this in my code by doing nodes.erase(nodes.begin() + smallestPosition);
But, I now realize that erasing is very bad. Is there a way to achieve this without erasing the vectors? Just skipping over the ones we've already seen?
Node* CGraph::ExtractSmallest(vector<Node*>& nodes)
{
int size = nodes.size();
if (size == 0) return NULL;
int smallestPosition = 0;
Node* smallest = nodes.at(0);
for (int i=1; i<size; ++i)
{
Node* current = nodes.at(i);
if (current->distanceFromStart <
smallest->distanceFromStart)
{
smallest = current;
smallestPosition = i;
}
}
nodes.erase(nodes.begin() + smallestPosition);
return smallest;
}
Option 1 You can have an additional vector<bool> on which you iterate in parallel. When you find the smallest element, mark that position in the bool vector as true. Whenever you iterate, skip the positions in both vectors that are marked as true.
Option 2 If order is not important, keep the number of elements removed so far. When you find the minimum, swap positions with the first non-excluded element. On a new iteration, start from the first non-excluded element.
Option 3 If order is not important, sort the array. (this takes O(n*log(n))). Removal will now take O(1) - you just exclude the first non-excluded element.
Option 4 If there are no duplicates, you can keep a std::set on the side with all excluded elements to this point. When you iterate, check whether the current element was already excluded or not.

Resources