Setting terms of specific powers in a sympy expression to zero - python

I have a sympy expression of the following form:
a, b = symbols('a b')
expr = a + a/b + a/b**2 + a**2/b**2 + a/b**3
I want to set any terms where the exponent of b is larger than the exponent of a to zero, such that the result is like this:
newexpr = a + a/b + a**2/b**2
How can I achieve this?

I managed to solve this by doing:
import sympy as sp
a, b, c = sp.symbols('a b c')
expr = a + a/b + a/b**2 + a**2/b**2 + a/b**3
newexpr = sp.limit(expr.subs(a/b, c), b, sp.oo).subs(c, a/b)
newexpr
out[1]: a + a/b + a**2/b**2

Here is a short plan for this:
we make the substitution 1/b -> c
we rewrite the resulting expression as a multivariate polynomial in a,c
we decompose the poly into monomials and only keep those terms that have exp_a >= exp_c , and we finish by substituting back c -> 1/b
#!/usr/bin/python3
from sympy import *
a, b = symbols('a b')
expr = a + a/b + a/b**2 + a**2/b**2 + a/b**3
def truncate(e):
c = symbols('c')
e1 = e.subs(S(1)/b,c)
p = 0
for m in poly(e1,a,c).monoms():
exp_a,exp_c = m
if exp_c <= exp_a:
p += a**exp_a * (1/b)**exp_c
return p
truncated_expr = truncate(expr)
print(truncated_expr)
OUTPUT:
a**2/b**2 + a + a/b

Related

simplify (a + b*(c+d)) / (c+d) in sympy

Given an expression like
a + b⋅(c + d)
─────────────
c + d
I would like to use sympy to simplify it to:
a
───── + b
c + d
It works when I substitute (c+d) to e and back:
import sympy as sp
a,b,c,d,e = sp.symbols('a b c d e')
expr = (a + b*(c+d)) / (c+d)
expr = expr.subs({(c+d):e}).simplify().subs({e:c+d})
print( sp.pretty(expr) )
# prints
# a
# ───── + b
# c + d
Why is this? Is there a way to do it without substitution?
Using apart helps simplifying fractions :
expr = sp.apart((a + b*(c + d))/(c + d), a)
Output is:
a
───── + b
c + d

Large Kartusba multiplication is failing. What is possibly going wrong?

I have implemented Karatsuba multiplication in Python.
The code and pseudocode are as follow:
def karatsuba(x, y):
"""
Input: two n-digit positive integers x and y.
Output: the product x·y.
Assumption: n is a power of 2. (NOT assuming this)
if n =1 then // base case
compute x·y in one step and return the result
else
a,b := first and second halves of x
c,d := first and second halves of y
compute p := a + b and q := c + d using grade-school addition
recursively compute ac := a·c, bd := b·d, and pq := p·q
compute adbc := pqacbd using grade-school addition
compute 10n ·ac + 10n/2 ·adbc + bd using grade-school addition and return the result
"""
str_x = str(x)
str_y = str(y)
if len(str_x) == 1 or len(str_y) == 1:
return x*y
else:
n = max(len(str_x), len(str_y))
n_half = int(n / 2)
a, b = x // 10**n_half, x % 10**n_half
c, d = y // 10**n_half, y % 10**n_half
p = a + b
q = c + d
ac = karatsuba(a, c)
bd = karatsuba(b, c)
pq = karatsuba(p, q)
adbc = pq - ac - bd
return 10**(2*n_half) * ac + 10**n_half * adbc + bd
When I do the multiplication of very large numbers, my code is failing.
Here is an example:
>>> a = 3141592653589793238462643383279502884197169399375105820974944592
>>> b = 2718281828459045235360287471352662497757247093699959574966967627
>>> mul_karatsuba = karatsuba(a, b)
>>> mul_builtin = a * b
>>> mul_karatsuba == mul_builtin
False
>>> mul_karatsuba
8945653667798941823160787739573304887842903322205621858854691873536479127635014727457078833467629169552143732979528067839403974
>>> mul_builtin
8539734222673567065463550869546574495034888535765114961879601127067743044893204848617875072216249073013374895871952806582723184
I am not able to find what exactly is wrong with my code. I have coded everything according to mentioned pseudocode.
Can you please help me?

