# Basic use of Function_from_Expression

The module `fun_expr` defines a class `Function_from_Expression` to handle functions which are defined by `sympy`-expressions.

It is useful, to import this as

`
from fun_expr import Function_from_Expression as FE
`

It is not necessary to use `Function_from_Expression` at al. This class is a simple wrapper to make live easier if you need to define functions from expressions and dont prefer to use expressions instead.


```python
from sympy import *
init_printing()

from IPython.display import display, Math

from fun_expr import Function_from_Expression as FE
```

To define a function from an expression, i.e.

$$
  f(x) = x^2
$$

you need a variable ($x$), which must be as `symbol`. The right hand side of the given
definition of a function ($x^2$) is the expression.


```python
# define the variable of the function
x = Symbol('x')

# define the function
f = FE(x, x**2)

# show the result
f
```

`str(f)` shows that $f$ essentially is an object of type `Lambda` which is a `sympy`-generalisation of `lambda`


```python
str(f)
```




    'Lambda(x, x**2)'



The `type` of instances of `FE` is


```python
type(f)
```




    fun_expr.function_from_expression.Function_from_Expression



`f` can be applied to an argument:


```python
f(2)
```

The argument can be a more complicated `sympy` expression


```python
a,b,c = symbols('a,b,c')
expr = (a+b)/c

f(expr)
```

The function can be plotted. For this, `matplotlib` is used.

The magic command `%matplotlib inline` shows the plots inside the notebook.

The magic command `%config InlineBackend.figure_format='retina'` is useful for OSX 

`numpy` is used to create numerical arrays 


```python
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format='retina' # for OSX

import numpy as np
```

The simplest way to plot a function using `matplotlib` is to use sympys `plot`-command. This works since $f(x)$ is an expression.


```python
plot(f(x))
```

Often it is desireable to have more control over what is plotted:


```python
# define new plot
fig, ax = plt.subplots()

# the x-values of the plot
lx = np.linspace(-1,1)

# the y-values of the plot
ax.plot(lx,f.lambdified(lx),label=r'$y={f}$'.format(f=latex(f(x))))

# additional commands
ax.grid(True)
ax.axhline(0,c='k')
ax.axvline(0,c='k')
ax.legend(loc='best')
```

It is possible, to differentiate the function. If `f` is a function of a single variable `x`, this is simply


```python
f_1 = f.diff()
f_1
```

This only works, if `x` is the only symbol in the expression `f(x)`. It is better, to specify the variable of differentiation:


```python
f_1 = f.diff(x)
f_1
```

The second derivative of `f` w.r.t. `x` is


```python
f_2 = f.diff(x,2)
f_2
```

If a function `f` is differentiated w.r.t. a variable, the result is a function of the same varibles as `f`. Sometimes, an expression is needed as the result of a differentiation. In this cases, the flag `as_function=False` can be used


```python
f.diff(x, as_function=False)
```

Another possibility is to use the expr of the result:


```python
f.diff(x).expr
```

The function can be integrated. This usually leads to an expression:


```python
f.integrate()
```


```python
# or
f.integrate(x)
```

It is possible to integrate oven an interval $[a,b]$:


```python
f.integrate((x,2,4))
```

The integral of a function is an expression. If the integral is needed as a function, the flag
`as_function=True` can be used


```python
f.integrate(x, as_function=True)
```

The integral can only be a function, if there are variables left. Otherwise an Error is thrown:


```python
try:
    f.integrate((x,2,4),as_function=True)
except TypeError as e:
    print("Error: " + str(e))
```

    Error: no variable left to define a function


It is possible, to define functions of several variables (not every symbol needs to be a variable)


```python
x,y,z = symbols('x,y,z')
f = FE((x,y), x*y*z)
display(f)
# or, as equation
display(Math("f(x,y)="+latex(f(x,y))))
```

In the above case, `z` is a free symbol of `f`


```python
f.free_symbols
```

The `atoms` are the smallest parts of the expression `f(x)`:


```python
f.atoms()
```


```python
f.variables
```


```python
f.expr
```

Free symbols can be substituted by other values:


```python
f.subs(z,3)
```

Variables cant be substituted. They are bound to the function:


```python
x_0 = Symbol('x_0')

try:
    p = f.subs(x,x_0)
    display(Math('p(y)='+latex(p(x))))
except ValueError as e:
    print("Error: " + str(e))
```

    Error: Substitution of variables is not valid: (x, x_0)


If this is needed, it is better to define a new function:


```python
p = FE(y, f.expr.subs(x,x_0))
Math("p(y)="+latex(p(y)))
```




$$p(y)=x_{0} y z$$



60e80a4edbe8146a1223cbbb28a805336394bae5
ipynb
Jupyter Notebook
docs/01-basic_use.ipynb
w-meiners/fun-expr
a44f0366f08c8c2d2eb2702176698bfe3f6febed
MIT
2017-12-20T16:16:40.000Z
2022-02-28T11:06:38.000Z
docs/01-basic_use.ipynb
w-meiners/fun-expr
a44f0366f08c8c2d2eb2702176698bfe3f6febed
MIT
docs/01-basic_use.ipynb
w-meiners/fun-expr
a44f0366f08c8c2d2eb2702176698bfe3f6febed
MIT
2020-01-27T09:50:59.000Z
2020-01-27T09:50:59.000Z
Qwen/Qwen-72B
1. YES
2. YES