Mercurial > octave
annotate scripts/linear-algebra/vecnorm.m @ 26376:00f796120a6d stable
maint: Update copyright dates in all source files.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 02 Jan 2019 16:32:43 -0500 |
parents | 6652d3823428 |
children | b442ec6dda5c |
rev | line source |
---|---|
26376
00f796120a6d
maint: Update copyright dates in all source files.
John W. Eaton <jwe@octave.org>
parents:
25054
diff
changeset
|
1 ## Copyright (C) 2017-2019 Marco Caliari |
24219
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
2 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
3 ## This file is part of Octave. |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
4 ## |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
24219
diff
changeset
|
5 ## Octave is free software: you can redistribute it and/or modify it |
24219
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
6 ## under the terms of the GNU General Public License as published by |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
24219
diff
changeset
|
7 ## the Free Software Foundation, either version 3 of the License, or |
24219
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
8 ## (at your option) any later version. |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
9 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
10 ## Octave is distributed in the hope that it will be useful, but |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
13 ## GNU General Public License for more details. |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
14 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
15 ## You should have received a copy of the GNU General Public License |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
16 ## along with Octave; see the file COPYING. If not, see |
24534
194eb4bd202b
maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents:
24219
diff
changeset
|
17 ## <https://www.gnu.org/licenses/>. |
24219
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
18 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
19 ## -*- texinfo -*- |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
20 ## @deftypefn {} {@var{n} =} vecnorm (@var{A}) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
21 ## @deftypefnx {} {@var{n} =} vecnorm (@var{A}, @var{p}) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
22 ## @deftypefnx {} {@var{n} =} vecnorm (@var{A}, @var{p}, @var{dim}) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
23 ## Return the p-norm of the elements of @var{A} along dimension @var{dim}. |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
24 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
25 ## The p-norm of a vector is defined as |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
26 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
27 ## @tex |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
28 ## $$ {\Vert A \Vert}_p = \left[ \sum_{i=1}^N {| A_i |}^p \right] ^ {1/p} $$ |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
29 ## @end tex |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
30 ## @ifnottex |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
31 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
32 ## @example |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
33 ## @var{p-norm} (@var{A}, @var{p}) = sum (abs (@var{A}) .^ @var{p})) ^ (1/@var{p}) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
34 ## @end example |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
35 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
36 ## @end ifnottex |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
37 ## If @var{p} is omitted it defaults to 2 (Euclidean norm). @var{p} can be |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
38 ## @code{Inf} (absolute value of largest element). |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
39 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
40 ## If @var{dim} is omitted the first non-singleton dimension is used. |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
41 ## |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
42 ## @seealso{norm} |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
43 ## @end deftypefn |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
44 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
45 function n = vecnorm (A, p = 2, dim) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
46 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
47 if (nargin < 1 || nargin > 3) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
48 print_usage (); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
49 endif |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
50 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
51 if (! isscalar (p) || ! isreal (p) || (p <= 0)) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
52 error ("vecnorm: P must be positive real scalar or Inf"); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
53 endif |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
54 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
55 sz = size (A); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
56 if (nargin <= 2) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
57 ## Find the first non-singleton dimension. |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
58 (dim = find (sz > 1, 1)) || (dim = 1); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
59 elseif (! (isscalar (dim) && dim == fix (dim) && dim > 0)) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
60 error ("vecnorm: DIM must be an integer and a valid dimension"); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
61 endif |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
62 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
63 ## Calculate norm using the value of p to accelerate special cases |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
64 switch (p) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
65 case {1} |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
66 n = sum (abs (A), dim); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
67 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
68 case {2} |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
69 n = sqrt (sumsq (A, dim)); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
70 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
71 case {Inf} |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
72 n = max (abs (A), [], dim); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
73 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
74 otherwise |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
75 if (rem (p,2) == 0) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
76 n = (sum ((real (A).^2 + imag (A).^2) .^ (p/2), dim)) .^ (1 / p); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
77 else |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
78 n = (sum (abs (A) .^ p, dim)) .^ (1 / p); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
79 endif |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
80 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
81 endswitch |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
82 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
83 endfunction |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
84 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
85 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
86 %!test |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
87 %! A = [0 1 2; 3 4 5]; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
88 %! c = vecnorm (A); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
89 %! r = vecnorm (A, 2, 2); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
90 %! i = vecnorm (A, Inf); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
91 %! assert (c, [3.0000, 4.1231, 5.3852], 1e-4); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
92 %! assert (r, [2.2361; 7.0711], 1e-4); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
93 %! assert (i, [3, 4, 5]); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
94 %!test |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
95 %! A = [1, 2]; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
96 %! assert (vecnorm (A), 2.2361, 1e-4); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
97 %!test |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
98 %! A(:, :, 1) = [1, 2]; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
99 %! A(:, :, 2) = [3, 4]; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
100 %! A(:, :, 3) = [5, 6]; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
101 %! ret(:, :, 1) = 2.2361; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
102 %! ret(:, :, 2) = 5; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
103 %! ret(:, :, 3) = 7.8102; |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
104 %! assert (vecnorm (A), ret, 1e-4); |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
105 |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
106 ## Test input validation |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
107 %!error vecnorm () |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
108 %!error vecnorm (1,2,3,4) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
109 %!error <P must be positive real scalar> vecnorm (1, [1 2]) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
110 %!error <P must be positive real scalar> vecnorm (1, i) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
111 %!error <P must be positive real scalar> vecnorm (1, -1) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
112 %!error <P must be positive real scalar> vecnorm (1, 0) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
113 %!error <DIM must be an integer and a valid dimension> vecnorm (1, 2, [1 2]) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
114 %!error <DIM must be an integer and a valid dimension> vecnorm (1, 2, [1 2]) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
115 %!error <DIM must be an integer and a valid dimension> vecnorm (1, 2, 0) |
3d96400df713
Add function vecnorm (bug #52342).
Marco Caliari <marco.caliari@univr.it>
parents:
diff
changeset
|
116 %!error <DIM must be an integer and a valid dimension> vecnorm (1, 2, -1) |