Working with tuples in Halide - c++11

I want to extract one channel in Halide,
Halide::Image<uint8_t> input = load_image("images/rgb.png");
Halide::Var x, y;
Halide::Func green;
green(x,y)= {0, input(x, y, 1), 0};
Halide::Image<uint8_t> output =
green.realize(input.width(), input.height());
gives
Can only cast single-element realizations to buffers or images
it must be simple

It sounds like you want a three channel output in which two are all zero and one is the content of the corresponding channel of the input image. To do this, try:
green(x, y, c) = select(c == 1, input(x, y, 1), 0);
If this is unrolled and bounded, there will be no conditional evaluation in the execution.

I think you want:
green(x, y) = input(x, y, 1);
The thing you have creates a tuple of three output images, two of which are zero.

Related

How would scanline fill algorithm iterate the pixel positions on the following image in an optimised way?

Can anyone explain me how would scanline fill algorithm turn the blue positions into pink? I wanted to know how the iterations will change when an obstruction is observed. Take for example in the third row, the algorithm will easily consider positions 40 to 46 being part of the same group. But how and when will the algorithm iterate the positions 52 to 59?
If possible, please explain from left to right instead of top to bottom. Also mention an optimised method to iterate.
Here is the simple code from wikipedia:
fn fill(x, y):
if not Inside(x, y) then return
let s = new empty stack or queue
add (x, y) to s
while s is not empty:
Remove an (x, y) from s
let lx = x
while Inside(lx - 1, y):
Set(lx - 1, y)
lx = lx - 1
while Inside(x, y):
Set(x, y)
x = x + 1
scan(lx, x - 1, y + 1, s)
scan(lx, x - 1, y - 1, s)
fn scan(lx, rx, y, s):
let added = false
for x in lx .. rx:
if not Inside(x, y):
added = false
else if not added:
Add (x, y) to s
added = true
So "s" is a seed list, basically you put some random point (must be empty) to start off the algorithm.
while s is not empty:
Remove an (x, y) from s
This is a basic loop where we are consuming seeds and when there are no seeds left in "s" then the algorithm is finished.
let lx = x
while Inside(lx - 1, y):
Set(lx - 1, y)
lx = lx - 1
while Inside(x, y):
Set(x, y)
x = x + 1
This is keeping track of the current scan line where lx is the leftmost empty pixel and (x-1) is the rightmost empty pixel (note as this may be confusing, x will be incremented at least once no matter what since all seed points are assured to be inside points). The first loop steps to the left and decrements lx every time it finds an empty pixel. The second loop steps to the right and increments x every time it finds an empty pixel. You can set pixel by pixel as stated, but depending on your library (if drawing lines is cheaper than pixel by pixel editing) you can instead draw a line after passing both of these loops, extending the line between (lx,y) and (x-1,y).
scan(lx, x - 1, y + 1, s)
scan(lx, x - 1, y - 1, s)
This is the "re-seeding" step. Basically the above steps consume seeds, this is the step that produces new seeds based on the results of the seed that was just consumed. "y+1" and "y-1" are single pixel offsets above and below the line that was just drawn, while "lx" and "x-1" describe the line that was just computed this step.
fn scan(lx, rx, y, s):
let added = false
for x in lx .. rx:
if not Inside(x, y):
added = false
else if not added:
Add (x, y) to s
added = true
All that is happening here is that any empty pixels on the scan line (remember this is above and below the last line checked based on arguments) is being added to the seed array to be later tested (this is not incrementing forward and backwards but exhaustively searching every point along the line). Keep in mind that s needs to be a byref argument here since you will be editing it.
One additional note: when I say "empty pixel" I mean two things (though they generally are handled the same in this aglo): 1 the pixel is not an edge point, 2 the pixel has not already be filled by the algo.
As can be seen in the graphic below, any seed can be pulled from the seed list in any order and the algo still functions properly.

Count sum of spaces between first element and a specific element prolog

