Python integrals - python

I'm trying to solve the integral of (2**(1/2)*y**(1/2)/2)**2 from 0 to 5 (also shown here). I've been using
func = lambda y: ( 2**(1/2) * y**(1/2)/2 )**2 and a == 0 and b == 5
from scipy import integrate
integrate.quad(func, a b)
For some reason, I keep getting the value 1.25, while wolfram says it should be 6.25? I can't seem to put my finger on the error.
p.s. sorry for the error katrie, i forgot that python uses and not && for logical AND
SOLVED:
this was a silly int/float error. thank you everyone.

Well, let me write your function in normal mathematical notation (I can't think in Python). I don't like **, as it gets confusing:
(2**(1/2)*y**(1/2)/2)**2 =>
(2^(1/2) * (1/2) * y^(1/2))^2 =>
2 * (1/4) * y =>
y / 2
So to integrate, antidifferentiate (I'm just thinking aloud):
antidifferentiate(y / 2) = y^2 / 4
Therefore
integral('y / 2', 0, 5) =
5^2 / 4 - 0^2 / 4 =
25 / 4 =
6.25
Right. Have you tried replacing 1/2 with 0.5? It could be interpreted as the quotient of two integers, which is rounded up.
Try this (as the others have suggested):
func = lambda y: (2**(0.5) * y**(0.5) / 2.0)**2.0 & a == 0 & b == 5
from scipy import integrate
integrate.quad(func, a b) # What's 'a b'? Maybe 'a, b' would work?
Good luck!

The problem is that Python sees (1/2) and evaluates it with integer division, yielding zero.

Well what's the value supposed to be? Also, you should put more parenthesis in your equation. I have no idea what (2**(1/2)*y**(1/2)/2)**2 gets parsed out to be.

Related

Anyway to get rid of `math.floor` for positive odd integers with `sympy.simplify`?

I'm trying to simplify some expressions of positive odd integers with sympy. But sympy refuses to expand floor, making the simplification hard to proceed.
To be specific, x is a positive odd integer (actually in my particular use case, the constraint is even stricter. But sympy can only do odd and positive, which is fine). x // 2 should be always equal to (x - 1) / 2. Example code here:
from sympy import Symbol, simplify
x = Symbol('x', odd=True, positive=True)
expr = x // 2 - (x - 1) / 2
print(simplify(expr))
prints -x/2 + floor(x/2) + 1/2. Ideally it should print 0.
What I've tried so far:
Simplify (x - 1) // 2 - (x - 1) / 2. Turns out to be 0.
Multiply the whole thing by 2: 2 * (x // 2 - (x - 1) / 2). Gives me: -x + 2*floor(x/2) + 1.
Try to put more weights on the FLOOR op by customizing the measure. No luck.
Use sympy.core.evaluate(False) context when creating the expression. Nuh.
Tune other parameters like ratio, rational, and play with other function like expand, factor, collect. Doesn't work either.
EDIT: Wolfram alpha can do this.
I tried to look like the assumptions of x along with some expressions. It surprises me that (x - 1) / 2).is_integer returns None, which means unknown.
I'm running out of clues. I'm even looking for alternativese of sympy. Any ideas guys?
I fail to see why sympy can't simplify that.
But, on another hand, I've discovered the existence of odd parameter just now, with your question.
What I would have done, without the knowledge of odd is
k = Symbol('k', positive=True, integer=True)
x = 2*k-1
expr = x // 2 - (x - 1) / 2
Then, expr is 0, without even the need to simplify.
So, can't say why you way doesn't work (and why that odd parameter exists if it is not used correctly to guess that x-1 is even, and therefore (x-1)/2 integer). But, in the meantime, my way of defining an odd integer x works.
There is some reluctance to make too much automatic in SymPy, but this seems like a case that could be addressed (since (x-1)/2 is simpler than floor(x/2). Until then, however, you can run a replacement on your expression which makes this transformation for you.
Let's define a preferred version of floor:
def _floor(x):
n, d = x.as_numer_denom()
if d == 2:
if n.is_odd:
return (n - 1)/2
if n.is_even:
return n/2
return floor(x)
When you have an expression with floor that you want to evaluate, replace floor with _floor:
>>> x = Symbol('x', odd=True)
>>> eq=x // 2 - (x - 1) / 2
>>> eq.replace(floor, _floor)
0

Why print(5 ** 2 ** 0 ** 1) = 5 in Python?

Can somebody explain me why Why print(5 ** 2 ** 0 ** 1) = 5 in Python?
I am trying to learn the language and somehow I am not quite sure how this math is done.
Thank you in advance.
Because, like many languages, the exponentiation operator binds right-to-left:
5 ** 2 ** (0 ** 1)
==
5 ** (2 ** 0)
==
5 ** 1
==
5
Exponentiation is right-associative, so your expression is the same as
5 ** (2 ** (0 ** 1))
== 5 ** (2 ** 0)
== 5 ** 1
== 5
where any integer raised to the zeroth power is 1 by definition.
Others have already pointed this out already, but I just wanted to mention the documentation. You can see this by typing help("OPERATORS") in your repl. There you will spot somewhere at the top:
Operators in the same box group left to right (except for exponentiation, which groups from right to left).
You are right to be surprised though, this seems like a very odd decision to me. In other languages, e.g. octave, 5 ^ 2 ^ 0 ^ 1 == 1 as you'd expect. Oddly enough, both Julia and R agree with python on this.
EDIT: On second thought, I suppose making exponentiation right-associative makes sense too; you would expect
to mean 5^8 rather than 25^3 ...
Incidentally, here's another trap. How much is: 5 * -1 ** 2 ? Is it 5 or -5?
See help("**") to see why it is what it is. (incidentally, this is how octave, R, and julia treat this case too).
The moral of the story is: always group when there is potential for ambiguity. Or at least check the precedence is what you think it is before ungrouping.
** is exponentiation.
0 raised to the power of 1 is 0. So, we could re-write the statement as print(5**2**0) without changing the result.
2 raised to the power of 0 is 1. So, we can re-write the statement as print(5**1) without changing the result.
5 raised to the power of 1 is 5. So, we can rewrite the statement as print(5) without changing the result.

Basic operation giving different results in Python

I was playing around with few basic operations in Python 3 and came across this
Code 1:
a = 6
b = 3
a = a / 2 * b
print(a)
Output is 9.0
In one of the trainings I have seen that
a = a / 2
can be written as
a /= 2
So I re-wrote my above code as below
Code 2:
a = 6
b = 3
a /= 2 * b
print(a)
But now the output is 1.0.
I was expecting 9.0 as output. Can someone help me understand why code behaves this way?
In the case of a /= 2 * b, you saying that a will be divided by expression after /=.
In other words, your expression could be rewritten as a = a / (2 * b) where a = 6, b = 3
in
a /= 2 * b
the 2 * b is carried out first so if b == 3 it can be rewritten as:
a /= 6
That's because they perform operations in different order.
The first of block of code divides a (6) by 2 and then multiplies that result by b (3)
E.g. (6 / 2) * 3 = 9
However the second block of code does the following:
6 / (2 * 3) = 1
Note, that
a /= 2 * b
is basically
a = a / (2 * b)
The previous code is different. It's not like the above (look at the parentheses)
a = a / 2 * b
This is different than
a = a / (2 * b)
Because the first code interpret it as division and then multiply, while the second code interpret it as multiply (bottom) and then division.
as you can see in the documentatiopn on operator precedence * and / have the same precedence. two operations with the same precedence are executed from left to right:
Operators in the same box group left to right
so your first example is evaluated as
(a / 2) * b
the second as
a / (2 * b)
regarding your comment
a = a / 2 and a /= 2 are always equivalent, right?
for the built-in python numbers you are right.
for your own classes you can make the operations differ. if a is an insance of a custom class a/x will call __truediv__(self, other) while a/=x will call __itruediv__(self, other) as described in the data model.
I'm surprised none of the other answers mention this, but the reason doesn't have anything to do with math, order of operations or implicit parentheses.
x /= y is just another way of saying x.__itruediv__(y). Your second example is not equivalent to your first example, because parameters are evaluated before being passed in to a function call. So, a /= 2 * b is equivalent to a.__itruediv__(2 * b), and naturally, the expression 2 * b must be evaluated before being passed in to __itruediv__.

Python sympy - simplify nonzero factors from an equation

I am using the sympy library for python3, and I am handling equations, such as the following one:
a, b = symbols('a b', positive = True)
my_equation = Eq((2 * a + b) * (a - b) / 2, 0)
my_equations gets printed exactly as I have defined it ((2 * a + b) * (a - b) / 2 == 0, that is), and I am unable to reduce it even using simplify or similar functions.
What I am trying to achieve is simplifying the nonzero factors from the equation (2 * a + b and 1 / 2); ideally, I'd want to be able to simplify a - b as well, if I am sure that a != b.
Is there any way I can reach this goal?
The point is that simplify() is not capable (yet) of complex reasoning about assumptions. I tested it on Wolfram Mathematica's simplify, and it works. It looks like it's a missing feature in SymPy.
Anyway, I propose a function to do what you're looking for.
Define this function:
def simplify_eq_with_assumptions(eq):
assert eq.rhs == 0 # assert that right-hand side is zero
assert type(eq.lhs) == Mul # assert that left-hand side is a multipl.
newargs = [] # define a list of new multiplication factors.
for arg in eq.lhs.args:
if arg.is_positive:
continue # arg is positive, let's skip it.
newargs.append(arg)
# rebuild the equality with the new arguments:
return Eq(eq.lhs.func(*newargs), 0)
Now you can call:
In [5]: simplify_eq_with_assumptions(my_equation)
Out[5]: a - b = 0
You can easily adapt this function to your needs. Hopefully, in some future version of SymPy it will be sufficient to call simplify.

how to exit recursive math formula and still get an answer

i wrote this python code, which from wolfram alpha says that its supposed to return the factorial of any positive value (i probably messed up somewhere), integer or not:
from math import *
def double_factorial(n):
if int(n) == n:
n = int(n)
if [0,1].__contains__(n):
return 1
a = (n&1) + 2
b = 1
while a<=n:
b*=a
a+= 2
return float(b)
else:
return factorials(n/2) * 2**(n/2) *(pi/2)**(.25 *(-1+cos(n * pi)))
def factorials(n):
return pi**(.5 * sin(n*pi)**2) * 2**(-n + .25 * (-1 + cos(2*n*pi))) * double_factorial(2*n)
the problem is , say i input pi to 6 decimal places. 2*n will not become a float with 0 as its decimals any time soon, so the equation turns out to be
pi**(.5 * sin(n*pi)**2) * 2**(-n + .25 * (-1 + cos(2*n*pi))) * double_factorial(loop(loop(loop(...)))))
how would i stop the recursion and still get the answer?
ive had suggestions to add an index to the definitions or something, but the problem is, if the code stops when it reaches an index, there is still no answer to put back into the previous "nests" or whatever you call them
You defined f in terms of g and g in terms of f. But you don't just have a circular definition with no base point to start the recursion. You have something worse. The definition of f is actually the definition of g inverted. f is precisely undoing what g did and vice versa. If you're trying to implement gamma yourself (ie. not using the one that's already there in the libraries) then you need to use a formula that expresses gamma in terms of something else that you know how to evaluate. Just using one formula and its inversion like that is a method that will fail for almost any problem you apply it to.
In your code, you define double_factorial like
double_factorial(n) = factorial(n/2) * f(n) ... (1)
and in the factorial you define it as
factorial(n) = double_factorial(2*n) / f(2*n) ... (2)
which is equivalent to equation (1), so you created a circular reference without an exit point. Even math can't help. You have to define either factorial or double_factorial, e.g.
def factorials(n):
return tgamma(n + 1)

Categories

Resources