How do I solve a problem with 3 simultaneous equations? My code shown below is not giving the correct results.
I am attempting to find the maximum area (A) whilst both lengths x and y follow the following property: 2x + y = 960.
I have already looked at the documentation, and it seems that the format of my arguments is correct.
Solve[{2 x + y == 960, A == x*y, D[A] == 0}, {x, y}]
I am unsure of this, however it might be too complex for the Solve function to work, as it is getting the derivative of one of the variables (D[A]).
However I am able to do this question by hand:
Rearrange 1st equation so that y = 960 - 2x
Substitute y into 2nd equation so that A = x(960 - 2x) = 2x^2 + 960x
Get the derivative: 4x + 960 and solve for 4x + 960 = 0
x = 240
Substitute x = 240 into y = 960 - 2x
y = 960 - 2(240) = 960 - 480 = 480
Therefore dimensions are 240 x 480.
I expect the output to be {240, 480}. Thanks :)
EDIT: Here is what I have typed into mathematica:
Clear[x, y, A]
Solve[{2 x + y == 960, A == x*y, D[A, x] == 0}, {x, y}]
OUT: {{x -> 1/2 (480 - Sqrt[2] Sqrt[115200 - A]),
y -> 480 + Sqrt[2] Sqrt[115200 - A]}, {x ->
1/2 (480 + Sqrt[2] Sqrt[115200 - A]),
y -> 480 - Sqrt[2] Sqrt[115200 - A]}
NMaximize[{x*y, 2 x + y == 960}, {x, y}]
OUT: {115200., {x -> 240., y -> 480.}}
Try this
NMaximize[{x*y,2x+y==960},{x,y}]
which is maximizing the area with your constraint expression and that instantly returns x->240, y->480
The difficulty you were having was with the use of D[A] when Mathematica needs to know what variable you are differentiating with respect to.
Perhaps something in this will help you understand what is happening with your derivative.
EDIT
Look at what Solve is going to be given:
Clear[x,y,A];
A == x*y;
D[A, x]
which gives 0. Why is that? You are taking the derivative of A with respect to x, but A has never been assigned any value, you have only declared that A and x*y are equal. Thus
Clear[x,y,A];
{2 x + y == 960, A == x*y, D[A, x] == 0}
is handing
{2*x + y == 960, A == x*y, True}
to Solve and that is perhaps less puzzling when Solve returns something with A in it.
When some function in Mathematica isn't giving you the result that you expect or that makes sense then checking exactly what is being given to that function as arguments is always a good first step.
There are always several ways of doing anything in Mathematica and some of those seem to make no sense at all
Related
Say that x and y are real numbers and y > 0. And say that I want to find for which values of A do (A + x + y > 0) and (A + x - y > 0) always hold, as long as x, y are in the domain.
How would I specify that on Wolfram Alpha? (Note: obviously these equations have no solution, but I just used it as an example.)
Or, if not on Wolfram, what software/website could I use?
I tried to write: solve for A: [input my first equation], y>0
but that didn't work, as it only gave integer solutions for when A, x, and y vary, instead of finding values of A such that it always holds no matter what x, y are.
https://www.wolframalpha.com/input?i=%28A+%2B+x+%2B+y+%3E+0%29+and+%28A+%2B+x+-+y+%3E+0%29+
[x>-A, -A - x<y<A + x]
How do I supply the Matematica Solve function with only references to equations, instead of whole equations?
I.e. let's say I have multiple equations, like:
eq1 = {x + y == 0}
eq2 = {x y - 2 == 0}
However, when I try to put them in Solve, Matematica throws an error:
Solve[{eq1 && eq2}, {x, y}]
Solve::naqs: {x+y==0}&&{-2+x y==0} is not a quantified system of equations and inequalities.
At the same time, re-writing whole equations works
Solve[x + y == 0 && x y - 1 == 0, {x, y}]
{{x->-I,y->I},{x->I,y->-I}}
but can quickly become cumbersome when the number and complexity of equations increases.
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'm not sur if return is the right word to describe it, but that's the best one I could find.)
I am trying to write a small program in prolog that uses the function add to do multiplications. When I run add by itself or even when it is called by the function test the result is "Z = the sum" ex: if I run add(2,3,Z) it will display Z=5.
My problem is that I can't get it to do the same thing when I call mult. The only solution that I found is to use write, but that's not the same thing. I tried a lot of stuff but most of it wasn't even compiling and the rest didn't change anything. Does anybody know how I could make it do that ("Z = the product")? What would be the way to make it do that (return) for a program in general?
Thank You
add(X,Y,Z) :-
Z is X + Y.
mult(X,Y,Z1):-
multiply(X,Y,0).
multiply(_,0,_):-
write(0).
multiply(0,_,Z):-
write(Z).
multiply(X,Y,Z):-
X > 0,
add(Y,Z,Z1),
X1 is X - 1,
multiply(X1,Y,Z1).
multiply(X,Y,Z):-
Y < 0,
X1 is abs(X),
Y1 is abs(Y),
multiply(X1,Y1,Z).
multiply(X,Y,Z):-
Y1 is Y * -1,
add(Y1,Z,Z1),
X1 is X + 1,
multiply(X1,Y,Z1).
test(X,Y,Z1):-
add(X,Y,Z1).
I managed to get it working by adding a 4th parameter. I don't know if it is the right way to do it but it works.
mult(X,Y,Z):-
multiply(X,Y,0,Z).
multiply(_,0,_,Z):-
Z is 0.
multiply(0,_,Z1,Z):-
Z is Z1.
multiply(X,Y,Z1,Z):-
X > 0,
add(Y,Z1,Z2),
X1 is X - 1,
multiply(X1,Y,Z2,Z).
multiply(X,Y,Z1,Z):-
Y < 0,
X1 is abs(X),
Y1 is abs(Y),
multiply(X1,Y1,Z1,Z).
multiply(X,Y,Z1,Z):-
Y1 is Y * -1,
add(Y1,Z1,Z2),
X1 is X + 1,
multiply(X1,Y,Z2,Z).
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()