From 69fc0e320bab92ab423631168af4f40c1b038d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Thu, 21 Oct 2010 12:33:18 +0200 Subject: [PATCH] New oct-file "qzcomplex" for bringing the complex QZ decomposition to Octave. Fixes issues with partial information under Octave. --- .gitignore | 1 + mex/build/octave/Makefile.am | 2 +- mex/build/octave/bytecode/Makefile.am | 1 + mex/build/octave/configure.ac | 3 +- mex/build/octave/dynare_simul_/Makefile.am | 1 + mex/build/octave/gensylv/Makefile.am | 1 + .../octave/k_order_perturbation/Makefile.am | 1 + mex/build/octave/kronecker/Makefile.am | 1 + mex/build/octave/libdynare++/Makefile.am | 1 + mex/build/octave/logposterior/Makefile.am | 1 + mex/build/octave/mex.am | 2 - mex/build/octave/mjdgges/Makefile.am | 1 + mex/build/octave/qzcomplex/Makefile.am | 8 ++ mex/build/octave/swz/Makefile.am | 1 + mex/sources/Makefile.am | 1 + mex/sources/qzcomplex/qzcomplex.cc | 104 ++++++++++++++++++ windows/dynare.nsi | 2 +- 17 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 mex/build/octave/qzcomplex/Makefile.am create mode 100644 mex/sources/qzcomplex/qzcomplex.cc diff --git a/.gitignore b/.gitignore index 832ab3590..1a4156923 100644 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,7 @@ ylwrap # DLL rules *.mex *.dll +*.oct *.mexglx *.mexa64 *.mexw32 diff --git a/mex/build/octave/Makefile.am b/mex/build/octave/Makefile.am index 616686a9b..6f7a3add2 100644 --- a/mex/build/octave/Makefile.am +++ b/mex/build/octave/Makefile.am @@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I ../../../m4 # libdynare++ must come before gensylv, k_order_perturbation, dynare_simul_ if DO_SOMETHING -SUBDIRS = mjdgges kronecker bytecode libdynare++ gensylv k_order_perturbation dynare_simul_ logposterior +SUBDIRS = mjdgges kronecker bytecode libdynare++ gensylv k_order_perturbation dynare_simul_ logposterior qzcomplex if HAVE_GSL SUBDIRS += swz endif diff --git a/mex/build/octave/bytecode/Makefile.am b/mex/build/octave/bytecode/Makefile.am index 954614256..549f73e8e 100644 --- a/mex/build/octave/bytecode/Makefile.am +++ b/mex/build/octave/bytecode/Makefile.am @@ -1,2 +1,3 @@ +EXEXET = .mex include ../mex.am include ../../bytecode.am diff --git a/mex/build/octave/configure.ac b/mex/build/octave/configure.ac index e58b3ff9c..e54aa85b0 100644 --- a/mex/build/octave/configure.ac +++ b/mex/build/octave/configure.ac @@ -101,6 +101,7 @@ AC_CONFIG_FILES([Makefile k_order_perturbation/Makefile dynare_simul_/Makefile swz/Makefile - logposterior/Makefile]) + logposterior/Makefile + qzcomplex/Makefile]) AC_OUTPUT diff --git a/mex/build/octave/dynare_simul_/Makefile.am b/mex/build/octave/dynare_simul_/Makefile.am index b7301c554..3bf23bd7c 100644 --- a/mex/build/octave/dynare_simul_/Makefile.am +++ b/mex/build/octave/dynare_simul_/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../dynare_simul_.am diff --git a/mex/build/octave/gensylv/Makefile.am b/mex/build/octave/gensylv/Makefile.am index 2750dc961..68bec8f8e 100644 --- a/mex/build/octave/gensylv/Makefile.am +++ b/mex/build/octave/gensylv/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../gensylv.am diff --git a/mex/build/octave/k_order_perturbation/Makefile.am b/mex/build/octave/k_order_perturbation/Makefile.am index 916f40d75..f60f2c2a2 100644 --- a/mex/build/octave/k_order_perturbation/Makefile.am +++ b/mex/build/octave/k_order_perturbation/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../k_order_perturbation.am diff --git a/mex/build/octave/kronecker/Makefile.am b/mex/build/octave/kronecker/Makefile.am index 41a9064ab..26b50e81c 100644 --- a/mex/build/octave/kronecker/Makefile.am +++ b/mex/build/octave/kronecker/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../kronecker.am diff --git a/mex/build/octave/libdynare++/Makefile.am b/mex/build/octave/libdynare++/Makefile.am index c1283b13c..6ab9e430a 100644 --- a/mex/build/octave/libdynare++/Makefile.am +++ b/mex/build/octave/libdynare++/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../libdynare++.am diff --git a/mex/build/octave/logposterior/Makefile.am b/mex/build/octave/logposterior/Makefile.am index aa5387bc2..a4d591844 100644 --- a/mex/build/octave/logposterior/Makefile.am +++ b/mex/build/octave/logposterior/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../logposterior.am diff --git a/mex/build/octave/mex.am b/mex/build/octave/mex.am index 029dc4521..9f450f524 100644 --- a/mex/build/octave/mex.am +++ b/mex/build/octave/mex.am @@ -1,5 +1,3 @@ -EXEEXT = .mex - CPPFLAGS += $(shell $(MKOCTFILE) -p CPPFLAGS) CPPFLAGS += $(shell $(MKOCTFILE) -p INCFLAGS) CPPFLAGS += -I$(top_srcdir)/../../sources diff --git a/mex/build/octave/mjdgges/Makefile.am b/mex/build/octave/mjdgges/Makefile.am index 63da413b7..e57291e65 100644 --- a/mex/build/octave/mjdgges/Makefile.am +++ b/mex/build/octave/mjdgges/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../mjdgges.am diff --git a/mex/build/octave/qzcomplex/Makefile.am b/mex/build/octave/qzcomplex/Makefile.am new file mode 100644 index 000000000..ca9692d8a --- /dev/null +++ b/mex/build/octave/qzcomplex/Makefile.am @@ -0,0 +1,8 @@ +EXEEXT = .oct +include ../mex.am + +vpath %.cc $(top_srcdir)/../../sources/qzcomplex + +noinst_PROGRAMS = qzcomplex + +nodist_qzcomplex_SOURCES = qzcomplex.cc diff --git a/mex/build/octave/swz/Makefile.am b/mex/build/octave/swz/Makefile.am index 94a3b4b6a..c9660dd37 100644 --- a/mex/build/octave/swz/Makefile.am +++ b/mex/build/octave/swz/Makefile.am @@ -1,2 +1,3 @@ +EXEEXT = .mex include ../mex.am include ../../swz.am diff --git a/mex/sources/Makefile.am b/mex/sources/Makefile.am index c0d4acd7d..ba2152c08 100644 --- a/mex/sources/Makefile.am +++ b/mex/sources/Makefile.am @@ -7,6 +7,7 @@ EXTRA_DIST = \ mjdgges \ kronecker \ bytecode \ + qzcomplex \ k_order_perturbation clean-local: diff --git a/mex/sources/qzcomplex/qzcomplex.cc b/mex/sources/qzcomplex/qzcomplex.cc new file mode 100644 index 000000000..009590a59 --- /dev/null +++ b/mex/sources/qzcomplex/qzcomplex.cc @@ -0,0 +1,104 @@ +/* + * Oct-file for bringing the complex QZ decomposition to Octave. + * Simple wrapper around LAPACK's zgges. + * + * Written by Sebastien Villemot . + */ + +/* + * Copyright (C) 2010 Dynare Team + * + * This file is part of Dynare. + * + * Dynare 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. + * + * Dynare 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 Dynare. If not, see . + */ + +#include +#include + +extern "C" +{ + F77_RET_T + F77_FUNC(zgges, ZGGES) (F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, + octave_idx_type (*) (Complex *, Complex *), const octave_idx_type &, + Complex *, const octave_idx_type &, Complex *, const octave_idx_type &, + octave_idx_type &, Complex *, Complex *, Complex *, const octave_idx_type &, + Complex *, const octave_idx_type &, Complex *, const octave_idx_type &, + double *, octave_idx_type *, octave_idx_type &); +} + +DEFUN_DLD (qzcomplex, args, nargout, "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} [ @var{aa}, @var{bb}, @var{q}, @var{z} ] = qzcomplex (@var{a}, @var{b})\n\ +\n\ +Computes the complex QZ decomposition of @math{(A, B)}, satisfying:\n\ +@example\n\ + AA = Q'*A*Z, BB = Q'*B*Z\n\ +@end example\n\ +@end deftypefn\n\ +") +{ + int nargin = args.length(); + octave_value_list retval; + + if (nargin != 2) + { + error("qzcomplex: needs two input arguments"); + return retval; + } + if (nargout != 4) + { + error("qzcomplex: needs four output arguments"); + return retval; + } + + ComplexMatrix A = args(0).complex_matrix_value(); + ComplexMatrix B = args(1).complex_matrix_value(); + if (error_state) + return retval; + + dim_vector dimA = A.dims(); + dim_vector dimB = B.dims(); + octave_idx_type n = dimA(0); + if (n != dimA(1) || n != dimB(0) || n != dimB(1)) + { + error("qzcomplex: input matrices must be square and of same size"); + return retval; + } + + octave_idx_type lwork = 2*n; + OCTAVE_LOCAL_BUFFER(Complex, alpha, n); + OCTAVE_LOCAL_BUFFER(Complex, beta, n); + OCTAVE_LOCAL_BUFFER(Complex, work, lwork); + OCTAVE_LOCAL_BUFFER(double, rwork, 8*n); + ComplexMatrix vsl(n, n), vsr(n,n); + octave_idx_type sdim, info; + + F77_XFCN (zgges, ZGGES, (F77_CONST_CHAR_ARG("V"), F77_CONST_CHAR_ARG("V"), + F77_CONST_CHAR_ARG("N"), NULL, + n, A.fortran_vec(), n, B.fortran_vec(), n, sdim, + alpha, beta, vsl.fortran_vec(), n, vsr.fortran_vec(), n, + work, lwork, rwork, NULL, info)); + + if (info != 0) + { + error("qzcomplex: zgges failed"); + return retval; + } + + retval(0) = octave_value(A); + retval(1) = octave_value(B); + retval(2) = octave_value(vsl); + retval(3) = octave_value(vsr); + return retval; +} diff --git a/windows/dynare.nsi b/windows/dynare.nsi index 507866357..555e0af06 100644 --- a/windows/dynare.nsi +++ b/windows/dynare.nsi @@ -110,7 +110,7 @@ SectionGroupEnd Section "MEX files for Octave 3.2.4 (MinGW build)" SetOutPath $INSTDIR\mex\octave - File ..\mex\octave\*.mex + File ..\mex\octave\*.mex ..\mex\octave\*.oct SectionEnd Section "Dynare++ (standalone executable)"