In Halide, is there a way to split up an input image into 2x2 quartets of pixels and implement a unique computation in each pixel of the quartet?
For example, I want to implement the following computations for each pixel in the quartet:
Upper left: (x + 1, y) + (x - 1, y) + (x, y + 1) + (x, y - 1)
Upper right: (x + 1, y) + (x - 1, y)
Lower left: (x, y + 1) + (x, y - 1)
Lower right: (x - 1, y - 1) + (x + 1, y - 1) + (x - 1, y + 1) + (x + 1, y + 1)
And I want this computational pattern to extend across the entire input image.
There are a number of ways to do this. You can do it perhaps most directly using a select on x%2==0 and y%2==0. Something like:
// Sub-terms
Expr ul = in(x+1,y) + in(x-1,y) + in(x,y+1) + in(x,y-1);
Expr ur = in(x+1,y) + in(x-1,y);
Expr ll = in(x,y+1) + in(x,y-1);
Expr ul = in(x-1,y-1) + in(x+1,y-1) + in(x-1,y+1) + in(x+1,y+1);
Expr ix = x%2==0;
Expr iy = y%2==0;
out(x,y) = select(iy,
select(ix, ul, ur),
select(ix, ll, lr));
(There’s also a multi-condition version of select into which you could pack this.)
If you then unroll the x and y dimensions of out each by 2, you'll get a tight loop over quartets with no control flow:
out.unroll(x,2).unroll(y,2);
This is quite similar to the patterns you see in a demosaicing algorithm, of which you can find one here in the official Halide reference apps. Inspired by that, you may also find it natural to pack your data from 2D into 3D, with the 3rd dimension being the 4 elements of a quartet:
packed(x,y,c) = in(x+c%2, y+c/2);
which you may find easier to work with in some cases.
I am attempting a problem that can be solved with MUC (method of undetermined coefficients).
However, when I use the Solve function, it gives an error.
y[x_] := a x^3 + b x^2 + c x + d
Solve[{y''[x] + 2 y'[x] + y[x] == x^3}, {a, b, c, d}]
[ERROR]:
Solve::svars: Equations may not give solutions for all "solve" variables.
Shouldn't this solve for all variables in the set?
Thank You for your help :)
Looks like some extra methodology is needed for this.
As you stated, a function with the finite family of derivatives for x^3 is
y[x_] := a x^3 + b x^2 + c x + d
Equating coefficients
sol = Solve[Thread[CoefficientList[
y''[x] + 2 y'[x] + y[x], x] == CoefficientList[x^3, x]]]
{{a -> 1, b -> -6, c -> 18, d -> -24}}
Checking the results
FullSimplify[y''[x] + 2 y'[x] + y[x] == x^3 /. sol]
{True}
I'm facing this problem, I want to derivate an expression with respect to a variable depending on another variable (not the actual expressions I'm using, they're way more long and complex):
y := x^2 + x + 1;
z := sqrt[y];
D[z, y]
General::ivar: 1+x+x^2 is not a valid variable.
I saw I can solve the problem if I expand the variables like this
D[sqrt[1 + x + x^2], x]
but for long expressions it doesn't seem viable. Is there a simpler way to solve this problem?
Thank you.
You are not consistent with your notations. If you replace D[z, y] by D[z, x], you will get the desired answer.
y := x^2 + x + 1;
z := Sqrt[y];
D[z, x]
Suppose I have an expression of the form
x^2Coth[y] + 2xyCoth[y] + y^2Coth[y],
this is equal to
(x - y)^2Coth[y].
Is there a way to ask Mathematica to do this collection? That is, something like
Collect[x^2Coth[y] + 2xyCoth[y] + y^2Coth[y], x - y]
giving output (x - y)^2Coth[y] ?
Thanks!
This uses Rojo's solution. There may be a simpler way.
expr = x^2 Coth[y] + 2 x y Coth[y] + y^2 Coth[y];
var = Coth[y];
doThat[expr_, vars_List] := Expand[Simplify[
expr /. Flatten[Solve[# == ToString##, First#Variables##] & /# vars]],
Alternatives ## ToString /# vars] /. Thread[ToString /# vars -> vars];
doThat[expr, {var}]
(* (x + y)^2 Coth[y] *)
Edit
Indeed there is a simpler way:
Collect[expr, var, Factor]
(* (x + y)^2 Coth[y] *)
So lately I have been toying around with how Mathematica's pattern matching and term rewriting might be put to good use in compiler optimizations...trying to highly optimize short blocks of code that are the inner parts of loops. Two common ways to reduce the amount of work it takes to evaluate an expression is to identify sub-expressions that occur more than once and store the result and then use the stored result at subsequent points to save work. Another approach is to use cheaper operations where possible. For instance, my understanding is that taking square roots take more clock cycles than additions and multiplications. To be clear, I am interested in the cost in terms of floating point operations that evaluating the expression would take, not how long it takes Mathematica to evaluate it.
My first thought was that I would tackle the problem developing using Mathematica's simplify function. It is possible to specify a complexity function that compares the relative simplicity of two expressions. I was going to create one using weights for the relevant arithmetic operations and add to this the LeafCount for the expression to account for the assignment operations that are required. That addresses the reduction in strength side, but it is the elimination of common subexpressions that has me tripped up.
I was thinking of adding common subexpression elimination to the possible transformation functions that simplify uses. But for a large expression there could be many possible subexpressions that could be replaced and it won't be possible to know what they are till you see the expression. I have written a function that gives the possible substitutions, but it seems like the transformation function you specify needs to just return a single possible transformation, at least from the examples in the documentation. Any thoughts on how one might get around this limitation? Does anyone have a better idea of how simplify uses transformation functions that might hint at a direction forward?
I imagine that behind the scenes that Simplify is doing some dynamic programming trying different simplifications on different parts of the expressions and returning the one with the lowest complexity score. Would I be better off trying to do this dynamic programming on my own using common algebraic simplifications such as factor and collect?
EDIT: I added the code that generates possible sub-expressions to remove
(*traverses entire expression tree storing each node*)
AllSubExpressions[x_, accum_] := Module[{result, i, len},
len = Length[x];
result = Append[accum, x];
If[LeafCount[x] > 1,
For[i = 1, i <= len, i++,
result = ToSubExpressions2[x[[i]], result];
];
];
Return[Sort[result, LeafCount[#1] > LeafCount[#2] &]]
]
CommonSubExpressions[statements_] := Module[{common, subexpressions},
subexpressions = AllSubExpressions[statements, {}];
(*get the unique set of sub expressions*)
common = DeleteDuplicates[subexpressions];
(*remove constants from the list*)
common = Select[common, LeafCount[#] > 1 &];
(*only keep subexpressions that occur more than once*)
common = Select[common, Count[subexpressions, #] > 1 &];
(*output the list of possible subexpressions to replace with the \
number of occurrences*)
Return[common];
]
Once a common sub-expression is chosen from the list returned by CommonSubExpressions the function that does the replacement is below.
eliminateCSE[statements_, expr_] := Module[{temp},
temp = Unique["r"];
Prepend[ReplaceAll[statements, expr -> temp], temp[expr]]
]
At the risk of this question getting long, I will put a little example code up. I thought a decent expression to try to optimize would be the classical Runge-Kutta method for solving differential equations.
Input:
nextY=statements[y + 1/6 h (f[t, n] + 2 f[0.5 h + t, y + 0.5 h f[t, n]] +
2 f[0.5 h + t, y + 0.5 h f[0.5 h + t, y + 0.5 h f[t, n]]] +
f[h + t,
y + h f[0.5 h + t, y + 0.5 h f[0.5 h + t, y + 0.5 h f[t, n]]]])];
possibleTransformations=CommonSubExpressions[nextY]
transformed=eliminateCSE[nextY, First[possibleTransformations]]
Output:
{f[0.5 h + t, y + 0.5 h f[0.5 h + t, y + 0.5 h f[t, n]]],
y + 0.5 h f[0.5 h + t, y + 0.5 h f[t, n]],
0.5 h f[0.5 h + t, y + 0.5 h f[t, n]],
f[0.5 h + t, y + 0.5 h f[t, n]], y + 0.5 h f[t, n], 0.5 h f[t, n],
0.5 h + t, f[t, n], 0.5 h}
statements[r1[f[0.5 h + t, y + 0.5 h f[0.5 h + t, y + 0.5 h f[t, n]]]],
y + 1/6 h (2 r1 + f[t, n] + 2 f[0.5 h + t, y + 0.5 h f[t, n]] +
f[h + t, h r1 + y])]
Finally, the code to judge the relative cost of different expressions is below. The weights are conceptual at this point as that is still an area I am researching.
Input:
cost[e_] :=
Total[MapThread[
Count[e, #1, Infinity, Heads -> True]*#2 &, {{Plus, Times, Sqrt,
f}, {1, 2, 5, 10}}]]
cost[transformed]
Output:
100
There are also some routines here implemented here by this author: http://stoney.sb.org/wordpress/2009/06/converting-symbolic-mathematica-expressions-to-c-code/
I packaged it into a *.M file and have fixed a bug (if the expression has no repeated subexpressions the it dies), and I am trying to find the author's contact info to see if I can upload his modified code to pastebin or wherever.
EDIT: I have received permission from the author to upload it and have pasted it here: http://pastebin.com/fjYiR0B3
To identify repeating subexpressions, you could use something like this
(*helper functions to add Dictionary-like functionality*)
index[downvalue_,
dict_] := (downvalue[[1]] /. HoldPattern[dict[x_]] -> x) //
ReleaseHold;
value[downvalue_] := downvalue[[-1]];
indices[dict_] :=
Map[#[[1]] /. {HoldPattern[dict[x_]] -> x} &, DownValues[dict]] //
ReleaseHold;
values[dict_] := Map[#[[-1]] &, DownValues[dict]];
items[dict_] := Map[{index[#, dict], value[#]} &, DownValues[dict]];
indexQ[dict_, index_] :=
If[MatchQ[dict[index], HoldPattern[dict[index]]], False, True];
(*count number of times each sub-expressions occurs *)
expr = Cos[x + Cos[Cos[x] + Sin[x]]] + Cos[Cos[x] + Sin[x]];
Map[(counts[#] = If[indexQ[counts, #], counts[#] + 1, 1]; #) &, expr,
Infinity];
items[counts] // Column
I tried to mimic the dictionary compression function appears on this blog: https://writings.stephenwolfram.com/2018/11/logic-explainability-and-the-future-of-understanding/
Here is what I made:
DictionaryCompress[expr_, count_, size_, func_] := Module[
{t, s, rule, rule1, rule2},
t = Tally#Level[expr, Depth[expr]];
s = Sort[
Select[{First##, Last##, Depth[First##]} & /#
t, (#[[2]] > count && #[[3]] > size) &], #1[[2]]*#1[[3]] < #2[[
2]]*#2[[2]] &];
rule = MapIndexed[First[#1] -> func ## #2 &, s];
rule = (# //. Cases[rule, Except[#]]) & /# rule;
rule1 = Select[rule, ! FreeQ[#, Plus] &];
rule2 = Complement[rule, rule1];
rule = rule1 //. (Reverse /# rule2);
rule = rule /. MapIndexed[ Last[#1] -> func ## #2 &, rule];
{
expr //. rule,
Reverse /# rule
}
];
poly = Sum[Subscript[c, k] x^k, {k, 0, 4}];
sol = Solve[poly == 0, x];
expr = x /. sol;
Column[{Column[
MapIndexed[
Style[TraditionalForm[Subscript[x, First[#2]] == #], 20] &, #[[
1]]], Spacings -> 1],
Column[Style[#, 20] & /# #[[2]], Spacings -> 1, Frame -> All]
}] &#DictionaryCompress[expr, 1, 1,
Framed[#, Background -> LightYellow] &]