aboutsummaryrefslogtreecommitdiff
path: root/src/algebra/defintrf.spad.pamphlet
diff options
context:
space:
mode:
Diffstat (limited to 'src/algebra/defintrf.spad.pamphlet')
-rw-r--r--src/algebra/defintrf.spad.pamphlet398
1 files changed, 398 insertions, 0 deletions
diff --git a/src/algebra/defintrf.spad.pamphlet b/src/algebra/defintrf.spad.pamphlet
new file mode 100644
index 00000000..097192a5
--- /dev/null
+++ b/src/algebra/defintrf.spad.pamphlet
@@ -0,0 +1,398 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra defintrf.spad}
+\author{Manuel Bronstein}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package DFINTTLS DefiniteIntegrationTools}
+<<package DFINTTLS DefiniteIntegrationTools>>=
+)abbrev package DFINTTLS DefiniteIntegrationTools
+++ Tools for definite integration
+++ Author: Manuel Bronstein
+++ Date Created: 15 April 1992
+++ Date Last Updated: 24 February 1993
+++ Description:
+++ \spadtype{DefiniteIntegrationTools} provides common tools used
+++ by the definite integration of both rational and elementary functions.
+DefiniteIntegrationTools(R, F): Exports == Implementation where
+ R : Join(GcdDomain, OrderedSet, RetractableTo Integer,
+ LinearlyExplicitRingOver Integer)
+ F : Join(TranscendentalFunctionCategory,
+ AlgebraicallyClosedFunctionSpace R)
+
+ B ==> Boolean
+ Z ==> Integer
+ Q ==> Fraction Z
+ SE ==> Symbol
+ P ==> Polynomial R
+ RF ==> Fraction P
+ UP ==> SparseUnivariatePolynomial F
+ K ==> Kernel F
+ OFE ==> OrderedCompletion F
+ UPZ ==> SparseUnivariatePolynomial Z
+ UPQ ==> SparseUnivariatePolynomial Q
+ REC ==> Record(left:Q, right:Q)
+ REC2==> Record(endpoint:Q, dir:Z)
+ U ==> Union(fin:REC, halfinf:REC2, all:"all", failed:"failed")
+ IGNOR ==> "noPole"
+
+ Exports ==> with
+ ignore?: String -> B
+ ++ ignore?(s) is true if s is the string that tells the integrator
+ ++ to assume that the function has no pole in the integration interval.
+ computeInt: (K, F, OFE, OFE, B) -> Union(OFE, "failed")
+ ++ computeInt(x, g, a, b, eval?) returns the integral of \spad{f} for x
+ ++ between a and b, assuming that g is an indefinite integral of
+ ++ \spad{f} and \spad{f} has no pole between a and b.
+ ++ If \spad{eval?} is true, then \spad{g} can be evaluated safely
+ ++ at \spad{a} and \spad{b}, provided that they are finite values.
+ ++ Otherwise, limits must be computed.
+ checkForZero: (P, SE, OFE, OFE, B) -> Union(B, "failed")
+ ++ checkForZero(p, x, a, b, incl?) is true if p has a zero for x between
+ ++ a and b, false otherwise, "failed" if this cannot be determined.
+ ++ Check for a and b inclusive if incl? is true, exclusive otherwise.
+ checkForZero: (UP, OFE, OFE, B) -> Union(B, "failed")
+ ++ checkForZero(p, a, b, incl?) is true if p has a zero between
+ ++ a and b, false otherwise, "failed" if this cannot be determined.
+ ++ Check for a and b inclusive if incl? is true, exclusive otherwise.
+
+ Implementation ==> add
+ import RealZeroPackage UPZ
+ import InnerPolySign(F, UP)
+ import ElementaryFunctionSign(R, F)
+ import PowerSeriesLimitPackage(R, F)
+ import UnivariatePolynomialCommonDenominator(Z, Q, UPQ)
+
+ mkLogPos : F -> F
+ keeprec? : (Q, REC) -> B
+ negative : F -> Union(B, "failed")
+ mkKerPos : K -> Union(F, "positive")
+ posRoot : (UP, B) -> Union(B, "failed")
+ realRoot : UP -> Union(B, "failed")
+ var : UP -> Union(Z, "failed")
+ maprat : UP -> Union(UPZ, "failed")
+ variation : (UP, F) -> Union(Z, "failed")
+ infeval : (UP, OFE) -> Union(F, "failed")
+ checkHalfAx : (UP, F, Z, B) -> Union(B, "failed")
+ findLimit : (F, K, OFE, String, B) -> Union(OFE, "failed")
+ checkBudan : (UP, OFE, OFE, B) -> Union(B, "failed")
+ checkDeriv : (UP, OFE, OFE) -> Union(B, "failed")
+ sameSign : (UP, OFE, OFE) -> Union(B, "failed")
+ intrat : (OFE, OFE) -> U
+ findRealZero: (UPZ, U, B) -> List REC
+
+ variation(p, a) == var p(monomial(1, 1)$UP - a::UP)
+ keeprec?(a, rec) == (a > rec.right) or (a < rec.left)
+
+ checkHalfAx(p, a, d, incl?) ==
+ posRoot(p(d * (monomial(1, 1)$UP - a::UP)), incl?)
+
+ ignore? str ==
+ str = IGNOR => true
+ error "integrate: last argument must be 'noPole'"
+
+ computeInt(k, f, a, b, eval?) ==
+ is?(f, "integral"::SE) => "failed"
+ if not eval? then f := mkLogPos f
+ ((ib := findLimit(f, k, b, "left", eval?)) case "failed") or
+ ((ia := findLimit(f, k, a, "right", eval?)) case "failed") => "failed"
+ infinite?(ia::OFE) and (ia::OFE = ib::OFE) => "failed"
+ ib::OFE - ia::OFE
+
+ findLimit(f, k, a, dir, eval?) ==
+ r := retractIfCan(a)@Union(F, "failed")
+ r case F =>
+ eval? => mkLogPos(eval(f, k, r::F))::OFE
+ (u := limit(f, equation(k::F, r::F), dir)) case OFE => u::OFE
+ "failed"
+ (u := limit(f, equation(k::F::OFE, a))) case OFE => u::OFE
+ "failed"
+
+ mkLogPos f ==
+ lk := empty()$List(K)
+ lv := empty()$List(F)
+ for k in kernels f | is?(k, "log"::SE) repeat
+ if (v := mkKerPos k) case F then
+ lk := concat(k, lk)
+ lv := concat(v::F, lv)
+ eval(f, lk, lv)
+
+ mkKerPos k ==
+ (u := negative(f := first argument k)) case "failed" =>
+ log(f**2) / (2::F)
+ u::B => log(-f)
+ "positive"
+
+ negative f ==
+ (u := sign f) case "failed" => "failed"
+ u::Z < 0
+
+ checkForZero(p, x, a, b, incl?) ==
+ checkForZero(
+ map(#1::F, univariate(p, x))$SparseUnivariatePolynomialFunctions2(P, F),
+ a, b, incl?)
+
+ checkForZero(q, a, b, incl?) ==
+ ground? q => false
+ (d := maprat q) case UPZ and not((i := intrat(a, b)) case failed) =>
+ not empty? findRealZero(d::UPZ, i, incl?)
+ (u := checkBudan(q, a, b, incl?)) case "failed" =>
+ incl? => checkDeriv(q, a, b)
+ "failed"
+ u::B
+
+ maprat p ==
+ ans:UPQ := 0
+ while p ^= 0 repeat
+ (r := retractIfCan(c := leadingCoefficient p)@Union(Q,"failed"))
+ case "failed" => return "failed"
+ ans := ans + monomial(r::Q, degree p)
+ p := reductum p
+ map(numer,(splitDenominator ans).num
+ )$SparseUnivariatePolynomialFunctions2(Q, Z)
+
+ intrat(a, b) ==
+ (n := whatInfinity a) ^= 0 =>
+ (r := retractIfCan(b)@Union(F,"failed")) case "failed" => ["all"]
+ (q := retractIfCan(r::F)@Union(Q, "failed")) case "failed" =>
+ ["failed"]
+ [[q::Q, n]]
+ (q := retractIfCan(retract(a)@F)@Union(Q,"failed")) case "failed"
+ => ["failed"]
+ (n := whatInfinity b) ^= 0 => [[q::Q, n]]
+ (t := retractIfCan(retract(b)@F)@Union(Q,"failed")) case "failed"
+ => ["failed"]
+ [[q::Q, t::Q]]
+
+ findRealZero(p, i, incl?) ==
+ i case fin =>
+ l := realZeros(p, r := i.fin)
+ incl? => l
+ select_!(keeprec?(r.left, #1) and keeprec?(r.right, #1), l)
+ i case all => realZeros p
+ i case halfinf =>
+ empty?(l := realZeros p) => empty()
+ bounds:REC :=
+ i.halfinf.dir > 0 => [i.halfinf.endpoint, "max"/[t.right for t in l]]
+ ["min"/[t.left for t in l], i.halfinf.endpoint]
+ l := [u::REC for t in l | (u := refine(p, t, bounds)) case REC]
+ incl? => l
+ select_!(keeprec?(i.halfinf.endpoint, #1), l)
+ error "findRealZero: should not happpen"
+
+ checkBudan(p, a, b, incl?) ==
+ r := retractIfCan(b)@Union(F, "failed")
+ (n := whatInfinity a) ^= 0 =>
+ r case "failed" => realRoot p
+ checkHalfAx(p, r::F, n, incl?)
+ (za? := zero? p(aa := retract(a)@F)) and incl? => true
+ (n := whatInfinity b) ^= 0 => checkHalfAx(p, aa, n, incl?)
+ (zb? := zero? p(bb := r::F)) and incl? => true
+ (va := variation(p, aa)) case "failed" or
+ (vb := variation(p, bb)) case "failed" => "failed"
+ m:Z := 0
+ if za? then m := inc m
+ if zb? then m := inc m
+ odd?(v := va::Z - vb::Z) => -- p has an odd number of roots
+ incl? or even? m => true
+-- one? v => false
+ (v = 1) => false
+ "failed"
+ zero? v => false -- p has no roots
+-- one? m => true -- p has an even number > 0 of roots
+ (m = 1) => true -- p has an even number > 0 of roots
+ "failed"
+
+ checkDeriv(p, a, b) ==
+ (r := retractIfCan(p)@Union(F, "failed")) case F => zero?(r::F)
+ (s := sameSign(p, a, b)) case "failed" => "failed"
+ s::B => -- p has the same nonzero sign at a and b
+ (u := checkDeriv(differentiate p,a,b)) case "failed" => "failed"
+ u::B => "failed"
+ false
+ true
+
+ realRoot p ==
+ (b := posRoot(p, true)) case "failed" => "failed"
+ b::B => true
+ posRoot(p(p - monomial(1, 1)$UP), true)
+
+ sameSign(p, a, b) ==
+ (ea := infeval(p, a)) case "failed" => "failed"
+ (eb := infeval(p, b)) case "failed" => "failed"
+ (s := sign(ea::F * eb::F)) case "failed" => "failed"
+ s::Z > 0
+
+-- returns true if p has a positive root. Include 0 is incl0? is true
+ posRoot(p, incl0?) ==
+ (z0? := zero?(coefficient(p, 0))) and incl0? => true
+ (v := var p) case "failed" => "failed"
+ odd?(v::Z) => -- p has an odd number of positive roots
+ incl0? or not(z0?) => true
+-- one?(v::Z) => false
+ (v::Z) = 1 => false
+ "failed"
+ zero?(v::Z) => false -- p has no positive roots
+ z0? => true -- p has an even number > 0 of positive roots
+ "failed"
+
+ infeval(p, a) ==
+ zero?(n := whatInfinity a) => p(retract(a)@F)
+ (u := signAround(p, n, sign)) case "failed" => "failed"
+ u::Z::F
+
+ var q ==
+ i:Z := 0
+ (lastCoef := negative leadingCoefficient q) case "failed" =>
+ "failed"
+ while ((q := reductum q) ^= 0) repeat
+ (next := negative leadingCoefficient q) case "failed" =>
+ return "failed"
+ if ((not(lastCoef::B)) and next::B) or
+ ((not(next::B)) and lastCoef::B) then i := i + 1
+ lastCoef := next
+ i
+
+@
+\section{package DEFINTRF RationalFunctionDefiniteIntegration}
+<<package DEFINTRF RationalFunctionDefiniteIntegration>>=
+)abbrev package DEFINTRF RationalFunctionDefiniteIntegration
+++ Definite integration of rational functions.
+++ Author: Manuel Bronstein
+++ Date Created: 2 October 1989
+++ Date Last Updated: 2 February 1993
+++ Description:
+++ \spadtype{RationalFunctionDefiniteIntegration} provides functions to
+++ compute definite integrals of rational functions.
+
+
+RationalFunctionDefiniteIntegration(R): Exports == Implementation where
+ R : Join(EuclideanDomain, OrderedSet, CharacteristicZero,
+ RetractableTo Integer, LinearlyExplicitRingOver Integer)
+
+ SE ==> Symbol
+ RF ==> Fraction Polynomial R
+ FE ==> Expression R
+ ORF ==> OrderedCompletion RF
+ OFE ==> OrderedCompletion FE
+ U ==> Union(f1:OFE, f2:List OFE, fail:"failed", pole:"potentialPole")
+
+ Exports ==> with
+ integrate: (RF, 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: (RF, 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".
+-- the following two are contained in the above, but they are for the
+-- interpreter... DO NOT COMMENT OUT UNTIL THE INTERPRETER IS BETTER!
+ integrate: (RF, SegmentBinding ORF) -> 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: (RF, SegmentBinding ORF, 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".
+
+ Implementation ==> add
+ import DefiniteIntegrationTools(R, FE)
+ import IntegrationResultRFToFunction(R)
+ import OrderedCompletionFunctions2(RF, FE)
+
+ int : (RF, SE, OFE, OFE, Boolean) -> U
+ nopole: (RF, SE, OFE, OFE) -> U
+
+ integrate(f:RF, s:SegmentBinding OFE) ==
+ int(f, variable s, lo segment s, hi segment s, false)
+
+ nopole(f, x, a, b) ==
+ k := kernel(x)@Kernel(FE)
+ (u := integrate(f, x)) case FE =>
+ (v := computeInt(k, u::FE, a, b, true)) case "failed" => ["failed"]
+ [v::OFE]
+ ans := empty()$List(OFE)
+ for g in u::List(FE) repeat
+ (v := computeInt(k, g, a, b, true)) case "failed" => return ["failed"]
+ ans := concat_!(ans, [v::OFE])
+ [ans]
+
+ integrate(f:RF, s:SegmentBinding ORF) ==
+ int(f, variable s, map(#1::FE, lo segment s),
+ map(#1::FE, hi segment s), false)
+
+ integrate(f:RF, s:SegmentBinding ORF, str:String) ==
+ int(f, variable s, map(#1::FE, lo segment s),
+ map(#1::FE, hi segment s), ignore? str)
+
+ integrate(f:RF, s:SegmentBinding OFE, str:String) ==
+ int(f, variable s, lo segment s, hi segment s, ignore? str)
+
+ int(f, x, a, b, ignor?) ==
+ a = b => [0::OFE]
+ (z := checkForZero(denom f, x, a, b, true)) case "failed" =>
+ ignor? => nopole(f, x, a, b)
+ ["potentialPole"]
+ z::Boolean => error "integrate: pole in path of integration"
+ nopole(f, x, a, b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<package DFINTTLS DefiniteIntegrationTools>>
+<<package DEFINTRF RationalFunctionDefiniteIntegration>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}