操作方程和不等式
方程 | 消去变量 |
解方程 | 关系运算符和逻辑运算符 |
方程和解的表示 | 求解逻辑组合的方程组 |
一元方程 | 不等式 |
多项式根的计数及隔离 | 不同域上的方程和不等式 |
代数数 | 解集的表示法 |
联立方程组 | 量词 |
通解和非通解 | 最小化和最大化 |
区分清楚 x=y 和 x==y 是很重要的. x=y 是强制进行赋值操作的声明,而 x==y 只检验 x 和 y 是否相等,而不引起明确的行动. 使用过C语言的用户会看出 Wolfram 语言的赋值和检验表示法与 C 语言是相同的.
Wolfram 语言并不检验这两个表达式是否相等. 此时,使用 Expand 将使他们有相同的形式:
Solve[lhs==rhs,x] | 解方程,给出 x 的替换规则列表 |
x/.solution | 使用替换规则得到 x 的值 |
expr/.solution | 使用规则得到表达式的值 |
解方程时,Solve 总试图给出精确的解析解. 然而,根据数学的基本结论,对很复杂的方程是求不出解析解的. 在解一元代数方程时,如果变量的最高次数不超过4,那么 Wolfram 语言总能给出解析解. 但如果最高次数是 5 或更高,给出精确解析解在数学上一般是不可能的.
对那些在数学上不可能求出精确解析解的方程,Wolfram 语言使用 Root 对象表示方程的解:
函数 Solve 也能处理具有符号函数的方程. 在此情况下,又显示一个警告,然后给出形式上的反函数的结果.
Solve[{lhs1==rhs1,lhs2==rhs2,…},{x,y,…}] | |
关于变量 x,y,… 求解方程组 |
一个方程组是否有解是一个很不清楚的问题. 例如,对 a 的大多数值,方程组 {x==1,x==a} 是不相容的,所以关于 x 无解. 然而,如果 a 等于 1,则方程有一个解. 函数 Solve 被设置为求方程的一般解. 不考虑那些仅对参数的特殊值才存在的解.
Solve[lhs==rhs,x] | 关于 x 求解方程 |
Solve[{lhs1==rhs1,lhs2==rhs2,…},{x,y,…}] | |
关于 x,y,… 求解联立方程组 | |
Eliminate[{lhs1==rhs1,lhs2==rhs2,…},{x,…}] | |
在联立方程组中,消去 x,… | |
Reduce[{lhs1==rhs1,lhs2==rhs2,…},{x,y,…}] | |
给出一组简化方程,包括所有可能的解 |
Wolfram 系统将方程作为逻辑语句处理. 如果键入一个方程如:x^2+3x==2,那么 Wolfram 系统将其解释为声明x^2+3x 等于 2 的语句. 如果已经明显地给 x 赋了值,如 x=4,那么 Wolfram 系统能确定逻辑声明x^2+3x==2 为 False.
二次方程 x^2+3x==2 可以看作关于 x 值的隐式描述. 综合上述例子所示,可以使用函数 Reduce 得到 x 值的显式描述. 由 Reduce 生成的表达式为 x==r1x==r2 的形式. 这还是一个逻辑语句,声明 x 等于 r1,或 x 等于 r2. 这个语句给出的 x 值与原方程给出的 x 值是完全一样的. 然而多数情况下,Reduce 给出的形式比原方程更有用.
多数情况下,把方程简单地作为逻辑语句处理是方便的. 但有时在其他运算中,用户实际上想使用方程的显式解. 此时,将形如 lhs==rhs 的方程转换为形如 lhsrhs 的变换规则是方便的. 一旦有了方程的具有显式变换规则形式的解,就可以使用算符 /. 将解代入表达式.
ToRules 将逻辑语句转换为变换规则的显式列表:
函数 Solve 直接生成解的变换规则:
Solve 和相关的 Wolfram 语言函数处理的方程主要是多项式方程.
对于这种能分解因式的多项式,Solve 直接求出根:
这个多项式不能分解多项式,但能分解成嵌套多项式,所以 Solve 也能求出根的显式公式:
Root[f,k] | 方程 f[x]==0 的 k 次根 |
如果用户最终想要数值解,那么使用 NSolve 将快得多:
这里是上面讨论的多项式的第一个根的 Root 对象:
函数 Round 使用精确计算求出最接近这个根的整数:
Solve 给出此方程的两个相等的解:
单变量的多项式方程组只有有限数目的解. 但是,超越方程往往有无穷多解. 通常的原因是,超越函数实际上有无穷多可能的逆函数. 使用默认选项设置 InverseFunctionsTrue,Solve 将假定任何这种函数有确定的逆函数. Solve 可能能够关于此逆函数返回特定的解.
Wolfram 语言关于 ProductLog 返回特定的解,但显示警告说明其他的解可能被丢失:
InverseFunction[f] | f 的逆函数 |
InverseFunction[f,k,n] | 具有 n 个参数的函数 f 关于第 k 个参数的逆函数 |
Reduce 知道这里不可能有解:
计算多项式根的数目
CountRoots[poly,x] | 给出多项式 poly 关于 x 的实数根的数目 |
CountRoots[poly,{x,a,b}] | 给出多项式 poly 关于 x 满足 的根的数目 |
CountRoots 接受具有高斯有理数系数的多项式. 根的数目包含了重数.
隔离区间
RootIntervals[{poly1,poly2,…}] | 给出任何一个多项式 polyi 的实根的不相交隔离区间的列表,连同一个有关与每个相连的根对应的是哪个多项式的列表 |
RootIntervals[poly] | 给出单个多项式的实根的不相交隔离区间 |
RootIntervals[polys,Complexes] | 给出 polys 的复数根的不相交隔离区间或矩形 |
IsolatingInterval[a] | 给出代数数 a 的一个隔离区间 |
IsolatingInterval[a,dx] | 给出一个宽度至多为 dx 的隔离区间 |
RootIntervals 接受具有有理数系数的多项式.
Root[f,k] | 多项式方程 f[x]==0 的 k 次根 |
当输入一个 Root 对象时,其中的多项式自动被化简为极小形式:
Root 对象是 Wolfram 语言表示代数数的方式. 代数数有这样的性质:当对其进行代数运算时,总是得到单个代数数.
还是能被化简成单个 Root 对象,尽管是相当复杂的:
RootReduce[expr] | 尝试化简 expr 为单个 Root 对象 |
ToRadicals[expr] | 尝试转换 Root 对象为显式根式 |
在这种简单情形下,Root 对象自动表示为根式:
当包含三次多项式时,Root 对象不能自动表示为根式:
如果 Solve 和 ToRadicals 不能成功地用根式表示某多项式方程的解,那么可以猜测其本质上是做不到的. 但应当认识到,有些特殊情形,化为根式在原理上是可能的. 但 Wolfram 系统找不到. 最简单的例子是方程 ,但这里用根式表示的解是非常复杂的. 方程 是另一个例子,此时 是一个解.
给出一个包含6次多项式的 Root 对象:
尽管存在单个的根式形式,ToRadicals 找不到:
RootApproximant[x] | 把数字 x 转换成一个近似的“最简单”的代数数 |
RootApproximant[x,n] | 求近似 x 的次数不超过 n 的代数数 |
确认 Root 表达式对应于 :
可以使用 N 得到数值结果:
如果不明显地指出要求解的对象,Solve 将对所有变量求解:
■ Solve[{lhs1==rhs1,lhs2==rhs2,…},vars] |
■ Solve[lhs1==rhs1&&lhs2==rhs2&&…,vars] |
■ Solve[{lhs1,lhs2,…}=={rhs1,rhs2,…},vars] |
给 Solve 提供联立方程组的几种方法.
Solve 将包含列表的方程转换为方程的列表:
可以使用 LogicalExpand 直接做转换:
在某些类型的计算中,可以方便地使用系数数组而非显式方程. 用户可以使用 CoefficientArrays 从方程构造数组.
如有一个方程 2x==0,显然仅有的解是 x0. 但是如果有方程 ax==0,事情就不那么清楚了. 当 a 不等于零时,仍然有唯一解 x0. 然而,当 a 实际上等于零时,那么 x 的任何值都是解. 可以使用 Reduce 查看这些功能.
Reduce 和 Solve 之间最重要的区别在于 Reduce 给出方程组的全部解,而 Solve 仅给出通解. 通解是指只涉及要求的变量条件,而不涉及方程中参数的条件. Reduce 和 Solve 的另一个区别是 Reduce 总是返回方程的组合,而 Solve 给出变换规则形式的结果.
Solve 给出的任意线性方程的解:
该解不是通解. 故被 Solve 拒绝:
当方程对任何值都成立时,Solve 返回的结果:
Solve 报告没有通解:
Solve 显示该方程组没有一般解:
Reduce 给出解存在的完全条件:
在 Wolfram 语言中,写出一组联立方程,也就是指定变量之间的约束集合. 使用 Solve,就是在方程的约束下,求一些变量用其他变量表示的值.
有时,用户可能想明显地构造变量已被消去的方程,使用 Eliminate 可以做到这一点.
SolveAlways[eqns,vars] | 求对 vars 的所有值 eqns 都被满足的参数值 |
x==y | 等于(也输入为 xy) |
x!=y | 不等于(也输入为 x≠y) |
x>y | 大于 |
x>=y | 大于等于(也输入为 x≥y) |
x<y | 小于 |
x<=y | 小于等于(也输入为 x≤y) |
x==y==z | 全相等 |
x!=y!=z | 互不相等(不同) |
x>y>z ,etc. | 严格递减,等等. |
这些数并非全不相等,故结果为 False:
!p | 非(也输入为 ¬p) |
p&&q&&… | 与(也输入为 p∧q∧…) |
pq… | 或(也输入为 p∨q∨…) |
Xor[p,q,…] | 异或(也输入为 p⊻q⊻…) |
Nand[p,q,…] and Nor[p,q,…] | 与非和或非(也输入为 ⊼ 和 ⊽) |
If[p,then,else] | |
LogicalExpand[expr] | 展开逻辑表达式 |
使用 LogicalExpand 展开这些项:
Solve 给出这个方程的三个解:
eqns1eqns2 | 解集的并 |
eqns1&&eqns2 | 解集的交 |
!eqns | 解集的补 |
Implies[eqns1,eqns2] | eqns1 中包含 eqns2 的部分 |
正如 "算符" 中讨论的,我们经常会发现对逻辑连接符使用特殊表示法往往是方便的.
Reduce[{ineq1,ineq2,…},x] | 化简关于 x 的不等式集合 |
当应用于方程时,Reduce[eqn,x] 试图获得由x 的形式 x==r1,… 的简单方程组组成的结果. 而当应用于不等式时,Reduce[ineq,x] 做完全类似的事情,并试图获得由 x 的形式为 l1<x<r1,… 的简单不等式组成的结果.
由 Reduce[ineq,x] 产生的结果可以用来代表由不等式描述的一系列区间. 由于 次多项式的图示可以上下起伏多达 次, 次多项不等式可以产生多达 个不同区间.
求解该不等式需要引入 ProductLog:
这个例子表明 Reduce 如何代表无穷多的区间:
Reduce[{ineq1,ineq2,…},{x1 , x2,… }] | 化简由一些变量组成的不等式集合 |
对于包含多个变量的不等式,Reduce 产生具体区间的嵌套集合,这里后来的变量具有依赖于前面变量的边界.
从几何上看,任何线性不等式把空间分为两半. 因此,线性不等式的列表定义了多面体,有时候是有界的,有时候不是. Reduce 用嵌套不等式表示这样的多面体. 多面体的角总是出现在这些不等式的终端.
如果有包含参数的不等式,Reduce 自动处理可能出现的不同情况,正如其对方程的处理一样.
FindInstance[ineqs,{x1,x2,…}] | 试图寻找满足 ineqs 的 xi 的例子 |
FindInstance[ineqs,vars,n] | 试图寻找 n 个例子 |
FindInstance 在一定程度上类似于用于方程的 Solve 的不等式. 类似于 Solve,返回一个给出变量具体值的规则列表. 但是,尽管对于方程,这些值可以笼统地给出所有解的准确表示,然而,对于不等式,只能对应于由不等式所描述的区域内的孤立样本点.
每次使用具体输入调用 FindInstance,将给出同样的输出. 并且当我们有对应于有些特殊或局限性的点的实例,将优先返回这些输出. 但一般而言,由 FindInstance 返回的实例的分布通常看起来有点随机. 然而,每个实例实际上建设性地证明了用户所提供的不等式是可以被满足的.
如果要求单位园板中的一点,FindInstance 给出原点:
Wolfram 语言通常假定方程中出现的变量可以代表任意复数. 但是当用户使用 Reduce 时,可以明确地告诉 Wolfram 语言变量表示更严格的域中的对象.
但是一旦我们有更多的变量时,情况就变得更复杂了,我们就有了对应于参数曲线或表面的方程的解,但是对这些参数曲线或表面来说,一些变量的值可以依赖于其他变量的值. 通常,这种依赖性可以使用方程或不等式的集合来描述,但是当我们从一种域到另一种域时,这种依赖的形式可能发生显著的变化.
虽然原则上 Reduce 总是可以对具有实变量或复数变量的多项式方程和不等式找到完整的解,由于组成部分的数目通常在变量数目增加的时候呈指数增长,所有结果经常是很复杂的.
一旦用户引入函数如 Sin 或者 Exp,即使是单个实变量或复数变量的方程也能有具有有限数目的组成部分的解. Reduce 通过引入其他额外的参数对这些组成部分加标签. 但是默认情况下,在一个给定的解中,第 个参数被命名为C[n]. 一般情况下,用户可以通过给出选项设置 GeneratedParameters->f 指明他应该被命名为 f[n].
Reduce 不仅可以处理实数变量和复数变量的方程,也能够处理整数变量的方程. 求解这样的 Diophantine equations 经常可能是很困难的问题.
Reduce 可以在整数域上求解任意线性方程或不等式系统. 在具有 个变量的 个线性方程的情况下,通常需要引入 个参数. 但是在不等式的情况下,可能需要引入更多更多的参数.
在两个变量的情况下,Reduce 可以在整数域上求解任何二次方程. 结果可以是形如 Fibonacci 的序列,由二次无理数的幂表示.
特定的 C[1] 的实际值是整数,正如他们本应该是的一样:
Reduce 可以处理整数域上的许多特殊的方程类别.
Reduce 对一个 Thue 方程求解:
对于在实数和复数域上的多项式方程,我们具有一个确定的决策过程( decision procedure )来决定是否有解存在. 但是对于整数域上的多项式方程,Hilbert’s tenth 问题的无解性表明不可能有这样的普遍适用的过程.
然而,对于一些专门类别的方程,我们可以找到这样的过程,事实上,许多这样的过程在 Reduce 中得到实现. 但是处理不同类别的方程可能经常需要使用数论的所有不同分支,而且也需要许多不同类别的计算. 事实上,我们称之为普遍 ( universal )整数多项式方程,在这种情况下,输入一些变量可以使其他变量的解对应于任何可能程序的输出. 这意味着对于这样的方程,一般不可能从固定元素,如代数函数,建立任何闭集解.
如果包含函数如 Sin,那么即使对涉及实数和复数的方程,也可能出现同样的问题.
Reduce 有效地在整数范围内求解一个方程:
Reduce 也可以处理涉及几个不同 moduli 的方程.
FindInstance[expr,{x1,x2,…},dom] | 试图寻找在 dom 中满足 expr 的 xi 的一个实例 |
FindInstance[expr,vars,dom,n] | 试图寻找 n 个实例 |
Complexes | 复数域 |
Reals | 实数域 |
Integers | 整数域 |
Booleans |
如果 FindInstance[expr,vars,dom] 返回 {},那么这意味着 Wolfram 语言可以有效地证明 expr 不能被特定域内的变量值所满足. 当 expr 可以被满足的时候,FindInstance 通常将任意选择值来实现,如 "不等式" 中关于不等式的讨论.
FindInstance 的一个特征是对于变量为 True 或 False 的布尔表达式也适用. 可以使用 FindInstance 来决定一个特定的表达式是否是可满足的,因此对于可使表达式为 True 的这些变量的真值,具有一些选择.
方程或不等式的任意组合可以被明确定义为某种空间的一个区域. 基本函数 Reduce 把这种类型的隐式描述转化为显式描述.
关于方程或不等式的隐式描述是足够的,如果用户只是想要测试由变量值指定的一个点是否位于区域内. 但是为了理解区域的结构,或者产生区域内的点,用户通常需要一个更明确的描述,如从 Reduce 中获得的一样.
Reduce 给出区域更明确的表示法:
Reduce[expr,{x1,x2,…}] 被设置用来描述区域,具体方法如下:首先给出对 x1 的固定条件,然后给出取决于 x1 的 x2 的条件,接下来是取决于 x1 和 x2 的 x3 的条件,以此类推. 该结构具有特征,允许用户通过连续对每个 xi 依次选值来挑选点—与当用户在函数如 Table 中使用迭代方法很相似.
在一些简单的情况下,由方程或不等式系统定义的区域将最终只有一个组成部分. 在这样的情况下,从 Reduce 得到的输出将具有形式 e1&&e2…,其中每个 ei 是一个涉及变量 xi 的方程或不等式.
然而,在大部分情况下,将有几个组成部分,由包含形式如 u1u2… 的输出表示. Reduce 通常试图最小化用来描述区域的组成部分的数量. 但是在一些情况下,可能需要多参数化来覆盖单个连接的组成部分,其中每个部分都将作为 Reduce 的输出中的不同部分出现.
在表示解集时,通常寻找一些可以使用如 …&&(u1u2)&&… 的形式描述的组成部分. 默认情况下,Reduce 这样做以使得返回结果尽可能的紧凑. 用户可以使用 LogicalExpand 来产生一个展开形式,其中每个组成部分分隔出现.
在产生最紧凑结果的过程中,有时候 Reduce 最终使后来的变量 xi 的条件更多取决于前面的 xi,然而这并不是严格必须的. 用户可以通过设置选项 BacksubstitutionTrue. 迫使 Reduce 产生特定 xi 只对前面的 xi 有最小依赖性的结果. 通常这将导致相当大的输出,虽然对结果可能更容易解释.
CylindricalDecomposition[expr,{x1,x2,…}] | |
产生由 expr 定义的区域的柱形代数分解 | |
GenericCylindricalDecomposition[expr,{x1,x2,…}] | |
寻找由 expr 定义区域的分解的完全维度部分,以及区域剩余部分的超曲面 | |
SemialgebraicComponentInstances[expr,{x1,x2,…}] | |
给出每个由 expr 定义区域的连接部分中的至少一个点 |
对于实数上的多项式方程或不等式,由 Reduce 返回的结果的结构通常是柱形代数分解 (cylindrical algebraic decomposition )或 CAD. 有时候 Reduce 可以产生更简单的形式. 但是在所有情况下,用户可以通过使用CylindricalDecomposition 获得完整的CAD. 对于只包含不等式的系统, GenericCylindricalDecomposition 给出“大部分”解集,并且通常更快.
ForAll[x,expr] | expr 对 x 所有值成立 |
ForAll[{x1,x2,…},expr] | expr 对所有 xi 的所有值成立 xi |
ForAll[{x1,x2,…},cond,expr] | expr 对所有满足 cond 的 xi 成立 |
Exists[x,expr] | 存在 x 的值使得 expr 成立 |
Exists[{x1,x2,…},expr] | 存在 xi 的值使得 expr 成立 |
Exists[{x1,…},cond,expr] | 存在 xi 的值满足 cond 并使得 expr 成立 |
用户可以在 Wolfram 语言中像使用方程、不等式或逻辑语句一样经常地使用量词. 在绝大多数情况下,量词将不会因为计算立即被改变. 但是可以通过函数如 FullSimplify 和 Reduce 简化或消去.
FullSimplify 验证了该声明为真:
Wolfram 语言支持在谓词逻辑和纯数学中使用的量词的标准记号版本. 可以输入 作为 \[ForAll] 或者 EscfaEsc,并且可以输入 作为 \[Exists] 或者 EscexEsc. 然而,为了使得记号更为精确,Wolfram 语言使量化的变量作为一个下标. 变量所满足的条件也可以在下标中提供,使用逗号分隔.
∀xexpr | ForAll[x,expr] |
∀{x1,x2,…}expr | ForAll[{x1,x2,…},expr] |
∀x,condexpr | ForAll[x,cond,expr] |
∃xexpr | Exists[x,expr] |
∃{x1,x2,…}expr | Exists[{x1,x2,…},expr] |
∃x,condexpr | Exists[x,cond,expr] |
Resolve 可以总是在复数范围内的多项式等式和不等式集合,以及实数范围内的多项式等式和不等式集合中消去量词. 其也可以从布尔表达式中消去量词.
也可以以 Reduce 的方式使用量词. 如果用户给 Reduce 提供了一个等式或者不等式的集合,那么他将会试图产生完整解集的具体表示. 但是有时候,用户可能想要表示一个更为全局的问题,比如,解集是否包含 x 的所有值,或者是否不包含任何值. 量词给我们提供了指明这些问题的方便的途径.
Minimize[expr,{x1,x2,…}] | 最小化 expr |
Minimize[{expr,cons},{x1,x2,…}] | 最小化 expr,约束条件为 cons |
Maximize[expr,{x1,x2,…}] | 最大化 expr |
Maximize[{expr,cons},{x1,x2,…}] | 最大化 expr,约束条件为 cons |
Minimize[expr,x] 最小化 expr,并允许 x 位于从 到 的所有可能值范围内. Minimize[{expr,cons},x] 最小化 expr,并满足约束条件 cons. 约束条件可以包括等式和不等式的任意组合.
Minimize 和 Maximize 的一个重要特征是他们总是寻找全局最小值和最大值. 通常,函数会有不同的局部极小值和极大值,在该处梯度为零. 但是 Minimize 和 Maximize 使用全局方法寻找绝对最小值和最大值,而非局部极值.
Maximize 寻找全局最大值:
如果给出无界函数,Minimize 和 Maximize 将返回 和 作为最小值和最大值. 如果用户给的约束条件永远不能满足,他们将返回 和 作为最小值和最大值,并且 Indeterminate 作为变量值.
Minimize 和 Maximize 的精妙之处是允许不严格的不等式 和严格不等式 . 在不严格不等式的情况下,最小值或最大值恰好位于边界 是没有问题的. 但是如果在严格不等式的情况下,原则上,一个最小值或最大值必须至少无限位于边界以内.
MinValue[{f,cons},{x,y,…}] | 给出 f 的最小值,约束条件为 cons |
MaxValue[{f,cons},{x,y,…}] | 给出 f 的最大值,约束条件为 cons |
ArgMin[{f,cons},{x,y,…}] | 给出 f 在约束条件 cons 下被最小化的位置 |
ArgMax[{f,cons},{x,y,…}] | 给出 f 在约束条件 cons 下被最大化的位置 |
Maximize 给出最大值的值和位置:
如果只需要最大值,则使用 MaxValue:
ArgMax 给出取得最大值的位置: