@c -----------------------------------------------------------------------------
@c File        : abs_integrate.de.texi
@c License     : GNU General Public License (GPL)
@c Language    : German
@c Original    : New file
@c Date        : 19.02.2011
@c Revision    : 24.06.2011
@c 
@c This file is part of Maxima -- GPL CAS based on DOE-MACSYMA
@c -----------------------------------------------------------------------------

@menu
* Introduction to abs_integrate::
* Functions and Variables for abs_integrate::
@end menu

@c -----------------------------------------------------------------------------
@node Introduction to abs_integrate, Functions and Variables for abs_integrate, abs_integrate, abs_integrate
@section Introduction to abs_integrate
@c -----------------------------------------------------------------------------

The package @code{abs_integrate} extends Maxima's integration code to
some integrands that involve the absolute value, max, min, signum, or
unit step functions.  For integrands of the form @math{p(x) |q(x)|},
where @math{p} is a polynomial and @math{q} is a polynomial that
@code{factor} is able to factor into a product of linear or constant
terms, the @code{abs_integrate} package determines an antiderivative
that is continuous on the entire real line.  Additionally, for an
integrand that involves one or more parameters, the function
@mref{conditional_integrate} tries to determine an antiderivative that
is valid for all parameter values.

Examples: 

To use the @code{abs_integrate} package, you'll first need to load it:

@example
(%i1) load("abs_integrate.mac")$
(%i2) integrate(abs(x),x);
                            x abs(x)
(%o2)                       --------
                               2
@end example

To convert (%o2) into an expression involving the absolute value function,
apply @mref{signum_to_abs}; thus

@example
(%i3) signum_to_abs(%);
                            x abs(x)
(%o3)                       --------
                               2
@end example

When the integrand has the form @math{p(x) |x - c1| |x - c2| ... |x - cn|},
where @math{p(x)} is a polynomial and @math{c1, c2, ..., cn} are constants,
the @code{abs_integrate} package returns an antiderivative that is valid on the
entire real line; thus @i{without} making assumptions on @math{a} and @math{b};
for example

@example
(%i4) factor(convert_to_signum(integrate(abs((x-a)*(x-b)),x,a,b)));
                            3       2
                     (b - a)  signum (b - a)
(%o4)                -----------------------
                                6
@end example

Additionally, @code{abs_integrate} is able to find antiderivatives of some
integrands involving @mrefcomma{max} @mrefcomma{min} @mrefcomma{signum} and
@mrefcomma{unit_step} examples:

@example
(%i5) integrate(max(x,x^2),x);
           3      2                                        3    2
        2 x  - 3 x    1                   1               x    x
(%o5) ((----------- + --) signum(x - 1) + --) signum(x) + -- + --
            12        12                  12              6    4
(%i6) integrate(signum(x) - signum(1-x),x);
(%o6)                  abs(x) + abs(x - 1)
@end example

A plot indicates that indeed (%o5) and (%o6) are continuous at zero and at one.

For definite integrals with numerical integration limits (including
both minus and plus infinity), the @code{abs_integrate} package
converts the integrand to signum form and then it tries to subdivide
the integration region so that the integrand simplifies to a
non-signum expression on each subinterval; for example

@example
(%i1) load("abs_integrate")$
(%i2) integrate(1 / (1 + abs(x-5)),x,-5,6);
(%o2)                   log(11) + log(2)
@end example

Finally, @code{abs_integrate} is able to determine antiderivatives of
@emph{some} functions of the form @math{F(x, |x - a|)}; examples

@example
(%i3) integrate(1/(1 + abs(x)),x);
      signum(x) (log(x + 1) + log(1 - x))
(%o3) -----------------------------------
                       2
                                          log(x + 1) - log(1 - x)
                                        + -----------------------
                                                     2
(%i4) integrate(cos(x + abs(x)),x);
         (signum(x) + 1) sin(2 x) - 2 x signum(x) + 2 x
(%o4)    ----------------------------------------------
                               4
@end example