Check equality using conditions sympy

I want to proove that (x/a)^2 + (y/b)^2 + (z/c)^2 == 1, if conditions x/a + y/b + z/c ==1 and a/x + b/y + c/z == 0 are given. I know that, for example, in Maple I can simply write
eq1 := x/a + y/b + z/c = 1;
eq2 := a/x + b/y + c/z = 0;
f := x^2/a^2 + y^2/b^2 + z^2/c^2 = 1;
simplify(lhs(f)-rhs(f), {eq1, eq2});
But I'm struggling to come up with solution using sympy.
Without loss of generality, let x <= x/a, etc...
>>> e1=Eq(x + y + z , 1)
>>> e2=Eq(1/x+1/y+1/z , 0)
>>> e3=Eq(x**2 + y**2 + z**2, 1)
Eq(x**2 + y**2 + z**2, 1)
>>> [e3.subs(i).expand() for i in solve((e1,e2))]
[True, True]
Thus, e3 is true for all values that satisfy e1 and e2

Screening out negatives before taking average

I have this program to read in data, average across a row of three and then average down columns, so far it does all this fine. However I am now trying to go back and have it take out negative data points and I'm having some trouble:
from __future__ import division
import csv
v = open("Pt_2_Test_Data.csv", 'wb') #created file to write output to
A =[]
B = []
with open("test2.xls") as w:
w.next() # skip over header row
for row in w:
(date, time, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
u, LZA, SZA, LAM) = row.split("\t") # split columns into fields
A.append([(float(a) + float(b) + float(c))/3,
(float(d) + float(e) + float(f))/3,
(float(g) + float(h) + float(i))/3,
(float(j) + float(k) + float(l))/3,
(float(m) + float(n) + float(o))/3,
(float(p) + float(q) + float(r))/3,
(float(s) + float(t) + float(u))/3])
def mean(B):
return sum(B) / len(B)
for x in A:
if x > 0:
B.append(x)
print B
C = map(mean, zip(*B))
print C
v.close()
(I'm not worried about writing the data to the file yet, just getting rid of the negatives before the final average is taken.)
I'm not sure this is what you mean, but you can make a change to your mean function like so:
def mean(B):
positives = [b for b in B if b >= 0]
return sum(positives) / len(positives)
This will give you the average of the non-negative members of B. Is this kind of what you were looking for?
In general, that comprehension is one way to get the non-negative members of a list. Another way, which makes more sense to me, is
filter (lambda i: i >=0, some_list)
This seems to be undergoing some deprecation, though.

What's wrong with my Extended Euclidean Algorithm (python)?

My algorithm to find the HCF of two numbers, with displayed justification in the form r = a*aqr + b*bqr, is only partially working, even though I'm pretty sure that I have entered all the correct formulae - basically, it can and will find the HCF, but I am also trying to provide a demonstration of Bezout's Lemma, so I need to display the aforementioned displayed justification. The program:
# twonumbers.py
inp = 0
a = 0
b = 0
mul = 0
s = 1
r = 1
q = 0
res = 0
aqc = 1
bqc = 0
aqd = 0
bqd = 1
aqr = 0
bqr = 0
res = 0
temp = 0
fin_hcf = 0
fin_lcd = 0
seq = []
inp = input('Please enter the first number, "a":\n')
a = inp
inp = input('Please enter the second number, "b":\n')
b = inp
mul = a * b # Will come in handy later!
if a < b:
print 'As you have entered the first number as smaller than the second, the program will swap a and b before proceeding.'
temp = a
a = b
b = temp
else:
print 'As the inputted value a is larger than or equal to b, the program has not swapped the values a and b.'
print 'Thank you. The program will now compute the HCF and simultaneously demonstrate Bezout\'s Lemma.'
print `a`+' = ('+`aqc`+' x '+`a`+') + ('+`bqc`+' x '+`b`+').'
print `b`+' = ('+`aqd`+' x '+`a`+') + ('+`bqd`+' x '+`b`+').'
seq.append(a)
seq.append(b)
c = a
d = b
while r != 0:
if s != 1:
c = seq[s-1]
d = seq[s]
res = divmod(c,d)
q = res[0]
r = res[1]
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
print `r`+' = ('+`aqr`+' x '+`a`+') + ('+`bqr`+' x '+`b`+').'
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
s = s + 1
seq.append(r)
fin_hcf = seq[-2] # Finally, the HCF.
fin_lcd = mul / fin_hcf
print 'Using Euclid\'s Algorithm, we have now found the HCF of '+`a`+' and '+`b`+': it is '+`fin_hcf`+'.'
print 'We can now also find the LCD (LCM) of '+`a`+' and '+`b`+' using the following method:'
print `a`+' x '+`b`+' = '+`mul`+';'
print `mul`+' / '+`fin_hcf`+' (the HCF) = '+`fin_lcd`+'.'
print 'So, to conclude, the HCF of '+`a`+' and '+`b`+' is '+`fin_hcf`+' and the LCD (LCM) of '+`a`+' and '+`b`+' is '+`fin_lcd`+'.'
I would greatly appreciate it if you could help me to find out what is going wrong with this.
Hmm, your program is rather verbose and hence hard to read. For example, you don't need to initialise lots of those variables in the first few lines. And there is no need to assign to the inp variable and then copy that into a and then b. And you don't use the seq list or the s variable at all.
Anyway that's not the problem. There are two bugs. I think that if you had compared the printed intermediate answers to a hand-worked example you should have found the problems.
The first problem is that you have a typo in the second line here:
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
in the second line, aqd should be bqd
The second problem is that in this bit of code
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
you make aqd be aqr and then aqc be aqd. So aqc and aqd end up the same. Whereas you actually want the assignments in the other order:
aqc = aqd
bqc = bqd
aqd = aqr
bqd = bqr
Then the code works. But I would prefer to see it written more like this which is I think a lot clearer. I have left out the prints but I'm sure you can add them back:
a = input('Please enter the first number, "a":\n')
b = input('Please enter the second number, "b":\n')
if a < b:
a,b = b,a
r1,r2 = a,b
s1,s2 = 1,0
t1,t2 = 0,1
while r2 > 0:
q,r = divmod(r1,r2)
r1,r2 = r2,r
s1,s2 = s2,s1 - q * s2
t1,t2 = t2,t1 - q * t2
print r1,s1,t1
Finally, it might be worth looking at a recursive version which expresses the structure of the solution even more clearly, I think.
Hope this helps.
Here is a simple version of Bezout's identity; given a and b, it returns x, y, and g = gcd(a, b):
function bezout(a, b)
if b == 0
return 1, 0, a
else
q, r := divide(a, b)
x, y, g := bezout(b, r)
return y, x - q * y, g
The divide function returns both the quotient and remainder.
The python program that does what you want (please note that extended Euclid algorithm gives only one pair of Bezout coefficients) might be:
import sys
def egcd(a, b):
if a == 0:
return (b, 0, 1)
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def main():
if len(sys.argv) != 3:
's program caluclates LCF, LCM and Bezout identity of two integers
usage %s a b''' % (sys.argv[0], sys.argv[0])
sys.exit(1)
a = int(sys.argv[1])
b = int(sys.argv[2])
g, x, y = egcd(a, b)
print 'HCF =', g
print 'LCM =', a*b/g
print 'Bezout identity: %i * (%i) + %i * (%i) = %i' % (a, x, b, y, g)
main()

Categories

Resources