int b = 900;
a |= b;
==>a = a|b
|是按位或操作,就是只要有一个1就是1,两个都是0才是0
a != b -----> a = a | ba &= b -----> a = a & b
a ^= b -----> a = a ^ b
int a = 35;
int b = 900;
a |= b;
==>a = a|b|是按位或操作,就是只要有一个1就是1,两个都是0才是0
a != b -----> a = a | b
a &= b -----> a = a & b
a ^= b -----> a = a ^ b
转载于:https://www.cnblogs.com/tank-/p/8257726.html
SymPy 是一个由 Python 语言编写的符号计算库。我将在本文中简要地介绍如何利用 SymPy 进行符号计算。在介绍 SymPy 之前,我们首先要明确何谓符号计算?计算机代数系统又是什么?
什么是符号计算 ?
处理数学对象的计算称为符号计算。在符号计算中,数学对象是精确表示的,而不是近似的,未计算的数学表达式会以符号形式保留。与符号计算相对应的是数值计算,下面将以两个例子来展示二者之间的区别。
数值计算示例
下面是一个计算
数值解的例子:
import math
math.pi
print(math.sin(math.pi))
符号计算示例
下面是一个计算
解析解的例子:
from sympy import *
sin(pi)
对比
的数值和符号计算结果可以发现,数值计算结果无法精确地表示出
,只能用一个很小的浮点数
表示,而符号计算结果则得出
。
明确了数值计算和符号计算之间的区别后,让我们再来认识什么是计算机代数系统。
什么是计算机代数系统 ?
计算机代数系统(Computer Algebra System,缩写作:CAS)是进行符号运算的软件。在计算机代数系统中运算的对象是数学表达式,通常表达式有如下几类:多元多项式
标准函数(三角函数、指数函数等)
特殊函数(
函数、Bessel 函数等)
多种函数组成的复合函数
表达式的导数、积分、和与积等
级数
矩阵
以下列出了几种典型的符号计算:表达式化简
表达式求值
表达式的变形:展开、积、幂、部分分式表示、将三角函数转换为指数函数等
一元或多元微分
带条件的化简
部分或完整的因式分解
求解线性或非线性方程
求解微分方程或差分方程
求极限
求函数的定积分、不定积分
泰勒展开、洛朗展开等
无穷级数展开
级数求和
矩阵运算
数学公式的
或
显示
通常符号计算软件也具备一定的数值运算能力,例如可以进行如下运算:求函数确切值
求高精度值,如
线性代数的数值运算
此外符号计算软件也具有描绘二维、三维函数图像的功能。
实际上,目前存在众多的计算机代数系统,下面列出了几种:Maple
MuPAD
Maxima
Mathcad
Mathematica
MATLAB Symbolic Math Toolbox
SageMath
为什么选择 SymPy ?
那么,是什么让 SymPy 从这众多软件中脱颖而出,让我们选择它呢?我觉得有如下 4 个原因:SymPy 是自由软件,免费开源,在遵守许可证条款的前提下,用户可以自由地根据自己的需求修改其源代码。与之形成对比的是,Maple、MuPad、Mathcad、MATLAB、Mathematica 等都是商业软件,价格昂贵;
SymPy 使用 Python 编写而成,与使用自己发明的语言的计算机代数系统相比(如 Maxima 由 LISP 编写),SymPy 具有很强的通用性。SymPy 完全用 Python 编写,完全在 Python 中执行。这样,只要您熟悉 Python,那么 SymPy 将会很容易入门;
与另一个使用 Python 的符号计算软件——SageMath 相比,SymPy 的优点是安装包体积小;
SymPy 的一个重要特性是,它可以作为库集成到其他软件中,为别的软件所用。SageMath 便是将 SymPy 作为其子模块,然后再加入其他模块,构建出一个功能齐全的数学软件。
准备知识
在学习如何使用 SymPy 进行符号计算之前,请确保您满足如下几个条件:学习过微积分
学习过线性代数
熟悉 Python 基本语法
了解 Python 面向对象编程方法
会使用 JupyterLab Notebook 交互式开发环境
了解
是什么东西
如何使用 SymPy ?
前面的第 1 个符号计算示例展示了如何利用 SymPy 精确地计算三角函数,实际上,它的功能远不仅于此。作为一个强大的符号计算库,它几乎能够计算所有带符号变量的表达式。下面从本节开始将介绍如何使用 SymPy。
导入 SymPy 库
在使用 SymPy 之前需要先将其导入,有两种方式:直接导入:
import sympy
2. 利用 from 语句导入:
from sympy import *
两种方式都导入了 SymPy 库中的所有函数、对象、变量等。区别是调用方式不同。比如在调用 sqrt(
)函数时,前者应写成 sympy.sqrt(2),后者则直接写成 sqrt(2)。为了力求简洁,我们使用第 2 种方式导入 SymPy 。注意:为了防止命名空间冲突,PEP 标准推荐使用第一种方式导入库。但是,通常一个符号运算 Python 源文件是单独使用的,稍加注意就可以避免命名空间冲突的问题。
新建符号
在使用符号之前,先要利用 symbols 函数定义符号,语句是:
# 新建符号 x, y
x, y = symbols('x y')
还有一个更简洁的方法是,利用 SymPy 的 abc 子模块导入所有拉丁、希腊字母:
# 利用 SymPy 的 abc 子模块新建符号 x, y
from sympy.abc import x, y注意:希腊字母
(lambda) 是 Python 保留关键字,当用户需要使用这个字母时,请写成 lamda(不写中间的 'b')。
新建符号变量时可以指定其定义域,比如指定
:
x = symbols('x', positive = True)
这样在求解过程中
必须满足这个前提条件。
可以利用 symbols 函数依次新建类似
的多个变量:
vars = symbols('x_1:5')
vars
(x_1, x_2, x_3, x_4)
vars[0]
下面是一个符号计算的完整例子:
from sympy import *
x, y, z = symbols('x y z')
y = expand((x + 1)**2) # expand() 是展开函数
y
z = Rational(1, 2) # 构造分数 1/2
z
符号计算基本操作
在本节中,我将介绍几个符号计算的基本操作。
替换
采用符号变量的 subs 方法进行替换操作,例如:
x = symbols('x')
expr = cos(x) + 1
expr.subs(x, 0)
将字符串转换为 SymPy 表达式
利用 sympify 函数可以将字符串表达式转换为 SymPy 表达式。注意:sympify 是符号化,与另一个函数 simplify (化简)拼写相近,不要混淆。
str_expr = 'x**2 + 2*x + 1'
expr = sympify(str_expr)
expr
转换为指定精度的数值解
可以使用符号变量的 evalf 方法将其转换为指定精度的数值解,例如:
pi.evalf(3) # pi 保留 3 位有效数字
利用 lambdify 函数将 SymPy 表达式转换为 NumPy 可使用的函数
如果进行简单的计算,使用 subs 和 evalf 是可行的,但要获得更高的精度,则需要使用更加有效的方法。例如,要保留小数点后 1000 位,则使用 SymPy 的速度会很慢。这时,您就需要使用 NumPy 库。
lambdify 函数的功能就是可以将 SymPy 表达式转换为 NumPy 可以使用的函数,然后用户可以利用 NumPy 计算获得更高的精度。
import numpy
a = numpy.pi / 3
x = symbols('x')
expr = sin(x)
f = lambdify(x, expr, 'numpy')
f(a)
0.8660254037844386
expr.subs(x, pi/3)
使用 simplify (化简)
在符号计算中,最常用的操作就是利用 simplify 函数对表达式化简。默认情况下,simplify 函数将自行寻找它认为的最简单的表达形式,呈现给用户。
simplify(sin(x)**2 + cos(x)**2)
alpha_mu = symbols('alpha_mu')
simplify(2*sin(alpha_mu)*cos(alpha_mu))
由于 simplify 函数执行过程是启发式的,它需要寻找它认为的最简形式,所以有时它的响应会比较慢。所以,当您知道化简形式是什么类型时,不要使用 simplify 函数,而应该使用专门的函数,如 factor(后续将会介绍)。
多项式和有理函数化简
下面介绍几个用于多项式或有理函数化简的函数。
expand (展开)
将多项式展开,使用 expand 函数。例如:
x_1 = symbols('x_1')
expand((x_1 + 1)**2)
factor (因式分解)
用 factor 函数可以对多项式进行因式分解,例如:
factor(x**3 - x**2 + x - 1)
实际上,多项式的展开和因式分解是互逆过程,因此 factor 和 expand 也是相对的。
collect (合并同类项)
利用 collect 合并同类项,例如:
expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3
collect(expr, x)
cancel (有理分式化简)
消去分子分母的公因式使用 cancel 函数,例如:
cancel((x**2 + 2*x + 1)/(x**2 + x))
apart (部分分式展开)
使用 apart 函数可以将分式展开,例如:
expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x)
expr
apart(expr)
微积分符号计算
在本节中,将介绍使用 SymPy 进行微积分的基本操作。
一元函数求导函数
求导函数使用 diff 函数,例如:
# 求一阶导数
diff(cos(x), x)
# 求 3 阶导数
diff(x**4, x, 3)
我们也可以用 符号变量的 diff 方法 求微分,例如:
expr = cos(x)
expr.diff(x, 2)
多元函数求偏导函数
可以用 diff 函数求多元函数的偏导数,例如:
expr = exp(x*y*z)
diff(expr, x)
integrate (积分)
使用 integrate 函数求积分,例如:
# 求不定积分
integrate(cos(x), x)
求
的定积分:
注意:在 SymPy 中,我们用 'oo' 表示
。
integrate(exp(-x), (x, 0, oo))
求函数
在
的二重积分:
integrate(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo))
limit (求极限)
使用 limit 函数求极限,例如:
limit(sin(x)/x, x, 0)
当
时,求
的极限:
limit(1/x, x, 0, '+')
series (级数展开)
使用符号变量的 series 方法可以对函数
在
处进行
阶展开。例如,对函数
在
处进行
阶展开:
expr = sin(x)
expr.series(x, 0, 4)
解方程
使用 solveset 求解方程。
求解一元二次方程
求解方程
,首先要构造方程,使用 Eq 函数构造等式:
Eq(x**2 - x, 0)注意:在 SymPy 中,我们用 Eq(左边表达式, 右边表达式) 表示左边表达式与右边表达式相等。
solveset(Eq(x**2 - x, 0), x, domain = S.Reals)
求解微分方程
使用 dsolve 函数求解微分方程。首先需要建立符号函数变量:
f = symbols('f', cls = Function)
然后求解微分方程:
diffeq = Eq(f(x).diff(x, 2) - 2*f(x).diff(x) + f(x), sin(x))
diffeq
dsolve(diffeq, f(x))
矩阵运算
我们在进行矩阵运算之前,需要用 Matrix 构造矩阵,例如:
# 构造矩阵
Matrix([[1, -1], [3, 4], [0, 2]])
# 构造列向量
Matrix([1, 2, 3])
# 构造行向量
Matrix([[1], [2], [3]]).T
矩阵转置用矩阵变量的 T 方法。
# 构造单位矩阵
eye(4)
# 构造零矩阵
zeros(4)
# 构造壹矩阵
ones(4)
# 构造对角矩阵
diag(1, 2, 3, 4)
矩阵转置
矩阵转置用矩阵变量的 T 方法。例如:
a = Matrix([[1, -1], [3, 4], [0, 2]])
a
# 求矩阵 a 的转置
a.T
求矩阵的幂
求矩阵
的
次幂:
# 求矩阵 M 的 2 次幂
M = Matrix([[1, 3], [-2, 3]])
M**2
特殊地,矩阵的
次幂就是矩阵的逆。
# 求矩阵 M 的逆
M**-1
求矩阵的行列式
用矩阵变量的 det 方法可以求其行列式:
M = Matrix([[1, 0, 1], [2, -1, 3], [4, 3, 2]])
M
M.det()
求矩阵的特征值和特征多项式
用矩阵变量的 eigenvals 和 charpoly 方法求其特征值和特征多项式。
M = Matrix([[3, -2, 4, -2], [5, 3, -3, -2], [5, -2, 2, -2], [5, -2, -3, 3]])
M
M.eigenvals()
{3: 1, -2: 1, 5: 2}
lamda = symbols('lamda')
p = M.charpoly(lamda)
factor(p)
Laplace 变换
可以利用 laplace_transform 函数进行 Laplace 变换,例如:
# Laplace (拉普拉斯)变换
from sympy.abc import t, s
expr = sin(t)
laplace_transform(expr, t, s)
利用 inverse_laplace_transform 函数进行逆 Laplace 变换:
expr = 1/(s - 1)
inverse_laplace_transform(expr, s, t)
利用 SymPy 画函数图像
使用 plot 函数绘制二维函数图像,例如:
from sympy.plotting import plot
from sympy.abc import x
plot(x**2, (x, -2, 2))
导入 SymPy 的 plot_implicit 函数绘制隐函数图像:
from sympy import plot_implicit
from sympy import Eq
from sympy.abc import x, y
plot_implicit(Eq(x**2 + y**2, 1))
注意:上图中
轴不是
,导致图像显示不是圆。
使用 SymPy 画出三维函数图像,例如:
from sympy.plotting import plot3d
from sympy.abc import x, y
from sympy import exp
plot3d(x*exp(-x**2 - y**2), (x, -3, 3), (y, -2, 2))
输出运算结果的
代码
使用 latex 函数可以输出运算结果的
代码,例如:
print(latex(integrate(sqrt(x), x)))
结束语
至此,本文就将 SymPy 符号计算库的基本功能和使用技巧介绍完毕,从前面的内容可以总结出如下 2 点结论:SymPy 基于 Python 编写,使用方法继承了 Python 简洁、直白的特点,非常适合初学者快速入门;
SymPy 的 2D、3D 函数绘图能力一般,画二维函数时会出现
轴比例不对。用户若有精确绘制函数图像的需求,应该求助于更加专业的 Python 绘图库,如 Matplotlib 。
单目运算符>双目运算符>三目运算符 优先及 运算符 运算类型 15(最高) () [] - > 14 ! ~ ++ -- -*& sizeof * /% 单目运算 13 * / % 双目算术 12 + - 双目算术 11 << >> 移位运算 10 < <= > >= 关系运算 9 == ! = 关系运算 8 & 位运算 7 ^ 位运算 6 | 位运算 5 && 逻辑运算 4 || 逻辑运算 3 ?: 三目运算 2 = += -= *= /= %= &= ^= | = >>= <<= 双目运算 1 , 顺序运算 注: 14及中 -是反符号运算,*是取地址运算.不要将它们与减,乘和位相混淆.分辨的方法 前4种是单目运算,后4中是2目运算.
1.运算符号是啥C语言中的运算就是对数据进行操作、处理的过程。那么运算符又干什么的呢?运算符就是指定该运算的处理方式。※ 算术运算符 ※ 赋值运算符※ 关系运算符※ 逻辑运算符※ 三目运算符2.算术运算符C语言基本算术运算符如下表:除法运算中注意:如果相除的两个数都是整数的话,则结果也为整数,小数部分省略,如8/3 = 2;而两数中有一个为小数(不分前后),结果则为小数,如:9.0/2 = 4.500000。取余运算中注意:该运算只适合用两个整数进行取余运算,如:10%3 = 1;而10.0%3则是错误的;运算后的符号取决于被模数的符号,如(-10)%3 = -1;而10%(-3) = 1。取决于前者注:C语言中没有乘方这个运算符,也不能用×,÷等算术符号。3.自增与自减运算符注意:无论是a++还是++a都等同于a=a+1,在表达式执行完毕后a的值都自增了1,无论是a--还是--a都等同于a=a-1,在表达式执行完毕后a的值都自减少1,但是在一开始的代码输入时必须先取值(即:a++),而在末尾段若出现a++或者a+那么最终的值仍为a(没运算),因为a++的意思是先取值再运算,a++的值只有在下一次运算上才用的上,但是如果下一次是printf("%d\n",a)的话,即没有运算,则取没运算的a例如:c=b++ 的值仍为b 而不是b+1,只有再下一次运算时的值才为b才变为b+14.赋值运算符C语言中赋值运算符分为简单赋值运算符和复合赋值运算符,之前我们已经接触过简单赋值运算符“=”号了,下面讲一下复合赋值运算符:复合赋值运算符就是在简单赋值符“=”之前加上其它运算符构成,例如+=、-=、*=、/=、%=。如:分析:定义整型变量a并赋值为3,a += 5;这个算式就等价于a = a+5; 将变量a和5相加之后再赋值给a同理:a *= 2 意思是 a = a * 2注意:复合运算符中运算符和等号之间是不存在空格的。5.关系运算符下面是C语言中的关系运算符:关系表达式的值是“真”和“假”,在C程序用整数1和0表示,0表示不存在的,假1表示存在的,真注意:>=,<=,==,!=这种符号之间不能存在空格。例子6.逻辑运算符下面我们看一下C语言中的逻辑运算符:那么前面的那个算式写成计算机可以看的懂的算式就是:x>7 && x<100;逻辑运算的值也是有两种分别为“真”和“假”,C语言中用整型的1和0来表示。其求值规则如下:1) 与运算(&&)参与运算的两个变量都为真时,结果才为真,否则为假。例如:5>=5 && 7>5 ,运算结果为真;2) 或运算(||)参与运算的两个变量只要有一个为真,结果就为真。 两个量都为假时,结果为假。例如:5>=5||5>8,运算结果为真;3) 非运算(!)参与运算的变量为真时,结果为假;参与运算量为假时,结果为真。例如:!(5>8),运算结果为真。例如:7.三目运算符C语言中的三目运算符:“?:”,其格式为:表达式1 ? 表达式2 : 表达式3;执行过程是:先判断表达式1的值是否为真,如果是真的话执行表达式2;如果是假的话执行表达式3。注意输出: printf("%c\n", price <= money? 'y': 'n')8.运算符大比拼之优先级比较优先级别为1的优先级最高,优先级别为10的优先级别最低。来看一看下面的例子:解析:C语言中运算符中最高等级的为(),因此执行过程为:1、先计算a>3和a+3的结果,计算后算式为1*a-14%3;2、再计算1*a和14%3的结果,计算后算式为11-2;3、最后算出结果为9。