Solve for x using python - python-3.x

I came across a problem. One string is taken as input say
input_string = "12345 + x = x * 5 + (1+x)* x + (1+18/100)"
And get output of x using python. I am not able to figure out logic for this.

Here is a complete SymPy example for your input:
from sympy import Symbol, solve, Eq
from sympy.parsing.sympy_parser import parse_expr
input_string = "12345 + x = x * 5 + (1+x)* x + (1+18/100)"
x = Symbol('x', real=True)
lhs = parse_expr(input_string.split('=')[0], local_dict={'x':x})
rhs = parse_expr(input_string.split('=')[1], local_dict={'x':x})
print(lhs, "=", rhs)
sol = solve(Eq(lhs, rhs), x)
print(sol)
print([s.evalf() for s in sol])
This outputs:
x + 12345 = x*(x + 1) + 5*x + 59/50
[-5/2 + 9*sqrt(15247)/10, -9*sqrt(15247)/10 - 5/2]
[108.630868798908, -113.630868798908]
Note that solve() gives a list of solutions. And that SymPy normally does not evaluate fractions and square roots, as it prefers solutions without loss of precision. evalf() evaluates a float value for these expressions.

Well, that example shows a quadratic equation which may have no solutions, one solution, or two solutions. You would have to rearrange the terms symbolically to come to
input_string = "x**2 + 5*x - 12345 + (118/100)"
But that means you need to implement rules for multiplication, addition, subtraction and potentially division. At least for Python there is a library called SymPy which can parse such strings and provide an expression that you can evaluate and even solve.

Related

Wrong result of sympy integration with symbol limits

