Halide Func reshape - halide

I want to convert the dimensions of a Halide Func. For example consider the following,
func1(x, y, z) = some operation
I know the range of each dimension of the function. Lets assume they are
x = [0, 3], y = [0, 3], z = [0, 15]
Now if I want to convert the func to 1 dimension, something like this
flatten(z * 16 + y * 4 + x) = func1(x, y, z)
But the above definition is not valid as the function definition does not have a pure Var. Is there anyway I can do this in Halide?

You'll need to express it as a pure function of one variable, e.g.:
flatten(x) = func1(x % 4, (x % 16) / 4, x / 16);
You can simplify away much of this added addressing arithmetic by scheduling flatten appropriately, for example:
// Require the bounds realized to be a multiple of 16.
flatten.align_bounds(x, 16);
// Split the loops at the "critical points" of the addressing arithmetic.
flatten
.unroll(x, 4, TailStrategy::RoundUp)
.split(x, xo, xi, 4, TailStrategy::RoundUp);

Related

List generation via Array in Wolfram Language

I have a code where we first need to generate n + 1 numbers in a range with a given step. However, I don't understand how and why it works:
a = 2;
b = 7;
h = (b-a)/n;
x[0] = a;
Array[x, n+1, 0];
For[i = 0, i < n + 1, i++, x[i] = a + h*i]
My questions are:
Are elements of x automatically generated when accessed? There's no mention of x before the line x[0] = a
Shouldn't index access be like x[[i]]?
What exactly does Array do here? It isn't assigned to anything which confuses me
Try Range[2,10,2] for a range of numbers from 2 to 10 in steps of 2, etc.
Beyond that there some faults in your code, or perhaps in your understanding of Mathematica ...
x[0] = a defines a function called x which, when presented with argument 0 returns a (or a's value since it is previously defined). Mathematica is particular about the bracketing characters used [ and ] enclose function argument lists. Since there is no other definition for the function x (at least not that we can see here) then it will return unevaluated for any argument other than 0.
And you are right, doubled square brackets, ie [[ and ]], are used to enclose index values. x[[2]] would indeed refer to the second element of a list called x. Note that Mathematica indexes from 1 so x[[0]] would produce an error if x existed and was a list.
The expression Array[x, n+1, 0] does return a value, but it is not assigned to any symbol so is lost. And the trailing ; on the line suppresses Mathematica's default behaviour to print the return value of any expression you execute.
Finally, on the issue of the use of For to make lists of values, refer to https://mathematica.stackexchange.com/questions/7924/alternatives-to-procedural-loops-and-iterating-over-lists-in-mathematica. And perhaps ask further Mathematica questions at that site, the real experts on the system are much more likely to be found there.
I suppose I might add ... if you are committed to using Array for some reason ask another question specifically about that. As you might (not) realise, I recommend not using that function to create a list of numbers.
From the docs, Array[f, n, r] generates a list using the index origin r.
On its own Array[x, n + 1, 0] just produces a list of x functions, e.g.
n = 4;
Array[x, n + 1, 0]
{x[0], x[1], x[2], x[3], x[4]}
If x is defined it is applied, e.g.
x[arg_] := arg^2
Array[x, 4 + 1, 0]
{0, 1, 4, 9, 16}
Alternatively, to use x as a function variable the Array can be set like so
Clear[x]
With[{z = Array[x, n + 1, 0]}, z = {m, n, o, p, q}]
{x[0], x[1], x[2], x[3], x[4]}
{m, n, o, p, q}
The OP's code sets function variables of x in the For loop, e.g.
Still with n = 4
a = 2;
b = 7;
h = (b - a)/n;
For[i = 0, i < n + 1, i++, x[i] = a + h*i]
which can be displayed by Array[x, n + 1, 0]
{2, 13/4, 9/2, 23/4, 7}
also x[0] == 2
True
The same could be accomplished thusly
Clear[x]
With[{z = Array[x, n + 1, 0]}, z = Table[a + h*i, {i, 0, 4}]]
{2, 13/4, 9/2, 23/4, 7}
Note also DownValues[x] shows the function definitions
{HoldPattern[x[0]] :> 2,
HoldPattern[x[1]] :> 13/4,
HoldPattern[x[2]] :> 9/2,
HoldPattern[x[3]] :> 23/4,
HoldPattern[x[4]] :> 7}

Matrix derivative doesn't get evaluated

I'm trying to evaluate the partial derivative of the most general 3D rotation matrix, like this:
phi, psi, theta = sympy.symbols("phi, psi, theta")
RMatrixPhi = sympy.Matrix([[cos(phi), sin(phi), 0],
[-sin(phi), cos(phi), 0],
[0, 0, 1]])
RMatrixPsi = sympy.Matrix([[cos(psi), 0, sin(psi)],
[0, 1, 0 ],
[-sin(psi), 0, cos(psi)]])
RMatrixTheta = sympy.Matrix([[1, 0, 0 ],
[0, cos(theta), sin(theta)],
[0, -sin(theta), cos(theta) ]])
RMatrix = RMatrixPhi * RMatrixPsi * RMatrixTheta
D = diff(RMatrix, phi)
However,D is then a sympy.Derivative object, and I cannot get it evaluated,
it's just printed out as Derivative(Matrix(...))
The only way I could get it working is by writing
sympy.Matrix([sympy.diff(r, phi) for r in RMatrix]).reshape(3,3)
but that looks ugly. What's the right way to compute such derivatives?
The Matrix class has a method called diff which, according to the documentation ...
Docstring:
Calculate the derivative of each element in the matrix.
So use
RMatrix.diff(phi)
to perform element-wise derivation.

Why is this recursion terminating (correctly) by rounding down the decimals to integers?

How is n being rounded down to integers in this example so that the terminators are effective??
For example with wonky_coins(5), the next round of recursion should call for wonky_coins(2.5), wonky_coins(1.666) and wonky_coins(1.25), correct???
def wonky_coins(n)
return 1 if n == 0
return 3 if n == 1
return wonky_coins(n / 2) + wonky_coins(n / 3) + wonky_coins(n / 4)
end
wonky_coins(5) == 11
Round 1: [2, 1, 1]
Round 2: [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
Round 3: [[[0, 0, 0], 0, 0], [0, 0, 0], [0, 0, 0]]
Try it with wonky_coins(5.0) !
In short, Ruby interprets / as integer division if both operands are Fixnum type.
If one or other of the operands is a Float then the result will be a Float, with the associated precision (and matching what you expected to see when you looked at the example code in the question).
This can catch you out sometimes. Often when you are generating ratios between values that might be integers, you don't want this behaviour, and may need to use defensive code like this:
ratio = x.to_f / y
which forces at least one of the operands to be Float, just in case.
Also, you will quite often see Float literals specified like this:
ONE_THIRD = 1.0 / 3
because 1 / 3 == 0.

Logarithmically spacing number

I would like to test several values of intensity.
I need them to be spaced logarithmically from 1 to 1000. Yet I just use 1, 10, 100, 1000, but I would like to have more data point, let`s say 10.
How could I find 10 logarithmically spaced number between 1 and 1000 in Mathematica ?
If a is start, c is end and b is number of intervals:
{a, b, c} = {1, 10, 1000};
t = (c/a)^(1/b) // N
a*t^Range[b]
1.99526
{1.99526, 3.98107, 7.94328, 15.8489, 31.6228, 63.0957, 125.893, 251.189, 501.187, 1000.}
I used N just to see better, what do we have.
Here is one way:
In[11]:= base = Block[{a}, a /. NSolve[a^9 == 1000, a][[-1, 1]]]
Out[11]= 2.15443
In[13]:= base^Range[0, 9]
Out[13]= {1., 2.15443, 4.64159, 10., 21.5443, 46.4159, 100.,
215.443,464.159, 1000.}
EDIT
Here is a much shorter and more direct way to get the same:
In[18]:= N[10^Range[0, 3, 1/3]]
Out[18]= {1., 2.15443, 4.64159, 10., 21.5443, 46.4159, 100.,
215.443, 464.159, 1000.}
Solve the equation x ** 9 = 1000 -- then your numbers are: x ** 0, x ** 1, ... x ** 9.
note: where x ** y means x to the power of y

Affine transformation algorithm

Does anyone know of any standard algorithms to determine an affine transformation matrix based upon a set of known points in two co-ordinate systems?
Affine transformations are given by 2x3 matrices. We perform an affine transformation M by taking our 2D input (x y), bumping it up to a 3D vector (x y 1), and then multiplying (on the left) by M.
So if we have three points (x1 y1) (x2 y2) (x3 y3) mapping to (u1 v1) (u2 v2) (u3 v3) then we have
[x1 x2 x3] [u1 u2 u3]
M [y1 y2 y3] = [v1 v2 v3].
[ 1 1 1]
You can get M simply by multiplying on the right by the inverse of
[x1 x2 x3]
[y1 y2 y3]
[ 1 1 1].
A 2x3 matrix multiplied on the right by a 3x3 matrix gives us the 2x3 we want. (You don't actually need the full inverse, but if matrix inverse is available it's easy to use.)
Easily adapted to other dimensions. If you have more than 3 points you may want a least squares best fit. You'll have to ask again for that, but it's a little harder.
I'm not sure how standard it is, but there is a nice formula especially for your case presented in "Beginner's guide to mapping simplexes affinely" and "Workbook on mapping simplexes affinely".
Putting it into code should look something like this (sorry for bad codestyle -- I'm mathematician, not programmer)
import numpy as np
# input data
ins = [[1, 1, 2], [2, 3, 0], [3, 2, -2], [-2, 2, 3]] # <- points
out = [[0, 2, 1], [1, 2, 2], [-2, -1, 6], [4, 1, -3]] # <- mapped to
# calculations
l = len(ins)
B = np.vstack([np.transpose(ins), np.ones(l)])
D = 1.0 / np.linalg.det(B)
entry = lambda r,d: np.linalg.det(np.delete(np.vstack([r, B]), (d+1), axis=0))
M = [[(-1)**i * D * entry(R, i) for i in range(l)] for R in np.transpose(out)]
A, t = np.hsplit(np.array(M), [l-1])
t = np.transpose(t)[0]
# output
print("Affine transformation matrix:\n", A)
print("Affine transformation translation vector:\n", t)
# unittests
print("TESTING:")
for p, P in zip(np.array(ins), np.array(out)):
image_p = np.dot(A, p) + t
result = "[OK]" if np.allclose(image_p, P) else "[ERROR]"
print(p, " mapped to: ", image_p, " ; expected: ", P, result)
This code recovers affine transformation from given points ("ins" transformed to "outs") and tests that it works.

Resources