Need help implementing if equivalent in Halide
if (current_pixel_mag > threshold) {
mag = 65535;
ed = 0;
}
I have tried Halide Select, but that is equivalent of ternary operator in C, and does not support multiple statements for given condition.
If I got you right, the following code should do the job:
Var x, y;
Func mag = ...;
Func ed = ...;
Expr threshold = ...;
mag(x, y) = select(mag(x, y) > threshold, 65535, mag(x, y));
ed(x, y) = select(mag(x, y) > threshold, 0, ed(x, y));
It's quite inefficient because of update definitions and it's difficult to schedule two functions in a single loop over x, y.
That said you could store multiple statements in a single function, then you could use tuples. There are another select function for tuples called tuple_select:
Func magAndEd;
magAndEd(x, y) = {mag(x, y), ed(x, y)};
magAndEd(x, y) = tuple_select(magAndEd(x, y)[0] > threshold, {65535, 0}, magAndEd(x, y));
Also, it might be possible to fold thresholding into initial definition of the magAndEd.
Related
How can I determine the largest number among three numbers using C++?
I need to simplify this
w=(z>((x>y)?x:y)?z:((x>y)?x:y));
Conditionals do not simplify this.
Starting from C++11, you can do
w = std::max({ x, y, z });
w = std::max(std::max(x, y), z);
is one way.
big = a > b ? (a > c ? a : c) : (b > c ? b : c) ;
Use the simple if condition
int w = x;
if(y > w)
w = y;
if(z > w)
w = z;
Where w is the max among three.
A variant on oisyn's answer (use an initializer list) and Bathesheba's answer (invoke no copies) is to use std::ref to create an initializer list of references, and then use std::max normally:
using std::ref;
w = std::max({ref(x), ref(y), ref(z)});
This is only advantageous if creating a reference is cheaper than creating a copy (and it isn't for primitives like int)
Demo
Given a vector v of length say 30, can auto differentiation tools in say theano or tensorflow be able to take the gradient of something like this:
x = np.random.rand(5, 1)
v = f(x, z)
w = v[0:25].reshape(5, 5)
y = g(np.matmul(w, x) + v[25:30])
minimize ( || y - x || )
Would this even make sense? The way I picture it in my mind I would have to do some multiplications by identity vectors/matrices with trailing 0's to convert v --> w
Slice and reshape operations fit into standard reverse mode AD framework in the same way as any other op. Below is a simple TensorFlow program that is similar to the example you gave (I had to change a couple of things to make dimensions match), and the resulting computation graph for the gradient
def f(x, z):
"""Adds values together, reshapes into vector"""
return tf.reshape(x+z, (5,))
x = tf.Variable(np.random.rand(5, 1))
z = tf.Variable(np.random.rand(5, 1))
v = f(x, z)
w = tf.slice(v, 0, 5)
w = tf.reshape(v, (5, 1))
y = tf.matmul(tf.reshape(w, (5, 1)), tf.transpose(x)) + tf.slice(v, 0, 5)
cost = tf.square(tf.reduce_sum(y-x))
print tf.gradients(cost, [x, z])
Let us take a look at the source code:
#ops.RegisterGradient("Reshape")
def _ReshapeGrad(op, grad):
return [array_ops.reshape(grad, array_ops.shape(op.inputs[0])), None]
This is how tensorflow automatically differentiates.
I am trying to understand Marching Cube Algorithm, so for I think I have understood how triangles are formed and how normals are calculated in each grid. I can see there is a linked list kind of structure that links each grid to another. But when I come across GetDepth(t[m]) which passes each triangles (those triangles of each grid) (t[0],..,..)individually, it returns depth of the node.
The function,
float GetDepth(TRIANGLE t) {
float z;
z = t.p[0].z;
z = t.p[1].z > z? t.p[1].z: z;
z = t.p[2].z > z? t.p[2].z: z;
return z;
}
It looks like its trying to find max z(is it true).
I can see that it compares " > " and then I lost it.
Can any one please explain what is happening here.
It would seem that you are unfamiliar with ? as a ternary operator.
The code you posted is equivalent to the following:
float GetDepth(TRIANGLE t) {
float z;
z = t.p[0].z;
if (t.p[1].z > z) {z = t.p[1].z;} else {z = z;}
if (t.p[2].z > z) {z = t.p[2].z;} else {z = z;}
return z;
}
And yes, this does find the maximum z in the p array.
This is the question:
Write the definition of a function minMax that has five parameters. The first three parameters are integers. The last two are set by the function to the largest and smallest of the values of the first three parameters. The function does not return a value.
The function can be used as follows:
int a = 31, b = 5, c = 19, big, small;
minMax(a, b, c, &big, &small); /* big is now 31; small is now 5 */
This is my code:
void minMax(int x, int y, int z, int* big, int* small)
{
if (x < y && x < z)
*small = x;
else if (y < x && y < z)
*small = y;
else if (z < x && z < y)
*small = z;
if (x > y && x > z)
*big = x;
else if (y > x && y > z)
*big = y;
else if (z > x && z > y)
*big = z;
}
This is the error I'm getting:
Your function did not change the value of small. Make sure you are dereferencing it in your function.
Not sure what's wrong?
Thanks.
I see one immediate problem.
What do you think will happen when you pass the numbers 1, 1 and 7?
Perhaps you may want to consider the use of <= and >= rather than just < and >.
Since that error message looks nothing like any compiler error I've seen before (and the code is valid syntactically), I'd suggest the message is coming from a test harness which probably:
sets the big/small values to numbers other than those being passed in (eg, -9999).
calls the function with test data (eg, 1,1,7).
checks the output varibales to ensure they've been changed to the correct values.
In addition, it's not the most readable code in the world (no offence intended). If you can structure your code in such a way that its intent is clear from a glance (including comments where appropriate), you'll have hordes of future programmers singing your praises and worshiping your name :-)
Something like this shows the intent a little more clearly (IMNSHO) than lots of those else if constructs:
// Populate big/small based on max/min of x, y and z.
void minMax (int x, int y, int z, int *big, int *small) {
// Set by default to x, only change if others are bigger.
*big = x;
if (y > *big) *big = y;
if (z > *big) *big = z;
// Same for small but with reversed comparisons.
*small = x;
if (y < *small) *small = y;
if (z < *small) *small = z;
}
I'm not sure what isn't working. It seems like that would basically work but could be better structured.
Maybe something like this:
void minMax(int x, int y, int z, int* big, int* small)
{
*big = *small = x;
if (y > *big)
*big = y;
if (y < *small)
*small = y;
if (z > *big)
*big = z;
if (z < *small)
*small = z;
}
The error message
Your function did not change the value of small. Make sure you are dereferencing it in your function.
… appears to come from a test harness provided to you by your teacher.
Anyway, it's correct: there are values that you can choose where your function will not assign anything to *small.
For example, with a, b and c the same value, your function will do nothing at all.
Anyway,
for future questions, please provide a complete example program that demonstrates the issue.
So that people will not have to guess and use unreliable telepathy.
Also, the assignment calls for you to implement a function with an ungood signature.
It teaches a Bad Way™ to design functions.
Here is a possible ordinary C++ function signature:
void getMinAndMax( int& smallest, int& largest, int a, int b, int c )
Here is an even better signature with modern C++ technology:
std::pair<int, int> minAndMax( int a, int b, int c )
The absence of a get prefix for the latter function's name is because it is an expression-oriented function, like sin and cos (you wouldn't write getSin or getCos, would you?), while the presence of that prefix for the first function is merely to make the name imperative, to reflect that it's not an expression-oriented function but instead an action-oriended function.
Of course, with C++11 one would let the function accept any number of arguments. Except that as I'm writing this, Visual C++ does not yet support that properly. For example, here is the signature of std::min from the C++11 standard library:
template<class T, class Compare>
T min(initializer_list<T> t, Compare comp);
With C++03 one can do that to some degree by accepting a single container argument, of templated type.
Basically what I want to do is illustrated here:
I start with A and B, then B is conformed to A to create C.
The idea is, given TLBR rectangles A, B, make C
I also need to know if it produces an empty rectangle (B outside of A case).
I tried this but it just isn't doing what I want:
if(clipRect.getLeft() > rect.getLeft())
L = clipRect.getLeft();
else
L = rect.getLeft();
if(clipRect.getRight() < rect.getRight())
R = clipRect.getRight();
else
R = rect.getRight();
if(clipRect.getBottom() > rect.getBottom())
B = clipRect.getBottom();
else
B = rect.getBottom();
if(clipRect.getTop() < rect.getTop())
T = clipRect.getTop();
else
T = rect.getTop();
if(L < R && B < T)
{
clipRect = AguiRectangle(0,0,0,0);
}
else
{
clipRect = AguiRectangle::fromTLBR(T,L,B,R);
}
Thanks
You seem to have a mistake in the final condition checking whether or not the intersection rectangle is empty.
You check L < R && B < T, but it seems like the condition for an empty rectangle should be:
L > R || B < T.
By the way, you can make your code a little simpler and easier to read by using Min and Max functions. You have a lot of this pattern:
if (x < y)
a = x;
else
a = y;
Which can be written simply as
a = Min(x, y);
Edit
Another mistake is that you take the maximum bottom and the minimum top. You should be taking the minimum bottom and the maximum top. (Assuming the rectangles correspond to screen coordinates, where the top actuallly has lower y values.
Logically, these are two different problems. I would first write an is_intersected() function returning an appropriate boolean value.
If the rects do intersect, I would then perform a clip operation that resembled the following pseudocode:
C.left.x = max(A.left.x, B.left.x);
C.right.x = min(A.right.x, B.right.x);
C.left.y = max(A.left.y, B.left.y);
C.right.y = min(A.right.y, B.right.y);