Mercurial > octave
changeset 22612:c05377052b50
maint: Merge stable to default.
author | Rik <rik@octave.org> |
---|---|
date | Tue, 11 Oct 2016 08:56:03 -0700 |
parents | dc872d5d74c5 (diff) 95aff68c443d (current diff) |
children | edd04ce99891 |
files | configure.ac |
diffstat | 15 files changed, 1204 insertions(+), 130 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Mon Oct 10 17:34:38 2016 -0400 +++ b/NEWS Tue Oct 11 08:56:03 2016 -0700 @@ -1,3 +1,11 @@ +Summary of important user-visible changes for version 4.4: +--------------------------------------------------------- + + ** Other new functions added in 4.4: + + gsvd + + Summary of important user-visible changes for version 4.2: ---------------------------------------------------------
--- a/configure.ac Mon Oct 10 17:34:38 2016 -0400 +++ b/configure.ac Tue Oct 11 08:56:03 2016 -0700 @@ -19,14 +19,14 @@ ### <http://www.gnu.org/licenses/>. AC_PREREQ([2.63]) -AC_INIT([GNU Octave], [4.2.0-rc2], [http://octave.org/bugs.html], [octave]) +AC_INIT([GNU Octave], [4.3.0+], [http://octave.org/bugs.html], [octave]) dnl Note that the version number is duplicated here and in AC_INIT dnl because AC_INIT requires it to be static, not computed from dnl shell variables. OCTAVE_MAJOR_VERSION=4 -OCTAVE_MINOR_VERSION=2 -OCTAVE_PATCH_VERSION=0-rc2 +OCTAVE_MINOR_VERSION=3 +OCTAVE_PATCH_VERSION=0+ dnl PACKAGE_VERSION is set by the AC_INIT VERSION arg OCTAVE_VERSION="$PACKAGE_VERSION"
--- a/doc/interpreter/linalg.txi Mon Oct 10 17:34:38 2016 -0400 +++ b/doc/interpreter/linalg.txi Tue Oct 11 08:56:03 2016 -0700 @@ -108,6 +108,8 @@ @DOCSTRING(givens) +@DOCSTRING(gsvd) + @DOCSTRING(planerot) @DOCSTRING(inv)
--- a/libinterp/corefcn/data.cc Mon Oct 10 17:34:38 2016 -0400 +++ b/libinterp/corefcn/data.cc Tue Oct 11 08:56:03 2016 -0700 @@ -3549,6 +3549,49 @@ return retval; } +/* +%!error <undefined> 1+Infj +%!error <undefined> 1+Infi + +%!test <31974> +%! assert (Inf + Inf*i, complex (Inf, Inf)) +%! +%! assert (1 + Inf*i, complex (1, Inf)) +%! assert (1 + Inf*j, complex (1, Inf)) +%! +%! ## whitespace should not affect parsing +%! assert (1+Inf*i, complex (1, Inf)) +%! assert (1+Inf*j, complex (1, Inf)) +%! +%! assert (NaN*j, complex (0, NaN)) +%! +%! assert (Inf * 4j, complex (0, Inf)) + +%!test <31974> +%! x = Inf; +%! assert (x * j, complex (0, Inf)) +%! j = complex (0, 1); +%! assert (Inf * j, complex (0, Inf)) + +%!test <31974> +%! exp = complex (zeros (2, 2), Inf (2, 2)); +%! assert (Inf (2, 2) * j, exp) +%! assert (Inf (2, 2) .* j, exp) +%! assert (Inf * (ones (2, 2) * j), exp) +%! assert (Inf (2, 2) .* (ones (2, 2) * j), exp) + +%!test <31974> +%! assert ([Inf; 0] * [i, 0], complex ([NaN NaN; 0 0], [Inf NaN; 0 0])) +%! assert ([Inf, 0] * [i; 0], complex (NaN, Inf)) +%! assert ([Inf, 0] .* [i, 0], complex ([0 0], [Inf 0])) + +%!test <31974> +%! m = @(x, y) x * y; +%! d = @(x, y) x / y; +%! assert (m (Inf, i), complex (0, +Inf)) +%! assert (d (Inf, i), complex (0, -Inf)) +*/ + DEFUN (isreal, args, , doc: /* -*- texinfo -*- @deftypefn {} {} isreal (@var{x})
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/corefcn/gsvd.cc Tue Oct 11 08:56:03 2016 -0700 @@ -0,0 +1,402 @@ +// Copyright (C) 2016 Barbara Lócsi +// Copyright (C) 2006, 2010 Pascal Dupuis <Pascal.Dupuis@uclouvain.be> +// Copyright (C) 1996, 1997 John W. Eaton +// +// 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/>. + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "dMatrix.h" +#include "CMatrix.h" +#include "dDiagMatrix.h" +#include "gsvd.h" + +#include "defun.h" +#include "defun-int.h" +#include "error.h" +#include "errwarn.h" +#include "utils.h" +#include "ovl.h" +#include "ov.h" + + +template <typename T> +static typename octave::math::gsvd<T>::Type +gsvd_type (int nargout) +{ + return ((nargout == 0 || nargout == 1) + ? octave::math::gsvd<T>::Type::sigma_only + : (nargout > 5) ? octave::math::gsvd<T>::Type::std + : octave::math::gsvd<T>::Type::economy); +} + +// Named like this to avoid conflicts with the gsvd class. +template <typename T> +static octave_value_list +function_gsvd (const T& A, const T& B, const octave_idx_type nargout) +{ + octave::math::gsvd<T> result (A, B, gsvd_type<T> (nargout)); + + octave_value_list retval (nargout); + if (nargout < 2) + { + DiagMatrix sigA = result.singular_values_A (); + DiagMatrix sigB = result.singular_values_B (); + for (int i = sigA.rows () - 1; i >= 0; i--) + sigA.dgxelem(i) /= sigB.dgxelem(i); + retval(0) = sigA.diag (); + } + else + { + retval(0) = result.left_singular_matrix_A (); + retval(1) = result.left_singular_matrix_B (); + if (nargout > 2) + retval(2) = result.right_singular_matrix (); + if (nargout > 3) + retval(3) = result.singular_values_A (); + if (nargout > 4) + retval(4) = result.singular_values_B (); + if (nargout > 5) + retval(5) = result.R_matrix (); + } + return retval; +} + +DEFUN (gsvd, args, nargout, + doc: /* -*- texinfo -*- +@deftypefn {} {@var{S} =} gsvd (@var{A}, @var{B}) +@deftypefnx {} {[@var{U}, @var{V}, @var{X}, @var{C}, @var{S}] =} gsvd (@var{A}, @var{B}) +@deftypefnx {} {[@var{U}, @var{V}, @var{X}, @var{C}, @var{S}] =} gsvd (@var{A}, @var{B}, 0) +Compute the generalized singular value decomposition of (@var{A}, @var{B}): + +@tex +$$ A = U C X^\dagger $$ +$$ B = V S X^\dagger $$ +$$ C^\dagger C + S^\dagger S = eye (columns (A)) $$ +@end tex +@ifnottex + +@example +@group +A = U*C*X' +B = V*S*X' +C'*C + S'*S = eye (columns (A)) +@end group +@end example + +@end ifnottex + +The function @code{gsvd} normally returns just the vector of generalized singular values +@tex +$$ \sqrt{{{diag (C^\dagger C)} \over {diag (S^\dagger S)}}} $$ +@end tex +@ifnottex +@code{sqrt (diag (C'*C) ./ diag (S'*S))}. +@end ifnottex +If asked for five return values, it also computes +@tex +$U$, $V$, $X$, and $C$. +@end tex +@ifnottex +U, V, X, and C. +@end ifnottex + +If the optional third input is present, @code{gsvd} constructs the +"economy-sized" decomposition where the number of columns of @var{U}, @var{V} +and the number of rows of @var{C}, @var{S} is less than or equal to the number +of columns of @var{A}. This option is not yet implemented. + +Programming Note: the code is a wrapper to the corresponding @sc{lapack} dggsvd +and zggsvd routines. + +@seealso{svd} +@end deftypefn */) +{ + int nargin = args.length (); + + if (nargin < 2 || nargin > 3) + print_usage (); + else if (nargin == 3) + warning ("gsvd: economy-sized decomposition is not yet implemented, returning full decomposition"); + + octave_value_list retval; + + octave_value argA = args(0); + octave_value argB = args(1); + + octave_idx_type nr = argA.rows (); + octave_idx_type nc = argA.columns (); + + octave_idx_type np = argB.columns (); + + // FIXME: This "special" case should be handled in the gsvd class, not here + if (nr == 0 || nc == 0) + { + retval = octave_value_list (nargout); + if (nargout < 2) // S = gsvd (A, B) + retval(0) = Matrix (0, 1); + else // [U, V, X, C, S, R] = gsvd (A, B) + { + retval(0) = identity_matrix (nc, nc); + retval(1) = identity_matrix (nc, nc); + if (nargout > 2) + retval(2) = identity_matrix (nr, nr); + if (nargout > 3) + retval(3) = Matrix (nr, nc); + if (nargout > 4) + retval(4) = identity_matrix (nr, nr); + if (nargout > 5) + retval(5) = identity_matrix (nr, nr); + } + } + else + { + if (nc != np) + print_usage (); + + // FIXME: Remove when interface to gsvd single class has been written + if (argA.is_single_type () && argB.is_single_type ()) + warning ("gsvd: no implementation for single matrices, converting to double"); + + if (argA.is_real_type () && argB.is_real_type ()) + { + Matrix tmpA = argA.xmatrix_value ("gsvd: A must be a real or complex matrix"); + Matrix tmpB = argB.xmatrix_value ("gsvd: B must be a real or complex matrix"); + + if (tmpA.any_element_is_inf_or_nan ()) + error ("gsvd: A cannot have Inf or NaN values"); + if (tmpB.any_element_is_inf_or_nan ()) + error ("gsvd: B cannot have Inf or NaN values"); + + retval = function_gsvd (tmpA, tmpB, nargout); + } + else if (argA.is_complex_type () || argB.is_complex_type ()) + { + ComplexMatrix ctmpA = argA.xcomplex_matrix_value ("gsvd: A must be a real or complex matrix"); + ComplexMatrix ctmpB = argB.xcomplex_matrix_value ("gsvd: B must be a real or complex matrix"); + + if (ctmpA.any_element_is_inf_or_nan ()) + error ("gsvd: A cannot have Inf or NaN values"); + if (ctmpB.any_element_is_inf_or_nan ()) + error ("gsvd: B cannot have Inf or NaN values"); + + retval = function_gsvd (ctmpA, ctmpB, nargout); + } + else + error ("gsvd: A and B must be real or complex matrices"); + } + + return retval; +} + +/* + +## Basic test of decomposition +%!test <48807> +%! A = reshape (1:15,5,3); +%! B = magic (3); +%! [U,V,X,C,S] = gsvd (A,B); +%! assert (U*C*X', A, 50*eps); +%! assert (V*S*X', B, 50*eps); +%! S0 = gsvd (A, B); +%! S1 = svd (A / B); +%! assert (S0, S1, 10*eps); + +## a few tests for gsvd.m +%!shared A, A0, B, B0, U, V, C, S, X, R, D1, D2 +%! A0 = randn (5, 3); +%! B0 = diag ([1 2 4]); +%! A = A0; +%! B = B0; + +## A (5x3) and B (3x3) are full rank +%!test <48807> +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros (5, 3); D1(1:3, 1:3) = C; +%! D2 = S; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 5x3 full rank, B: 3x3 rank deficient +%!test <48807> +%! B(2, 2) = 0; +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros (5, 3); D1(1, 1) = 1; D1(2:3, 2:3) = C; +%! D2 = [zeros(2, 1) S; zeros(1, 3)]; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 5x3 rank deficient, B: 3x3 full rank +%!test <48807> +%! B = B0; +%! A(:, 3) = 2*A(:, 1) - A(:, 2); +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(5, 3); D1(1:3, 1:3) = C; +%! D2 = S; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A and B are both rank deficient +%!test <48807> +%! B(:, 3) = 2*B(:, 1) - B(:, 2); +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(5, 2); D1(1:2, 1:2) = C; +%! D2 = [S; zeros(1, 2)]; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*[zeros(2, 1) R]) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*[zeros(2, 1) R]) <= 1e-6); + +## A (now 3x5) and B (now 5x5) are full rank +%!test <48807> +%! A = A0.'; +%! B0 = diag ([1 2 4 8 16]); +%! B = B0; +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = [C zeros(3,2)]; +%! D2 = [S zeros(3,2); zeros(2, 3) eye(2)]; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 3x5 full rank, B: 5x5 rank deficient +%!test <48807> +%! B(2, 2) = 0; +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(3, 5); D1(1, 1) = 1; D1(2:3, 2:3) = C; +%! D2 = zeros(5, 5); D2(1:2, 2:3) = S; D2(3:4, 4:5) = eye (2); +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 3x5 rank deficient, B: 5x5 full rank +%!test <48807> +%! B = B0; +%! A(3, :) = 2*A(1, :) - A(2, :); +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros (3, 5); D1(1:3, 1:3) = C; +%! D2 = zeros (5, 5); D2(1:3, 1:3) = S; D2(4:5, 4:5) = eye (2); +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A and B are both rank deficient +%!test <48807> +%! A = A0.'; B = B0.'; +%! A(:, 3) = 2*A(:, 1) - A(:, 2); +%! B(:, 3) = 2*B(:, 1) - B(:, 2); +%! [U, V, X, C, S, R]=gsvd (A, B); +%! D1 = zeros(3, 4); D1(1:3, 1:3) = C; +%! D2 = eye (4); D2(1:3, 1:3) = S; D2(5,:) = 0; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*[zeros(4, 1) R]) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*[zeros(4, 1) R]) <= 1e-6); + +## A: 5x3 complex full rank, B: 3x3 complex full rank +%!test <48807> +%! A0 = A0 + j*randn (5, 3); +%! B0 = diag ([1 2 4]) + j*diag ([4 -2 -1]); +%! A = A0; +%! B = B0; +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(5, 3); D1(1:3, 1:3) = C; +%! D2 = S; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 5x3 complex full rank, B: 3x3 complex rank deficient +%!test <48807> +%! B(2, 2) = 0; +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(5, 3); D1(1, 1) = 1; D1(2:3, 2:3) = C; +%! D2 = [zeros(2, 1) S; zeros(1, 3)]; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 5x3 complex rank deficient, B: 3x3 complex full rank +%!test <48807> +%! B = B0; +%! A(:, 3) = 2*A(:, 1) - A(:, 2); +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(5, 3); D1(1:3, 1:3) = C; +%! D2 = S; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A (5x3) and B (3x3) are both complex rank deficient +%!test <48807> +%! B(:, 3) = 2*B(:, 1) - B(:, 2); +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(5, 2); D1(1:2, 1:2) = C; +%! D2 = [S; zeros(1, 2)]; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*[zeros(2, 1) R]) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*[zeros(2, 1) R]) <= 1e-6); + +## A (now 3x5) complex and B (now 5x5) complex are full rank +## now, A is 3x5 +%!test <48807> +%! A = A0.'; +%! B0 = diag ([1 2 4 8 16]) + j*diag ([-5 4 -3 2 -1]); +%! B = B0; +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = [C zeros(3,2)]; +%! D2 = [S zeros(3,2); zeros(2, 3) eye(2)]; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 3x5 complex full rank, B: 5x5 complex rank deficient +%!test <48807> +%! B(2, 2) = 0; +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(3, 5); D1(1, 1) = 1; D1(2:3, 2:3) = C; +%! D2 = zeros(5,5); D2(1:2, 2:3) = S; D2(3:4, 4:5) = eye (2); +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (2, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A: 3x5 complex rank deficient, B: 5x5 complex full rank +%!test <48807> +%! B = B0; +%! A(3, :) = 2*A(1, :) - A(2, :); +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(3, 5); D1(1:3, 1:3) = C; +%! D2 = zeros(5,5); D2(1:3, 1:3) = S; D2(4:5, 4:5) = eye (2); +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*R) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*R) <= 1e-6); + +## A and B are both complex rank deficient +%!test <48807> +%! A = A0.'; +%! B = B0.'; +%! A(:, 3) = 2*A(:, 1) - A(:, 2); +%! B(:, 3) = 2*B(:, 1) - B(:, 2); +%! [U, V, X, C, S, R] = gsvd (A, B); +%! D1 = zeros(3, 4); D1(1:3, 1:3) = C; +%! D2 = eye (4); D2(1:3, 1:3) = S; D2(5,:) = 0; +%! assert (norm (diag (C).^2 + diag (S).^2 - ones (3, 1)) <= 1e-6); +%! assert (norm ((U'*A*X) - D1*[zeros(4, 1) R]) <= 1e-6); +%! assert (norm ((V'*B*X) - D2*[zeros(4, 1) R]) <= 1e-6); + +*/ +
--- a/libinterp/corefcn/module.mk Mon Oct 10 17:34:38 2016 -0400 +++ b/libinterp/corefcn/module.mk Tue Oct 11 08:56:03 2016 -0700 @@ -173,6 +173,7 @@ libinterp/corefcn/gl2ps-print.cc \ libinterp/corefcn/graphics.cc \ libinterp/corefcn/gripes.cc \ + libinterp/corefcn/gsvd.cc \ libinterp/corefcn/hash.cc \ libinterp/corefcn/help.cc \ libinterp/corefcn/hess.cc \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/numeric/gsvd.cc Tue Oct 11 08:56:03 2016 -0700 @@ -0,0 +1,371 @@ +// Copyright (C) 2016 Barbara Lócsi +// Copyright (C) 2006 Pascal Dupuis <Pascal.Dupuis@uclouvain.be> +// Copyright (C) 1996, 1997 John W. Eaton +// +// 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/>. + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <vector> + +#include "gsvd.h" + +#include "lo-error.h" +#include "lo-lapack-proto.h" +#include "dMatrix.h" +#include "fMatrix.h" +#include "CMatrix.h" +#include "fCMatrix.h" +#include "dDiagMatrix.h" +#include "fDiagMatrix.h" + +namespace octave +{ + namespace math + { + template <> + void + gsvd<Matrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, + octave_idx_type& k, octave_idx_type& l, + double *tmp_dataA, octave_idx_type m1, + double *tmp_dataB, octave_idx_type p1, Matrix& alpha, + Matrix& beta, double *u, octave_idx_type nrow_u, + double *v, octave_idx_type nrow_v, double *q, + octave_idx_type nrow_q, + Matrix& work, octave_idx_type* iwork, + octave_idx_type& info) + { + F77_XFCN (dggsvd, DGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, tmp_dataA, m1, + tmp_dataB, p1, alpha.fortran_vec (), + beta.fortran_vec (), u, nrow_u, + v, nrow_v, q, nrow_q, work.fortran_vec (), + iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); + } + + template <> + void + gsvd<FloatMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, + octave_idx_type& k, octave_idx_type& l, + float *tmp_dataA, octave_idx_type m1, + float *tmp_dataB, octave_idx_type p1, + FloatMatrix& alpha, FloatMatrix& beta, float *u, + octave_idx_type nrow_u, float *v, + octave_idx_type nrow_v, float *q, + octave_idx_type nrow_q, FloatMatrix& work, + octave_idx_type* iwork, octave_idx_type& info) + { + F77_XFCN (sggsvd, SGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, tmp_dataA, m1, + tmp_dataB, p1, alpha.fortran_vec (), + beta.fortran_vec (), u, nrow_u, + v, nrow_v, q, nrow_q, work.fortran_vec (), + iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); + } + + template <> + void + gsvd<ComplexMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, octave_idx_type& k, + octave_idx_type& l, Complex *tmp_dataA, + octave_idx_type m1, Complex *tmp_dataB, + octave_idx_type p1, Matrix& alpha, + Matrix& beta, Complex *u, + octave_idx_type nrow_u, + Complex *v, octave_idx_type nrow_v, Complex *q, + octave_idx_type nrow_q, ComplexMatrix& work, + octave_idx_type* iwork, octave_idx_type& info) + { + Matrix rwork(2*n, 1); + F77_XFCN (zggsvd, ZGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, F77_DBLE_CMPLX_ARG (tmp_dataA), + m1, F77_DBLE_CMPLX_ARG (tmp_dataB), p1, + alpha.fortran_vec (), beta.fortran_vec (), + F77_DBLE_CMPLX_ARG (u), nrow_u, + F77_DBLE_CMPLX_ARG (v), nrow_v, + F77_DBLE_CMPLX_ARG (q), nrow_q, + F77_DBLE_CMPLX_ARG (work.fortran_vec ()), + rwork.fortran_vec (), iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); + } + + template <> + void + gsvd<FloatComplexMatrix>::ggsvd (char& jobu, char& jobv, char& jobq, + octave_idx_type m, octave_idx_type n, + octave_idx_type p, octave_idx_type& k, + octave_idx_type& l, + FloatComplex *tmp_dataA, + octave_idx_type m1, + FloatComplex *tmp_dataB, + octave_idx_type p1, FloatMatrix& alpha, + FloatMatrix& beta, FloatComplex *u, + octave_idx_type nrow_u, FloatComplex *v, + octave_idx_type nrow_v, FloatComplex *q, + octave_idx_type nrow_q, + FloatComplexMatrix& work, + octave_idx_type* iwork, + octave_idx_type& info) + { + FloatMatrix rwork(2*n, 1); + F77_XFCN (cggsvd, CGGSVD, (F77_CONST_CHAR_ARG2 (&jobu, 1), + F77_CONST_CHAR_ARG2 (&jobv, 1), + F77_CONST_CHAR_ARG2 (&jobq, 1), + m, n, p, k, l, F77_CMPLX_ARG (tmp_dataA), m1, + F77_CMPLX_ARG (tmp_dataB), p1, + alpha.fortran_vec (), beta.fortran_vec (), + F77_CMPLX_ARG (u), nrow_u, + F77_CMPLX_ARG (v), nrow_v, + F77_CMPLX_ARG (q), nrow_q, + F77_CMPLX_ARG (work.fortran_vec ()), + rwork.fortran_vec (), iwork, info + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1) + F77_CHAR_ARG_LEN (1))); + } + + template <typename T> + T + gsvd<T>::left_singular_matrix_A (void) const + { + if (type == gsvd::Type::sigma_only) + { + (*current_liboctave_error_handler) + ("gsvd: U not computed because type == gsvd::sigma_only"); + return T (); + } + else + return left_smA; + } + + template <typename T> + T + gsvd<T>::left_singular_matrix_B (void) const + { + if (type == gsvd::Type::sigma_only) + { + (*current_liboctave_error_handler) + ("gsvd: V not computed because type == gsvd::sigma_only"); + return T (); + } + else + return left_smB; + } + + template <typename T> + T + gsvd<T>::right_singular_matrix (void) const + { + if (type == gsvd::Type::sigma_only) + { + (*current_liboctave_error_handler) + ("gsvd: X not computed because type == gsvd::sigma_only"); + return T (); + } + else + return right_sm; + } + + template <typename T> + T + gsvd<T>::R_matrix (void) const + { + if (type != gsvd::Type::std) + { + (*current_liboctave_error_handler) + ("gsvd: R not computed because type != gsvd::std"); + return T (); + } + else + return R; + } + + template <typename T> + gsvd<T>::gsvd (const T& a, const T& b, gsvd::Type gsvd_type) + { + octave_idx_type info; + + octave_idx_type m = a.rows (); + octave_idx_type n = a.cols (); + octave_idx_type p = b.rows (); + + T atmp = a; + P *tmp_dataA = atmp.fortran_vec (); + + T btmp = b; + P *tmp_dataB = btmp.fortran_vec (); + + char jobu = 'U'; + char jobv = 'V'; + char jobq = 'Q'; + + octave_idx_type nrow_u = m; + octave_idx_type nrow_v = p; + octave_idx_type nrow_q = n; + + octave_idx_type k, l; + + switch (gsvd_type) + { + case gsvd<T>::Type::sigma_only: + + // Note: for this case, both jobu and jobv should be 'N', but + // there seems to be a bug in dgesvd from Lapack V2.0. To + // demonstrate the bug, set both jobu and jobv to 'N' and find + // the singular values of [eye(3), eye(3)]. The result is + // [-sqrt(2), -sqrt(2), -sqrt(2)]. + // + // For Lapack 3.0, this problem seems to be fixed. + + jobu = 'N'; + jobv = 'N'; + jobq = 'N'; + nrow_u = nrow_v = nrow_q = 1; + break; + + default: + break; + } + + type = gsvd_type; + + if (! (jobu == 'N' || jobu == 'O')) + left_smA.resize (nrow_u, m); + + P *u = left_smA.fortran_vec (); + + if (! (jobv == 'N' || jobv == 'O')) + left_smB.resize (nrow_v, p); + + P *v = left_smB.fortran_vec (); + + if (! (jobq == 'N' || jobq == 'O')) + right_sm.resize (nrow_q, n); + + P *q = right_sm.fortran_vec (); + + octave_idx_type lwork = 3*n; + lwork = lwork > m ? lwork : m; + lwork = (lwork > p ? lwork : p) + n; + + T work (lwork, 1); + real_matrix alpha (n, 1); + real_matrix beta (n, 1); + + std::vector<octave_idx_type> iwork (n); + + gsvd<T>::ggsvd (jobu, jobv, jobq, m, n, p, k, l, + tmp_dataA, m, tmp_dataB, p, alpha, beta, u, + nrow_u, v, nrow_v, q, nrow_q, work, iwork.data (), info); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in *ggsvd"); + + if (info < 0) + (*current_liboctave_error_handler) ("*ggsvd.f: argument %d illegal", + -info); + else + { + if (info > 0) + (*current_liboctave_error_handler) + ("*ggsvd.f: Jacobi-type procedure failed to converge."); + else + { + octave_idx_type i, j; + + if (gsvd<T>::Type::std == gsvd_type) + { + R.resize(k+l, k+l); + int astart = n-k-l; + if (m - k - l >= 0) + { + astart = n-k-l; + // R is stored in A(1:K+L,N-K-L+1:N) + for (i = 0; i < k+l; i++) + for (j = 0; j < k+l; j++) + R.xelem (i, j) = atmp.xelem (i, astart + j); + } + else + { + // (R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N), + // ( 0 R22 R23 ) + + for (i = 0; i < m; i++) + for (j = 0; j < k+l; j++) + R.xelem (i, j) = atmp.xelem (i, astart + j); + // and R33 is stored in B(M-K+1:L,N+M-K-L+1:N) + for (i = k+l-1; i >=m; i--) + { + for (j = 0; j < m; j++) + R.xelem(i, j) = 0.0; + for (j = m; j < k+l; j++) + R.xelem (i, j) = btmp.xelem (i - k, astart + j); + } + } + } + + if (m-k-l >= 0) + { + // Fills in C and S + sigmaA.resize (l, l); + sigmaB.resize (l, l); + for (i = 0; i < l; i++) + { + sigmaA.dgxelem(i) = alpha.elem(k+i); + sigmaB.dgxelem(i) = beta.elem(k+i); + } + } + else + { + // Fills in C and S + sigmaA.resize (m-k, m-k); + sigmaB.resize (m-k, m-k); + for (i = 0; i < m-k; i++) + { + sigmaA.dgxelem(i) = alpha.elem(k+i); + sigmaB.dgxelem(i) = beta.elem(k+i); + } + } + } + } + } + + // Instantiations we need. + template class gsvd<Matrix>; + template class gsvd<FloatMatrix>; + template class gsvd<ComplexMatrix>; + template class gsvd<FloatComplexMatrix>; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/numeric/gsvd.h Tue Oct 11 08:56:03 2016 -0700 @@ -0,0 +1,102 @@ +// Copyright (C) 2016 Barbara Lócsi +// Copyright (C) 2006 Pascal Dupuis <Pascal.Dupuis@uclouvain.be> +// Copyright (C) 1996, 1997 John W. Eaton +// +// 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/>. + +#if !defined (octave_gsvd_h) +#define octave_gsvd_h 1 + +#include "octave-config.h" + +namespace octave +{ + namespace math + { + template <typename T> + class + gsvd + { + public: + + enum class Type + { + std, + economy, + sigma_only + }; + + gsvd (void) : sigmaA (), sigmaB (), left_smA (), left_smB (), right_sm () + { } + + gsvd (const T& a, const T& b, + gsvd::Type gsvd_type = gsvd<T>::Type::economy); + + gsvd (const gsvd& a) + : type (a.type), + sigmaA (a.sigmaA), sigmaB (a.sigmaB), + left_smA (a.left_smA), left_smB (a.left_smB), right_sm (a.right_sm), + R(a.R) { } + + gsvd& operator = (const gsvd& a) + { + if (this != &a) + { + type = a.type; + sigmaA = a.sigmaA; + sigmaB = a.sigmaB; + left_smA = a.left_smA; + left_smB = a.left_smB; + right_sm = a.right_sm; + R = a.R; + } + + return *this; + } + + ~gsvd (void) { } + + typename T::real_diag_matrix_type + singular_values_A (void) const { return sigmaA; } + + typename T::real_diag_matrix_type + singular_values_B (void) const { return sigmaB; } + + T left_singular_matrix_A (void) const; + T left_singular_matrix_B (void) const; + + T right_singular_matrix (void) const; + T R_matrix (void) const; + + private: + typedef typename T::value_type P; + typedef typename T::real_matrix_type real_matrix; + + gsvd::Type type; + typename T::real_diag_matrix_type sigmaA, sigmaB; + T left_smA, left_smB; + T right_sm, R; + + void ggsvd (char& jobu, char& jobv, char& jobq, octave_idx_type m, + octave_idx_type n, octave_idx_type p, octave_idx_type& k, + octave_idx_type& l, P *tmp_dataA, octave_idx_type m1, + P *tmp_dataB, octave_idx_type p1, real_matrix& alpha, + real_matrix& beta, P *u, octave_idx_type nrow_u, P *v, + octave_idx_type nrow_v, P *q, octave_idx_type nrow_q, T& work, + octave_idx_type* iwork, octave_idx_type& info); + }; + } +} + +#endif
--- a/liboctave/numeric/lo-lapack-proto.h Mon Oct 10 17:34:38 2016 -0400 +++ b/liboctave/numeric/lo-lapack-proto.h Tue Oct 11 08:56:03 2016 -0700 @@ -807,6 +807,126 @@ F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL); + // GGSVD + + F77_RET_T + F77_FUNC (dggsvd, DGGSVD) + (F77_CONST_CHAR_ARG_DECL, // JOBU + F77_CONST_CHAR_ARG_DECL, // JOBV + F77_CONST_CHAR_ARG_DECL, // JOBQ + const F77_INT&, // M + const F77_INT&, // N + const F77_INT&, // P + F77_INT &, // K + F77_INT &, // L + F77_DBLE*, // A(LDA,N) + const F77_INT&, // LDA + F77_DBLE*, // B(LDB,N) + const F77_INT&, // LDB + F77_DBLE*, // ALPHA(N) + F77_DBLE*, // BETA(N) + F77_DBLE*, // U(LDU,M) + const F77_INT&, // LDU + F77_DBLE*, // V(LDV,P) + const F77_INT&, // LDV + F77_DBLE*, // Q(LDQ,N) + const F77_INT&, // LDQ + F77_DBLE*, // WORK + F77_INT*, // IWORK(N) + F77_INT& // INFO + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL); + + F77_RET_T + F77_FUNC (sggsvd, SGGSVD) + (F77_CONST_CHAR_ARG_DECL, // JOBU + F77_CONST_CHAR_ARG_DECL, // JOBV + F77_CONST_CHAR_ARG_DECL, // JOBQ + const F77_INT&, // M + const F77_INT&, // N + const F77_INT&, // P + F77_INT &, // K + F77_INT &, // L + F77_REAL*, // A + const F77_INT&, // LDA + F77_REAL*, // B + const F77_INT&, // LDB + F77_REAL*, // ALPHA + F77_REAL*, // BETA + F77_REAL*, // U + const F77_INT&, // LDU + F77_REAL*, // V + const F77_INT&, // LDV + F77_REAL*, // Q + const F77_INT&, // LDQ + F77_REAL*, // WORK + F77_INT*, // IWORK + F77_INT& // INFO + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL); + + F77_RET_T + F77_FUNC (zggsvd, ZGGSVD) + (F77_CONST_CHAR_ARG_DECL, // JOBU + F77_CONST_CHAR_ARG_DECL, // JOBV + F77_CONST_CHAR_ARG_DECL, // JOBQ + const F77_INT&, // M + const F77_INT&, // N + const F77_INT&, // P + F77_INT &, // K + F77_INT &, // L + F77_DBLE_CMPLX*, // A(LDA,N) + const F77_INT&, // LDA + F77_DBLE_CMPLX*, // B(LDB,N) + const F77_INT&, // LDB + F77_DBLE*, // ALPHA(N) + F77_DBLE*, // BETA(N) + F77_DBLE_CMPLX*, // U(LDU,M) + const F77_INT&, // LDU + F77_DBLE_CMPLX*, // V(LDV,P) + const F77_INT&, // LDV + F77_DBLE_CMPLX*, // Q(LDQ,N) + const F77_INT&, // LDQ + F77_DBLE_CMPLX*, // WORK + F77_DBLE*, // RWORK + F77_INT*, // IWORK(N) + F77_INT& // INFO + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL); + + F77_RET_T + F77_FUNC (cggsvd, CGGSVD) + (F77_CONST_CHAR_ARG_DECL, // JOBU + F77_CONST_CHAR_ARG_DECL, // JOBV + F77_CONST_CHAR_ARG_DECL, // JOBQ + const F77_INT&, // M + const F77_INT&, // N + const F77_INT&, // P + F77_INT &, // K + F77_INT &, // L + F77_CMPLX*, // A + const F77_INT&, // LDA + F77_CMPLX*, // B + const F77_INT&, // LDB + F77_REAL*, // ALPHA + F77_REAL*, // BETA + F77_CMPLX*, // U + const F77_INT&, // LDU + F77_CMPLX*, // V + const F77_INT&, // LDV + F77_CMPLX*, // Q + const F77_INT&, // LDQ + F77_CMPLX*, // WORK + F77_REAL*, // RWORK + F77_INT*, // IWORK + F77_INT& // INFO + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL + F77_CHAR_ARG_LEN_DECL); + // GTSV F77_RET_T
--- a/liboctave/numeric/module.mk Mon Oct 10 17:34:38 2016 -0400 +++ b/liboctave/numeric/module.mk Tue Oct 11 08:56:03 2016 -0700 @@ -18,6 +18,7 @@ liboctave/numeric/DASSL.h \ liboctave/numeric/DET.h \ liboctave/numeric/EIG.h \ + liboctave/numeric/gsvd.h \ liboctave/numeric/LSODE.h \ liboctave/numeric/ODE.h \ liboctave/numeric/ODEFunc.h \ @@ -69,6 +70,7 @@ liboctave/numeric/DASRT.cc \ liboctave/numeric/DASSL.cc \ liboctave/numeric/EIG.cc \ + liboctave/numeric/gsvd.cc \ liboctave/numeric/LSODE.cc \ liboctave/numeric/ODES.cc \ liboctave/numeric/Quad.cc \
--- a/liboctave/operators/mx-defs.h Mon Oct 10 17:34:38 2016 -0400 +++ b/liboctave/operators/mx-defs.h Tue Oct 11 08:56:03 2016 -0700 @@ -66,6 +66,8 @@ class EIG; +template <typename T> class gsvd; + template <typename T> class hess; template <typename T> class schur;
--- a/liboctave/operators/mx-ext.h Mon Oct 10 17:34:38 2016 -0400 +++ b/liboctave/operators/mx-ext.h Tue Oct 11 08:56:03 2016 -0700 @@ -57,6 +57,11 @@ #include "EIG.h" +// Result of a Generalized Singular Value Decomposition. + +#include "gsvd.h" + + // Result of an LU decomposition. #include "lu.h"
--- a/scripts/help/__unimplemented__.m Mon Oct 10 17:34:38 2016 -0400 +++ b/scripts/help/__unimplemented__.m Tue Oct 11 08:56:03 2016 -0700 @@ -49,11 +49,6 @@ txt = ["exifread is deprecated. " ... "The functionality is available in the imfinfo function."]; - case "gsvd" - txt = ["gsvd is not currently part of core Octave. ", ... - "See the linear-algebra package at ", ... - "@url{http://octave.sourceforge.net/linear-algebra/}."]; - case "funm" txt = ["funm is not currently part of core Octave. ", ... "See the linear-algebra package at ", ... @@ -657,7 +652,6 @@ "graph", "graymon", "griddedInterpolant", - "gsvd", "guide", "h5create", "h5disp",
--- a/scripts/plot/util/private/__gnuplot_draw_axes__.m Mon Oct 10 17:34:38 2016 -0400 +++ b/scripts/plot/util/private/__gnuplot_draw_axes__.m Tue Oct 11 08:56:03 2016 -0700 @@ -500,7 +500,10 @@ while (! isempty (kids)) - obj = get (kids(end)); + h_obj = kids(end); + kids = kids(1:(end-1)); + + obj = get (h_obj); if (isfield (obj, "xdata")) obj.xdata = double (obj.xdata); @@ -515,13 +518,12 @@ if (isfield (obj, "units")) units = obj.units; unwind_protect - set (kids(end), "units", "data"); - obj = get (kids(end)); + set (h_obj, "units", "data"); + obj = get (h_obj); unwind_protect_cleanup - set (kids(end), "units", units); + set (h_obj, "units", units); end_unwind_protect endif - kids = kids(1:(end-1)); if (strcmp (obj.visible, "off")) continue; @@ -540,10 +542,6 @@ obj.zdata(obj.zdata<=0) = NaN; endif - if (strcmp (get (obj.parent, "type"), "hggroup")) - obj.displayname = get (obj.parent, "displayname"); - endif - switch (obj.type) case "image" img_data = mapcdata (obj.cdata, obj.cdatamapping, clim, cmap_sz); @@ -634,7 +632,6 @@ titlespec{data_idx} = ['title "' tmp '"']; endif usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata)); - errbars = ""; if (nd == 3) xdat = obj.xdata(:); ydat = obj.ydata(:); @@ -657,7 +654,7 @@ endif [style, sidx] = do_linestyle_command (obj, obj.color, data_idx, - plot_stream, errbars); + plot_stream); if isempty (style{1}) style{1} = "points"; @@ -691,6 +688,43 @@ style{3}, sidx(3)); endif + if (strcmp (get (obj.parent, "type"), "hggroup")) + hg = get (obj.parent, "children"); + if (hg(1) == h_obj) + # Place phantom errorbar data for legend + data_idx += 1; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = have_cdata(data_idx - 1); + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + obj.displayname = get (obj.parent, "displayname"); + if (isempty (get (obj.parent, "displayname"))) + titlespec{data_idx} = "title \"\""; + else + tmp = undo_string_escapes ( + __maybe_munge_text__ (enhanced, obj, "displayname") + ); + titlespec{data_idx} = ['title "' tmp '"']; + endif + data{data_idx} = nan (4,1); + usingclause{data_idx} = sprintf ("record=1 using ($1):($2):($3):($4)"); + switch (get (obj.parent, "format")) + case {"box" "boxy" "boxxy"} + errbars = "boxxy"; + case "xyerr" + errbars = "xyerrorbars"; + case "yerr" + errbars = "yerrorbars"; + case "xerr" + errbars = "xerrorbars"; + otherwise + errbars = "xerrorbars"; + endswitch + withclause{data_idx} = sprintf ("with %s linestyle %d", + errbars, sidx(1)); + endif + endif + case "patch" [nr, nc] = size (obj.xdata); @@ -1850,7 +1884,7 @@ endfunction function [style, ltidx] = do_linestyle_command (obj, linecolor, idx, - plot_stream, errbars = "") + plot_stream) idx = idx + 8; style = {}; ltidx = []; @@ -1882,9 +1916,6 @@ if (! isempty (lt)) fprintf (plot_stream, " %s", lt); endif - if (! isempty (errbars)) - found_style = true; - endif if (isfield (obj, "linewidth")) fprintf (plot_stream, " linewidth %f", obj.linewidth); @@ -1898,111 +1929,105 @@ endif sidx = 1; - if (isempty (errbars)) - if (isempty (lt)) - style{sidx} = ""; - else - style{sidx} = "lines"; - endif - ltidx(sidx) = idx; + if (isempty (lt)) + style{sidx} = ""; + else + style{sidx} = "lines"; + endif + ltidx(sidx) = idx; - facesame = true; - if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") - && ! strcmp (obj.markerfacecolor, "none")) - if (strcmp (obj.markerfacecolor, "auto") - || (isnumeric (obj.markerfacecolor) - && isequal (color, obj.markerfacecolor))) - if (! isempty (pt2)) - fprintf (plot_stream, " pointtype %s", pt2); - style{sidx} = [style{sidx} "points"]; - endif - if (isfield (obj, "markersize")) - fprintf (plot_stream, " pointsize %f", obj.markersize / 3); - endif + facesame = true; + if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") + && ! strcmp (obj.markerfacecolor, "none")) + if (strcmp (obj.markerfacecolor, "auto") + || (isnumeric (obj.markerfacecolor) + && isequal (color, obj.markerfacecolor))) + if (! isempty (pt2)) + fprintf (plot_stream, " pointtype %s", pt2); + style{sidx} = [style{sidx} "points"]; + endif + if (isfield (obj, "markersize")) + fprintf (plot_stream, " pointsize %f", obj.markersize / 3); + endif + else + facesame = false; + if (! found_style) + fputs (plot_stream, " default"); + endif + fputs (plot_stream, ";\n"); + if (! isempty (style{sidx})) + sidx += 1; + idx += 1; else - facesame = false; - if (! found_style) - fputs (plot_stream, " default"); - endif fputs (plot_stream, ";\n"); - if (! isempty (style{sidx})) - sidx += 1; - idx += 1; - else - fputs (plot_stream, ";\n"); - endif - fprintf (plot_stream, "set style line %d default;\n", idx); - fprintf (plot_stream, "set style line %d", idx); - if (isnumeric (obj.markerfacecolor)) - fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", - round (255*obj.markerfacecolor)); - else - fprintf (plot_stream, " palette"); - endif - if (! isempty (pt2)) - style{sidx} = "points"; - ltidx(sidx) = idx; - fprintf (plot_stream, " pointtype %s", pt2); - endif - if (isfield (obj, "markersize")) - fprintf (plot_stream, " pointsize %f", obj.markersize / 3); - endif + endif + fprintf (plot_stream, "set style line %d default;\n", idx); + fprintf (plot_stream, "set style line %d", idx); + if (isnumeric (obj.markerfacecolor)) + fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", + round (255*obj.markerfacecolor)); + else + fprintf (plot_stream, " palette"); + endif + if (! isempty (pt2)) + style{sidx} = "points"; + ltidx(sidx) = idx; + fprintf (plot_stream, " pointtype %s", pt2); + endif + if (isfield (obj, "markersize")) + fprintf (plot_stream, " pointsize %f", obj.markersize / 3); endif endif - if (! isempty(pt) && isfield (obj, "markeredgecolor") - && ! strcmp (obj.markeredgecolor, "none")) - if (facesame && ! isempty (pt) - && (strcmp (obj.markeredgecolor, "auto") - || (isnumeric (obj.markeredgecolor) - && isequal (color, obj.markeredgecolor)))) - if (sidx == 1 && ((length (style{sidx}) == 5 - && strncmp (style{sidx}, "lines", 5)) || isempty (style{sidx}))) - if (! isempty (pt)) - style{sidx} = [style{sidx} "points"]; - fprintf (plot_stream, " pointtype %s", pt); - endif - if (isfield (obj, "markersize")) - fprintf (plot_stream, " pointsize %f", obj.markersize / 3); - endif - endif - else - if (! found_style) - fputs (plot_stream, " default"); - endif - fputs (plot_stream, ";\n"); - if (! isempty (style{sidx})) - sidx += 1; - idx += 1; - else - fputs (plot_stream, ";\n"); - endif - fprintf (plot_stream, "set style line %d default;\n", idx); - fprintf (plot_stream, "set style line %d", idx); - if (isnumeric (obj.markeredgecolor) || strcmp (obj.markeredgecolor, "auto")) - if (isnumeric (obj.markeredgecolor)) - edgecolor = obj.markeredgecolor; - else - edgecolor = obj.color; - end - fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", - round (255*edgecolor)); - else - fprintf (plot_stream, " palette"); - endif + endif + if (! isempty(pt) && isfield (obj, "markeredgecolor") + && ! strcmp (obj.markeredgecolor, "none")) + if (facesame && ! isempty (pt) + && (strcmp (obj.markeredgecolor, "auto") + || (isnumeric (obj.markeredgecolor) + && isequal (color, obj.markeredgecolor)))) + if (sidx == 1 && ((length (style{sidx}) == 5 + && strncmp (style{sidx}, "lines", 5)) || isempty (style{sidx}))) if (! isempty (pt)) - style{sidx} = "points"; - ltidx(sidx) = idx; + style{sidx} = [style{sidx} "points"]; fprintf (plot_stream, " pointtype %s", pt); endif if (isfield (obj, "markersize")) fprintf (plot_stream, " pointsize %f", obj.markersize / 3); endif endif + else + if (! found_style) + fputs (plot_stream, " default"); + endif + fputs (plot_stream, ";\n"); + if (! isempty (style{sidx})) + sidx += 1; + idx += 1; + else + fputs (plot_stream, ";\n"); + endif + fprintf (plot_stream, "set style line %d default;\n", idx); + fprintf (plot_stream, "set style line %d", idx); + if (isnumeric (obj.markeredgecolor) || strcmp (obj.markeredgecolor, "auto")) + if (isnumeric (obj.markeredgecolor)) + edgecolor = obj.markeredgecolor; + else + edgecolor = obj.color; + end + fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", + round (255*edgecolor)); + else + fprintf (plot_stream, " palette"); + endif + if (! isempty (pt)) + style{sidx} = "points"; + ltidx(sidx) = idx; + fprintf (plot_stream, " pointtype %s", pt); + endif + if (isfield (obj, "markersize")) + fprintf (plot_stream, " pointsize %f", obj.markersize / 3); + endif endif - else - style{1} = errbars; - ltidx(1) = idx; - fputs (plot_stream, " pointtype 0"); endif if (! found_style && isempty (style{1})) @@ -2106,7 +2131,7 @@ ## FIXME: Should be 6 pt start, using "*" instead pt = pt2 = "3"; case "none" - pt = pt2 = ""; + pt = pt2 = "-1"; otherwise pt = pt2 = ""; endswitch
--- a/scripts/polynomial/residue.m Mon Oct 10 17:34:38 2016 -0400 +++ b/scripts/polynomial/residue.m Tue Oct 11 08:56:03 2016 -0700 @@ -333,21 +333,10 @@ endfor ## Add the direct term. - if (numel (k)) pnum += conv (pden, k); endif - ## Check for leading zeros and trim the polynomial coefficients. - if (isa (r, "single") || isa (p, "single") || isa (k, "single")) - small = max ([max(abs(pden)), max(abs(pnum)), 1]) * eps ("single"); - else - small = max ([max(abs(pden)), max(abs(pnum)), 1]) * eps; - endif - - pnum(abs (pnum) < small) = 0; - pden(abs (pden) < small) = 0; - pnum = polyreduce (pnum); pden = polyreduce (pden); @@ -383,7 +372,7 @@ %! assert (isempty (k)); %! assert (e, [1; 2; 1; 2]); %! [br, ar] = residue (r, p, k); -%! assert (br, b, 1e-12); +%! assert (br, [0,b], 1e-12); %! assert (ar, a, 1e-12); %!test @@ -431,6 +420,14 @@ %! b = [1, z1]; %! a = [1, -(p1 + p2), p1*p2, 0, 0]; %! [br, ar] = residue (r, p, k, e); -%! assert (br, b, 1e-8); +%! assert (br, [0,0,b], 1e-7); %! assert (ar, a, 1e-8); +%!test <49291> +%! rf = [1e3, 2e3, 1e3, 2e3]; +%! cf = [316.2e-9, 50e-9, 31.6e-9, 5e-9]; +%! [num, den] = residue (1./cf,-1./(rf.*cf),0); +%! assert (numel (num), 4); +%! assert (numel (den), 5); +%! assert (den(1), 1); +