I'm looking for an example of operations with logarithms in Python. I've tried with sympy and numpy and I still can't do what I want. For example, for an input like this:
log(x+1)+log(4-x)=log(100) # it's just an example
the output should give me the x value. I need to do this with any other functions like log(x+1)=4 or log(x)-log(x+1)=log(x).
Is there some method or somewhere (documentation or similar) where can I find how to do this?
I may be misunderstanding what you need to do because you said you tried sympy already. However, it looks like you just want to solve for x in an algebraic equation.
Solving for x in the equation
log(x+1)+log(4-x)=log(100)
using sympy would be
>>> from sympy import Symbol, solve, log
>>> x = Symbol('x')
>>> solve(log(x+1) + log(4-x) - log(100), x)
[3/2 - 5*sqrt(15)*I/2, 3/2 + 5*sqrt(15)*I/2]
If you want, you can check that these two solutions are correct with numpy.
>>> import numpy as np
>>> a = 3/2 - 5*np.sqrt(15)*1j/2
>>> b = 3/2 + 5*np.sqrt(15)*1j/2
>>> np.log(a + 1) + np.log(4-a)
(4.6051701859880918+0j)
>>> np.log(b + 1) + np.log(4-b)
(4.6051701859880918+0j)
>>> np.log(100)
4.6051701859880918
Is that not what you are looking for?
Since log is a non-linear function, you will need to use a non-linear solver like scipy.optimize.fsolve. It take in a function and a guess value and returns the answer in the form of an array. For simplicity reason, I defined the function as a lambda function since we don't need it outside of this line, but creating a function using standard def methods would work as well. The [0] on the back end get the value out of the array to return just the float.
import scipy.optimize
import math
scipy.optimize.fsolve(lambda x: math.log(x+1) - 4, 5)[0] # 5 is guess value
>>> 53.598
# Check
math.exp(4) - 1
>>> 53.598
Good advice already given. I just note that you can also check the answer in SymPy.
>>> L, R = log(x+1)+log(4-x), log(100)
>>> eq = Eq(L, R)
>>> eq
log(-x + 4) + log(x + 1) == log(100)
>>> sol = solve(eq)
>>> [eq.subs(x, i) for i in sol]
[True, True]
So in the Eq form the solutions were verified automatically. This is not always
true but you can use numerical evaluation to check the value:
>>> f = eq.lhs - eq.rhs; f
log(-x + 4) + log(x + 1) - log(100)
>>> f.subs(x, sol[0])
-log(100) + log(5/2 - 5*sqrt(15)*I/2) + log(5/2 + 5*sqrt(15)*I/2)
>>> _.n()
0.e-124 + 0.e-125*I
>>> f.subs(x, sol[0]).n(chop=True) # the small numbers can be chopped
0
Related
I use sympy (ver1.9).
I calculate the following expressions((1)~(4)) by sympy.simplify().
All of them are expected to be identical to 1 analytically.
but (4) did not return 1, and the expression isn't simplified.
Why does this happen?
Try rewriting to exp and then simplifying:
>>> eq=tanh(x-y)**2 + sech(x-y)**2
>>> eq.rewrite(exp).simplify()
1
or use the function to rewrite hyperbolics to trigonometric functions before simplifying, e.g. with fu:
>>> from sympy.simplify.fu import hyper_as_trig
>>> e,f=hyper_as_trig(eq)
>>> f(fu(e))
1
See also hyper_as_trig in simplify/fu.py.
I am using python (3.7.3) with sympy (1.6.2) to store a function with squared terms and non-squared terms, with each term being the product of exactly two variables.
For example,
>> import sympy as sy
>> x = sy.Symbol('x')
>> y = sy.Symbol('y')
>> F = x*x+x*y
>> print(F)
x**2+x*y
I want to be able to iterate through the terms and get each operand.
For example,
terms = F.expand(basic=True).args
for term in terms
(t0,t1) = term.args
print('t0:{}, t1:{}'.format(t0,t1))
# do some stuff using t0, t1
This works for the x*y term, but not the x**2 term.
>> print((x*y).args)
(x,y)
>> print((x**2).args) # I want this to be (x,x)
(x,2)
I tried running (x**2).expand(), but this appears to be the fully expanded version of the expression.
My question is twofold:
is there a way to expand x**2 so that it is stored as x*x?
is there a better way to go about getting each operand in each term than the for loop I show above?
You could define a custom function that defactors in the way you want:
def get_factors(expr):
if expr.func == sy.Mul:
return expr.args
elif expr.func == sy.Pow:
return tuple(expr.args[0] for _ in range(expr.args[1]))
else:
raise NotImplementedError()
Usage:
>>> a, b = terms
>>> get_factors(a)
(x, x)
>>> get_factors(b)
(x, y)
I've been trying this now for hours. I think I don't understand a basic concept, that's why I couldn't answer this question to myself so far.
What I'm trying is to implement a simple mathematical function, like this:
f(x) = x**2 + 1
After that I want to derive that function.
I've defined the symbol and function with:
x = sympy.Symbol('x')
f = sympy.Function('f')(x)
Now I'm struggling with defining the equation to this function f(x). Something like f.exp("x**2 + 1") is not working.
I also wonder how I could get a print out to the console of this function after it's finally defined.
sympy.Function is for undefined functions. Like if f = Function('f') then f(x) remains unevaluated in expressions.
If you want an actual function (like if you do f(1) it evaluates x**2 + 1 at x=1, you can use a Python function
def f(x):
return x**2 + 1
Then f(Symbol('x')) will give a symbolic x**2 + 1 and f(1) will give 2.
Or you can assign the expression to a variable
f = x**2 + 1
and use that. If you want to substitute x for a value, use subs, like
f.subs(x, 1)
Here's your solution:
>>> import sympy
>>> x = sympy.symbols('x')
>>> f = x**2 + 1
>>> sympy.diff(f, x)
2*x
Another possibility (isympy command prompt):
>>> type(x)
<class 'sympy.core.symbol.Symbol'>
>>> f = Lambda(x, x**2)
>>> f
2
x ↦ x
>>> f(3)
9
Calculating the derivative works like that:
>>> g = Lambda(x, diff(f(x), x))
>>> g
x ↦ 2x
>>> g(3)
6
Have a look to:
Sympy how to define variables for functions, integrals and polynomials
You can define it according to ways:
a python function with def as describe above
a python expression g=x**2 + 1
I recommended :
first, define a symbolic variable
x = sympy.symbols('x')
second, define a symbolic function
f = sympy.Function('f')(x)
define a formula
f = x**x+1
if you have so many variable can use this function
def symbols_builder(arg):
globals()[arg]=sp.symbols(str(arg))
if you have so many functions can use this function
def func_build(name, *args):
globals()[name]=sp.Function(str(name))(args)
say I want to print the equation g(x) in the form g(x) = x^2 *........
how do I do it? This is my first time using python
import numpy as np
import matplotlib.pyplot as plt
import math
from sympy.mpmath import *
f = lambda x: ((x^2)*math.exp(-x))
dfdx = lambda x: diff(f,x)
d2fdx2 = lambda x: diff(dfdx,x)
g = lambda x: ((math.exp(x)/math.factorial(2))*d2fdx2)
print(g)
(edit) the output im getting is
function lambda at 0x0671C198
First of drop all the the unnecessary imports and stick to what you really need. Symbolic math is what sympy was made for so check out the documentation for that.
In sympy you have to define symbols first
import sympy
x = symbols('x')
Now you would use the symbol x to construct an expression using builtin operators and functions in the sympy module. Be aware that ** is exponentiation and ^ is logical xor.
f = x ** 2 * sympy.exp(-x)
dfdx = sympy.diff(f, x)
d2fdx2 = sympy.diff(f, x, x)
g = sympy.exp(x) / sympy.factorial(2) * d2fdx2
When you write g in the interactive interpreter it will write the expression the way you want it. Can't show that here but atleast I can do this:
>>> print(g)
x**2/2 - 2*x + 1
You cannot do what you want with the math, sympy.mpmath and numpy modules as they exist for numerical evalutions - they want numbers and give you number.
If you later want to evaluate your expression for a given value of x you could do
val_at_point = g.evalf(subs={x: 1.5})
where subs is a dictionary.
Or you could turn g into a python lambda function:
fun_g = sympy.lambdify(x, g)
val_at_point = fun_g(1.5)
If you're doing this for a math class you probably want to be working in the interpreter anyway in which case you can start by writing
>>> from sympy import *
so that you can skip all the sympy. stuff in the above code samples. I left them there just to show where symbols come from.
I need a calculate below expression using sympy in python?
exp = '(a+b)*40-(c-a)/0.5'
In a=6, b=5, c=2 this case how to calculate expression using sympy in python? Please help me.
The documentation is here: http://docs.sympy.org/. You should really read it!
To "calculate" your expression, write something like this:
from sympy import Symbol
a = Symbol("a")
b = Symbol("b")
c = Symbol("c")
exp = (a+b)*40-(c-a)/0.5
And that's it. If you meant something else by "calculate", you could also solve exp = 0:
sympy.solve(exp)
> {a: [0.0476190476190476*c - 0.952380952380952*b],
> b: [0.05*c - 1.05*a],
> c: [20.0*b + 21.0*a]}
For everything else, you should really read the docs. Maybe start here: http://docs.sympy.org/0.7.1/tutorial.html#tutorial
UPDATE: since you added the values for a, b, c to the question, you can add this to the solution:
exp.evalf(subs={a:6, b:5, c:2})
You can convert your string into a sympy expression using the parse_expr() function in the module sympy.parsing.sympy_parser.
>>> from sympy.abc import a, b, c
>>> from sympy.parsing.sympy_parser import parse_expr
>>> sympy_exp = parse_expr('(a+b)*40-(c-a)/0.5')
>>> sympy_exp.evalf(subs={a:6, b:5, c:2})
448.000000000000
I realise this was already answered above, but in the case of getting a string expression with unknown symbols and needing access to those symbols, here is the code I used
# sympy.S is a shortcut to sympify
from sympy import S, Symbol
# load the string as an expression
expression = S('avar**2 + 3 * (anothervar / athirdvar)')
# get the symbols from the expression and convert to a list
# all_symbols = ['avar', 'anothervar', 'athirdvar']
all_symbols = [str(x) for x in expression.atoms(Symbol)]
# do something with the symbols to get them into a dictionary of values
# then we can find the result. e.g.
# symbol_vals = {'avar': 1, 'anothervar': 2, 'athirdvar': 99}
result = expression.subs(symbols_vals)
Well, I know that eval is evil, but if you have a,b and c defined in your program, and you can make sure that it's safe to do the eval, you don't need sympy.
>>> a=5
>>> b=5
>>> c=2
>>> exp = '(a+b)*40-(c-a)/0.5'
>>> eval(exp)
406.0
>>> a, b, c = sympy.symbols('a b c')
>>> exp = (a + b) * 40 - (c - a) / 0.5
>>> exp.evalf(6, subs={a:6, b:5, c:2})
448.000