Basically trying to figure out how you would make a predicate where given two parameters, a list and a number, you would sum up the amount of spaces from the first element to the specific letter.
Example, say 'w' is the letter, given the statement
h1([e,w,b,a,w,w,c], 10)
would return true since 10 = 1+4+5 where 1,4,5 are the distances from element 0 and would return false if not 10.
Heres what I have so far
h2(List, H) :- sum(List,0,H).
sum([],TotalCount,TotalCount):- !.
sum([w|T],CurrentCount, TotalCount) :-
NewCount is CurrentCount + CountSince,
sum(T, NewCount, 0)
sum([_|T], NewCount, 0) :-
CountSince is CountSince + 1,
sum(T, NewCount, CountSince).
As said in the comment, you can solve this problem with three lines of code, using findall/3 and sum_list/2. Here the code:
h2(L,E,V):-
findall(P,nth0(P,L,E),LP),
( LP = [] -> false;
sum_list(LP,V)).
I wrote h2/3 and not h2/2 to make it more modular (i.e. you can pass the element you want to find to the predcate). Since you want false as answer if the element is not in the list, i've added an if statement to check if the list from findall/3 is empty. If it's not, simply sum the elements with sum_list/2.
?- h2([e, w, b, a, w, w, c],f,V).
false
?- h2([e, w, b, a, w, w, c],w,V).
V = 10

How does the power function work

This is My First Logic Programming Language course so this is a really Dumb Question But I cannot for the life of me figure out how does this power predicate work I've tried making a search tree to trace it But I still cannot understand how is it working
mult(_ , 0 ,0).
mult(X , Y, Z):-
Y > 0,
Y1 is Y - 1,
mult(X,Y1,Z1),
Z is Z1 + X.
exp2(_ ,0 , 1).
exp2(X,Y,Z):-
Y > 0,
Y1 is Y - 1,
exp2(X , Y1 , Z1),
mult(X,Z1,Z).
I so far get that I'm going to call the exp2 predicate till I reach the point where the Y is going to be Zero then I'm going to start multiplying from there, but At the last call when it's at exp2(2 , 1 , Z) what is the Z value and how does the predicate work from there?
Thank you very much =)
EDIT: I'm really sorry for the Late reply I had some problems and couldn't access my PC
I'll walk through mult/3 in more detail here, but I'll leave exp2/3 to you as an exercise. It's similar..
As I mentioned in my comment, you want to read a Prolog predicate as a rule.
mult(_ , 0 ,0).
This rule says 0 is the result of multiplying anything (_) by 0. The variable _ is an anonymous variable, meaning it is not only a variable, but you don't care what its value is.
mult(X, Y, Z) :-
This says, Z is the result of multiplying X by Y if....
Y > 0,
Establish that Y is greater than 0.
Y1 is Y - 1,
And that Y1 has the value of Y minus 1.
mult(X, Y1, Z1),
And that Z1 is the result of multiplying X by Y1.
Z is Z1 + X.
And Z is the value of Z1 plus X.
Or reading the mult(X, Y, Z) rule altogether:
Z is the result of multiplying X by Y if Y is greater than 0, and Y1 is Y-1, and Z1 is the result of multiplying X by Y1, and Z is the result of adding Z1 to X.
Now digging a little deeper, you can see this is a recursive definition, as in the multiplication of two numbers is being defined by another multiplication. But what is being multiplied is important. Mathematically, it's using the fact that x * y is equal to x * (y - 1) + x. So it keeps reducing the second multiplicand by 1 and calling itself on the slightly reduced problem. When does this recursive reduction finally end? Well, as shown above, the second rule says Y must be greater than 0. If Y is 0, then the first rule, mult(_, 0, 0) applies and the recursion finally comes back with a 0.
If you are not sure how recursion works or are unfamiliar with it, I highly recommend Googling it to understand it. That is, indeed, a concept that applies to many computer languages. But you need to be careful about learning Prolog via comparison with other languages. Prolog is fundamentally different in it's behavior from procedural/imperative languages like Java, Python, C, C++, etc. It's best to get used to interpreting Prolog rules and facts as I have described above.
Say you want to compute 2^3 as assign result to R.
For that you will call exp2(2, 3, R).
It will recursively call exp2(2, 2, R1) and then exp2(2, 1, R2) and finally exp(2, 0, R3).
At this point exp(_, 0, 1) will match and R3 will be assigned to 1.
Then when call stack unfolds 1 will be multiplied by 2 three times.
In Java this logic would be encoded as follows. Execution would go pretty much the same route.
public static int Exp2(int X, int Y) {
if (Y == 0) { // exp2(_, 0, 1).
return 1;
}
if (Y > 0) { // Y > 0
int Y1 = Y - 1; // Y1 is Y - 1
int Z1 = Exp2(X, Y1); // exp2(X, Y1, Z1);
return X * Z1; // mult(X, Z1, Z).
}
return -1; // this should never happen.
}