from sympy import *
s = Symbol("s")
y = Symbol("y")
raw_function = 1/(150.0-0.5*y)
result = integrate(raw_function, (y, 0, s)
The above snippet gets a wrong result: -2.0*log(0.5*s - 150.0) + 10.0212705881925 + 2.0*I*pi,
but we can know the right result is -2.0*log(-0.5*s + 150.0) + 10.0212705881925, so what's wrong?
Are you sure about the correct result, WolframAlpha says it is the same as Sympy here.
Edit:
This function diverges (and the integral too) around y=300, see its plot here (it diverges the same way as 1/x does but offset to y=300)
Meaning that you are constrained to s < 300 to have a well defined (and finite) integrale. In that range, the value of the integral is equal to what sympy is providing you.

Splitting an int64 into two int32, performing math, then re-joining

I am working within constraints of hardware that has 64bit integer limit. Does not support floating point. I am dealing with very large integers that I need to multiply and divide. When multiplying I encounter an overflow of the 64bits. I am prototyping a solution in python. This is what I have in my function:
upper = x >> 32 #x is cast as int64 before being passed to this function
lower = x & 0x00000000FFFFFFFF
temp_upper = upper * y // z #Dividing first is not an option, as this is not the actual equation I am working with. This is just to make sure in my testing I overflow unless I do the splitting.
temp_lower = lower * y // z
return temp_upper << 32 | lower
This works, somewhat, but I end up losing a lot of precision (my result is off by sometimes a few million). From looking at it, it appears that this is happening because of the division. If sufficient enough it shifts the upper to the right. Then when I shift it back into place I have a gap of zeroes.
Unfortunately this topic is very hard to google, since anything with upper/lower brings up results about rounding up/down. And anything about splitting ints returns results about splitting them into a char array. Anything about int arithmetic bring up basic algebra with integer math. Maybe I am just not good at googling. But can you guys give me some pointers on how to do this?
Splitting like this is just a thing I am trying, it doesnt have to be the solution. All I need to be able to do is to temporarily go over 64bit integer limit. The final result will be under 64bit (After the division part). I remember learning in college about splitting it up like this and then doing the math and re-combining. But unfortunately as I said I am having trouble finding anything online on how to do the actual math on it.
Lastly, my numbers are sometimes small. So I cant chop off the right bits. I need the results to basically be equivalent to if I used something like int128 or something.
I suppose a different way to look at this problem is this. Since I have no problem with splitting the int64, we can forget about that part. So then we can pretend that two int64's are being fed to me, one is upper and one is lower. I cant combine them, because they wont fit into a single int64. So I need to divide them first by Z. Combining step is easy. How do I do the division?
Thanks.
As I understand it, you want to perform (x*y)//z.
Your numbers x,y,z all fit on 64bits, except that you need 128 bits for intermediate x*y.
The problem you have is indeed related to division: you have
h * y = qh * z + rh
l * y = ql * z + rl
h * y << 32 + l*y = (qh<<32 + ql) * z + (rh<<32 + rl)
but nothing says that (rh<<32 + rl) < z, and in your case high bits of l*y overlap low bits of h * y, so you get the wrong quotient, off by potentially many units.
What you should do as second operation is rather:
rh<<32 + l * y = ql' * z + rl'
Then get the total quotient qh<<32 + ql'
But of course, you must care to avoid overflow when evaluating left operand...
Since you are splitting only one of the operands of x*y, I'll assume that the intermediate result always fits on 96 bits.
If that is correct, then your problem is to divide a 3 32bits limbs x*y by a 2 32bits limbs z.
It is thus like Burnigel - Ziegler divide and conquer algorithm for division.
The algorithm can be decomposed like this:
obtain the 3 limbs a2,a1,a0 of multiplication x*y by using karatsuba for example
split z into 2 limbs z1,z0
perform the div32( (a2,a1,a0) , (z1,z0) )
here is some pseudo code, only dealing with positive operands, and with no guaranty to be correct, but you get an idea of implementation:
p = 1<<32;
function (a1,a0) = split(a)
a1 = a >> 32;
a0 = a - (a1 * p);
function (a2,a1,a0) = mul22(x,y)
(x1,x0) = split(x) ;
(y1,y0) = split(y) ;
(h1,h0) = split(x1 * y1);
assert(h1 == 0); -- assume that results fits on 96 bits
(l1,l0) = split(x0 * y0);
(m1,m0) = split((x1 - x0) * (y0 - y1)); -- karatsuba trick
a0 = l0;
(carry,a1) = split( l1 + l0 + h0 + m0 );
a2 = l1 + m1 + h0 + carry;
function (q,r) = quorem(a,b)
q = a // b;
r = a - (b * q);
function (q1,q0,r0) = div21(a1,a0,b0)
(q1,r1) = quorem(a1,b0);
(q0,r0) = quorem( r1 * p + a0 , b0 );
(q1,q0) = split( q1 * p + q0 );
function q = div32(a2,a1,a0,b1,b0)
(q,r) = quorem(a2*p+a1,b1*p+b0);
q = q * p;
(a2,a1)=split(r);
if a2<b1
(q1,q0,r)=div21(a2,a1,b1);
assert(q1==0); -- since a2<b1...
else
q0=p-1;
r=(a2-b1)*p+a1+b1;
(d1,d0) = split(q0*b0);
r = (r-d1)*p + a0 - d0;
while(r < 0)
q = q - 1;
r = r + b1*p + b0;
function t=muldiv(x,y,z)
(a2,a1,a0) = mul22(x,y);
(z1,z0) = split(z);
if z1 == 0
(q2,q1,r1)=div21(a2,a1,z0);
assert(q2==0); -- otherwise result will not fit on 64 bits
t = q1*p + ( ( r1*p + a0 )//z0);
else
t = div32(a2,a1,a0,z1,z0);

Create a Recursive Function as Well as a Closed Function Definition

The goal of this assignment is to take the recurrence relation given at the bottom, and then create a recursive function under recFunc(n), as well as a closed function definition underneath nonRecFunc(n). A closed function means our function should solely depend on n, and that its output should
match the recursive function's exactly. Then, find the value for n = 15 and n = 20, and use it as instructed below. You should probably need to use a characteristic equation to solve this problem.
What is the value for nonRecFunc(20) (divided by) nonRecFunc(15), rounded to the nearest integer.
Problem:
Solve the recurrence relation a_n = 12a_n-1 - 32a_n-2 with initial conditions a_0 = 1 and a_1 = 4.
I am confused as to how I should attack this problem and how I can use recursion to solve the issue.
def recFunc(n):
if n == 0:
return 1
elif n == 1:
return 2
else:
return recFunc(n - 1) + 6 * recFunc(n - 2)
def nonRecFunc(n):
return 4/5 * 3 ** n + 1/5 * (-2) ** n
for i in range(0,10):
print(recFunc(i))
print(nonRecFunc(i))
print()
As mentioned in a my comment above, I leave the recursive solution to you.
For the more mathematical question of the non-recursive solution consider this:
you have
x_n = a x_(n-1) + b x_(n-2)
This means that the change of x is more or less proportional to x as x_n and x_(n-1) will be of same order of magnitude. In other words we are looking for a function type giving
df(n)/dn ~ f(n)
This is something exponential. So the above assumption is
x_n = alpha t^n + beta s^n
(later when solving for s and t the motivation for this becomes clear) from the start values we get
alpha + beta = 1
and
alpha t + beta s = 2
The recursion provides
alpha t^n + beta s^n = a ( alpa t^(n-1) + beta s^(n-1) ) + b ( alpa t^(n-2) + beta s^(n-2) )
or
t^2 alpha t^(n-2) + s^2 beta s^(n-2) = a ( t alpa t^(n-2) + s beta s^(n-2) ) + b ( alpa t^(n-2) + beta s^(n-2) )
This equation holds for all n such that you can derive an equation for t and s.
Plugging in the results in the above equations gives you the non-recursive solution.
Try to reproduce it and then go for the actual task.
Cheers.

How did they come up with the equation for calculating module of 2 numbers "a%b = a-b*(a//b)"

if we try different example you can see it satisfy the equation
print(13 % -4)
print(-10 % 9)
the question is where did they get the equation
a%b = b*(a//b)-a from
It is the intuitive way to define a "remainder" operation, and also it's actually in the python documentation, you just have to tweak the equation a littlebit.
The floor division and modulo operators are connected by the following
identity: x == (x//y)*y + (x%y). Floor division and modulo are also
connected with the built-in function divmod(): divmod(x, y) == (x//y,
x%y).
So subtracting (x//y)*y from x == (x//y)*y + (x%y) gives you x%y == x - (x//y)*y.

Sympy Solveset Multi Variable Non-Linear Solutions

I am having a bit of trouble with Sympy's solveset. I am trying to use Sympy to find a solution to an basic circuit analysis question involving three unknown resistors and two equations. I realize that I will have to guess at the value of one of the resistors and then calculate the value of the other two resistors. I am using superposition to solve the circuit.
This is the circuit and superposition I am trying to solve
import sympy
V_outa, V_outb, R_1, R_2, R_3, V_1, V_2 = symbols('V_outa V_outb R_1 R_2 R_3 V_1 V_2')
### Here are a bunch of variable definitions.
R_eq12 = R_2*R_3/(R_2+R_3)
R_eq123 = R_eq12 + R_1
V_outa = V_1 *R_eq12/R_eq123
R_eq13 = R_1*R_3/(R_1+R_3)
R_eq123b = R_2 + R_eq13
V_outb = V_2 * R_eq13/R_eq123b
### Here is my governing equation.
V_out = 0.5* V_outb + (1/6) *V_outa
### Now I can start setting up the equations to solve. This sets the
### coefficient of the V1 term equal to the 1/2 in the governing equation
### and the coefficient of the V2 term equal to 1/6. I have also guessed
### that R_3 is equal to 10 ohms.
eq1 = Eq(1.0/2.0, V_out.coeff(V_2).subs(R_3, 10))
eq2 = Eq(1.0/6.0, V_out.coeff(V_2).subs(R_3, 10))
#### Now when I try to solve eq1 and eq2 with solveset, I get an error.
solveset([eq1, eq2], (R_2, R_3))
And here is the error I get:
ValueError: [Eq(0.500000000000000, 10*R_1/((R_1 + 10)*(10*R_1/(R_1 +
10) + R_2))), Eq(0.166666666666667, 10*R_1/((R_1 + 10)*(10*R_1/(R_1 +
10) + R_2)))] is not a valid SymPy expression
The other thing I don't understand is the set type I get when I try to solve it this way. Could someone also explain what set type this is, and how to make use of it?
expr3 = -1.0/2.0 + V_out.coeff(V_2).subs(R_3, 10)
solveset(expr3, R_2)
A screen shot of the weird set type
Any help would be much appreciated. I know it is a solvable set because Wolfram Alpha had no problems with it.
Thanks!
David

Resources