This file is indexed.

/usr/share/octave/packages/interval-2.1.0/@infsup/expm.m is in octave-interval 2.1.0-2.

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
## Copyright 2016 Oliver Heimlich
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @documentencoding UTF-8
## @defmethod {@@infsup} expm (@var{A})
## 
## Compute the matrix exponential of square matrix @var{A}.
##
## The matrix exponential is defined as the infinite Taylor series
##
## @tex
## $$
##  {\rm expm} (A) = \sum_{k = 0}^{\infty} {A^k \over k!}
## $$
## @end tex
## @ifnottex
## @group
## @verbatim
##                     A²     A³
## expm (A) = I + A + ---- + ---- + …
##                     2!     3!
## @end verbatim
## @end group
## @end ifnottex
##
## The function implements the following algorithm:  1. The matrix is scaled,
## 2. an enclosure of the Taylor series is computed using the Horner scheme,
## 3. the matrix is squared.  That is, the algorithm computes
## @code{expm (@var{A} ./ pow2 (@var{L})) ^ pow2 (@var{L})}.  The scaling
## reduces the matrix norm below 1, which reduces errors during exponentiation.
## Exponentiation typically is done by Padé approximation, but that doesn't
## work for interval matrices, so we compute a Horner evaluation of the Taylor
## series.  Finally, the exponentiation with @code{pow2 (@var{L})} is computed
## with @var{L} successive interval matrix square operations.  Interval matrix
## square operations can be done without dependency errors (regarding each
## single step).
##
## The algorithm has been published by Alexandre Goldsztejn and Arnold
## Neumaier (2009), “On the Exponentiation of Interval Matrices.” 
##
## Accuracy: The result is a valid enclosure.
##
## @example
## @group
## vec (expm (infsup(magic (3))))
##   @result{} ans ⊂ 9×1 interval vector
##
##        [1.0897e+06, 1.0898e+06]
##        [1.0896e+06, 1.0897e+06]
##        [1.0896e+06, 1.0897e+06]
##        [1.0895e+06, 1.0896e+06]
##        [1.0897e+06, 1.0898e+06]
##        [1.0897e+06, 1.0898e+06]
##        [1.0896e+06, 1.0897e+06]
##        [1.0896e+06, 1.0897e+06]
##        [1.0896e+06, 1.0897e+06]
##
## @end group
## @end example
## @seealso{@@infsup/mpower, @@infsup/exp}
## @end defmethod

## Author: Oliver Heimlich
## Keywords: interval
## Created: 2016-01-26

function result = expm (A)

if (nargin ~= 1)
    print_usage ();
    return
endif

if (isscalar (A))
    ## Short-circuit for scalars
    result = exp (A);
    return
endif

if (not (issquare (A.inf)))
    error ("interval:InvalidOperand", ...
           "expm: must be square matrix");
endif

## Choose L such that ||A|| / 2^L < 0.1 and 10 <= L <= 100
L = min (max (inf (ceil (log2 (10 * norm (A, inf)))), 10), 100);
## Choose K such that K + 2 > ||A|| and 10 <= K <= 170
K = min (max (inf (ceil (norm (A, inf) - 2)), 10), 170);

## 1. Scale
A = rdivide (A, pow2 (L));

## 2. Compute Taylor series
## Compute Horner scheme: I + A*(I + A/2*(I + A/3*( ... (I + A/K) ... )))
result = I = eye (size (A.inf));
for k = K : -1 : 1
    result = I + A ./ k * result;
endfor
## Truncation error for the exponential series
alpha = norm (A, inf);
rho = pown (alpha, K + 1) ./ ...
      (factorial (infsup (K + 1)) * (1 - alpha ./ (K + 2)));
warning ("off", "interval:ImplicitPromote", "local");
truncation_error = rho .* infsup (-1, 1);
result = result + truncation_error;

## 3. Squaring
result = mpower (result, pow2 (L));

endfunction

%!# from the paper
%!test
%! A = infsup ([0 1; 0 -3], [0 1; 0 -2]);
%! assert (all (all (subset (infsup ([1, 0.316738; 0, 0.0497871], [1, 0.432332; 0, 0.135335]), expm (A)))));