I am using xmaxima to solve two simultaneous non-linear equations using the 'solve' command.The answer displayed is x=[ans1, ans2,..], y=[ans1,ans2,...], But it is'int getting stored onto the variable 'x' and 'y' .
How do I assign the output to a variable so that I can use the output for further calculations.
The xmaxima code is as below:
A:0.500000000000000$
B:0.709506070053745$
C:0.242527534593605$
D:0.719012140107490$
E: 0.357164044380080$
F:-0.505315948652670$
G:0.181895650945204$
H: 0.300000000000000$
[x,y]=solve([x^2*(A*y^3+B*y-C)-D*x*y^2+E*y^3,A*x^2+(x/y^2)*(H*y+G)+F],[x,y]),numer;
output is:
[x, y] = [[x = 0.0611142802814223, y = 0.167915465898175],
[x = - 6.026109660574413, y = 0.305609155632444],
[x = 0.290917101108745, y = 0.445210848095313],
[x = 0.456144541234576 %i + 1.180400965797426,
y = 0.869595022612534 %i + 0.051360830266336],
[x = 1.180400965797425 - 0.456144541234575 %i,
y = 0.051360830266336 - 0.869595022612534 %i],
[x = 0.0609759975012744 %i - 0.777728688525087,
y = 0.792517145089706 %i - 0.51072855430292],
[x = - 0.0609759975012744 %i - 0.777728688525087,
y = - 0.792517145089706 %i - 0.51072855430292],
[x = 0, y = 0]]
Firstly, note that there is more than one solution, so you have to decide what you want to do with them. One option is the following:
(%i9) solutions: solve([x^2*(A*y^3+B*y-C)-D*x*y^2+E*y^3,A*x^2+(x/y^2)*(H*y+G)+F],[x,y]), numer$
<snipped some info lines from rat>
(%i10) xvals: map(rhs, map(first, solutions));
(%o10) [.06111426947129051, - 6.026109660574413, .2909171173159695,
.4561445354339108 %i + 1.180400961416986,
1.180400961416985 - .4561445354339104 %i,
.06097600174281474 %i - 0.77772869099467,
- .06097600174281463 %i - 0.77772869099467, 0]
(%i11) yvals: map(rhs, map(second, solutions));
(%o11) [.1679154401926679, .3056091599125177, .4452108480953128,
.8695950265919334 %i + .05136082885038127,
.05136082885038127 - .8695950265919334 %i,
0.792517152411182 %i - .5107285531053073,
- 0.792517152411182 %i - .5107285531053073, 0]
Then you can get hold of the x,y pair for a solution via xvals[k] and yvals[k] (where you choose k between 1 and 8).
Related
I have the following cubic polynomial f(x)=x³ - 3 x² + x -5 for which the cubic spline should provide the exact same polynomial assuming the following data:
(-1, -10), (0,-5), (1, -6) with second derivative at the extremes f''(-1)=-12, f''(1)=0 (note that f''(x)=6x-6.)
Here the piece of code that I tried on:
/* polynomial to interpolate and data */
f(x) := x^3 - 3* x^2 + x - 5$
x0:-1$
x1:0$
x2:1$
y0:f(x0)$
y1:f(x1)$
y2:f(x2)$
p:[[x0,y0],[x1,y1],[x2,y2]]$
fpp(x) := diff(f(x),x,2);
fpp0 : at( fpp(x), [x=x0]);
fpp2 : at( fpp(x), [x=x2]);
/* here I call cspline with d1=fpp0 and dn=fpp2 */
load(interpol)$
cspline(p, d1=fpp0, dn=fpp2);
I expected the original polynomial (f(x)=x³ -3 x² + x -5) but I got the result:
(%o40) (-16*x^3-15*x^2+6*x-5)*charfun2(x,-inf,0)+(8*x^3-15*x^2+6*x-5)*charfun2(x,0,inf)
which does not agrees with the original polynomial.
Evenmore. Here is a test on the results provided by Maxima.
Code:
/* verification */
h11(x) := -16*x^3 - 15* x^2 + 6* x - 5;
h22(x) := 8* x^3 - 15*x^2 + 6* x - 5;
h11pp(x) := diff(h11(x), x, 2);
h11pp0: at( h11pp(x), [x=x0]);
h22pp(x) := diff(h22(x), x, 2);
h22pp2 : at(h22pp(x), [x=x2]);
which throws 66 and 18 as the boundary conditions, which should be instead -12 and 0.
Thanks.
It appears you've misinterpreted the arguments d1 and dn for cspline. As the description of cspline says, d1 and dn specify the first derivative for the spline at the endpoints, not the second derivative.
When I use the first derivative of f to specify the values for d1 and dn, I get the expected result:
(%i2) f(x) := x^3 - 3* x^2 + x - 5$
(%i3) [x0, x1, x2]: [-1, 0, 1] $
(%i4) [y0, y1, y2]: map (f, %);
(%o4) [- 10, - 5, - 6]
(%i5) p: [[x0, y0], [x1, y1], [x2, y2]];
(%o5) [[- 1, - 10], [0, - 5], [1, - 6]]
(%i6) load (interpol) $
(%i7) cspline (p, d1 = at(diff(f(x), x), x=x0), dn = at(diff(f(x), x), x=x2));
3 2
(%o7) (x - 3 x + x - 5) charfun2(x, minf, 0)
3 2
+ (x - 3 x + x - 5) charfun2(x, 0, inf)
Can the following code be refactored to be more concise or more clear? I have also attached a picture below to help illustrate what I have in mind.
local playerAreaPos = {
{x = playerPos.x, y = playerPos.y - 1, z = playerPos.z}, -- NORTH
{x = playerPos.x, y = playerPos.y + 1, z = playerPos.z}, -- SOUTH
{x = playerPos.x + 1, y = playerPos.y, z = playerPos.z}, -- EAST
{x = playerPos.x - 1, y = playerPos.y, z = playerPos.z}, -- WEST
{x = playerPos.x - 1, y = playerPos.y + 1, z = playerPos.z}, -- SOUTH-WEST
{x = playerPos.x + 1, y = playerPos.y + 1, z = playerPos.z}, -- SOUTH-EAST
{x = playerPos.x - 1, y = playerPos.y - 1, z = playerPos.z}, -- NORTH-WEST
{x = playerPos.x + 1, y = playerPos.y - 1, z = playerPos.z} -- NORTH-EAST
}
local posTable = {
{x = playerPos.x, y = playerPos.y - 2, z = playerPos.z, dir = "NORTH"},
{x = playerPos.x, y = playerPos.y - 3, z = playerPos.z, dir = "NORTH"},
{x = playerPos.x, y = playerPos.y + 2, z = playerPos.z, dir = "SOUTH"},
{x = playerPos.x, y = playerPos.y + 3, z = playerPos.z, dir = "SOUTH"},
{x = playerPos.x + 2, y = playerPos.y, z = playerPos.z, dir = "EAST"},
{x = playerPos.x + 3, y = playerPos.y, z = playerPos.z, dir = "EAST"},
{x = playerPos.x - 2, y = playerPos.y, z = playerPos.z, dir = "WEST"},
{x = playerPos.x - 3, y = playerPos.y, z = playerPos.z, dir = "WEST"},
{x = playerPos.x - 2, y = playerPos.y - 2, z = playerPos.z, dir = "NORTH_WEST"},
{x = playerPos.x - 3, y = playerPos.y - 3, z = playerPos.z, dir = "NORTH_WEST"},
{x = playerPos.x + 2, y = playerPos.y - 2, z = playerPos.z, dir = "NORTH_EAST"},
{x = playerPos.x + 3, y = playerPos.y - 3, z = playerPos.z, dir = "NORTH_EAST"},
{x = playerPos.x - 2, y = playerPos.y + 2, z = playerPos.z, dir = "SOUTH_WEST"},
{x = playerPos.x - 3, y = playerPos.y + 3, z = playerPos.z, dir = "SOUTH_WEST"},
{x = playerPos.x + 2, y = playerPos.y + 2, z = playerPos.z, dir = "SOUTH_EAST"},
{x = playerPos.x + 3, y = playerPos.y + 3, z = playerPos.z, dir = "SOUTH_EAST"}
}
for i = 1, #posTable do
if targetPos == Position(posTable[i]) then
if posTable[i].dir == "NORTH_EAST" then
print("TELEPORT TO: ", playerAreaPos[8].x, playerAreaPos[8].y)
elseif posTable[i].dir == "NORTH_WEST" then
print("TELEPORT TO: ", playerAreaPos[7].x, playerAreaPos[7].y)
elseif posTable[i].dir == "NORTH" then
print("TELEPORT TO: ", playerAreaPos[1].x, playerAreaPos[1].y)
elseif posTable[i].dir == "SOUTH_WEST" then
print("TELEPORT TO: ", playerAreaPos[5].x, playerAreaPos[5].y)
elseif posTable[i].dir == "SOUTH_EAST" then
print("TELEPORT TO: ", playerAreaPos[6].x, playerAreaPos[6].y)
elseif posTable[i].dir == "SOUTH" then
print("TELEPORT TO: ", playerAreaPos[2].x, playerAreaPos[2].y)
elseif posTable[i].dir == "EAST" then
print("TELEPORT TO: ", playerAreaPos[3].x, playerAreaPos[3].y)
elseif posTable[i].dir == "WEST" then
print("TELEPORT TO: ", playerAreaPos[4].x, playerAreaPos[4].y)
end
end
end
The aim of this function is to teleport enemies from posTable to playerAreaPos while ensuring they teleport within the corresponding line, which means if they are 3 squares north from main character they will be teleported to 1 square north of main character
local enemyPos = {x = 11, y = 22, z = 33}
local playerPos = {x = 10, y = 20, z = 30}
local beam_length = 3
if enemyPos.z == playerPos.z then
local dx = enemyPos.x - playerPos.x
local dy = enemyPos.y - playerPos.y
local ax, ay = math.abs(dx), math.abs(dy)
local len_max, len_min = math.max(ax, ay), math.min(ax, ay)
if len_max >= 2 and len_max <= beam_length and len_min % len_max == 0 then
print("TELEPORT TO: ", playerPos.x + dx / len_max, playerPos.y + dy / len_max)
end
end
There's a many way to implementation your question but I'm going try to use some math and after I'm going do some considerations about them.
Look at the next diagram there's a minimum distance between our hero and enemy when enemy fall into range it'll be teleport to hero's radius and after, foe can not teleport unless our hero throw it far its radius.
When these consideration, I made this implementation
-- returns math functions as local functions
local deg = math.deg
local sin = math.sin
local cos = math.cos
local atan2 = math.atan2
-- returns the distance between two points
local lengthOf = function ( dots )
local dx, dy = dots.x[2]-dots.x[1], dots.y[2]-dots.y[1]
return (dx*dx + dy*dy)^.5
end
-- returns the degrees between two points
-- note: 0 degrees is 'east'
local angleBetweenPoints = function ( dots )
local x, y = dots.x[2]-dots.x[1], dots.y[2]-dots.y[1]
local radian = atan2(x, y)
local angle = deg(radian)
angle = angle < 0 and (360 + angle) or angle
return angle
end
--config your hero
local hero = {}
hero.posX, hero.posY = 0, 0
hero.radius = 10
-- config enemy
local foe = {}
foe.posX, foe.posY = 0, 18
foe.radius = 8
foe.theta = 0
foe.teleported = false
foe.distToHero = 18
foe.points = {}
foe.curDist = 0
-- this part will be a sort like frame
foe.points = {x={hero.posX,foe.posX}, y={hero.posY,foe.posY}}
foe.curDist = lengthOf( foe.points )
if foe.distToHero<=foe.curDist and not foe.teleported then
foe.theta = angleBetweenPoints ( foe.points )
foe.posX = hero.radius*sin( foe.theta ) -- yes it's reverse
foe.posY = hero.radius*cos( foe.theta ) -- yes it's reverse
foe.teleported = true
else
foe.teleported = false -- if enemy is hit far of the hero
end
print(foe.posX,foe.posY)
-- printed output: 0, 10
The previous implementation, require a lot calculation if you put a lot foes on the landscape my suggestion is use C API or Box2D this last use a sensor fixture when a collision occur and is very useful for this sort situations. Currently there's many Lua SDK with these features so you can kickstart.
When I try to do this:
(%i1) declare (z, complex);
(%o1) done
(%i2) eq1: z^3 + 3 * %i * conjugate(z) = 0;
3
(%o2) 3 %i conjugate(z) + z = 0
(%i3) solve(eq1, z);
1/6 5/6 1/3 1/3
(- 1) (3 %i - 3 ) conjugate(z)
(%o3) [z = - -----------------------------------------,
2
1/6 5/6 1/3 1/3
(- 1) (3 %i + 3 ) conjugate(z)
z = -----------------------------------------,
2
1/6 1/3 1/3
z = - (- 1) 3 conjugate(z) ]
conjugates are not simplified. And the solution for z in terms of z isn't very useful. Is there a way to simplify it?
Also, how can I simplify out the (-1)^(1/6) part?
Also, this equation clearly has 0 as its root, but it's not in the solution set, why?
I don't think solve knows anything about conjugate. Try this to solve it with the real and imaginary parts of z as two variables. Like this:
(%i2) declare ([zr, zi], real) $
(%i3) z : zr + %i*zi $
(%i4) eq1: z^3 + 3 * %i * conjugate(z) = 0;
(%o4) (zr+%i*zi)^3+3*%i*(zr-%i*zi) = 0
(%i5) solve (eq1, [zr, zi]);
(%o5) [[zr = %r1,
zi = (sqrt(9*%r1^2-%i)+3*%r1)^(1/3)-%i/(sqrt(9*%r1^2-%i)+3*%r1)^(1/3)
+%i*%r1],
[zr = %r2,
zi = ((sqrt(3)*%i)/2-1/2)*(sqrt(9*%r2^2-%i)+3*%r2)^(1/3)
-(%i*((-(sqrt(3)*%i)/2)-1/2))/(sqrt(9*%r2^2-%i)+3*%r2)^(1/3)
+%i*%r2],
[zr = %r3,
zi = ((-(sqrt(3)*%i)/2)-1/2)*(sqrt(9*%r3^2-%i)+3*%r3)^(1/3)
-(%i*((sqrt(3)*%i)/2-1/2))/(sqrt(9*%r3^2-%i)+3*%r3)^(1/3)+%i*%r3]]
Note the variables%r1, %r2, and %r3 in the solution. These represent arbitrary values.
Certain problem in transport Phenomena is solved using the following code:
T_max, T_0, S, R, k, I, k_e, L, R, E, a = Reals('T_max T_0 S R k I k_e L R E a')
k = a*k_e*T_0
I = k_e*E/L
S = (I**2)/k_e
eq = T_0 + S* R**2/(4*k)
print eq
equations = [
T_max == eq,
]
print "Temperature equations:"
print equations
problem = [
R == 2, L == 5000,
T_0 == 20 + 273,
T_max == 30 + 273, k_e == 1,
a == 2.23*10**(-8), E > 0
]
print "Problem:"
print problem
print "Solution:"
solve(equations + problem)
using this code online we obtain
This output gives the correct answer but there are two issues in the code: a) the expresion named "eq" is not fully simplified and then it is necessary to give an arbitrary value for k_e . My question is: How to simplify the expression "eq" in such way that k_e be eliminated from "eq"?
Other example: To determine the radius of a tube
Code:
def inte(n,a,b):
return (b**(n+1))/(n+1)-(a**(n+1))/(n+1)
P_0, P_1, L, R, mu, q, C = Reals('P_0 P_1 L R mu q C')
k = (P_0 - P_1)/(2*mu*L)
equations = [0 == -k*inte(1,0,R) +C,
q == 2*3.1416*(-(k/2)*inte(3,0,R) + C*inte(1,0,R))]
print "Fluid equations:"
print equations
problem = [
L == 50.02/100, mu == (4.03*10**(-5)),
P_0 == 4.829*10**5, P_1==0,
q == 2.997*10**(-3), R >0
]
print "Problem:"
print problem
print "Solution:"
solve(equations + problem)
Output:
Fluid equations:
[-((P_0 - P_1)/(2·mu·L))·(R2/2 - 0) + C = 0, q =
3927/625·
(-(((P_0 - P_1)/(2·mu·L))/2)·(R4/4 - 0) + C·(R2/2 - 0))]
Problem:
[L = 2501/5000, mu = 403/10000000, P_0 = 482900, P_1 = 0, q = 2997/1000000, R > 0]
Solution:
[R = 0.0007512843?,
q = 2997/1000000,
P_1 = 0,
P_0 = 482900,
mu = 403/10000000,
L = 2501/5000,
C = 3380.3149444289?]
After using the solve command to solve two simultaneous non linear equations, I am getting an array of x and y and I need to access specific elements in this array.
A: 0.500000000000000$
B: 0.709506070053745$
C: 0.242527534593605$
D: 0.719012140107490$
E: 0.357164044380080$
F:-0.505315948652670$
G: 0.181895650945204$
H: 0.300000000000000$
solve([
x^2*(A*y^3+B*y-C)-D*x*y^2+E*y^3,
A*x^2+(x/y^2)*(H*y+G)+F
] ,[x,y]),numer;
Here, x and y contain 8 values each and I need to access say only the 2nd element.
Maxima returns a list of results here (a maxima array is something slightly different). Each element of the list is a pair of equations (x = ... and y = ...). For others reading this, the results look like
[[x = .06111426947129051, y = .1679154401926679],
[x = - 6.026109660574413, y = .3056091599125177],
[x = .2909171173159695, y = .4452108480953128],
[x = .4561445354339108 %i + 1.180400961416986,
y = .8695950265919334 %i + .05136082885038127],
[x = 1.180400961416985 - .4561445354339104 %i,
y = .05136082885038127 - .8695950265919334 %i],
[x = .06097600174281474 %i - 0.77772869099467,
y = 0.792517152411182 %i - .5107285531053073],
[x = - .06097600174281463 %i - 0.77772869099467,
y = - 0.792517152411182 %i - .5107285531053073],
[x = 0, y = 0]]
Now, I'm not sure from your question whether you want just each y coordinate, or whether you want the second solution that solve found. For the second solution, just use [n] to get the n'th thing. So if I stored the list above as the variable solns, I could use
(%i12) solns[2];
(%o12) [x = - 6.026109660574413, y = .3056091599125177]
If you want each y coordinate, you have to map into the list. For example, try this:
(%i14) map(lambda([pair], rhs(second(pair))), solns);
(%o14) [.1679154401926679,
.3056091599125177,
.4452108480953128,
.8695950265919334 %i + .05136082885038127,
.05136082885038127 - .8695950265919334 %i,
0.792517152411182 %i - .5107285531053073,
- 0.792517152411182 %i - .5107285531053073,
0]
(I tidied up the formatting of the output slightly). Or you could equally do
map(rhs, map(second, solns));
which gives exactly the same answer but without needing to write a lambda form.