I have the following
(f.x.f(f x))(y.y+1) = x.(y.y+1)((y.y+1) x)
= x.(y.y+1)(x+1)
= x.x+1+1
I don't understand why is it ok the last transformation?
Shouldn't it be x.(y.y+1)(x+1)= y+1? Why can he get rid of the y
(y . y + 1) is applied to its argument (x + 1), so it's substituted for y to give ((x + 1) + 1).
I don't see how you come up with x . (y . y + 1)(x + 1)= y + 1. y only exists in the scope of the inner function.
Related
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 was looking at the problem and the discussion here: Easy interview question got harder: given numbers 1..100, find the missing number(s)
One of the user provided a solution using following equation.
k1 + k2 = x
k1^2 + k2^2 = y
Substituting provides (x-k2)^2 + k2^2 = y
I am trying to solve this equation further and come up with a C program to solve the problem of finding duplicates.
Inspite of spending lot of time I couldn't solve this equation to get k1 or k2 one side. I always ended up with k1 or k2 on both side of equation.
Any help is appreciated.
Expand the equation
(x - k2)^2 + k2^2 = y
and get
x^2 - 2xk2 + 2k2^2 = y
or
2k2^2 - 2xk2 + x^2 - y = 0
Now use the formula for solving the quadratic equation az^2 + bz + c = 0 which is (-b +/- sqrt(b^2 - 4ac))/2a. Only that in our case z=k2. So
k2 = (2x +/- sqrt(4x^2 - 8(x^2 - y))) / 4
or
k2 = (x +/- sqrt(x^2 - 2(x^2 - y))) / 2
= (x +/- sqrt(2y - x^2)) / 2
and you can put
k2 = (x + sqrt(2y - x^2)) / 2
k1 = (x - sqrt(2y - x^2)) / 2.
I need to draw circles using pixels with these constraints:
the total of pixels across the diameter is an even number,
there is no empty pixels between two circles of radius R and R+1 (R is an integer).
The midpoint algorithm can’t be used but I found out that Eric Andres wrote the exact thing I want. The algorithm can be found in this article under the name of “half integer centered circle”. For those who don’t have access to it, I put the interesting part is at the end of the question.
I encounter difficulties to implement the algorithm. I copied the algorithm in Processing using the Python syntax (for the ease of visualisation):
def half_integer_centered_circle(xc, yc, R):
x = 1
y = R
d = R
while y >= x:
point(xc + x, yc + y)
point(xc + x, yc - y + 1)
point(xc - x + 1, yc + y)
point(xc - x + 1, yc - y + 1)
point(xc + y, yc + x)
point(xc + y, yc - x + 1)
point(xc - y + 1, yc + x)
point(xc - y + 1, yc - x + 1)
if d > x:
d = d - x
x = x + 1
elif d < R + 1 - y:
d = d + y - 1
y = y - 1
else:
d = d + y - x - 1
x = x + 1
y = y - 1
The point() function just plot a pixel at the given coordinates. Please also note that in the article, x is initialised as S, which is strange because there is no S elsewhere (it’s not explained at all), however it is said that the circle begins at (x, y) = (1, R), so I wrote x = 1.
There is the result I get for a radii between 1 pixel and 20 pixels:
As you can see, there are holes between circles and the circle with R = 3 is different from the given example (see below). Also, the circles are not really round compared to what you get with the midpoint algorithm.
How can I get the correct result?
Original Eric Andres’ algorithm:
I don't understand the way in which the algorithm has been presented in that paper. As I read it the else if clause associated with case (b) doesn't have a preceding if. I get the same results as you when transcribing it as written
Looking at the text, rather than the pseudocode, the article seems to be suggesting an algorithm of the following form:
x = 1
y = R
while x is less than or equal to y:
draw(x, y)
# ...
if the pixel to the right has radius between R - 1/2 and R + 1/2:
move one pixel to the right
if the pixel below has radius between R - 1/2 and R + 1/2:
move one pixel down
else:
move one pixel diagonally down and right
Which seems plausible. In python:
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as pp
fg = pp.figure()
ax = fg.add_subplot(111)
def point(x, y, c):
xx = [x - 1/2, x + 1/2, x + 1/2, x - 1/2, x - 1/2 ]
yy = [y - 1/2, y - 1/2, y + 1/2, y + 1/2, y - 1/2 ]
ax.plot(xx, yy, 'k-')
ax.fill_between(xx, yy, color=c, linewidth=0)
def half_integer_centered_circle(R, c):
x = 1
y = R
while y >= x:
point(x, y, c)
point(x, - y + 1, c)
point(- x + 1, y, c)
point(- x + 1, - y + 1, c)
point(y, x, c)
point(y, - x + 1, c)
point(- y + 1, x, c)
point(- y + 1, - x + 1, c)
def test(x, y):
rSqr = x**2 + y**2
return (R - 1/2)**2 < rSqr and rSqr < (R + 1/2)**2
if test(x + 1, y):
x += 1
elif test(x, y - 1):
y -= 1
else:
x += 1
y -= 1
for i in range(1, 5):
half_integer_centered_circle(2*i - 1, 'r')
half_integer_centered_circle(2*i, 'b')
pp.axis('equal')
pp.show()
This seems to work as intended. Note that I removed the circle centre for simplicity. It should be easy enough to add in again.
Edit Realised I could match the radius 3 image if I tweaked the logic a bit.
I have been looking into this matter and observed three issues in the original paper:
The arithmetic circle copied here (Figure 10.a in the paper) is not consistent with the formal definition of the "half integer centered circle". In one case the distance to the center must be between R-1/2 and R+1/2 and in the other between integer values. The consequence is that this specific algorithm, if properly implemented, can never generate the circle of Figure 10.a.
There is a mistake in one of the inequalities of the algorithm pseudo code: the test for case (b) should be d <= (R + 1 - y) instead of d < (R + 1 - y).
All those pixels that satisfy x==y have only 4-fold symmetry (not 8-fold) and are generated twice by the algorithm. Although producing duplicated pixels may not be a problem for a drawing routine, it is not acceptable for the application that I am interested in. However this can be easily fixed by adding a simple check of the x==y condition and skipping the four duplicated pixels.
The python code of the original question includes the inequality error mentioned above and an additional mistake due to missing parenthesis in one of the expressions that should read d = d + (y - x - 1).
The following implementation fixes all this and is compatible with python2 and python3 (no integer division issues in the point() function):
import numpy as np
import matplotlib.pyplot as pp
fg = pp.figure()
ax = fg.add_subplot(111)
def point(x, y, c):
xx = [x - 0.5, x + 0.5, x + 0.5, x - 0.5, x - 0.5 ]
yy = [y - 0.5, y - 0.5, y + 0.5, y + 0.5, y - 0.5 ]
ax.plot(xx, yy, 'k-')
ax.fill_between(xx, yy, color=c, linewidth=0)
def half_integer_centered_circle(R, c):
x = 1
y = R
d = R
while y >= x:
point(x, y, c)
point(x, - y + 1, c)
point(- x + 1, y, c)
point(- x + 1, - y + 1, c)
if y != x:
point(y, x, c)
point(y, - x + 1, c)
point(- y + 1, x, c)
point(- y + 1, - x + 1, c)
if d > x:
d = d - x
x = x + 1
elif d <= R + 1 - y:
d = d + y - 1
y = y - 1
else:
d = d + (y - x - 1)
x = x + 1
y = y - 1
for i in range(1, 5):
half_integer_centered_circle(2*i - 1, 'r')
half_integer_centered_circle(2*i, 'b')
pp.axis('equal')
pp.show()
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] *)
Running into a problem with the following example code for which I hope there is a way around.
Say I have defined a function:
f[x_,y_,z_] = x + y + z + x Log[x] + y Log[y] +z Log[z]
and I was to assign
f[x_,y_,z_] = x + y + z + x Log[x] + y Log[y] +z Log[z]//.x->1//.y->1//.z->0
But rather than have Mathematica replace z with 0 I just want z to be ignored to give the result f[x_,y_] = 2 without having to define a new function. Entering the above code into Mathematica results in an obvious Indeterminate solution
Helping this novice out is greatly appreciated.
Assuming that you want the treatment you describe for z to apply to x and y as well, you could do this:
f[x_, y_, z_] := g[x] + g[y] + g[z]
g[0] = 0;
g[x_] := x + x Log[x]
The helper function g handles the zero case explicitly. These definitions yield results like these:
f[1, E, E^2]
(* 1 + 2*E + 3*E^2 *)
f[1, 1, 1]
(* 3 *)
f[1, 1, 0]
(* 2 *)
f[0, 0, E]
(* 2*E *)
First, function application occurs by calling the function:
f[1,1,1]
Second, why not introduce a new function using limit?
f[x_,y_,z_] := x + y + z + x*Log[x] + y*Log[y] +z*Log[z]
g[x_,y_]:=Limit[f[x,y,z],z->0]
g[1,1]
That should give you the 2, though I'm not in front of mathematica now so i havent checked