I have what I think it's the most basic problem I have ever encountered:
import sympy
from sympy.abc import x
x == 1.0 * x
>> False
x == x * 1.
>> False
x == sympy.Mul(x, 1)
>> False
x == x * 1
>> True
While researching about this, I found sympy's FAQ and tried all the solutions suggested. simplify, expand, and I cannot get a True if the multiplication is done by a float 1.0. Am I doing something wrong?
PS: I found this issue when working with vectors, and the floating 1 comes from an operation that I cannot transform to integer (mathematically it would have no sense).
Related
I have a hard time getting sympy to work with complex numbers.
Take the following example:
from sympy import *
x = Symbol("x")
expr = sqrt(x) # note that this is imaginary for x<0
# Find all solutions such that |expr| < 1
print( solve( abs(expr)<1, x ) )
This, however, only finds 0<=x<1.
It misses the negative x region -1<x.
How can I make this work?
Since abs(sqrt(x)) = sqrt(x**2) for real numbers, you could solve sqrt(x**2)<1 instead.
>>> solve(sqrt(x**2)<1)
(-1 < x) & (x < 1)
You can perhaps find the boundaries of the solution by replacing your argument of the sqrt with a negative or nonnegative symbol:
>>> solve(abs(sqrt(n))-1)
[-1]
>>> var('nn',nonnegative=1)
nn
>>> solve(abs(sqrt(nn))-1)
[1]
Could you get the boundaries numerically?
>>> [nsolve((abs(x**2+2*x-sqrt(x+5)))-1,i) for i in (-3,-1,0,1)]
[-2.86080585311170, 0.533751168755204, 0.533751168755204, 1.11490754147676]
Tell me please, How to forbid to open brackets? For example,
8 * (x + 1) It should be that way, not 8 * x + 8
Using evaluate = False doesn't help
The global evaluate flag will allow you to do this in the most natural manner:
>>> with evaluate(False):
... 8*(x+1)
...
8*(x + 1)
Otherwise, Mul(8, x + 1, evaluate=False) is a lower level way to do this. And conversion from a string (already in that form) is possible as
>>> S('8*(x+1)',evaluate=False)
8*(x + 1)
In general, SymPy will convert the expression to its internal format, which includes some minimal simplifications. For example, sqrt is represented internally as Pow(x,1/2). Also, some reordering of terms may happen.
In your specific case, you could try:
from sympy import factor
from sympy.abc import x, y
y = x + 1
g = 8 * y
g = factor(g)
print(g) # "8 * (x + 1)"
But, if for example you have g = y * y, SymPy will either represent it as a second power ((x + 1)**2), or expand it to x**2 + 2*x + 1.
PS: See also this answer by SymPy's maintainer for some possible workarounds. (It might complicate things later when you would like to evaluate or simplify this expression in other calculations.)
How about sympy.collect_const(sympy.S("8 * (x + 1)"), 8)?
In general you might be interested in some of these expression manipulations: https://docs.sympy.org/0.7.1/modules/simplify/simplify.html
I have written a program to solve a transcendental equation using Sympy Solvers, but I keep getting a TypeError. The code I have written is the following:
from sympy.solvers import solve
from sympy import Symbol
import sympy as sp
import numpy as np
x = Symbol('x',positive=True)
def converts(d):
M = 1.0
res = solve(-2*M*sp.sqrt(1+2*M/x)-d,x)[0]
return res
print converts(0.2)
which returns the following error:
raise TypeError('invalid input: %s' % p)
TypeError: invalid input: -2.0*sqrt(1 + 2/x)
I've solved transcendental equations this way before, but this is the first time I'm facing this error.
From what I gather, it looks like Sympy is seeing my input as a string instead of a rational number, but I'm not sure if or why it is so. Can someone please tell me why I'm getting this error and/or how to fix it?
Edit: I've rewritten my code to make it clearer but the result is still the same
This is the equation I'm trying to solve
Let's first recreate the actual equation.
from sympy import *
init_printing()
M, x, d = symbols("M, x, d")
eq = Eq(-2*M * sqrt(1 + 2*M/x) - d, 0)
eq
As in your code, we can substitute values: M=1, d=0.2
to_solve = eq.subs({M:1, d:0.2})
to_solve
Now, we may attempt to solve it directly
solve(to_solve, x)
Unfortunately, solve fails to find the solution in this case. If we take a closer look at the equation, the square root part should return a negative number for this equation to be valid.
-2 * (-1/10) - 0.2 = 0
As square root of a number can not be negative, correct me if I'm wrong, sympy is unable to find a value for x such that sqrt(1+2/x) == -1/10
This problem is due to our choice of values for d and M. Solution exists if M and d are of opposite signs.
to_solve = eq.subs({M:-1, d:0.2})
to_solve
solve(to_solve, x)
[2.02020202020202]
Run this code on sympy live and experiment with other values.
I'm trying to setup sympy to calculate derivatives. When I test it with simple equation, I'm finding the same answer (equality is true between sympy calculation and my own calculation). However when I try with more complicated ones, when it doesnt work (I checked answers with wolfram alpha too).
Here is my code:
from __future__ import division
from sympy import simplify, cos, sin, expand
from sympy import *
x, y, z, t = symbols('x y z t')
k, m, n = symbols('k m n', integer=True)
f, g, h = symbols('f g h', cls=Function)
equation = (x**3*y-x*y**3)/(x**2+y**2)
equation2 = (x**4*y+4*x**2*y**3-y**5)/((x**2+y**2)**2)
pprint(equation)
print ""
pprint(equation2)
print diff(equation,x) == equation2
This is a common "gotcha" in Sympy. For creating symbolic equalities, you should use sympy.Eq and not = or == (see the tutorial). For your example,
Eq(equation.diff(x), equation2).simplify()
True
Note, as above, that you may have to call simplify() in order to see wheather the Eq object corresponds to True or False
sorry i am a bit of a newbie with programming but I am getting a float division error in a simple loop which I am not sure how to rectify.
Here is a code in python 2.7
import random
N = 100
A = []
p = 0
q = 0
k = 1
while k<=N:
x = random.random()
if x<= 0.5:
p+= 1
else:
q+=1
y = p/q
A.append(y)
k+=1
Running this code gives a zero division error. which I am not able to rectify. Can anyone tell me how to rectify this?
You are getting zero division error because of this code
if x <= 0.5:
p+=1
else:
q+=1
y= p/q
You have initialised q = 0 thus when while loop is run first time and if x <= 0.5 then p will be incremented but q will be equal to zero and in next step you are dividing p by q(which is zero). You need to put a check condition before performing division so that denominator is not zero. You can rectify it in following manner.
if x <= 0.5:
p+=1
else:
q+=1
if (q == 0):
print "Denominator is zero"
else:
y= p/q
This is just one solution since I don't know what you are trying to do in your code.
You can use numpy.nextafter(q, 1).
This gives you the next floating-point value after q towards 1, which is very small number.