Python的sympy库的基础运用

基础运用

from sympy import *
注意全局引用,容易发生错误

symbols()——构件符号变量——
x,y,z=symbols('x  y  z')
m0,m1,m2,m3=symbols('m0:4')  #创建多个符号变量

平时变量不多时往往这么写
from sympy.abc import x,y,pi   #引进符号变量x,y及常量pi

n()或evalf()——取一个数的浮点近似值
print(pi.n())   #默认保留15位有效数字
print("pi的两种显示格式:{},{}".format(pi,pi.evalf(3)))  #format里不能使用n()函数
>>> pi的两种显示格式:pi,3.14

subs()——求值、替换
1、求值
expr1=y*sin(y**2)
expr2=y**2+sin(y)*cos(y)+sin(z)
print("y=5时,expr1=",expr1.subs(y,5))
print("y=2,z=3时,expr2=",expr2.subs({y:2,z:3}))
2、替换
x,y = symbols('x,y')
a = x + 1
print(a.subs(x,y))
>>> y + 1

together()——表达式相加
simplify(),apart()——化简
x1,x2,x3,x4=symbols('m1:5');
print(together(x1/x2+x3/x4))
>>> (m1*m4 + m2*m3)/(m2*m4)
x=symbols('x')
print(simplify((2*x**2+3*x+4)/(x+1)))  #化简没有效果
>>> (2*x**2 + 3*x + 4)/(x + 1)
print(apart((2*x**2+3*x+4)/(x+1)))
>>> 2*x + 1 + 3/(x + 1)

expand()——扩展代数表达式,消除幂和乘法
expr = sin(x+y) / (sin(y)*cos(x))
print(expr)
>>>sin(x + y)/(sin(y)*cos(x))
expr = simplify(expr)
print(expr)
>>>tan(x)/tan(y) + 1

equals()——比较表达式
a = cos(x)**2 - sin(x)**2
b = cos(2*x)
print(a.equals(b))
print(a == b)
>>>True
False

solve()——求解方程
sol = solve(x**2 - x, x)    #x^2 - x = 0
print(sol)
>>>[0, 1]

solveset()——求给定求目标区间内的解
sol = solveset(x**2 - 1, x, Interval(0, 50))   #解在区间(0,50)
print(sol)
sol2 = solveset(x**2 - 1, x, Interval(-10, 50))  #解在区间(-10,50)
print(sol2)
>>>FiniteSet(1)
FiniteSet(-1, 1)

limit()——求极限
print(limit(sin(x)/x,x,0))
print(limit(pow(1+1/x,x),x,oo))  #这里是两个小”o”,表示正无穷

diff()——求导
diff(func:求导的函数,x:要对其求导的变量,n:可选,求n阶导数,默认为1阶导数)
x,y=symbols('x y')    #定义两个符号变量
z=sin(x)+x**2*exp(y)     #构造符号表达式
print("关于x的二阶偏导数为:",diff(z,x,2))
print("关于y的一阶偏导数为:",diff(z,y))
print("函数对x先求偏导,然后对y求偏导:",diff(z,x,y))
求某一个点的导数
print(diff(x**4,x).subs(x,2))   # 表示将x = 2,带入导函数4*x**3中

summation()——级数的求和
factor()——因式分解
k,n=symbols('k  n')
print(summation(k**2,(k,1,n)))
print(factor(summation(k**2,(k,1,n))))  #把计算结果因式分解
print(summation(1/k**2,(k,1,oo)))  #这里是两个小o表示正无穷

integrate()——求不定积分与定积分
1、不定积分
expr = exp(x) * sin(x) + exp(x) * cos(x)
print(integrate(expr, x))    #integrate是积分的意思
2、定积分
print(integrate(sin(x)/x, (x,0,oo)))

solve()/roots()——方程(组)求解
from sympy.abc import x,y
print(solve(x**3 - 4*x**2 - 3*x + 18))
print(roots(x**3 - 4*x**2 - 3*x + 18))  #如果要求多重根重复次数可以用roots
print(solve([x - y + 2, x + y - 3], [x, y]))  #求解方程组
>>>[-2, 3]  #如果有重根仅显示一个
{-2: 1, 3: 2}   #表示 -2 是1重根,3 是2重根
#因此x**3 - 4*x**2 - 3*x + 18 = 0 的解:-2,3,3
{x: 1/2, y: 5/2}

Function()——声明微分方程
下面两种声明方式效果一样
y=Function('y')
y=symbols('y',cls=Function)

dsolve()——求常微分方程
见下面例题23

建图

