GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
gsvd.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1997-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #include "dMatrix.h"
31 #include "CMatrix.h"
32 #include "dDiagMatrix.h"
33 #include "gsvd.h"
34 
35 #include "defun.h"
36 #include "defun-int.h"
37 #include "error.h"
38 #include "errwarn.h"
39 #include "utils.h"
40 #include "ovl.h"
41 #include "ov.h"
42 
43 
44 template <typename T>
45 static typename octave::math::gsvd<T>::Type
46 gsvd_type (int nargout)
47 {
48  return ((nargout == 0 || nargout == 1)
50  : (nargout > 5) ? octave::math::gsvd<T>::Type::std
52 }
53 
54 // Named like this to avoid conflicts with the gsvd class.
55 template <typename T>
56 static octave_value_list
57 do_gsvd (const T& A, const T& B, const octave_idx_type nargout,
58  bool is_single = false)
59 {
60  octave::math::gsvd<T> result (A, B, gsvd_type<T> (nargout));
61 
62  octave_value_list retval (nargout);
63  if (nargout < 2)
64  {
65  if (is_single)
66  {
67  FloatDiagMatrix sigA = result.singular_values_A ();
68  FloatDiagMatrix sigB = result.singular_values_B ();
69  for (int i = sigA.rows () - 1; i >= 0; i--)
70  sigA.dgxelem(i) /= sigB.dgxelem(i);
71  retval(0) = sigA.diag ();
72  }
73  else
74  {
75  DiagMatrix sigA = result.singular_values_A ();
76  DiagMatrix sigB = result.singular_values_B ();
77  for (int i = sigA.rows () - 1; i >= 0; i--)
78  sigA.dgxelem(i) /= sigB.dgxelem(i);
79  retval(0) = sigA.diag ();
80  }
81  }
82  else
83  {
84  retval(0) = result.left_singular_matrix_A ();
85  retval(1) = result.left_singular_matrix_B ();
86  if (nargout > 2)
87  retval(2) = result.right_singular_matrix ();
88  if (nargout > 3)
89  retval(3) = result.singular_values_A ();
90  if (nargout > 4)
91  retval(4) = result.singular_values_B ();
92  if (nargout > 5)
93  retval(5) = result.R_matrix ();
94  }
95  return retval;
96 }
97 
98 DEFUN (gsvd, args, nargout,
99  doc: /* -*- texinfo -*-
100 @deftypefn {} {@var{S} =} gsvd (@var{A}, @var{B})
101 @deftypefnx {} {[@var{U}, @var{V}, @var{X}, @var{C}, @var{S}] =} gsvd (@var{A}, @var{B})
102 @deftypefnx {} {[@var{U}, @var{V}, @var{X}, @var{C}, @var{S}] =} gsvd (@var{A}, @var{B}, 0)
103 Compute the generalized singular value decomposition of (@var{A}, @var{B}).
104 
105 The generalized singular value decomposition is defined by the following
106 relations:
107 
108 @tex
109 $$ A = U C X^\dagger $$
110 $$ B = V S X^\dagger $$
111 $$ C^\dagger C + S^\dagger S = eye (columns (A)) $$
112 @end tex
113 @ifnottex
114 
115 @example
116 @group
117 A = U*C*X'
118 B = V*S*X'
119 C'*C + S'*S = eye (columns (A))
120 @end group
121 @end example
122 
123 @end ifnottex
124 
125 The function @code{gsvd} normally returns just the vector of generalized
126 singular values
127 @tex
128 $$ \sqrt{{{diag (C^\dagger C)} \over {diag (S^\dagger S)}}} $$
129 @end tex
130 @ifnottex
131 @code{sqrt (diag (C'*C) ./ diag (S'*S))}.
132 @end ifnottex
133 If asked for five return values, it also computes
134 @tex
135 $U$, $V$, $X$, and $C$.
136 @end tex
137 @ifnottex
138 U, V, X, and C.
139 @end ifnottex
140 
141 If the optional third input is present, @code{gsvd} constructs the
142 "economy-sized" decomposition where the number of columns of @var{U}, @var{V}
143 and the number of rows of @var{C}, @var{S} is less than or equal to the number
144 of columns of @var{A}. This option is not yet implemented.
145 
146 Programming Note: the code is a wrapper to the corresponding @sc{lapack} dggsvd
147 and zggsvd routines.
148 
149 @seealso{svd}
150 @end deftypefn */)
151 {
152  int nargin = args.length ();
153 
154  if (nargin < 2 || nargin > 3)
155  print_usage ();
156  else if (nargin == 3)
157  warning ("gsvd: economy-sized decomposition is not yet implemented, returning full decomposition");
158 
160 
161  octave_value argA = args(0);
162  octave_value argB = args(1);
163 
164  octave_idx_type nr = argA.rows ();
165  octave_idx_type nc = argA.columns ();
166 
167  octave_idx_type np = argB.columns ();
168 
169  // FIXME: This "special" case should be handled in the gsvd class, not here
170  if (nr == 0 || nc == 0)
171  {
172  retval = octave_value_list (nargout);
173  if (nargout < 2) // S = gsvd (A, B)
174  {
175  if (argA.is_single_type () || argB.is_single_type ())
176  retval(0) = FloatMatrix (0, 1);
177  else
178  retval(0) = Matrix (0, 1);
179  }
180  else // [U, V, X, C, S, R] = gsvd (A, B)
181  {
182  if (argA.is_single_type () || argB.is_single_type ())
183  {
186  if (nargout > 2)
188  if (nargout > 3)
189  retval(3) = FloatMatrix (nr, nc);
190  if (nargout > 4)
192  if (nargout > 5)
194  }
195  else
196  {
197  retval(0) = octave::identity_matrix (nc, nc);
198  retval(1) = octave::identity_matrix (nc, nc);
199  if (nargout > 2)
200  retval(2) = octave::identity_matrix (nr, nr);
201  if (nargout > 3)
202  retval(3) = Matrix (nr, nc);
203  if (nargout > 4)
204  retval(4) = octave::identity_matrix (nr, nr);
205  if (nargout > 5)
206  retval(5) = octave::identity_matrix (nr, nr);
207  }
208  }
209  }
210  else
211  {
212  if (nc != np)
213  print_usage ();
214 
215  if (argA.is_single_type () || argB.is_single_type ())
216  {
217  if (argA.isreal () && argB.isreal ())
218  {
219  FloatMatrix tmpA = argA.xfloat_matrix_value ("gsvd: A must be a real or complex matrix");
220  FloatMatrix tmpB = argB.xfloat_matrix_value ("gsvd: B must be a real or complex matrix");
221 
222  if (tmpA.any_element_is_inf_or_nan ())
223  error ("gsvd: A cannot have Inf or NaN values");
224  if (tmpB.any_element_is_inf_or_nan ())
225  error ("gsvd: B cannot have Inf or NaN values");
226 
227  retval = do_gsvd (tmpA, tmpB, nargout, true);
228  }
229  else if (argA.iscomplex () || argB.iscomplex ())
230  {
231  FloatComplexMatrix ctmpA = argA.xfloat_complex_matrix_value ("gsvd: A must be a real or complex matrix");
232  FloatComplexMatrix ctmpB = argB.xfloat_complex_matrix_value ("gsvd: B must be a real or complex matrix");
233 
234  if (ctmpA.any_element_is_inf_or_nan ())
235  error ("gsvd: A cannot have Inf or NaN values");
236  if (ctmpB.any_element_is_inf_or_nan ())
237  error ("gsvd: B cannot have Inf or NaN values");
238 
239  retval = do_gsvd (ctmpA, ctmpB, nargout, true);
240  }
241  else
242  error ("gsvd: A and B must be real or complex matrices");
243  }
244  else
245  {
246  if (argA.isreal () && argB.isreal ())
247  {
248  Matrix tmpA = argA.xmatrix_value ("gsvd: A must be a real or complex matrix");
249  Matrix tmpB = argB.xmatrix_value ("gsvd: B must be a real or complex matrix");
250 
251  if (tmpA.any_element_is_inf_or_nan ())
252  error ("gsvd: A cannot have Inf or NaN values");
253  if (tmpB.any_element_is_inf_or_nan ())
254  error ("gsvd: B cannot have Inf or NaN values");
255 
256  retval = do_gsvd (tmpA, tmpB, nargout);
257  }
258  else if (argA.iscomplex () || argB.iscomplex ())
259  {
260  ComplexMatrix ctmpA = argA.xcomplex_matrix_value ("gsvd: A must be a real or complex matrix");
261  ComplexMatrix ctmpB = argB.xcomplex_matrix_value ("gsvd: B must be a real or complex matrix");
262 
263  if (ctmpA.any_element_is_inf_or_nan ())
264  error ("gsvd: A cannot have Inf or NaN values");
265  if (ctmpB.any_element_is_inf_or_nan ())
266  error ("gsvd: B cannot have Inf or NaN values");
267 
268  retval = do_gsvd (ctmpA, ctmpB, nargout);
269  }
270  else
271  error ("gsvd: A and B must be real or complex matrices");
272  }
273  }
274 
275  return retval;
276 }
277 
278 /*
279 
280 ## Basic test of decomposition
281 %!test <48807>
282 %! A = reshape (1:15,5,3);
283 %! B = magic (3);
284 %! [U,V,X,C,S] = gsvd (A,B);
285 %! assert (U*C*X', A, 50*eps);
286 %! assert (V*S*X', B, 50*eps);
287 %! S0 = gsvd (A, B);
288 %! S1 = svd (A / B);
289 %! assert (S0, S1, 10*eps);
290 
291 ## a few tests for gsvd.m
292 %!shared A, A0, B, B0, U, V, C, S, X, R, D1, D2
293 %! A0 = randn (5, 3);
294 %! B0 = diag ([1 2 4]);
295 %! A = A0;
296 %! B = B0;
297 
298 ## A (5x3) and B (3x3) are full rank
299 %!test <48807>
300 %! [U, V, X, C, S, R] = gsvd (A, B);
301 %! D1 = zeros (5, 3); D1(1:3, 1:3) = C;
302 %! D2 = S;
303 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
304 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
305 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
306 
307 ## A: 5x3 full rank, B: 3x3 rank deficient
308 %!test <48807>
309 %! B(2, 2) = 0;
310 %! [U, V, X, C, S, R] = gsvd (A, B);
311 %! D1 = zeros (5, 3); D1(1, 1) = 1; D1(2:3, 2:3) = C;
312 %! D2 = [zeros(2, 1) S; zeros(1, 3)];
313 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6);
314 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
315 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
316 
317 ## A: 5x3 rank deficient, B: 3x3 full rank
318 %!test <48807>
319 %! B = B0;
320 %! A(:, 3) = 2*A(:, 1) - A(:, 2);
321 %! [U, V, X, C, S, R] = gsvd (A, B);
322 %! D1 = zeros(5, 3); D1(1:3, 1:3) = C;
323 %! D2 = S;
324 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
325 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
326 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
327 
328 ## A and B are both rank deficient
329 %!test <48807>
330 %! B(:, 3) = 2*B(:, 1) - B(:, 2);
331 %! [U, V, X, C, S, R] = gsvd (A, B);
332 %! D1 = zeros(5, 2); D1(1:2, 1:2) = C;
333 %! D2 = [S; zeros(1, 2)];
334 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6);
335 %! assert (norm ((U'*A*X) - D1*[zeros(2, 1) R]) <= 1e-6);
336 %! assert (norm ((V'*B*X) - D2*[zeros(2, 1) R]) <= 1e-6);
337 
338 ## A (now 3x5) and B (now 5x5) are full rank
339 %!test <48807>
340 %! A = A0.';
341 %! B0 = diag ([1 2 4 8 16]);
342 %! B = B0;
343 %! [U, V, X, C, S, R] = gsvd (A, B);
344 %! D1 = [C zeros(3,2)];
345 %! D2 = [S zeros(3,2); zeros(2, 3) eye(2)];
346 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
347 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
348 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
349 
350 ## A: 3x5 full rank, B: 5x5 rank deficient
351 %!test <48807>
352 %! B(2, 2) = 0;
353 %! [U, V, X, C, S, R] = gsvd (A, B);
354 %! D1 = zeros(3, 5); D1(1, 1) = 1; D1(2:3, 2:3) = C;
355 %! D2 = zeros(5, 5); D2(1:2, 2:3) = S; D2(3:4, 4:5) = eye (2);
356 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6);
357 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
358 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
359 
360 ## A: 3x5 rank deficient, B: 5x5 full rank
361 %!test <48807>
362 %! B = B0;
363 %! A(3, :) = 2*A(1, :) - A(2, :);
364 %! [U, V, X, C, S, R] = gsvd (A, B);
365 %! D1 = zeros (3, 5); D1(1:3, 1:3) = C;
366 %! D2 = zeros (5, 5); D2(1:3, 1:3) = S; D2(4:5, 4:5) = eye (2);
367 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
368 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
369 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
370 
371 ## A and B are both rank deficient
372 %!test <48807>
373 %! A = A0.'; B = B0.';
374 %! A(:, 3) = 2*A(:, 1) - A(:, 2);
375 %! B(:, 3) = 2*B(:, 1) - B(:, 2);
376 %! [U, V, X, C, S, R]=gsvd (A, B);
377 %! D1 = zeros(3, 4); D1(1:3, 1:3) = C;
378 %! D2 = eye (4); D2(1:3, 1:3) = S; D2(5,:) = 0;
379 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
380 %! assert (norm ((U'*A*X) - D1*[zeros(4, 1) R]) <= 1e-6);
381 %! assert (norm ((V'*B*X) - D2*[zeros(4, 1) R]) <= 1e-6);
382 
383 ## A: 5x3 complex full rank, B: 3x3 complex full rank
384 %!test <48807>
385 %! A0 = A0 + j*randn (5, 3);
386 %! B0 = diag ([1 2 4]) + j*diag ([4 -2 -1]);
387 %! A = A0;
388 %! B = B0;
389 %! [U, V, X, C, S, R] = gsvd (A, B);
390 %! D1 = zeros(5, 3); D1(1:3, 1:3) = C;
391 %! D2 = S;
392 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
393 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
394 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
395 
396 ## A: 5x3 complex full rank, B: 3x3 complex rank deficient
397 %!test <48807>
398 %! B(2, 2) = 0;
399 %! [U, V, X, C, S, R] = gsvd (A, B);
400 %! D1 = zeros(5, 3); D1(1, 1) = 1; D1(2:3, 2:3) = C;
401 %! D2 = [zeros(2, 1) S; zeros(1, 3)];
402 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6);
403 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
404 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
405 
406 ## A: 5x3 complex rank deficient, B: 3x3 complex full rank
407 %!test <48807>
408 %! B = B0;
409 %! A(:, 3) = 2*A(:, 1) - A(:, 2);
410 %! [U, V, X, C, S, R] = gsvd (A, B);
411 %! D1 = zeros(5, 3); D1(1:3, 1:3) = C;
412 %! D2 = S;
413 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
414 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
415 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
416 
417 ## A (5x3) and B (3x3) are both complex rank deficient
418 %!test <48807>
419 %! B(:, 3) = 2*B(:, 1) - B(:, 2);
420 %! [U, V, X, C, S, R] = gsvd (A, B);
421 %! D1 = zeros(5, 2); D1(1:2, 1:2) = C;
422 %! D2 = [S; zeros(1, 2)];
423 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6);
424 %! assert (norm ((U'*A*X) - D1*[zeros(2, 1) R]) <= 1e-6);
425 %! assert (norm ((V'*B*X) - D2*[zeros(2, 1) R]) <= 1e-6);
426 
427 ## A (now 3x5) complex and B (now 5x5) complex are full rank
428 ## now, A is 3x5
429 %!test <48807>
430 %! A = A0.';
431 %! B0 = diag ([1 2 4 8 16]) + j*diag ([-5 4 -3 2 -1]);
432 %! B = B0;
433 %! [U, V, X, C, S, R] = gsvd (A, B);
434 %! D1 = [C zeros(3,2)];
435 %! D2 = [S zeros(3,2); zeros(2, 3) eye(2)];
436 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
437 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
438 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
439 
440 ## A: 3x5 complex full rank, B: 5x5 complex rank deficient
441 %!test <48807>
442 %! B(2, 2) = 0;
443 %! [U, V, X, C, S, R] = gsvd (A, B);
444 %! D1 = zeros(3, 5); D1(1, 1) = 1; D1(2:3, 2:3) = C;
445 %! D2 = zeros(5,5); D2(1:2, 2:3) = S; D2(3:4, 4:5) = eye (2);
446 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6);
447 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
448 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
449 
450 ## A: 3x5 complex rank deficient, B: 5x5 complex full rank
451 %!test <48807>
452 %! B = B0;
453 %! A(3, :) = 2*A(1, :) - A(2, :);
454 %! [U, V, X, C, S, R] = gsvd (A, B);
455 %! D1 = zeros(3, 5); D1(1:3, 1:3) = C;
456 %! D2 = zeros(5,5); D2(1:3, 1:3) = S; D2(4:5, 4:5) = eye (2);
457 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
458 %! assert (norm ((U'*A*X) - D1*R) <= 1e-6);
459 %! assert (norm ((V'*B*X) - D2*R) <= 1e-6);
460 
461 ## A and B are both complex rank deficient
462 %!test <48807>
463 %! A = A0.';
464 %! B = B0.';
465 %! A(:, 3) = 2*A(:, 1) - A(:, 2);
466 %! B(:, 3) = 2*B(:, 1) - B(:, 2);
467 %! [U, V, X, C, S, R] = gsvd (A, B);
468 %! D1 = zeros(3, 4); D1(1:3, 1:3) = C;
469 %! D2 = eye (4); D2(1:3, 1:3) = S; D2(5,:) = 0;
470 %! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6);
471 %! assert (norm ((U'*A*X) - D1*[zeros(4, 1) R]) <= 1e-6);
472 %! assert (norm ((V'*B*X) - D2*[zeros(4, 1) R]) <= 1e-6);
473 
474 ## Test that single inputs produce single outputs
475 %!test
476 %! s = gsvd (single (ones (0,1)), B);
477 %! assert (class (s), "single");
478 %! s = gsvd (single (ones (1,0)), B);
479 %! assert (class (s), "single");
480 %! s = gsvd (single (ones (1,0)), B);
481 %! [U,V,X,C,S,R] = gsvd (single ([]), B);
482 %! assert (class (U), "single");
483 %! assert (class (V), "single");
484 %! assert (class (X), "single");
485 %! assert (class (C), "single");
486 %! assert (class (S), "single");
487 %! assert (class (R), "single");
488 %!
489 %! s = gsvd (single (A), B);
490 %! assert (class (s), "single");
491 %! [U,V,X,C,S,R] = gsvd (single (A), B);
492 %! assert (class (U), "single");
493 %! assert (class (V), "single");
494 %! assert (class (X), "single");
495 %! assert (class (C), "single");
496 %! assert (class (S), "single");
497 %! assert (class (R), "single");
498 
499 */
bool any_element_is_inf_or_nan(void) const
Definition: CNDArray.cc:271
T & dgxelem(octave_idx_type i)
Definition: DiagArray2.h:151
octave_idx_type rows(void) const
Definition: DiagArray2.h:88
bool any_element_is_inf_or_nan(void) const
Definition: fCNDArray.cc:271
bool any_element_is_inf_or_nan(void) const
Definition: fNDArray.cc:281
MArray< T > diag(octave_idx_type k=0) const
Definition: MDiagArray2.h:102
Definition: dMatrix.h:42
bool any_element_is_inf_or_nan(void) const
Definition: dNDArray.cc:324
Definition: mx-defs.h:72
T right_singular_matrix(void) const
Definition: gsvd.cc:461
T R_matrix(void) const
Definition: gsvd.cc:475
T left_singular_matrix_A(void) const
Definition: gsvd.cc:433
T::real_diag_matrix_type singular_values_A(void) const
Definition: gsvd.h:79
T::real_diag_matrix_type singular_values_B(void) const
Definition: gsvd.h:82
T left_singular_matrix_B(void) const
Definition: gsvd.cc:447
bool isreal(void) const
Definition: ov.h:691
octave_idx_type rows(void) const
Definition: ov.h:504
FloatMatrix xfloat_matrix_value(const char *fmt,...) const
ComplexMatrix xcomplex_matrix_value(const char *fmt,...) const
FloatComplexMatrix xfloat_complex_matrix_value(const char *fmt,...) const
octave_idx_type columns(void) const
Definition: ov.h:506
bool is_single_type(void) const
Definition: ov.h:651
Matrix xmatrix_value(const char *fmt,...) const
bool iscomplex(void) const
Definition: ov.h:694
OCTINTERP_API void print_usage(void)
Definition: defun.cc:53
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void warning(const char *fmt,...)
Definition: error.cc:1050
void error(const char *fmt,...)
Definition: error.cc:968
static octave::math::gsvd< T >::Type gsvd_type(int nargout)
Definition: gsvd.cc:46
static octave_value_list do_gsvd(const T &A, const T &B, const octave_idx_type nargout, bool is_single=false)
Definition: gsvd.cc:57
F77_RET_T const F77_INT F77_CMPLX const F77_INT F77_CMPLX * B
F77_RET_T const F77_INT F77_CMPLX * A
Matrix identity_matrix(octave_idx_type nr, octave_idx_type nc)
Definition: utils.cc:1299
FloatMatrix float_identity_matrix(octave_idx_type nr, octave_idx_type nc)
Definition: utils.cc:1314
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811