define a "derivation" function in sympy - python-3.x

I am trying to make a derivation Function in sympy (I am using sympy version 1.4), but I am not sure how. In particular, I am trying to define a general function (that could just take sympy variables, not functions for now) that has the following properties:
d(f+g)=d(f)+d(g)
d(f*g)=f*d(g)+d(f)*g
I have tried reading the sympy documentation on defining Functions but I am not sure how to define a Function class that has the above properties for any two symbols.
For some background/context, I know how to make derivations in Mathematica; I would just type
d[f_+g_]:=d[f]+d[g]
d[f_ g_]:=f d[g] + d[f] g

You can write your own rule. The following might get you started:
def d(e, func):
"""
>>> from sympy import x, y
>>> from sympy import Function
>>> D = Function('D')
>>> d(x + y, D)
D(x) + D(y)
"""
if e.is_Add:
return Add(*[d(a, func) for a in e.args])
elif e.is_Mul:
return Add(*[Mul(*(e.args[:i]+(d(e.args[i],func),)+e.args[i+1:]))
for i in range(len(e.args))])
else:
return func(e)
Or you could try this with a class:
class d(Function):
#classmethod
def eval(cls, e):
if e.is_Add:
return Add(*[d(a) for a in e.args])
elif e.is_Mul:
return Add(*[Mul(*(e.args[:i]+(d(e.args[i]),)+e.args[i+1:]))
for i in range(len(e.args))])
else:
return d(e, evaluate=False)
See also, linapp.

Related

How does one get a parameter from a params (pytree) in haiku? (jax framework)

For example you set up a module and that has params. But if you want do regularize something in a loss what is the pattern?
import jax.numpy as jnp
import jax
def loss(params, x, y):
l = jnp.sum((y - mlp.apply(params, x)) ** 2)
w = hk.get_params(params, 'w') # does not work like this
l += jnp.sum(w ** w)
return l
There is some pattern missing in the examples.
params is essentially a read-only dictionary, so you can get the value of a parameter by treating it as a dictionary:
print(params['w'])
If you want to update the parameters, you cannot do it in-place, but have to first convert it to a mutable dictionary:
params_mutable = hk.data_structures.to_mutable_dict(params)
params_mutable['w'] = 3.14
params_new = hk.data_structures.to_immutable_dict(params_mutable)

oneliner using reduce in python

I'm trying to take my Python skills (beginner) to the next level.
and I'm trying to teach myself the functools.reduce() function
So I'm running every time into the same error;
I'd appreciate if someone could explain to me what is the problem in my code
I'm trying to build a simple func that receive a number and return the sum of number digits
import functools
def sum_using_reduce(number):
return str(number)[0] + str(number)[1]
number = 104
print(functools.reduce(sum_using_reduce, number))
Try this:
number = 104
functools.reduce(lambda x, y: x+y, [int(i) for i in str(number)])
Output: 5
Using your example:
import functools
def sum_using_reduce(x, y) -> int:
return x + y
print(functools.reduce(sum_using_reduce, [int(i) for i in str(105)]))
Output: 6
Another approach:
import functools
def sum_using_reduce(number: int) -> int:
return functools.reduce(lambda x, y: x+y, [int(i) for i in str(number)])
print(sum_using_reduce(124))
Output: 7
In your sum_using_reduce function you are trying to sum two strings, which would simply perform concatenation. Moreover, you are providing an integer as the second argument to the reduce function, where the reduce function requires an iterable to be provided.
Below is a solution that fixes both these requirements:
from functools import reduce
number=104
print(reduce(lambda x,y:x+y,map(int,str(number))))
map(int,str(number)) transforms the number to a string (104->"104") and then turns every character in the string to an integer, returning an iterable map object ("104"->[1,0,4]).
lambda x,y:x+y is a function which takes two integers and sums them.

Why does overloading math operators in python depend on what order it is used?

If I create a class such as 'A' below:
class A(object):
a = 1
def __truediv__(self, var):
return self.a / var
and then try to divide an int by A as:
print(3 / A())
python raises a TypeError. However, if I divide an int by this object python prints:
print(A() / 3)
python prints 0.333333.
How can I make the class work so that I can perform mathematical operations in any order?
N.B. Numpy arrays seem to be able to work both ways i.e:
import numpy as np
1 / np.arange(1, 5)
np.arange(1, 5) / 1
runs and works as expected.
Also implement the reflected dunder methods. In your case, that's __rtruediv__()

Python 3.x finding derivatives

I'm trying to make a derivative calculator.
Here is my code.
from sympy import symbols, Limit, S
x, h = symbols('x, h')
def g(x):
def f(x):
y = input("Function:")
return eval(y, {'__builtins__': {}}, {'x': x})
return Limit((f(x+h)-f(x))/h , h, S.Zero).doit()
print (g(x))
But when I run the code, I have to put the "Functions" twice. It seems that it happens because there are two f's ( f(x+h) and f(x) ) when g(x) is defined.
How can I fix it? I mean, I don't want to put my function two times...
Anyone can help me?

Trapezoidal approximation error plotting in python

Im trying to code a function that plots the error of the composite trapezoidal rule against the step size.
Obviously this doesn't look to good since i'm just starting to learn these things.
Anyhow i managed to get the plot and everything, but i'm supposed to get a plot with slope 2, so i am in need of help to figure out where i did go wrong.
from scipy import *
from pylab import *
from matplotlib import *
def f(x): #define function to integrate
return exp(x)
a=int(input("Integrate from? ")) #input for a
b=int(input("to? ")) #inpput for b
n=1
def ctrapezoidal(f,a,b,n): #define the function ctrapezoidal
h=(b-a)/n #assign h
s=0 #clear sum1-value
for i in range(n): #create the sum of the function
s+=f(a+((i)/n)*(b-a)) #iterate th sum
I=(h/2)*(f(a)+f(b))+h*s #the function + the sum
return (I, h) #returns the approximation of the integral
val=[] #start list
stepsize=[]
error=[]
while len(val)<=2 or abs(val[-1]-val[-2])>1e-2:
I, h=ctrapezoidal(f,a,b,n)
val.append(I)
stepsize.append(h)
n+=1
for i in range(len(val)):
error.append(abs(val[i]-(e**b-e**a)))
error=np.array(error)
stepsize=np.array(stepsize)
plt.loglog(stepsize, error, basex=10, basey=10)
plt.grid(True,which="both",ls="steps")
plt.ylabel('error')
plt.xlabel('h')

Resources