<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <p>
<img src="http
Step1:  Stirling array $\mathcal{S}$
Step2:  power function
Step3:  inverse function
Step4:  sqrt function
Step5:  expt function
Step6:  log function
Step7:  sin function
Step8:  cos function
<ASSISTANT_TASK:>
Python Code:
from sympy import *
from sympy.abc import n, i, N, x, lamda, phi, z, j, r, k, a, alpha
from commons import *
from matrix_functions import *
from sequences import *
import functions_catalog
init_printing()
Explanation: <p>
<img src="http://www.cerm.unifi.it/chianti/images/logo%20unifi_positivo.jpg" 
        alt="UniFI logo" style="float: left; width: 20%; height: 20%;">
<div align="right">
Massimo Nocentini<br>
<small>
<br>November 20, 2018: cleanup, `sin` and `cos` $g$ polys
<br>November 16 and 18, 2016: classic $g$ polys
</small>
</div>
</p>
<br>
<br>
<div align="center">
<b>Abstract</b><br>
Theory of matrix functions, with applications to Stirling array $\mathcal{S}$.
</div>
End of explanation
from sympy.functions.combinatorial.numbers import stirling
m=8
S2 = define(let=Symbol(r'\mathcal{{S}}_{{ {} }}'.format(m)), 
            be=Matrix(m, m, lambda n,k: stirling(n,k, kind=2)))
S2 # this version is the pure one
S2 = define(let=Symbol(r'\mathcal{{S}}_{{ {} }}'.format(m)), 
            be=Matrix(m, m, riordan_matrix_exponential(
                riordan_matrix_by_convolution(d=Eq(Function('d')(z), exp(z)),
                                              h=Eq(Function('h')(z), exp(z)-1),
                                              dim=m))))
S2
inspect(S2.rhs)
production_matrix(S2.rhs)
eigendata = spectrum(S2)
eigendata
data, eigenvals, multiplicities = eigendata.rhs
Phi_poly = Phi_poly_ctor(deg=m-1)
Phi_poly
Phi_polynomials = component_polynomials(eigendata, early_eigenvals_subs=True)
Phi_polynomials
cmatrices = component_matrices(S2, Phi_polynomials)
cmatrices
Explanation: Stirling array $\mathcal{S}$
End of explanation
f_power, g_power, G_power = functions_catalog.power(eigendata, Phi_polynomials)
S2_power = G_power(S2)
S2_power
define(S2_power.lhs, S2_power.rhs.applyfunc(factor)) # factored
S2_power.rhs[:,0]
assert (S2.rhs**r).applyfunc(simplify) == S2_power.rhs
inspect(S2_power.rhs)
production_matrix(S2_power.rhs).applyfunc(factor)
Explanation: power function
End of explanation
f_inverse, g_inverse, G_inverse = functions_catalog.inverse(eigendata, Phi_polynomials)
S2_inverse = G_inverse(S2)
S2_inverse, G_inverse(S2_inverse)
inspect(S2_inverse.rhs)
production_matrix(S2_inverse.rhs)
assert S2_inverse.rhs*S2.rhs == Matrix(m, m, identity_matrix())
assert S2_inverse.rhs == S2_power.rhs.subs({r:-1})
Explanation: inverse function
End of explanation
f_sqrt, g_sqrt, G_sqrt = functions_catalog.square_root(eigendata, Phi_polynomials)
S2_sqrt = G_sqrt(S2)
S2_sqrt
inspect(S2_sqrt.rhs)
production_matrix(S2_sqrt.rhs)
inspect(S2_sqrt.rhs)
production_matrix(S2_sqrt.rhs, exp=False)
assert S2_sqrt.rhs == S2.rhs**(S(1)/2)
assert S2_sqrt.rhs == S2_power.rhs.subs({r:S(1)/2})
Explanation: sqrt function
End of explanation
f_exp, g_exp, G_exp = functions_catalog.exp(eigendata, Phi_polynomials)
S2_exp = G_exp(S2)
S2_exp
define(S2_exp.lhs, S2_exp.rhs.applyfunc(factor))
S2_exp1 = define(let=Subs(S2_exp.lhs, alpha, 1), be=S2_exp.rhs.subs({alpha:1}))
S2_exp1
inspect(S2_exp.rhs)
inspect(S2_exp1.rhs)
Explanation: expt function
End of explanation
f_log, g_log, G_log = functions_catalog.log(eigendata, Phi_polynomials)
S2_log = G_log(S2)
S2_log
inspect(S2_log.rhs[1:,:-1])
production_matrix(S2_log.rhs[1:,:-1])
Explanation: log function
End of explanation
f_sin, g_sin, G_sin = functions_catalog.sin(eigendata, Phi_polynomials)
S2_sin = G_sin(S2)    
S2_sin
Explanation: sin function
End of explanation
f_cos, g_cos, G_cos = functions_catalog.cos(eigendata, Phi_polynomials)
S2_cos = G_cos(S2)    
S2_cos
assert (S2_sin.rhs**2 + S2_cos.rhs**2).applyfunc(trigsimp) == Matrix(m, m, identity_matrix())
Explanation: cos function
End of explanation
<END_TASK>