plot()——二维建图
1、plot(表达式,范围,属性)
2、plot(表达式1,表达式2,范围1,范围2,属性)	#但要求变量一样,这样不能用pi或其他,不推荐用
3、plot((表达式1,范围1),(表达式2,范围2))	#常用
plot((2*sin(x),(x,-6,6)),(cos(x+pi/4),(x,-5,5)))

plot3d()——三维建图
from sympy.plotting import plot3d
plot3d(sin(sqrt(x**2+y**2)),(x,-10,10),(y,-10,10))

plot_implicit()——隐函数建图
from sympy import plot_implicit as pt,Eq
pt(Eq((x-1)**2+(y-2)**3,4),(x,-6,6),(y,-2,4))

有趣的建图
plot_implicit(Eq(11 * x ** 2 - 12 * abs(x) * y + 11 * y ** 2, 121))


简单例题

例题1:
求f(x)=2*x**3-5*x**2+x函数驻点,在[0,1]上的最大值
x=symbols('x')
y=2*x**3-5*x**2+x
x0=solve(diff(y,x),x)   #求驻点
print("驻点的精确解为",x0)
#列表中的符号数无法整体转换为浮点数
print("驻点的浮点数表示为:",[x0[i].n() for i in range(len(x0))])  
y0=[y.subs(x,0),y.subs(x,1),y.subs(x,x0[0]).n()] #代入区间端点和一个驻点的值
print("三个点的函数值分别为:",y0)

例题2:
求(非)齐次方程通解:
x=symbols('x'); y=symbols('y',cls=Function)
eq1=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)
eq2=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)-x*exp(2*x)
print("齐次方程的解为:",dsolve(eq1,y(x)))
print("非齐次方程的解为:",dsolve(eq2,y(x)))

例题3:
求下列微分方程的解:
x=symbols('x'); y=symbols('y',cls=Function)
eq1=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)
eq2=diff(y(x),x,2)-5*diff(y(x),x)+6*y(x)-x*exp(2*x)
print("初值问题的解为:{}".format(dsolve(eq1,y(x),ics={y(0):1,diff(y(x),x).subs(x,0):0})))
y2=dsolve(eq2,y(x),ics={y(0):1,y(2):0})
print("初值问题的解为:{}".format(y2))

高阶运用

三种方法求定积分

import numpy as np
from scipy.integrate import quad
def trapezoid(f,n,a,b):    #定义梯形公式的函数
    xi=np.linspace(a,b,n); h=(b-a)/(n-1)
    return h*(np.sum(f(xi))-(f(a)+f(b))/2)
def simpson(f,n,a,b):     #定义辛普森公式的函数
    xi, h=np.linspace(a,b,2*n+1), (b-a)/(2.0*n)
    xe=[f(xi[i]) for i in range(len(xi)) if i%2==0]
    xo=[f(xi[i]) for i in range(len(xi)) if i%2!=0]
    return h*(2*np.sum(xe)+4*np.sum(xo)-f(a)-f(b))/3.0
a=0; b=1; n=1000
f=lambda x: np.sin(np.sqrt(np.cos(x)+x**2))
print("梯形积分I1=",trapezoid(f,n,a,b))
print("辛普森积分I2=",simpson(f,n,a,b))
print("SciPy积分I3=",quad(f,a,b))

dblquad()——求二重积分
在这里插入图片描述

import numpy as np
from scipy.integrate import dblquad
f1=lambda y, x: x*y**2  #第一个被积函数
print("I1:",dblquad(f1, 0, 2, 0, 1))
f2=lambda y, x: np.exp(-x**2/2)*np.sin(x**2+y)
bd=lambda x: np.sqrt(1-x**2)
print("I2:",dblquad(f2, -1, 1, lambda x: -bd(x), bd))

tplquad()——求多重积分
在这里插入图片描述

import numpy as np
from scipy.integrate import tplquad
f=lambda z, y, x: z*np.sqrt(x**2+y**2+1)
ybd=lambda x: np.sqrt(2*x-x**2)
print("I=",tplquad(f, 0, 2, lambda x: -ybd(x),ybd, 0, 6))

fsolve()——非线性方程(组)数值解

import numpy as np
from scipy.optimize import fsolve
def binary_search(f, eps, a, b):  #二分法函数
    c=(a+b)/2
    while np.abs(f(c))>eps:
        if f(a)*f(c)<0: b=c
        else: a=c
        c=(a+b)/2
    return c
def newton_iter(f, eps, x0, dx=1E-8):  #牛顿迭代法函数
    def diff(f, dx=dx):   #求数值导数函数
        return lambda x: (f(x+dx)-f(x-dx))/(2*dx)
    df=diff(f,dx)
    x1=x0-f(x0)/df(x0)
    while np.abs(x1-x0)>=eps:
        x1, x0=x1-f(x1)/df(x1), x1
    return x1
