annotate scripts/optimization/pqpnonneg.m @ 30564:796f54d4ddbf stable

update Octave Project Developers copyright for the new year In files that have the "Octave Project Developers" copyright notice, update for 2021. In all .txi and .texi files except gpl.txi and gpl.texi in the doc/liboctave and doc/interpreter directories, change the copyright to "Octave Project Developers", the same as used for other source files. Update copyright notices for 2022 (not done since 2019). For gpl.txi and gpl.texi, change the copyright notice to be "Free Software Foundation, Inc." and leave the date at 2007 only because this file only contains the text of the GPL, not anything created by the Octave Project Developers. Add Paul Thomas to contributors.in.
author John W. Eaton <jwe@octave.org>
date Tue, 28 Dec 2021 18:22:40 -0500
parents 7854d5752dd2
children e5e35410da90
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
27923
bd51beb6205e update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents: 27919
diff changeset
1 ########################################################################
bd51beb6205e update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents: 27919
diff changeset
2 ##
30564
796f54d4ddbf update Octave Project Developers copyright for the new year
John W. Eaton <jwe@octave.org>
parents: 29359
diff changeset
3 ## Copyright (C) 2008-2022 The Octave Project Developers
27918
b442ec6dda5c use centralized file for copyright info for individual contributors
John W. Eaton <jwe@octave.org>
parents: 26376
diff changeset
4 ##
27923
bd51beb6205e update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents: 27919
diff changeset
5 ## See the file COPYRIGHT.md in the top-level directory of this
bd51beb6205e update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents: 27919
diff changeset
6 ## distribution or <https://octave.org/copyright/>.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
7 ##
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
8 ## This file is part of Octave.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
9 ##
24534
194eb4bd202b maint: Update punctuation for GPL v3 license text.
Rik <rik@octave.org>
parents: 23220
diff changeset
10 ## Octave is free software: you can redistribute it and/or modify it
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
11 ## 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: 23220
diff changeset
12 ## the Free Software Foundation, either version 3 of the License, or
22755
3a2b891d0b33 maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents: 22323
diff changeset
13 ## (at your option) any later version.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
14 ##
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
15 ## Octave is distributed in the hope that it will be useful, but
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
16 ## WITHOUT ANY WARRANTY; without even the implied warranty of
22755
3a2b891d0b33 maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents: 22323
diff changeset
17 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3a2b891d0b33 maint: Standardize Copyright formatting.
Rik <rik@octave.org>
parents: 22323
diff changeset
18 ## GNU General Public License for more details.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
19 ##
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
20 ## You should have received a copy of the GNU General Public License
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
21 ## 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: 23220
diff changeset
22 ## <https://www.gnu.org/licenses/>.
27923
bd51beb6205e update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents: 27919
diff changeset
23 ##
bd51beb6205e update formatting of copyright notices
John W. Eaton <jwe@octave.org>
parents: 27919
diff changeset
24 ########################################################################
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
25
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
26 ## -*- texinfo -*-
20852
516bb87ea72e 2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents: 20735
diff changeset
27 ## @deftypefn {} {@var{x} =} pqpnonneg (@var{c}, @var{d})
516bb87ea72e 2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents: 20735
diff changeset
28 ## @deftypefnx {} {@var{x} =} pqpnonneg (@var{c}, @var{d}, @var{x0})
22760
c4d80b9d2898 maint: Capitalize variable names appearing in error() messages of m-files.
Rik <rik@octave.org>
parents: 22755
diff changeset
29 ## @deftypefnx {} {@var{x} =} pqpnonneg (@var{c}, @var{d}, @var{x0}, @var{options})
20852
516bb87ea72e 2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents: 20735
diff changeset
30 ## @deftypefnx {} {[@var{x}, @var{minval}] =} pqpnonneg (@dots{})
516bb87ea72e 2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents: 20735
diff changeset
31 ## @deftypefnx {} {[@var{x}, @var{minval}, @var{exitflag}] =} pqpnonneg (@dots{})
516bb87ea72e 2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents: 20735
diff changeset
32 ## @deftypefnx {} {[@var{x}, @var{minval}, @var{exitflag}, @var{output}] =} pqpnonneg (@dots{})
516bb87ea72e 2015 Code Sprint: remove class of function from docstring for all m-files.
Rik <rik@octave.org>
parents: 20735
diff changeset
33 ## @deftypefnx {} {[@var{x}, @var{minval}, @var{exitflag}, @var{output}, @var{lambda}] =} pqpnonneg (@dots{})
20165
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
34 ##
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
35 ## Minimize @code{1/2*@var{x}'*@var{c}*@var{x} + @var{d}'*@var{x}} subject to
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
36 ## @code{@var{x} >= 0}.
20165
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
37 ##
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
38 ## @var{c} and @var{d} must be real matrices, and @var{c} must be symmetric and
20165
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
39 ## positive definite.
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
40 ##
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
41 ## @var{x0} is an optional initial guess for the solution @var{x}.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
42 ##
22760
c4d80b9d2898 maint: Capitalize variable names appearing in error() messages of m-files.
Rik <rik@octave.org>
parents: 22755
diff changeset
43 ## @var{options} is an options structure to change the behavior of the
28959
5394d688d456 doc: Use @code{} within alternate text for @xref,@pxref macros for better Info display.
Rik <rik@octave.org>
parents: 28942
diff changeset
44 ## algorithm (@pxref{XREFoptimset,,@code{optimset}}). @code{pqpnonneg}
5394d688d456 doc: Use @code{} within alternate text for @xref,@pxref macros for better Info display.
Rik <rik@octave.org>
parents: 28942
diff changeset
45 ## recognizes one option: @qcode{"MaxIter"}.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
46 ##
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
47 ## Outputs:
14366
b76f0740940e doc: Periodic grammar check of documentation.
Rik <octave@nomad.inbox5.com>
parents: 14363
diff changeset
48 ##
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
49 ## @table @var
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
50 ##
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
51 ## @item x
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
52 ## The solution matrix
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
53 ##
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
54 ## @item minval
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
55 ## The minimum attained model value,
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
56 ## @code{1/2*@var{xmin}'*@var{c}*@var{xmin} + @var{d}'*@var{xmin}}
10821
693e22af08ae Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents: 10793
diff changeset
57 ##
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
58 ## @item exitflag
20165
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
59 ## An indicator of convergence. 0 indicates that the iteration count was
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
60 ## exceeded, and therefore convergence was not reached; >0 indicates that the
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
61 ## algorithm converged. (The algorithm is stable and will converge given
f1d0f506ee78 doc: Update more docstrings to have one sentence summary as first line.
Rik <rik@octave.org>
parents: 19833
diff changeset
62 ## enough iterations.)
10821
693e22af08ae Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents: 10793
diff changeset
63 ##
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
64 ## @item output
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
65 ## A structure with two fields:
14366
b76f0740940e doc: Periodic grammar check of documentation.
Rik <octave@nomad.inbox5.com>
parents: 14363
diff changeset
66 ##
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
67 ## @itemize @bullet
25003
2365c2661b3c doc: Spellcheck documentation ahead of 4.4 release.
Rik <rik@octave.org>
parents: 24534
diff changeset
68 ## @item @qcode{"algorithm"}: The algorithm used (@nospell{@qcode{"nnls"}})
10821
693e22af08ae Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents: 10793
diff changeset
69 ##
17281
bc924baa2c4e doc: Add new @qcode macro for code samples which are quoted.
Rik <rik@octave.org>
parents: 14366
diff changeset
70 ## @item @qcode{"iterations"}: The number of iterations taken.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
71 ## @end itemize
10821
693e22af08ae Grammarcheck documentation of m-files
Rik <octave@nomad.inbox5.com>
parents: 10793
diff changeset
72 ##
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
73 ## @item lambda
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
74 ## @c FIXME: Something is output from the function, but what is it?
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
75 ## Undocumented output
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
76 ## @end table
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
77 ## @seealso{lsqnonneg, qp, optimset}
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
78 ## @end deftypefn
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
79
13027
b9a89ca0fb75 prevent optimization functions from setting ans in workspace at startup
John W. Eaton <jwe@octave.org>
parents: 11588
diff changeset
80 ## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup.
b9a89ca0fb75 prevent optimization functions from setting ans in workspace at startup
John W. Eaton <jwe@octave.org>
parents: 11588
diff changeset
81 ## PKG_ADD: [~] = __all_opts__ ("pqpnonneg");
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
82
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
83 ## This is analogical to the lsqnonneg implementation, which is implemented
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
84 ## from Lawson and Hanson's 1973 algorithm on page 161 of Solving Least Squares
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
85 ## Problems. It shares the convergence guarantees.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
86
22769
9bd2ea5703e2 lsqnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22764
diff changeset
87 function [x, minval, exitflag, output, lambda] = pqpnonneg (c, d, x0 = [],
9bd2ea5703e2 lsqnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22764
diff changeset
88 options = struct ())
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
89
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
90 ## Special case: called to find default optimization options
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
91 if (nargin == 1 && ischar (c) && strcmp (c, "defaults"))
26138
804e18e3e320 Reenable query of optimization options (bugs #54952 and #55089).
Kai T. Ohlhus <k.ohlhus@gmail.com>
parents: 25579
diff changeset
92 x = struct ("MaxIter", 1e5);
17312
088d014a7fe2 Use semicolon after "return" statement in core m-files.
Rik <rik@octave.org>
parents: 17281
diff changeset
93 return;
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
94 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
95
28789
28de41192f3c Eliminate unneeded verification of nargin, nargout in m-files.
Rik <rik@octave.org>
parents: 27923
diff changeset
96 if (nargin < 2)
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
97 print_usage ();
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
98 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
99
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
100 if (! (isnumeric (c) && ismatrix (c)) || ! (isnumeric (d) && ismatrix (d)))
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
101 error ("pqpnonneg: C and D must be numeric matrices");
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
102 endif
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
103 if (! issquare (c))
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
104 error ("pqpnonneg: C must be a square matrix");
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
105 endif
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
106
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
107 if (! isstruct (options))
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
108 error ("pqpnonneg: OPTIONS must be a struct");
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
109 endif
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
110
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
111 ## Lawson-Hanson Step 1 (LH1): initialize the variables.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
112 n = columns (c);
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
113 if (isempty (x0))
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
114 ## Initial guess is all zeros.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
115 x = zeros (n, 1);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
116 else
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
117 ## ensure nonnegative guess.
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
118 x = max (x0, 0);
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
119 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
120
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
121 max_iter = optimget (options, "MaxIter", 1e5);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
122
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
123 ## Initialize P, according to zero pattern of x.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
124 p = find (x > 0).';
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
125 ## Initialize the Cholesky factorization.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
126 r = chol (c(p, p));
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
127 usechol = true;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
128
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
129 iter = 0;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
130
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
131 ## LH3: test for completion.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
132 while (iter < max_iter)
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
133 while (iter < max_iter)
20735
418ae0cb752f Replace ++,-- with in-place operators for performance.
Rik <rik@octave.org>
parents: 20165
diff changeset
134 iter += 1;
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
135
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
136 ## LH6: compute the positive matrix and find the min norm solution
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
137 ## of the positive problem.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
138 if (usechol)
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
139 xtmp = -(r \ (r' \ d(p)));
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
140 else
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
141 xtmp = -(c(p,p) \ d(p));
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
142 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
143 idx = find (xtmp < 0);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
144
11587
c792872f8942 all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents: 11523
diff changeset
145 if (isempty (idx))
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
146 ## LH7: tmp solution found, iterate.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
147 x(:) = 0;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
148 x(p) = xtmp;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
149 break;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
150 else
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
151 ## LH8, LH9: find the scaling factor.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
152 pidx = p(idx);
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
153 sf = x(pidx) ./ (x(pidx) - xtmp(idx));
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
154 alpha = min (sf);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
155 ## LH10: adjust X.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
156 xx = zeros (n, 1);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
157 xx(p) = xtmp;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
158 x += alpha*(xx - x);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
159 ## LH11: move from P to Z all X == 0.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
160 ## This corresponds to those indices where minimum of sf is attained.
19833
9fc020886ae9 maint: Clean up m-files to follow Octave coding conventions.
Rik <rik@octave.org>
parents: 19697
diff changeset
161 idx = idx(sf == alpha);
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
162 p(idx) = [];
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
163 if (usechol)
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
164 ## update the Cholesky factorization.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
165 r = choldelete (r, idx);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
166 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
167 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
168 endwhile
11587
c792872f8942 all script files: untabify and strip trailing whitespace
John W. Eaton <jwe@octave.org>
parents: 11523
diff changeset
169
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
170 ## compute the gradient.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
171 w = -(d + c*x);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
172 w(p) = [];
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
173 if (! any (w > 0))
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
174 if (usechol)
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
175 ## verify the solution achieved using qr updating.
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
176 ## In the best case, this should only take a single step.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
177 usechol = false;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
178 continue;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
179 else
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
180 ## we're finished.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
181 break;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
182 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
183 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
184
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
185 ## find the maximum gradient.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
186 idx = find (w == max (w));
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
187 if (numel (idx) > 1)
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
188 warning ("pqpnonneg:nonunique",
11588
d5bd2766c640 style fixes for warning and error messages in script files
John W. Eaton <jwe@octave.org>
parents: 11587
diff changeset
189 "a non-unique solution may be returned due to equal gradients");
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
190 idx = idx(1);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
191 endif
21751
b571fc85953f maint: Use two spaces after period to indicate sentence break.
Rik <rik@octave.org>
parents: 21178
diff changeset
192 ## move the index from Z to P. Keep P sorted.
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
193 z = [1:n]; z(p) = [];
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
194 zidx = z(idx);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
195 jdx = 1 + lookup (p, zidx);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
196 p = [p(1:jdx-1), zidx, p(jdx:end)];
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
197 if (usechol)
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
198 ## insert the column into the Cholesky factorization.
10200
7c1b1c084af1 handle cholesky update failure in pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents: 9635
diff changeset
199 [r, bad] = cholinsert (r, jdx, c(p,zidx));
7c1b1c084af1 handle cholesky update failure in pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents: 9635
diff changeset
200 if (bad)
7c1b1c084af1 handle cholesky update failure in pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents: 9635
diff changeset
201 ## If the insertion failed, we switch off updates and go on.
7c1b1c084af1 handle cholesky update failure in pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents: 9635
diff changeset
202 usechol = false;
7c1b1c084af1 handle cholesky update failure in pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents: 9635
diff changeset
203 endif
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
204 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
205
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
206 endwhile
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
207 ## LH12: complete.
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
208
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
209 ## Generate the additional output arguments.
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
210 if (isargout (2))
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
211 minval = 1/2*(x'*c*x) + d'*x;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
212 endif
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
213 if (isargout (3))
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
214 if (iter >= max_iter)
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
215 exitflag = 0;
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
216 else
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
217 exitflag = iter;
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
218 endif
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
219 endif
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
220 if (isargout (4))
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
221 output = struct ("algorithm", "nnls-pqp", "iterations", iter);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
222 endif
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
223 if (isargout (5))
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
224 lambda = zeros (size (x));
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
225 lambda(p) = w;
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
226 endif
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
227
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
228 endfunction
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
229
14363
f3d52523cde1 Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents: 14138
diff changeset
230
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
231 %!test
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
232 %! C = [5 2;2 2];
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
233 %! d = [3; -1];
14363
f3d52523cde1 Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents: 14138
diff changeset
234 %! assert (pqpnonneg (C, d), [0;0.5], 100*eps);
9635
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
235
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
236 ## Test equivalence of lsq and pqp
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
237 %!test
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
238 %! C = rand (20, 10);
36d885c4a1ac implement pqpnonneg
Jaroslav Hajek <highegg@gmail.com>
parents:
diff changeset
239 %! d = rand (20, 1);
14363
f3d52523cde1 Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents: 14138
diff changeset
240 %! assert (pqpnonneg (C'*C, -C'*d), lsqnonneg (C, d), 100*eps);
f3d52523cde1 Use Octave coding conventions in all m-file %!test blocks
Rik <octave@nomad.inbox5.com>
parents: 14138
diff changeset
241
28942
fc4bb4bd1d5e maint: Use '##' as lead-in for full-line comments.
Rik <rik@octave.org>
parents: 28896
diff changeset
242 ## Test input validation
28896
90fea9cc9caa test: Add expected error message <Invalid call> to BIST tests for nargin.
Rik <rik@octave.org>
parents: 28789
diff changeset
243 %!error <Invalid call> pqpnonneg ()
90fea9cc9caa test: Add expected error message <Invalid call> to BIST tests for nargin.
Rik <rik@octave.org>
parents: 28789
diff changeset
244 %!error <Invalid call> pqpnonneg (1)
22764
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
245 %!error <C .* must be numeric matrices> pqpnonneg ({1},2)
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
246 %!error <C .* must be numeric matrices> pqpnonneg (ones (2,2,2),2)
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
247 %!error <D must be numeric matrices> pqpnonneg (1,{2})
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
248 %!error <D must be numeric matrices> pqpnonneg (1, ones (2,2,2))
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
249 %!error <C must be a square matrix> pqpnonneg ([1 2], 2)
d261dcd73dcf pqpnonneg.m: Overhaul function.
Rik <rik@octave.org>
parents: 22760
diff changeset
250 %!error <OPTIONS must be a struct> pqpnonneg (1, 2, [], 3)