Combining multiple halide functions but keeping the dimensions same

I have three Halide functions which have the following output dimensions:
40 x 40 x 64
40 x 40 x 128
40 x 40 x 64
I want to combine them into a single function so that I get a function handle for later use. So for here , the resulting function should have a dimension of
40 x 40 x 256
I am using Halide::select but it results in 4 dimensions
concat(x,y,z,c)=Halide::select(c == 0, func_1(x, y, z), c == 1, func_2(x, y, z), func_3(x, y, z));
Is there any way to produce a merged 3D function?
You may want to return a Pipeline object instead of a Func. Pipelines compile to functions with multiple output parameters, which can be buffers of different shapes.
If you do want a single Func, you want something like:
concat(x, y, z) =
Halide::select(z < 64, func_1(x, y, clamp(z, 0, 63)),
z < 192, func_2(x, y, clamp(z - 64, 0, 127)),
func_3(x, y, clamp(z - 192, 0, 63)));
You can use a Tuple. It's a little complicated by the different size of the 3rd dimension since the members of a Tuple have to be the same size. This complication exists for your 4d solution as well.
result(x, y, z) = Tuple
( func_1(x, y, z)
, func_2(x, y, z * 2 + 0) // Even z
, func_2(x, y, z * 2 + 1) // Odd z
, func_3(x, y, z)
);
If you keep the 4d solution, add unroll(c) to the schedule and the 3 (now 4) functions will be evaluated sequentially inside the innermost loop.
Rather than concatenating the three functions in the third dimension, adding another dimension or using a Tuple is the better way to go, IMHO.
Edit: Besides unroll(c), you'll need reorder(c,x,y,z) to change the loop order.

How to preserve results from Maximize in Mathematica?

I aim to calculate and preserve the results from the maximization of a function with two arguments and one exogenous parameter, when the maximum can not be derived (in closed form) by maximize. For instance, let
f[x_,y_,a_]=Max[0,Min[a-y,1-x-y]
be the objective function where a is positive. The maximization shall take place over [0,1]^2, therefore I set
m[a_]=Maximize[{f[x, y, a], 0 <= x <= 1 && 0 <= y <= 1 && 0 <= a}, {x,y}]
Obviously m can be evaluated at any point a and it is therefore possible to plot the maximizing x by employing
Plot[x /. m[a][[2]], {a, 0.01, 1}]
As I need to do several plots and further derivations containing the optimal solutions x and y (which of course are functions of a), i would like to preserve/save the results from the optimization for further use. Is there an elegant way to do this, or do I have to write some kind of loop to extract the values myself?
Now that I've seen the full text of your comment on my original comment, I suspect that you do understand the differences between Set and SetDelayed well enough. I think what you may be looking for is memoisation, sometimes implemented a bit like this;
f[x_,y_] := f[x,y] = Max[0,Min[a-y,1-x-y]]
When you evaluate, for example f[3,4] for the first time it will evaluate to the entire expression to the right of the :=. The rhs is the assignment f[3,4] = Max[0,Min[a-y,1-x-y]]. Next time you evaluate f[3,4] Mathematica already has a value for it so doesn't need to recompute it, it just recalls it. In this example the stored value would be Max[0,Min[a-4,-6]] of course.
I remain a little uncertain of what you are trying to do so this answer may not be any use to you at all.
Simple approach
results = Table[{x, y, a} /. m[a][[2]], {a, 0.01, 1, .01}]
ListPlot[{#[[3]], #[[1]]} & /# results, Joined -> True]
(The Set = is ok here so long as 'a' is not previosly defined )
If you want to utilise Plot[]s automatic evaluation take a look at Reap[]/Sow[]
{p, data} = Reap[Plot[x /. Sow[m[a]][[2]], {a, 0.01, 1}]];
Show[p]
(this takes a few minutes as the function output is a mess..).
hmm try this again: assuming you want x,y,a and the minimum value:
{p, data} = Reap[Plot[x /. Sow[{a, m[a]}][[2, 2]], {a, 0.01, .1}]];
Show[p]
results = {#[[1]], x /. #[[2, 2]], y /. #[[2, 2]], #[[2, 1]]} & /# data[[1]]
BTW Your function appears to be independent of x over some ranges which is why the plot is a mess..

Resources