#三种方法求下列方程实根的近似值,误差不超过1e-6
f=lambda x: x**3+1.1*x**2+0.9*x-1.4
print("二分法求得的根为:", binary_search(f,1E-6,0,1))
print("牛顿迭代法求得的根为:",newton_iter(f,1E-6,0))
print("直接调用SciPy求得的根为:",fsolve(f,0))

在这里插入图片描述

from scipy.optimize import fsolve
f=lambda x: [5*x[1]+3, 4*x[0]**2-2*sin(x[1]*x[2]), x[1]*x[2]-1.5]
print("result=",fsolve(f, [1.0, 1.0, 1.0]))
#另一种写法:
def Pfun(x):
    x1,x2,x3=x.tolist()  #x转换成列表
    return 5*x2+3, 4*x1**2-2*sin(x2*x3), x2*x3-1.5
print("result=",fsolve(Pfun, [1.0, 1.0, 1.0]))

fminbound()/fmin()——求一元函数的极值点

from scipy.optimize import fminbound
f=lambda x: exp(x)*cos(2*x)
x0=fminbound(f,0,3)
#方法一
print("极小点为:{},极小值为:{}".format(x0,f(x0)))
#方法二:
x0=fmin(f,0)
print("极小点为:{},极小值为:{}".format(x0,f(x0)))

minimize()——求多元函数的极值点

from scipy.optimize import minimize
f=lambda x: 100*(x[1]-x[0]**2)**2+(1-x[0])**2; 
x0=minimize(f,[2.0, 2.0])
print("极小点为:{},极小值为:{}".format(x0.x,x0.fun))

矩阵模块

import sympy as sp
import numpy as np

A=sp.Matrix([[1],[2],[3]])  #列向量,即3×1矩阵
B=sp.Matrix([[4],[5],[6]])  
print("A的模为:",A.norm())
print("A的模的浮点数为:",A.norm().evalf())
print("A的转置矩阵为:",A.T)
print("A和B的点乘为:",A.dot(B))
print("A和B的叉乘为:",A.cross(B))

A=sp.Matrix(np.arange(1,17).reshape(4,4))
B=sp.eye(4)     #4阶单位矩阵
print("A的行列式为:",sp.det(A))
print("A的秩为:",A.rank())
print("A的转置矩阵为:",A.transpose())  #等价于A.T
print("所求的逆阵为:",(A+10*B).inv())
print("A的平方为:",A**2)
print("A,B的乘积为:",A*B)
print("横连矩阵为:",A.row_join(B))
print("纵连矩阵为:",A.col_join(B))
print("A1为:",A[0:2,0:2])  #截取    
A2=A.copy(); A2.row_del(3)  #行删除
print("A2为:",A2)

A=sp.Matrix([[0, -2, 2],[-2, -3, 4], [2, 4, -3]])
print("A的特征值为:",A.eigenvals())
print("A的特征向量为:",A.eigenvects())

#将矩阵相似对角化
from sympy import Matrix, diag
A=Matrix([[0, -2, 2],[-2, -3, 4], [2, 4, -3]])
if A.is_diagonalizable(): print("A的对角化矩阵为:",A.diagonalize())
else: print("A不能对角化")


在这里插入图片描述

A=sp.Matrix([[2, 1, -5, 1],[1, -3, 0, -6],[0, 2, -1, 2],[1, 4, -7, 6]])
b=sp.Matrix([8, 6, -2, 2]); b.transpose()
print("系数矩阵A的秩为:",A.rank())
print("线性方程组的唯一解为:",A.inv()*b)

在这里插入图片描述

A=sp.Matrix([[1, -5, 2, -3],[5, 3, 6, -1], [2, 4, 2, 1]])
print("A的零空间(即基础解系)为:",A.nullspace())

在这里插入图片描述

A=sp.Matrix([[1, 1, -3, -1],[3, -1, -3, 4], [1, 5, -9, -8]])
b=sp.Matrix([1, 4, 0]); b.transpose()
C=A.row_join(b)  #构造增广矩阵
print("增广阵的行最简形为:\n",C.rref())

在这里插入图片描述
向量和矩阵的运算

from numpy import arange, cross, inner 
from numpy.linalg import norm
a=arange(1,4); b=arange(4,7)       #创建数组
print("a的二范数为:",norm(a))
print("a点乘b=", a.dot(b))      #行向量a乘以列向量b
print("a,b的内积=",inner(a,b))  #a,b的内积,这里与dot(a,b)等价
print("a叉乘b=", cross(a,b))

  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值