/usr/share/axiom-20170501/src/algebra/DEFINTEF.spad is in axiom-source 20170501-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | )abbrev package DEFINTEF ElementaryFunctionDefiniteIntegration
++ Author: Manuel Bronstein
++ Date Created: 14 April 1992
++ Date Last Updated: 2 February 1993
++ Description:
++ \spadtype{ElementaryFunctionDefiniteIntegration}
++ provides functions to compute definite
++ integrals of elementary functions.
ElementaryFunctionDefiniteIntegration(R, F) : SIG == CODE where
R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
RetractableTo Integer, LinearlyExplicitRingOver Integer)
F : Join(TranscendentalFunctionCategory, PrimitiveFunctionCategory,
AlgebraicallyClosedFunctionSpace R)
B ==> Boolean
SE ==> Symbol
Z ==> Integer
P ==> SparseMultivariatePolynomial(R, K)
K ==> Kernel F
UP ==> SparseUnivariatePolynomial F
OFE ==> OrderedCompletion F
U ==> Union(f1:OFE, f2:List OFE, fail:"failed", pole:"potentialPole")
SIG ==> with
integrate : (F, SegmentBinding OFE) -> U
++ integrate(f, x = a..b) returns the integral of
++ \spad{f(x)dx} from a to b.
++ Error: if f has a pole for x between a and b.
integrate : (F, SegmentBinding OFE, String) -> U
++ integrate(f, x = a..b, "noPole") returns the
++ integral of \spad{f(x)dx} from a to b.
++ If it is not possible to check whether f has a pole for x
++ between a and b (because of parameters), then this function
++ will assume that f has no such pole.
++ Error: if f has a pole for x between a and b or
++ if the last argument is not "noPole".
innerint : (F, SE, OFE, OFE, B) -> U
++ innerint(f, x, a, b, ignore?) should be local but conditional
CODE ==> add
import ElementaryFunctionSign(R, F)
import DefiniteIntegrationTools(R, F)
import FunctionSpaceIntegration(R, F)
polyIfCan : (P, K) -> Union(UP, "failed")
int : (F, SE, OFE, OFE, B) -> U
nopole : (F, SE, K, OFE, OFE) -> U
checkFor0 : (P, K, OFE, OFE) -> Union(B, "failed")
checkSMP : (P, SE, K, OFE, OFE) -> Union(B, "failed")
checkForPole: (F, SE, K, OFE, OFE) -> Union(B, "failed")
posit : (F, SE, K, OFE, OFE) -> Union(B, "failed")
negat : (F, SE, K, OFE, OFE) -> Union(B, "failed")
moreThan : (OFE, Fraction Z) -> Union(B, "failed")
if R has Join(ConvertibleTo Pattern Integer, PatternMatchable Integer)
and F has SpecialFunctionCategory then
import PatternMatchIntegration(R, F)
innerint(f, x, a, b, ignor?) ==
((u := int(f, x, a, b, ignor?)) case f1) or (u case f2)
or ((v := pmintegrate(f, x, a, b)) case "failed") => u
[v::F::OFE]
else
innerint(f, x, a, b, ignor?) == int(f, x, a, b, ignor?)
integrate(f:F, s:SegmentBinding OFE) ==
innerint(f, variable s, lo segment s, hi segment s, false)
integrate(f:F, s:SegmentBinding OFE, str:String) ==
innerint(f, variable s, lo segment s, hi segment s, ignore? str)
int(f, x, a, b, ignor?) ==
a = b => [0::OFE]
k := kernel(x)@Kernel(F)
(z := checkForPole(f, x, k, a, b)) case "failed" =>
ignor? => nopole(f, x, k, a, b)
["potentialPole"]
z::B => error "integrate: pole in path of integration"
nopole(f, x, k, a, b)
checkForPole(f, x, k, a, b) ==
((u := checkFor0(d := denom f, k, a, b)) case "failed") or (u::B) => u
((u := checkSMP(d, x, k, a, b)) case "failed") or (u::B) => u
checkSMP(numer f, x, k, a, b)
-- true if p has a zero between a and b exclusive
checkFor0(p, x, a, b) ==
(u := polyIfCan(p, x)) case UP => checkForZero(u::UP, a, b, false)
(v := isTimes p) case List(P) =>
for t in v::List(P) repeat
((w := checkFor0(t, x, a, b)) case "failed") or (w::B) => return w
false
(r := retractIfCan(p)@Union(K, "failed")) case "failed" => "failed"
k := r::K
-- functions with no real zeros
is?(k, "exp"::SE) or is?(k, "acot"::SE) or is?(k, "cosh"::SE) => false
-- special case for log
is?(k, "log"::SE) =>
(w := moreThan(b, 1)) case "failed" or not(w::B) => w
moreThan(-a, -1)
"failed"
-- returns true if a > b, false if a < b, "failed" if can't decide
moreThan(a, b) ==
(r := retractIfCan(a)@Union(F, "failed")) case "failed" => -- infinite
whatInfinity(a) > 0
(u := retractIfCan(r::F)@Union(Fraction Z, "failed")) case "failed" =>
"failed"
u::Fraction(Z) > b
-- true if p has a pole between a and b
checkSMP(p, x, k, a, b) ==
(u := polyIfCan(p, k)) case UP => false
(v := isTimes p) case List(P) =>
for t in v::List(P) repeat
((w := checkSMP(t, x, k, a, b)) case "failed") or (w::B) => return w
false
(v := isPlus p) case List(P) =>
n := 0 -- number of summand having a pole
for t in v::List(P) repeat
(w := checkSMP(t, x, k, a, b)) case "failed" => return w
if w::B then n := n + 1
zero? n => false -- no summand has a pole
(n = 1) => true -- only one summand has a pole
"failed" -- at least 2 summands have a pole
(r := retractIfCan(p)@Union(K, "failed")) case "failed" => "failed"
kk := r::K
-- nullary operators have no poles
nullary? operator kk => false
f := first argument kk
-- functions which are defined over all the reals:
is?(kk, "exp"::SE) or is?(kk, "sin"::SE) or is?(kk, "cos"::SE)
or is?(kk, "sinh"::SE) or is?(kk, "cosh"::SE) or is?(kk, "tanh"::SE)
or is?(kk, "sech"::SE) or is?(kk, "atan"::SE) or is?(kk, "acot"::SE)
or is?(kk, "asinh"::SE) => checkForPole(f, x, k, a, b)
-- functions which are defined on (-1,+1):
is?(kk, "asin"::SE) or is?(kk, "acos"::SE) or is?(kk, "atanh"::SE) =>
((w := checkForPole(f, x, k, a, b)) case "failed") or (w::B) => w
((w := posit(f - 1, x, k, a, b)) case "failed") or (w::B) => w
negat(f + 1, x, k, a, b)
-- functions which are defined on (+1, +infty):
is?(kk, "acosh"::SE) =>
((w := checkForPole(f, x, k, a, b)) case "failed") or (w::B) => w
negat(f - 1, x, k, a, b)
-- functions which are defined on (0, +infty):
is?(kk, "log"::SE) =>
((w := checkForPole(f, x, k, a, b)) case "failed") or (w::B) => w
negat(f, x, k, a, b)
"failed"
-- returns true if it is certain that f takes at least one strictly positive
-- value for x in (a,b), false if it is certain that f takes no strictly
-- positive value in (a,b), "failed" otherwise
-- f must be known to have no poles in (a,b)
posit(f, x, k, a, b) ==
z :=
(r:= retractIfCan(a)@Union(F, "failed")) case "failed" => sign(f, x, a)
sign(f, x, r::F, "right")
(b1 := z case Z) and z::Z > 0 => true
z :=
(r:= retractIfCan(b)@Union(F, "failed")) case "failed" => sign(f, x, b)
sign(f, x, r::F, "left")
(b2 := z case Z) and z::Z > 0 => true
b1 and b2 =>
((w:= checkFor0(numer f, k, a, b)) case "failed") or (w::B) => "failed"
false
"failed"
-- returns true if it is certain that f takes at least one strictly negative
-- value for x in (a,b), false if it is certain that f takes no strictly
-- negative value in (a,b), "failed" otherwise
-- f must be known to have no poles in (a,b)
negat(f, x, k, a, b) ==
z :=
(r:= retractIfCan(a)@Union(F, "failed")) case "failed" => sign(f, x, a)
sign(f, x, r::F, "right")
(b1 := z case Z) and z::Z < 0 => true
z :=
(r:= retractIfCan(b)@Union(F, "failed")) case "failed" => sign(f, x, b)
sign(f, x, r::F, "left")
(b2 := z case Z) and z::Z < 0 => true
b1 and b2 =>
((w:= checkFor0(numer f, k, a, b)) case "failed") or (w::B) => "failed"
false
"failed"
-- returns a UP if p is only a poly w.r.t. the kernel x
polyIfCan(p, x) ==
q := univariate(p, x)
ans:UP := 0
while q ^= 0 repeat
member?(x, tower(c := leadingCoefficient(q)::F)) => return "failed"
ans := ans + monomial(c, degree q)
q := reductum q
ans
-- integrate f for x between a and b assuming that f has no pole in between
nopole(f, x, k, a, b) ==
(u := integrate(f, x)) case F =>
(v := computeInt(k, u::F, a, b, false)) case "failed" => ["failed"]
[v::OFE]
ans := empty()$List(OFE)
for g in u::List(F) repeat
(v := computeInt(k, g, a, b, false)) case "failed" => return ["failed"]
ans := concat_!(ans, [v::OFE])
[ans]
|