@noindent
Barton Willis (Professor of Mathematics, University of Nebraska at
Kearney) wrote the @code{abs_integrate} package and its English
language user documentation.  This documentation also describes the
@code{partition} package for integration.  Richard Fateman wrote
@code{partition}.  Additional documentation for @code{partition} is
located at@*
@url{http://www.cs.berkeley.edu/~fateman/papers/partition.pdf}

@c -----------------------------------------------------------------------------
@node Functions and Variables for abs_integrate,  , Introduction to abs_integrate, abs_integrate
@section Functions and Variables for abs_integrate
@c -----------------------------------------------------------------------------

@c -----------------------------------------------------------------------------
@anchor{extra_integration_methods}
@defvr {Option variable} extra_integration_methods
Default value: @code{['signum_int, 'abs_integrate_use_if]}

The list @code{extra_integration_methods} is a list of functions for
integration.  When @mref{integrate} is unable to find an
antiderivative, Maxima uses the methods in
@code{extra_integration_methods} to attempt to determine an
antiderivative.

Each function @code{f} in @code{extra_integration_methods} should have
the form @code{f(integrand, variable)}.  The function @code{f} may
either return @code{false} to indicate failure, or it may return an
expression involving an integration noun form.  The integration methods
are tried from the first to the last member of
@code{extra_integration_methods}; when no method returns an expression
that does not involve an integration noun form, the value of the
integral is the last value that does not fail (or a pure noun form if
all methods fail).

When the function @code{abs_integrate_use_if} is successful, it returns
a conditional expression; for example

@example
(%i1) load("abs_integrate")$
(%i2) integrate(1/(1 + abs(x+1) + abs(x-1)),x);
                           log(1 - 2 x)            2
(%o2) %if(- (x + 1) > 0, - ------------ + log(3) - -, 
                                2                  3
                                   x   log(3)   1  log(2 x + 1)
                %if(- (x - 1) > 0, - + ------ - -, ------------))
                                   3     2      3       2
(%i3) integrate(exp(-abs(x-1) - abs(x)),x);
                     2 x - 1
                   %e              - 1
(%o3) %if(- x > 0, --------- - 2 %e   , 
                       2
                                               - 1      1 - 2 x
                                   - 1     3 %e       %e
              %if(- (x - 1) > 0, %e    x - -------, - ---------))
                                              2           2
@end example

For definite integration, these conditional expressions can cause trouble:

@example
(%i4) integrate(exp(-abs(x-1) - abs(x)),x, minf,inf);
                               - 1    2 x
                             %e    (%e    - 4)
(%o4) limit     %if(- x > 0, -----------------, 
      x -> inf-                      2
                     - 1                1 - 2 x
                   %e    (2 x - 3)    %e
%if(- (x - 1) > 0, ---------------, - ---------))
                          2               2
                             - 1    2 x
                           %e    (%e    - 4)
 - limit      %if(- x > 0, -----------------, 
   x -> minf+                      2
                     - 1                1 - 2 x
                   %e    (2 x - 3)    %e
%if(- (x - 1) > 0, ---------------, - ---------))
                          2               2
@end example

For such definite integrals, try disallowing the method
@code{abs_integrate_use_if}:

@example
(%i5) integrate(exp(-abs(x-1) - abs(x)),x, minf,inf),
          extra_integration_methods : ['signum_int];
                                 - 1
(%o5)                        2 %e
@end example

Related options @mrefdot{extra_definite_integration_methods}

To use @code{load("abs_integrate")}
@end defvr

@c -----------------------------------------------------------------------------
@anchor{extra_definite_integration_methods}
@defvr {Option variable} extra_definite_integration_methods
Default value: @code{['abs_defint]}

The list @code{extra_definite_integration_methods} is a list of extra
functions for @i{definite} integration.  When @mref{integrate} is
unable to find a definite integral, Maxima uses the methods in
@code{extra_definite_integration_methods} to attempt to determine an
antiderivative.

Each function @code{f} in @code{extra_definite_integration_methods}
should have the form @code{f(integrand, variable, lo, hi)}, where
@code{lo} and @code{hi} are the lower and upper limits of integration,
respectively.  The function @code{f} may either return @code{false} to
indicate failure, or it may return an expression involving an
integration noun form.  The integration methods are tried from the
first to the last member of @code{extra_definite_integration_methods};
when no method returns an expression that does not involve an
integration noun form, the value of the integral is the last value
that does not fail (or a pure noun form if all methods fail).

Related options @mrefdot{extra_integration_methods}

To use @code{load("abs_integrate")}.
@end defvr

@c -----------------------------------------------------------------------------
@anchor{intfudu}
@deffn {Function} intfudu (@var{e}, @var{x})

This function uses the derivative divides rule for integrands of the
form @math{f(w(x)) * diff(w(x),x)}.  When @code{infudu} is unable to find
an antiderivative, it returns false.

@example
(%i1) load("abs_integrate")$
(%i2) intfudu(cos(x^2) * x,x);
                                  2
                             sin(x )
(%o2)                        -------
                                2
(%i3) intfudu(x * sqrt(1+x^2),x);
                             2     3/2
                           (x  + 1)
(%o3)                      -----------
                                3
(%i4) intfudu(x * sqrt(1 + x^4),x);
(%o4)                         false
@end example

For the last example, the derivative divides rule fails, so
@code{intfudu} returns false.

A hashed array @code{intable} contains the antiderivative data.  To append a
fact to the hash table, say @math{integrate(f) = g}, do this:

@example
(%i5) intable[f] : lambda([u],  [g(u),diff(u,%voi)]);
(%o5)          lambda([u], [g(u), diff(u, %voi)])
(%i6) intfudu(f(z),z);
(%o6)                         g(z)
(%i7) intfudu(f(w(x)) * diff(w(x),x),x);
(%o7)                        g(w(x))
@end example

An alternative to calling @code{intfudu} directly is to use the 
@mref{extra_integration_methods} mechanism; an example:

@c TODO: DAS FOLGENDE BEISPIEL IST NICHT MEHR KORREKT. MAXIMA KANN DIE
@c       BESSELFUNKTIONEN STANDARDMAESSIG INTEGRIEREN.

@example
(%i1) load("abs_integrate")$
(%i2) load("basic")$
(%i3) load("partition.mac")$

(%i4) integrate(bessel_j(1,x^2) * x,x);
                                       2
                          bessel_j(0, x )
(%o4)                   - ---------------
                                 2
(%i5) push('intfudu, extra_integration_methods)$

(%i6) integrate(bessel_j(1,x^2) * x,x);
                                       2
                          bessel_j(0, x )
(%o6)                   - ---------------
                                 2
@end example

To use @code{load("partition")}.

Additional documentation@*
@url{http://www.cs.berkeley.edu/~fateman/papers/partition.pdf}.

Related functions @mrefdot{intfugudu}
@end deffn

@c -----------------------------------------------------------------------------
@anchor{intfugudu}
@deffn {Function} intfugudu (@var{e}, @var{x})

This function uses the derivative divides rule for integrands of the
form @math{f(w(x)) * g(w(x)) * diff(w(x),x)}.  When @code{infugudu} is
unable to find an antiderivative, it returns false.

@example
(%i1) load("abs_integrate")$
(%i2) diff(jacobi_sn(x,2/3),x);
                              2               2
(%o2)            jacobi_cn(x, -) jacobi_dn(x, -)
                              3               3
(%i3) intfugudu(%,x);
                                      2
(%o3)                    jacobi_sn(x, -)
                                      3
(%i4) diff(jacobi_dn(x^2,a),x);
                               2                2
(%o4)       - 2 a x jacobi_cn(x , a) jacobi_sn(x , a)
(%i5) intfugudu(%,x);
                                   2
(%o5)                   jacobi_dn(x , a)
@end example

For a method for automatically calling @code{infugudu} from @code{integrate},
see the documentation for @code{intfudu}.

To use @code{load("partition")}.

Additional documentation@*
@url{http://www.cs.berkeley.edu/~fateman/papers/partition.pdf}

Related functions @mrefdot{intfudu}
@end deffn

@c -----------------------------------------------------------------------------
@anchor{signum_to_abs}
@deffn {Function} signum_to_abs (@var{e})
 
This function replaces subexpressions of the form @math{q signum(q)} by
@math{abs(q)}.  Before it does these substitutions, it replaces
subexpressions of the form @math{signum(p) * signum(q)} by
@math{signum(p * q)}; examples:

@example
(%i1) load("abs_integrate")$
(%i2) map('signum_to_abs, [x * signum(x), 
                           x * y * signum(x)* signum(y)/2]);
                              abs(x) abs(y)
(%o2)                [abs(x), -------------]
                                    2
@end example

To use @code{load("abs_integrate")}.
@end deffn

@c -----------------------------------------------------------------------------
@anchor{simp_assuming}
@deffn {Macro} simp_assuming (@var{e}, @var{f_1}, @var{f_2}, @dots{}, @var{f_n})

Appended the facts @math{f_1, f_2, @dots{}, f_n} to the current context and
simplify @math{e}.  The facts are removed before returning the simplified
expression @math{e}.

@example
(%i1) load("abs_integrate")$
(%i2) simp_assuming(x + abs(x), x < 0);
(%o2)                           0
@end example

The facts in the current context aren't ignored:

@example
(%i3) assume(x > 0)$
(%i4) simp_assuming(x + abs(x),x < 0);
(%o4)                          2 x
@end example

Since @code{simp_assuming} is a macro, effectively @code{simp_assuming} quotes
is arguments; this allows

@example
(%i5) simp_assuming(asksign(p), p < 0);
(%o5)                          neg
@end example

To use @code{load("abs_integrate")}.
@end deffn

@c -----------------------------------------------------------------------------
@anchor{conditional_integrate}
@deffn {Function} conditional_integrate (@var{e}, @var{x})

For an integrand with one or more parameters, this function tries to determine
an antiderivative that is valid for all parameter values.  When successful, this
function returns a conditional expression for the antiderivative.

@example
(%i1) load("abs_integrate")$
(%i2) conditional_integrate(cos(m*x),x);
                                sin(m x)
(%o2)                %if(m # 0, --------, x)
                                   m
(%i3) conditional_integrate(cos(m*x)*cos(x),x);

(%o3) %if((m - 1 # 0) %and (m + 1 # 0), 
(m - 1) sin((m + 1) x) + (- m - 1) sin((1 - m) x)
-------------------------------------------------, 
                       2
                    2 m  - 2
sin(2 x) + 2 x
--------------)
      4
(%i4) sublis([m=6],%);
                     5 sin(7 x) + 7 sin(5 x)
(%o4)                -----------------------
                               70
(%i5) conditional_integrate(exp(a*x^2+b*x),x);
@group
                                  2
                                 b
                               - ---
                                 4 a      2 a x + b
                   sqrt(%pi) %e      erf(-----------)
                                         2 sqrt(- a)
(%o5) %if(a # 0, - ----------------------------------, 
                              2 sqrt(- a)
                                                         b x
                                                       %e
                                            %if(b # 0, -----, x))
                                                         b
@end group
@end example
@end deffn

@c -----------------------------------------------------------------------------
@anchor{convert_to_signum}
@deffn {Function} convert_to_signum (@var{e})

This function replaces subexpressions of the form @code{abs(q), unit_step(q),
min(q1, q2, ..., qn)} and @code{max(q1, q2, ..., qn)} by equivalent
@math{signum} terms.

@example
(%i1) load("abs_integrate")$
(%i2) map('convert_to_signum, [abs(x), unit_step(x), 
                               max(a,2), min(a,2)]);

                    signum(x) (signum(x) + 1)
(%o2) [x signum(x), -------------------------, 
                                2
  (a - 2) signum(a - 2) + a + 2  - (a - 2) signum(a - 2) + a + 2
  -----------------------------, -------------------------------]
                2                               2
@end example

To convert @mref{unit_step} to signum form, the function
@code{convert_to_signum} uses @math{unit_step(x) = (1 + signum(x))/2}.

To use @code{load("abs_integrate")}.

Related functions @mrefdot{signum_to_abs}
@end deffn

@c --- End of file abs_integrate.de.texi ---------------------------------------

