Mercurial > hg > octave-terminal
changeset 13660:632f653a29a0
Merge with Savannah
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Mon, 05 Sep 2011 06:52:45 -0500 |
parents | d98c6ef06dff (current diff) bf61bc523805 (diff) |
children | 8a1896fb82d4 |
files | doc/interpreter/contributors.in scripts/plot/__gnuplot_drawnow__.m |
diffstat | 140 files changed, 2819 insertions(+), 870 deletions(-) [+] |
line wrap: on
line diff
--- a/build-aux/common.mk +++ b/build-aux/common.mk @@ -162,8 +162,6 @@ RDYNAMIC_FLAG = @RDYNAMIC_FLAG@ -RLD_FLAG = @RLD_FLAG@ - FLIBS = @FLIBS@ LIBOCTINTERP = @LIBOCTINTERP@ @@ -535,8 +533,12 @@ -e "s|%OCTAVE_CONF_MAGICK_LDFLAGS%|\"${MAGICK_LDFLAGS}\"|" \ -e "s|%OCTAVE_CONF_MAGICK_LIBS%|\"${MAGICK_LIBS}\"|" \ -e 's|%OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%|\"@MKOCTFILE_DL_LDFLAGS@\"|' \ + -e "s|%OCTAVE_CONF_OCTAVE_LINK_DEPS%|\"${OCTAVE_LINK_DEPS}\"|" \ + -e "s|%OCTAVE_CONF_OCTAVE_LINK_OPTS%|\"${OCTAVE_LINK_OPTS}\"|" \ -e "s|%OCTAVE_CONF_OCTINCLUDEDIR%|\"${octincludedir}\"|" \ -e "s|%OCTAVE_CONF_OCTLIBDIR%|\"${octlibdir}\"|" \ + -e "s|%OCTAVE_CONF_OCT_LINK_DEPS%|\"${OCT_LINK_DEPS}\"|" \ + -e "s|%OCTAVE_CONF_OCT_LINK_OPTS%|\"${OCT_LINK_OPTS}\"|" \ -e "s|%OCTAVE_CONF_OPENGL_LIBS%|\"${OPENGL_LIBS}\"|" \ -e "s|%OCTAVE_CONF_PREFIX%|\"${prefix}\"|" \ -e "s|%OCTAVE_CONF_PTHREAD_CFLAGS%|\"${PTHREAD_CFLAGS}\"|" \ @@ -551,7 +553,6 @@ -e "s|%OCTAVE_CONF_RDYNAMIC_FLAG%|\"${RDYNAMIC_FLAG}\"|" \ -e "s|%OCTAVE_CONF_READLINE_LIBS%|\"${READLINE_LIBS}\"|" \ -e "s|%OCTAVE_CONF_REGEX_LIBS%|\"${REGEX_LIBS}\"|" \ - -e "s|%OCTAVE_CONF_RLD_FLAG%|\"${RLD_FLAG}\"|" \ -e "s|%OCTAVE_CONF_SED%|\"${SED}\"|" \ -e "s|%OCTAVE_CONF_SHARED_LIBS%|\"${SHARED_LIBS}\"|" \ -e "s|%OCTAVE_CONF_SHLEXT%|\"${SHLEXT}\"|" \
--- a/configure.ac +++ b/configure.ac @@ -1157,7 +1157,7 @@ AC_ARG_ENABLE([dl], [AS_HELP_STRING([--enable-dl], - [create shared libraries (not all systems)])], [ + [allow loading of dynamically linked modules (not all systems)])], [ case "${enableval}" in yes) ENABLE_DYNAMIC_LINKING=true ;; no) ENABLE_DYNAMIC_LINKING=false ;; @@ -1170,16 +1170,6 @@ AC_MSG_ERROR([You can't disable building static AND shared libraries!]) fi -AC_ARG_ENABLE(rpath, - [AS_HELP_STRING([--enable-rpath], - [override the default link options for rpath; e.g., --enable-rpath='-rpath $(octlibdir)'])], - [ if test "$enableval" = no; then use_rpath=false; - else - use_rpath=true - if test "$enableval" = yes; then true; - else enable_rpath_arg="$enableval"; fi - fi], [use_rpath=true]) - CPICFLAG=-fPIC CXXPICFLAG=-fPIC FPICFLAG=-fPIC @@ -1200,7 +1190,6 @@ DL_LDFLAGS='$(SH_LDFLAGS)' MKOCTFILE_DL_LDFLAGS='$(DL_LDFLAGS)' SONAME_FLAGS= -RLD_FLAG= NO_OCT_FILE_STRIP=false TEMPLATE_AR='$(AR)' TEMPLATE_ARFLAGS="$ARFLAGS" @@ -1221,14 +1210,12 @@ ;; *-*-freebsd*) SH_LDFLAGS="-shared -Wl,-x" - RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)' ;; alpha*-dec-osf*) CPICFLAG= CXXPICFLAG= FPICFLAG= SH_LDFLAGS="-shared -Wl,-expect_unresolved -Wl,'*'" - RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)' ;; *-*-darwin*) DL_LDFLAGS='-bundle -bundle_loader $(top_builddir)/src/octave $(LDFLAGS)' @@ -1335,11 +1322,9 @@ *-*-linux* | *-*-gnu*) MKOCTFILE_DL_LDFLAGS="-shared -Wl,-Bsymbolic" SONAME_FLAGS='-Wl,-soname -Wl,$@' - RLD_FLAG='-Wl,-rpath -Wl,$(octlibdir)' ;; i[[3456]]86-*-sco3.2v5*) SONAME_FLAGS='-Wl,-h -Wl,$@' - RLD_FLAG= SH_LDFLAGS=-G ;; rs6000-ibm-aix* | powerpc-ibm-aix*) @@ -1356,7 +1341,6 @@ fi SHLEXT=sl SH_LDFLAGS="-shared -fPIC" - RLD_FLAG='-Wl,+b -Wl,$(octlibdir)' library_path_var=SHLIB_PATH ;; ia64*-hp-hpux*) @@ -1366,13 +1350,11 @@ FPICFLAG=+Z fi SH_LDFLAGS="-shared -fPIC" - RLD_FLAG='-Wl,+b -Wl,$(octlibdir)' ;; *-sgi-*) CPICFLAG= CXXPICFLAG= FPICFLAG= - RLD_FLAG='-rpath $(octlibdir)' ;; sparc-sun-sunos4*) if test "$ac_cv_f77_compiler_gnu" = yes; then @@ -1382,7 +1364,6 @@ fi SH_LD=ld SH_LDFLAGS="-assert nodefinitions" - RLD_FLAG='-L$(octlibdir)' ;; sparc-sun-solaris2* | i386-pc-solaris2*) if test "$ac_cv_f77_compiler_gnu" = yes; then @@ -1402,7 +1383,6 @@ CXXPICFLAG=-KPIC SH_LDFLAGS=-G fi - RLD_FLAG='-R $(octlibdir)' ## Template closures in archive libraries need a different mechanism. if test "$GXX" = yes; then true @@ -1416,14 +1396,6 @@ AM_CONDITIONAL([AMCOND_BUILD_COMPILED_AUX_PROGRAMS], [test x$BUILD_COMPILED_AUX_PROGRAMS = xtrue]) -if $use_rpath; then - if test -n "$enable_rpath_arg"; then - RLD_FLAG="$enable_rpath_arg" - fi -else - RLD_FLAG="" -fi - AC_MSG_NOTICE([defining FPICFLAG to be $FPICFLAG]) AC_MSG_NOTICE([defining CPICFLAG to be $CPICFLAG]) AC_MSG_NOTICE([defining CXXPICFLAG to be $CXXPICFLAG]) @@ -1445,7 +1417,6 @@ AC_MSG_NOTICE([defining MKOCTFILE_DL_LDFLAGS to be $MKOCTFILE_DL_LDFLAGS]) AC_MSG_NOTICE([defining SONAME_FLAGS to be $SONAME_FLAGS]) AC_MSG_NOTICE([defining NO_OCT_FILE_STRIP to be $NO_OCT_FILE_STRIP]) -AC_MSG_NOTICE([defining RLD_FLAG to be $RLD_FLAG]) AC_MSG_NOTICE([defining TEMPLATE_AR to be $TEMPLATE_AR]) AC_MSG_NOTICE([defining TEMPLATE_ARFLAGS to be $TEMPLATE_ARFLAGS]) AC_MSG_NOTICE([defining CRUFT_DLL_DEFS to be $CRUFT_DLL_DEFS]) @@ -1474,7 +1445,6 @@ AC_SUBST(MKOCTFILE_DL_LDFLAGS) AC_SUBST(SONAME_FLAGS) AC_SUBST(NO_OCT_FILE_STRIP) -AC_SUBST(RLD_FLAG) AC_SUBST(TEMPLATE_AR) AC_SUBST(TEMPLATE_ARFLAGS) AC_SUBST(CRUFT_DLL_DEFS) @@ -1488,28 +1458,42 @@ AC_CHECK_FUNCS(getpwnam, [], [AC_CHECK_LIB(sun, getpwnam)]) -NO_UNDEFINED_LDFLAG= case "$canonical_host_type" in *-*-mingw*) if test "$have_msvc" = "yes"; then AC_CHECK_LIB(dirent, opendir) LIBS="$LIBS -ladvapi32 -lgdi32 -lws2_32 -luser32 -lkernel32" - NO_UNDEFINED_LDFLAG=-no-undefined else LIBS="$LIBS -lgdi32 -lws2_32 -luser32 -lkernel32" - NO_UNDEFINED_LDFLAG=-no-undefined fi LIBS="$LIBS -lgdi32 -lws2_32 -luser32 -lkernel32" - NO_UNDEFINED_LDFLAG=-no-undefined ;; *-*-msdosmsvc*) AC_CHECK_LIB(dirent, opendir) LIBS="$LIBS -ladvapi32 -lgdi32 -lws2_32 -luser32 -lkernel32" - NO_UNDEFINED_LDFLAG=-no-undefined ;; esac + +AC_ARG_ENABLE([no-undefined], + [AS_HELP_STRING([--enable-no-undefined], + [pass -no-undefined to libtool when linking linking Octave and its shared libraries (on by default)])], + [case "${enableval}" in + yes) NO_UNDEFINED_LDFLAG="-no-undefined" ;; + no) NO_UNDEFINED_LDFLAG="" ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-link-all-depenencies]) ;; + esac], [NO_UNDEFINED_LDFLAG="-no-undefined"]) AC_SUBST(NO_UNDEFINED_LDFLAG) +AC_ARG_ENABLE([link-all-dependencies], + [AS_HELP_STRING([--enable-link-all-dependencies], + [link Octave and its shared libraries with all dependencies, not just those immediately referenced (should not be needed on most systems)])], + [case "${enableval}" in + yes) link_all_deps=true ;; + no) link_all_deps=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-link-all-depenencies]) ;; + esac], [link_all_deps=false]) +AM_CONDITIONAL([AMCOND_LINK_ALL_DEPS], [test x$link_all_deps = xtrue]) + ### Type stuff. AC_TYPE_MODE_T @@ -1685,7 +1669,7 @@ OCTAVE_CXX_FLAG(-rdynamic, [RDYNAMIC_FLAG=-rdynamic]) ;; shl_load) - shl_load_api=true + shl_load_api=truenn DL_API_MSG="(shl_load)" AC_DEFINE(HAVE_SHL_LOAD_API, 1, [Define if your system has shl_load and shl_findsym for dynamic linking]) ;; @@ -1704,12 +1688,18 @@ DL_LIBS="$lt_cv_dlopen_libs" AC_SUBST(DL_LIBS) + ## Disable dynamic linking if capability is not present. if $dlopen_api || $shl_load_api || $loadlibrary_api || $dyld_api; then - ENABLE_DYNAMIC_LINKING=true - AC_DEFINE(ENABLE_DYNAMIC_LINKING, 1, [Define if using dynamic linking]) + true + else + ENABLE_DYNAMIC_LINKING=false fi fi +if $ENABLE_DYNAMIC_LINKING; then + AC_DEFINE(ENABLE_DYNAMIC_LINKING, 1, [Define if using dynamic linking]) +fi + AM_CONDITIONAL([AMCOND_ENABLE_DYNAMIC_LINKING], [test x$ENABLE_DYNAMIC_LINKING = xtrue])
--- a/doc/interpreter/contributors.in +++ b/doc/interpreter/contributors.in @@ -9,6 +9,7 @@ Alexander Barth David Bateman Heinz Bauschke +Roman Belov Karl Berry David Billinghurst Don Bindner
--- a/doc/interpreter/linalg.txi +++ b/doc/interpreter/linalg.txi @@ -187,6 +187,8 @@ @node Specialized Solvers @section Specialized Solvers +@DOCSTRING(bicg) + @DOCSTRING(bicgstab) @DOCSTRING(cgs)
--- a/doc/interpreter/matrix.txi +++ b/doc/interpreter/matrix.txi @@ -81,6 +81,9 @@ @DOCSTRING(lookup) +If you wish to check if a variable exists at all, instead of properties +its elements may have, consult @ref{Status of Variables}. + @node Rearranging Matrices @section Rearranging Matrices
--- a/doc/interpreter/mkoctfile.1 +++ b/doc/interpreter/mkoctfile.1 @@ -95,28 +95,29 @@ Print configuration variable \fIVAR\fP. Recognized variables are: .RS .Vb - ALL_CFLAGS FFTW3F_LDFLAGS - ALL_CXXFLAGS FFTW3F_LIBS - ALL_FFLAGS FLIBS - ALL_LDFLAGS FPICFLAG - BLAS_LIBS INCFLAGS - CC LAPACK_LIBS - CFLAGS LDFLAGS - CPICFLAG LD_CXX - CPPFLAGS LD_STATIC_FLAG - CXX LFLAGS - CXXFLAGS LIBCRUFT - CXXPICFLAG LIBOCTAVE - DEPEND_EXTRA_SED_PATTERN LIBOCTINTERP - DEPEND_FLAGS LIBS - DL_LD OCTAVE_LIBS - DL_LDFLAGS RDYNAMIC_FLAG - EXEEXT READLINE_LIBS - F77 RLD_FLAG - F77_INTEGER_8_FLAG SED - FFLAGS XTRA_CFLAGS - FFTW3_LDFLAGS XTRA_CXXFLAGS - FFTW3_LIBS + ALL_CFLAGS FFTW3F_LIBS + ALL_CXXFLAGS FLIBS + ALL_FFLAGS FPICFLAG + ALL_LDFLAGS INCFLAGS + BLAS_LIBS LAPACK_LIBS + CC LDFLAGS + CFLAGS LD_CXX + CPICFLAG LD_STATIC_FLAG + CPPFLAGS LFLAGS + CXX LIBCRUFT + CXXFLAGS LIBOCTAVE + CXXPICFLAG LIBOCTINTERP + DEPEND_EXTRA_SED_PATTERN LIBS + DEPEND_FLAGS OCTAVE_LIBS + DL_LD OCTAVE_LINK_DEPS + DL_LDFLAGS OCT_LINK_DEPS + EXEEXT RDYNAMIC_FLAG + F77 READLINE_LIBS + F77_INTEGER_8_FLAG SED + FFLAGS XTRA_CFLAGS + FFTW3_LDFLAGS XTRA_CXXFLAGS + FFTW3_LIBS + FFTW3F_LDFLAGS .Ve .RE .TP
--- a/doc/interpreter/numbers.txi +++ b/doc/interpreter/numbers.txi @@ -836,3 +836,7 @@ @DOCSTRING(islogical) @DOCSTRING(isprime) + +If instead of knowing properties of variables, you wish to know which +variables are defined and to gather other information about the +workspace itself, see @ref{Status of Variables}.
--- a/libcruft/Makefile.am +++ b/libcruft/Makefile.am @@ -34,6 +34,13 @@ @CRUFT_DLL_DEFS@ \ $(AM_CPPFLAGS) +include link-deps.mk + +libcruft_la_LIBADD = \ + libranlib.la \ + ../libgnu/libgnu.la \ + $(LIBCRUFT_LINK_DEPS) + # Increment these as needed and according to the rules in the libtool # manual: libcruft_current = 0 @@ -46,13 +53,8 @@ -version-info $(libcruft_version_info) \ $(NO_UNDEFINED_LDFLAG) \ @XTRA_CRUFT_SH_LDFLAGS@ \ - -bindir $(bindir) - -libcruft_la_LIBADD = \ - ../libgnu/libgnu.la \ - libranlib.la \ - $(LAPACK_LIBS) $(BLAS_LIBS) \ - $(FLIBS) + -bindir $(bindir) \ + $(LIBCRUFT_LINK_OPTS) libcruft_la_DEPENDENCIES = cruft.def
new file mode 100644 --- /dev/null +++ b/libcruft/link-deps.mk @@ -0,0 +1,30 @@ +## The following libraries may be needed to satisfy gnulib dependencies: +## +## $(COPYSIGN_LIBM) +## $(FLOOR_LIBM) +## $(GETHOSTNAME_LIB) +## $(LIBSOCKET) +## $(LIB_NANOSLEEP) +## $(LTLIBINTL) +## $(ROUNDF_LIBM) +## $(ROUND_LIBM) +## $(TRUNCF_LIBM) +## $(TRUNC_LIBM) + +LIBCRUFT_LINK_DEPS = \ + $(COPYSIGN_LIBM) \ + $(FLOOR_LIBM) \ + $(GETHOSTNAME_LIB) \ + $(LIBSOCKET) \ + $(LIB_NANOSLEEP) \ + $(LTLIBINTL) \ + $(ROUNDF_LIBM) \ + $(ROUND_LIBM) \ + $(TRUNCF_LIBM) \ + $(TRUNC_LIBM) \ + $(LAPACK_LIBS) \ + $(BLAS_LIBS) \ + $(FLIBS) \ + $(LIBS) + +LIBCRUFT_LINK_OPTS =
--- a/liboctave/MSparse.h +++ b/liboctave/MSparse.h @@ -65,6 +65,8 @@ explicit MSparse (octave_idx_type r, octave_idx_type c, T val) : Sparse<T> (r, c, val) { } + explicit MSparse (const PermMatrix& a) : Sparse<T>(a) { } + MSparse (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : Sparse<T> (r, c, num_nz) { } ~MSparse (void) { }
--- a/liboctave/Makefile.am +++ b/liboctave/Makefile.am @@ -492,21 +492,6 @@ LIBOCT_READLINE_SOURCES = $(LIBOCT_READLINE_CXX_SOURCES) $(LIBOCT_READLINE_C_SOURCES) -LINK_DEPS = \ - $(RLD_FLAG) \ - ../libcruft/libcruft.la \ - ../libcruft/libranlib.la \ - ../libgnu/libgnu.la \ - $(SPARSE_XLIBS) \ - $(ARPACK_LIBS) \ - $(QRUPDATE_LIBS) \ - $(FFTW_XLIBS) \ - $(LAPACK_LIBS) $(BLAS_LIBS) \ - $(READLINE_LIBS) $(TERM_LIBS) \ - $(LIBGLOB) $(REGEX_LIBS) $(DL_LIBS) \ - $(FLIBS) \ - $(PTHREAD_LIBS) $(LIBS) - liboctave_la_SOURCES = \ $(LIBOCTAVE_CXX_SOURCES) \ $(LIBOCTAVE_C_SOURCES) \ @@ -517,7 +502,11 @@ nodist_liboctave_la_SOURCES = \ $(BUILT_LIBOCTAVE_CXX_SOURCES) -liboctave_la_LIBADD = $(LINK_DEPS) +include link-deps.mk + +liboctave_la_LIBADD = \ + ../libcruft/libcruft.la \ + $(LIBOCTAVE_LINK_DEPS) liboctave_la_CPPFLAGS = \ @OCTAVE_DLL_DEFS@ \ @@ -538,10 +527,7 @@ -version-info $(liboctave_version_info) \ $(NO_UNDEFINED_LDFLAG) \ -bindir $(bindir) \ - $(SPARSE_XLDFLAGS) \ - $(ARPACK_LDFLAGS) \ - $(QRUPDATE_LDFLAGS) \ - $(FFTW_XLDFLAGS) + $(LIBOCTAVE_LINK_OPTS) octinclude_HEADERS = \ $(INCS) \
--- a/liboctave/Sparse.cc +++ b/liboctave/Sparse.cc @@ -50,6 +50,34 @@ #include "oct-spparms.h" #include "mx-inlines.cc" +#include "PermMatrix.h" + +template <class T> +Sparse<T>::Sparse (const PermMatrix& a) + : rep (new typename Sparse<T>::SparseRep (a.rows (), a.cols (), a.rows ())), + dimensions (dim_vector (a.rows (), a.cols())) +{ + octave_idx_type n = a.rows (); + for (octave_idx_type i = 0; i <= n; i++) + cidx (i) = i; + + const Array<octave_idx_type> pv = a.pvec (); + + if (a.is_row_perm ()) + { + for (octave_idx_type i = 0; i < n; i++) + ridx (pv (i)) = i; + } + else + { + for (octave_idx_type i = 0; i < n; i++) + ridx (i) = pv (i); + } + + for (octave_idx_type i = 0; i < n; i++) + data (i) = 1.0; +} + template <class T> T& Sparse<T>::SparseRep::elem (octave_idx_type _r, octave_idx_type _c)
--- a/liboctave/Sparse.h +++ b/liboctave/Sparse.h @@ -41,6 +41,7 @@ #include "oct-mem.h" class idx_vector; +class PermMatrix; // Two dimensional sparse class. Handles the reference counting for // all the derived classes. @@ -195,6 +196,10 @@ : rep (new typename Sparse<T>::SparseRep (nr, nc, nz)), dimensions (dim_vector (nr, nc)) { } + // Both SparseMatrix and SparseBoolMatrix need this ctor, and this + // is their only common ancestor. + explicit Sparse (const PermMatrix& a); + // Type conversion case. Preserves capacity (). template <class U> Sparse (const Sparse<U>& a)
--- a/liboctave/boolSparse.h +++ b/liboctave/boolSparse.h @@ -57,6 +57,8 @@ explicit SparseBoolMatrix (const boolNDArray& a) : Sparse<bool> (a) { } + explicit SparseBoolMatrix (const PermMatrix& a) : Sparse<bool> (a) { }; + SparseBoolMatrix (const Array<bool>& a, const idx_vector& r, const idx_vector& c, octave_idx_type nr = -1, octave_idx_type nc = -1, bool sum_terms = true,
--- a/liboctave/bsxfun-decl.h +++ b/liboctave/bsxfun-decl.h @@ -42,6 +42,12 @@ BSXFUN_OP_DECL (min, ARRAY, API) \ BSXFUN_OP_DECL (max, ARRAY, API) +#define BSXFUN_MIXED_INT_DECLS(INT_TYPE, API) \ + BSXFUN_OP2_DECL (pow, INT_TYPE, INT_TYPE, NDArray, API) \ + BSXFUN_OP2_DECL (pow, INT_TYPE, INT_TYPE, FloatNDArray, API) \ + BSXFUN_OP2_DECL (pow, INT_TYPE, NDArray, INT_TYPE, API) \ + BSXFUN_OP2_DECL (pow, INT_TYPE, FloatNDArray, INT_TYPE, API) + #define BSXFUN_STDREL_DECLS(ARRAY, API) \ BSXFUN_REL_DECL (eq, ARRAY, API) \ BSXFUN_REL_DECL (ne, ARRAY, API) \
--- a/liboctave/bsxfun-defs.cc +++ b/liboctave/bsxfun-defs.cc @@ -174,4 +174,11 @@ BSXFUN_REL_DEF_MXLOOP (gt, ARRAY, mx_inline_gt) \ BSXFUN_REL_DEF_MXLOOP (ge, ARRAY, mx_inline_ge) +//For bsxfun power with mixed integer/float types +#define BSXFUN_POW_MIXED_MXLOOP(INT_TYPE) \ + BSXFUN_OP2_DEF_MXLOOP (pow, INT_TYPE, INT_TYPE, NDArray, mx_inline_pow) \ + BSXFUN_OP2_DEF_MXLOOP (pow, INT_TYPE, INT_TYPE, FloatNDArray, mx_inline_pow)\ + BSXFUN_OP2_DEF_MXLOOP (pow, INT_TYPE, NDArray, INT_TYPE, mx_inline_pow) \ + BSXFUN_OP2_DEF_MXLOOP (pow, INT_TYPE, FloatNDArray, INT_TYPE, mx_inline_pow) + #endif
--- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -3117,11 +3117,11 @@ %! cv = randn(10,1); %! rv = randn(1,10); %! rvt = rv'; -%!assert([M*cv,M*cv],M*[cv,cv],1e-14) -%!assert([M'*cv,M'*cv],M'*[cv,cv],3e-14) -%!assert([rv*M;rv*M],[rv;rv]*M,3e-14) -%!assert([rv*M';rv*M'],[rv;rv]*M',3e-14) -%!assert(2*rv*cv,[rv,rv]*[cv;cv],3e-14) +%!assert([M*cv,M*cv],M*[cv,cv],1e-13) +%!assert([M'*cv,M'*cv],M'*[cv,cv],1e-13) +%!assert([rv*M;rv*M],[rv;rv]*M,1e-13) +%!assert([rv*M';rv*M'],[rv;rv]*M',1e-13) +%!assert(2*rv*cv,[rv,rv]*[cv;cv],1e-13) %!assert(M'\cv,Mt\cv,1e-14) %!assert(M'\rv',Mt\rvt,1e-14) */
--- a/liboctave/dSparse.cc +++ b/liboctave/dSparse.cc @@ -180,29 +180,6 @@ cidx(i) = j; } -SparseMatrix::SparseMatrix (const PermMatrix& a) - : MSparse<double> (a.rows (), a.cols (), a.rows ()) -{ - octave_idx_type n = a.rows (); - for (octave_idx_type i = 0; i <= n; i++) - cidx (i) = i; - const Array<octave_idx_type> pv = a.pvec (); - - if (a.is_row_perm ()) - { - for (octave_idx_type i = 0; i < n; i++) - ridx (pv (i)) = i; - } - else - { - for (octave_idx_type i = 0; i < n; i++) - ridx (i) = pv (i); - } - - for (octave_idx_type i = 0; i < n; i++) - data (i) = 1.0; -} - bool SparseMatrix::operator == (const SparseMatrix& a) const {
--- a/liboctave/dSparse.h +++ b/liboctave/dSparse.h @@ -82,7 +82,7 @@ explicit SparseMatrix (const DiagMatrix& a); - explicit SparseMatrix (const PermMatrix& a); + explicit SparseMatrix (const PermMatrix& a) : MSparse<double>(a) { } SparseMatrix (octave_idx_type r, octave_idx_type c, octave_idx_type num_nz) : MSparse<double> (r, c, num_nz) { }
--- a/liboctave/fNDArray.cc +++ b/liboctave/fNDArray.cc @@ -885,3 +885,5 @@ BSXFUN_OP_DEF_MXLOOP (pow, FloatNDArray, mx_inline_pow) BSXFUN_OP2_DEF_MXLOOP (pow, FloatComplexNDArray, FloatComplexNDArray, FloatNDArray, mx_inline_pow) +BSXFUN_OP2_DEF_MXLOOP (pow, FloatComplexNDArray, FloatNDArray, + FloatComplexNDArray, mx_inline_pow)
--- a/liboctave/fNDArray.h +++ b/liboctave/fNDArray.h @@ -182,5 +182,7 @@ BSXFUN_OP_DECL (pow, FloatNDArray, OCTAVE_API) BSXFUN_OP2_DECL (pow, FloatComplexNDArray, FloatComplexNDArray, FloatNDArray, OCTAVE_API) +BSXFUN_OP2_DECL (pow, FloatComplexNDArray, FloatNDArray, + FloatComplexNDArray, OCTAVE_API) #endif
--- a/liboctave/int16NDArray.cc +++ b/liboctave/int16NDArray.cc @@ -56,3 +56,5 @@ BSXFUN_STDREL_DEFS_MXLOOP (int16NDArray) BSXFUN_OP_DEF_MXLOOP (pow, int16NDArray, mx_inline_pow) + +BSXFUN_POW_MIXED_MXLOOP (int16NDArray)
--- a/liboctave/int16NDArray.h +++ b/liboctave/int16NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (int16NDArray, octave_int16, OCTAVE_API) BSXFUN_STDOP_DECLS (int16NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(int16NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (int16NDArray, OCTAVE_API) #endif
--- a/liboctave/int32NDArray.cc +++ b/liboctave/int32NDArray.cc @@ -56,3 +56,4 @@ BSXFUN_STDREL_DEFS_MXLOOP (int32NDArray) BSXFUN_OP_DEF_MXLOOP (pow, int32NDArray, mx_inline_pow) +BSXFUN_POW_MIXED_MXLOOP (int32NDArray)
--- a/liboctave/int32NDArray.h +++ b/liboctave/int32NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (int32NDArray, octave_int32, OCTAVE_API) BSXFUN_STDOP_DECLS (int32NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(int32NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (int32NDArray, OCTAVE_API) #endif
--- a/liboctave/int64NDArray.cc +++ b/liboctave/int64NDArray.cc @@ -56,3 +56,5 @@ BSXFUN_STDREL_DEFS_MXLOOP (int64NDArray) BSXFUN_OP_DEF_MXLOOP (pow, int64NDArray, mx_inline_pow) + +BSXFUN_POW_MIXED_MXLOOP (int64NDArray)
--- a/liboctave/int64NDArray.h +++ b/liboctave/int64NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (int64NDArray, octave_int64, OCTAVE_API) BSXFUN_STDOP_DECLS (int64NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(int64NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (int64NDArray, OCTAVE_API) #endif
--- a/liboctave/int8NDArray.cc +++ b/liboctave/int8NDArray.cc @@ -56,3 +56,4 @@ BSXFUN_STDREL_DEFS_MXLOOP (int8NDArray) BSXFUN_OP_DEF_MXLOOP (pow, int8NDArray, mx_inline_pow) +BSXFUN_POW_MIXED_MXLOOP (int8NDArray)
--- a/liboctave/int8NDArray.h +++ b/liboctave/int8NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (int8NDArray, octave_int8, OCTAVE_API) BSXFUN_STDOP_DECLS (int8NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(int8NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (int8NDArray, OCTAVE_API) #endif
new file mode 100644 --- /dev/null +++ b/liboctave/link-deps.mk @@ -0,0 +1,27 @@ +include ../libcruft/link-deps.mk + +LIBOCTAVE_LINK_DEPS = \ + $(SPARSE_XLIBS) \ + $(ARPACK_LIBS) \ + $(QRUPDATE_LIBS) \ + $(FFTW_XLIBS) \ + $(LAPACK_LIBS) \ + $(BLAS_LIBS) \ + $(READLINE_LIBS) \ + $(TERM_LIBS) \ + $(LIBGLOB) \ + $(REGEX_LIBS) \ + $(DL_LIBS) \ + $(PTHREAD_LIBS) \ + $(LIBS) + +LIBOCTAVE_LINK_OPTS = \ + $(SPARSE_XLDFLAGS) \ + $(ARPACK_LDFLAGS) \ + $(QRUPDATE_LDFLAGS) \ + $(FFTW_XLDFLAGS) + +if AMCOND_LINK_ALL_DEPS + LIBOCTAVE_LINK_DEPS += $(LIBCRUFT_LINK_DEPS) + LIBOCTAVE_LINK_OPTS += $(LIBCRUFT_LINK_OPTS) +endif
--- a/liboctave/oct-inttypes.cc +++ b/liboctave/oct-inttypes.cc @@ -578,6 +578,23 @@ template <class T> octave_int<T> +pow (const float& a, const octave_int<T>& b) +{ return octave_int<T> (pow (a, b.float_value ())); } + +template <class T> +octave_int<T> +pow (const octave_int<T>& a, const float& b) +{ + return ((b >= 0 && b < std::numeric_limits<T>::digits && b == xround (b)) + ? pow (a, octave_int<T> (static_cast<T> (b))) + : octave_int<T> (pow (a.double_value (), static_cast<double> (b)))); +} + +// FIXME: Do we really need a differently named single-precision +// function integer power function here instead of an overloaded +// one? +template <class T> +octave_int<T> powf (const float& a, const octave_int<T>& b) { return octave_int<T> (pow (a, b.float_value ())); } @@ -595,6 +612,8 @@ template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const octave_int<T>&); \ template OCTAVE_API octave_int<T> pow (const double&, const octave_int<T>&); \ template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const double&); \ + template OCTAVE_API octave_int<T> pow (const float&, const octave_int<T>&); \ + template OCTAVE_API octave_int<T> pow (const octave_int<T>&, const float&); \ template OCTAVE_API octave_int<T> powf (const float&, const octave_int<T>&); \ template OCTAVE_API octave_int<T> powf (const octave_int<T>&, const float&); \ template OCTAVE_API octave_int<T> \
--- a/liboctave/oct-inttypes.h +++ b/liboctave/oct-inttypes.h @@ -874,6 +874,17 @@ template <class T> extern OCTAVE_API octave_int<T> +pow (const float& a, const octave_int<T>& b); + +template <class T> +extern OCTAVE_API octave_int<T> +pow (const octave_int<T>& a, const float& b); + +// FIXME: Do we really need a differently named single-precision +// function integer power function here instead of an overloaded +// one? +template <class T> +extern OCTAVE_API octave_int<T> powf (const float& a, const octave_int<T>& b); template <class T>
--- a/liboctave/uint16NDArray.cc +++ b/liboctave/uint16NDArray.cc @@ -56,3 +56,4 @@ BSXFUN_STDREL_DEFS_MXLOOP (uint16NDArray) BSXFUN_OP_DEF_MXLOOP (pow, uint16NDArray, mx_inline_pow) +BSXFUN_POW_MIXED_MXLOOP (uint16NDArray)
--- a/liboctave/uint16NDArray.h +++ b/liboctave/uint16NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (uint16NDArray, octave_uint16, OCTAVE_API) BSXFUN_STDOP_DECLS (uint16NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(uint16NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (uint16NDArray, OCTAVE_API) #endif
--- a/liboctave/uint32NDArray.cc +++ b/liboctave/uint32NDArray.cc @@ -56,3 +56,4 @@ BSXFUN_STDREL_DEFS_MXLOOP (uint32NDArray) BSXFUN_OP_DEF_MXLOOP (pow, uint32NDArray, mx_inline_pow) +BSXFUN_POW_MIXED_MXLOOP (uint32NDArray)
--- a/liboctave/uint32NDArray.h +++ b/liboctave/uint32NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (uint32NDArray, octave_uint32, OCTAVE_API) BSXFUN_STDOP_DECLS (uint32NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(uint32NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (uint32NDArray, OCTAVE_API) #endif
--- a/liboctave/uint64NDArray.cc +++ b/liboctave/uint64NDArray.cc @@ -56,3 +56,5 @@ BSXFUN_STDREL_DEFS_MXLOOP (uint64NDArray) BSXFUN_OP_DEF_MXLOOP (pow, uint64NDArray, mx_inline_pow) +BSXFUN_POW_MIXED_MXLOOP (uint64NDArray) +
--- a/liboctave/uint64NDArray.h +++ b/liboctave/uint64NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (uint64NDArray, octave_uint64, OCTAVE_API) BSXFUN_STDOP_DECLS (uint64NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(uint64NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (uint64NDArray, OCTAVE_API) #endif
--- a/liboctave/uint8NDArray.cc +++ b/liboctave/uint8NDArray.cc @@ -55,4 +55,6 @@ BSXFUN_STDOP_DEFS_MXLOOP (uint8NDArray) BSXFUN_STDREL_DEFS_MXLOOP (uint8NDArray) +BSXFUN_POW_MIXED_MXLOOP (uint8NDArray) BSXFUN_OP_DEF_MXLOOP (pow, uint8NDArray, mx_inline_pow) +
--- a/liboctave/uint8NDArray.h +++ b/liboctave/uint8NDArray.h @@ -44,6 +44,7 @@ MINMAX_DECLS (uint8NDArray, octave_uint8, OCTAVE_API) BSXFUN_STDOP_DECLS (uint8NDArray, OCTAVE_API) +BSXFUN_MIXED_INT_DECLS(uint8NDArray, OCTAVE_API) BSXFUN_STDREL_DECLS (uint8NDArray, OCTAVE_API) #endif
--- a/scripts/general/celldisp.m +++ b/scripts/general/celldisp.m @@ -80,4 +80,8 @@ %!demo %! c = {1, 2, {31, 32}}; -%! celldisp(c, "b") \ No newline at end of file +%! celldisp(c, "b") + +%!error celldisp (); +%!error celldisp ({}, "name", 1); +%!error celldisp (1);
--- a/scripts/general/profile.m +++ b/scripts/general/profile.m @@ -113,3 +113,38 @@ %! profile ('off'); %! T = profile ('info'); %! profshow (T); + +%!error profile (); +%!error profile ('on', 2); + +%!test +%! on_struct.ProfilerStatus = "on"; +%! off_struct.ProfilerStatus = "off"; +%! profile ('on'); +%! result = logm (rand (200) + 10 * eye (200)); +%! assert (profile ('status'), on_struct); +%! profile ('off'); +%! assert (profile ('status'), off_struct); +%! profile ('resume'); +%! result = logm (rand (200) + 10 * eye (200)); +%! profile ('off'); +%! assert (profile ('status'), off_struct); +%! info = profile ('info'); +%! assert (isstruct (info)); +%! assert (size (info), [1, 1]); +%! assert (fieldnames (info), {'FunctionTable'; 'Hierarchical'}); +%! ftbl = info.FunctionTable; +%! assert (fieldnames (ftbl), {'FunctionName'; 'TotalTime'; 'NumCalls'; 'IsRecursive'; 'Parents'; 'Children'}); +%! hier = info.Hierarchical; +%! assert (fieldnames (hier), {'Index'; 'SelfTime'; 'NumCalls'; 'Children'}); +%! profile ('clear'); +%! info = profile ('info'); +%! assert (isstruct (info)); +%! assert (size (info), [1, 1]); +%! assert (fieldnames (info), {'FunctionTable'; 'Hierarchical'}); +%! ftbl = info.FunctionTable; +%! assert (size (ftbl), [0, 1]); +%! assert (fieldnames (ftbl), {'FunctionName'; 'TotalTime'; 'NumCalls'; 'IsRecursive'; 'Parents'; 'Children'}); +%! hier = info.Hierarchical; +%! assert (size (hier), [0, 1]); +%! assert (fieldnames (hier), {'Index'; 'SelfTime'; 'NumCalls'; 'Children'});
--- a/scripts/general/profshow.m +++ b/scripts/general/profshow.m @@ -100,3 +100,7 @@ %! myfib (20); %! profile ("off"); %! profshow (profile ("info"), 5); + +%!error profshow (); +%!error profshow (1, 2, 3); +%!error profshow (struct (), 1.2);
--- a/scripts/geometry/inpolygon.m +++ b/scripts/geometry/inpolygon.m @@ -130,3 +130,14 @@ %! disp("Green points are inside polygon, magenta are outside,"); %! disp("and blue are on boundary."); +%!error inpolygon (); +%!error inpolygon (1, 2); +%!error inpolygon (1, 2, 3); + +%!error inpolygon (1, [1,2], [3, 4], [5, 6]); +%!error inpolygon ([1,2], [3, 4], [5, 6], 1); + +%!test +%! [in, on] = inpolygon ([1, 0], [1, 0], [-1, -1, 1, 1], [-1, 1, 1, -1]); +%! assert (in, [false, true]); +%! assert (on, [true, false]);
--- a/scripts/help/__makeinfo__.m +++ b/scripts/help/__makeinfo__.m @@ -119,3 +119,6 @@ end_unwind_protect endfunction +## No test needed for internal helper function. +%!assert (1) +
--- a/scripts/help/gen_doc_cache.m +++ b/scripts/help/gen_doc_cache.m @@ -32,6 +32,7 @@ ## @end deftypefn function gen_doc_cache (out_file = "doc-cache", directory = []) + ## Check input if (!ischar (out_file)) print_usage (); @@ -143,3 +144,8 @@ cache = create_cache (list); endfunction + +%% No true tests desirable for this function. +%% Test input validation +%!error gen_doc_cache (1) +
--- a/scripts/io/beep.m +++ b/scripts/io/beep.m @@ -26,10 +26,13 @@ function beep () - if (nargin == 0) - puts ("\a"); - else + if (nargin != 0) print_usage (); endif + puts ("\a"); + endfunction + + +%!error (beep (1))
--- a/scripts/linear-algebra/cross.m +++ b/scripts/linear-algebra/cross.m @@ -90,3 +90,26 @@ endif endfunction + +%!test +%! x = [1 0 0]; +%! y = [0 1 0]; +%! r = [0 0 1]; +%! assert(cross(x, y), r, 2e-8); + +%!test +%! x = [1 2 3]; +%! y = [4 5 6]; +%! r = [(2*6-3*5) (3*4-1*6) (1*5-2*4)]; +%! assert(cross(x, y), r, 2e-8); + +%!test +%! x = [1 0 0; 0 1 0; 0 0 1]; +%! y = [0 1 0; 0 0 1; 1 0 0]; +%! r = [0 0 1; 1 0 0; 0 1 0]; +%! assert(cross(x, y, 2), r, 2e-8); +%! assert(cross(x, y, 1), -r, 2e-8); + +%!error cross(0,0); +%!error cross(); +
--- a/scripts/linear-algebra/duplication_matrix.m +++ b/scripts/linear-algebra/duplication_matrix.m @@ -86,3 +86,35 @@ endfor endfunction + +%!test +%! N = 2; +%! A = rand(N); +%! B = A * A'; +%! C = A + A'; +%! D = duplication_matrix (N); +%! assert (D * vech (B), vec (B), 1e-6); +%! assert (D * vech (C), vec (C), 1e-6); + +%!test +%! N = 3; +%! A = rand(N); +%! B = A * A'; +%! C = A + A'; +%! D = duplication_matrix (N); +%! assert (D * vech (B), vec (B), 1e-6); +%! assert (D * vech (C), vec (C), 1e-6); + +%!test +%! N = 4; +%! A = rand(N); +%! B = A * A'; +%! C = A + A'; +%! D = duplication_matrix (N); +%! assert (D * vech (B), vec (B), 1e-6); +%! assert (D * vech (C), vec (C), 1e-6); + +%!error duplication_matrix (); +%!error duplication_matrix (0.5); +%!error duplication_matrix (-1); +%!error duplication_matrix (ones(1,4));
--- a/scripts/linear-algebra/housh.m +++ b/scripts/linear-algebra/housh.m @@ -23,8 +23,8 @@ ## ## @example ## @group -## (I - beta*housv*housv')x = norm(x)*e(j) if x(1) < 0, -## (I - beta*housv*housv')x = -norm(x)*e(j) if x(1) >= 0 +## (I - beta*housv*housv')x = norm(x)*e(j) if x(j) < 0, +## (I - beta*housv*housv')x = -norm(x)*e(j) if x(j) >= 0 ## @end group ## @end example ## @@ -91,3 +91,43 @@ endif endfunction + +%!test +%! x = [1 2 3]'; +%! j = 3; +%! [hv, b, z] = housh(x, j, 0); +%! r = (eye(3) - b*hv*hv') * x; +%! d = - norm(x) * [0 0 1]'; +%! assert(r, d, 2e-8); +%! assert(z, 0, 2e-8); + +%!test +%! x = [7 -3 1]'; +%! j = 2; +%! [hv, b, z] = housh(x, j, 0); +%! r = (eye(3) - b*hv*hv') * x; +%! d = norm(x) * [0 1 0]'; +%! assert(r, d, 2e-8); +%! assert(z, 0, 2e-8); + +%!test +%! x = [1 0 0]'; +%! j = 1; +%! [hv, b, z] = housh(x, j, 10); +%! r = (eye(3) - b*hv*hv') * x; +%! d = norm(x) * [1 0 0]'; +%! assert(r, d, 2e-8); +%! assert(z, 1, 2e-8); + +%!test +%! x = [5 0 4 1]'; +%! j = 2; +%! [hv, b, z] = housh(x, j, 0); +%! r = (eye(4) - b*hv*hv') * x; +%! d = - norm(x) * [0 1 0 0]'; +%! assert(r, d, 2e-8); +%! assert(z, 0, 2e-8); + +%!error housh([0]); +%!error housh(); +
--- a/scripts/linear-algebra/logm.m +++ b/scripts/linear-algebra/logm.m @@ -63,11 +63,14 @@ [u, s] = rsf2csf (u, s); endif - if (any (diag (s) < 0)) + eigv = diag (s); + if (any (eigv < 0)) warning ("Octave:logm:non-principal", "logm: principal matrix logarithm is not defined for matrices with negative eigenvalues; computing non-principal logarithm"); endif + real_eig = all (eigv >= 0); + k = 0; ## Algorithm 11.9 in "Function of matrices", by N. Higham theta = [0, 0, 1.61e-2, 5.38e-2, 1.13e-1, 1.86e-1, 2.6429608311114350e-1]; @@ -100,6 +103,11 @@ s = 2^k * u * s * u'; + ## Remove small complex values (O(eps)) which may have entered calculation + if (real_eig) + s = real (s); + endif + if (nargout == 2) iters = k; endif
--- a/scripts/linear-algebra/orth.m +++ b/scripts/linear-algebra/orth.m @@ -79,3 +79,12 @@ endif endfunction + +%!test +%! for ii=1:20 +%! A = rand (10, 10); +%! V = orth (A); +%! if (det (A) != 0) +%! assert (V'*V, eye (10), 100*eps) +%! endif +%! endfor
--- a/scripts/linear-algebra/planerot.m +++ b/scripts/linear-algebra/planerot.m @@ -34,3 +34,14 @@ G = givens (x(1), x(2)); y = G * x(:); endfunction + +%!test +%! x = [3 4]; +%! [g y] = planerot(x); +%! assert(g - [x(1) x(2); -x(2) x(1)] / sqrt(x(1)^2 + x(2)^2), zeros(2), 2e-8); +%! assert(y(2), 0, 2e-8); + +%!error planerot([0]); +%!error planerot([0 0 0]); +%!error planerot(); +
--- a/scripts/linear-algebra/qzhess.m +++ b/scripts/linear-algebra/qzhess.m @@ -90,3 +90,52 @@ endfor endfunction + +%!test +%! a = [1 2 1 3; +%! 2 5 3 2; +%! 5 5 1 0; +%! 4 0 3 2]; +%! b = [0 4 2 1; +%! 2 3 1 1; +%! 1 0 2 1; +%! 2 5 3 2]; +%! mask = [0 0 0 0; +%! 0 0 0 0; +%! 1 0 0 0; +%! 1 1 0 0]; +%! [aa, bb, q, z] = qzhess(a, b); +%! assert(inv(q) - q', zeros(4), 2e-8); +%! assert(inv(z) - z', zeros(4), 2e-8); +%! assert(q * a * z, aa, 2e-8); +%! assert(aa .* mask, zeros(4), 2e-8); +%! assert(q * b * z, bb, 2e-8); +%! assert(bb .* mask, zeros(4), 2e-8); + +%!test +%! a = [1 2 3 4 5; +%! 3 2 3 1 0; +%! 4 3 2 1 1; +%! 0 1 0 1 0; +%! 3 2 1 0 5]; +%! b = [5 0 4 0 1; +%! 1 1 1 2 5; +%! 0 3 2 1 0; +%! 4 3 0 3 5; +%! 2 1 2 1 3]; +%! mask = [0 0 0 0 0; +%! 0 0 0 0 0; +%! 1 0 0 0 0; +%! 1 1 0 0 0; +%! 1 1 1 0 0]; +%! [aa, bb, q, z] = qzhess(a, b); +%! assert(inv(q) - q', zeros(5), 2e-8); +%! assert(inv(z) - z', zeros(5), 2e-8); +%! assert(q * a * z, aa, 2e-8); +%! assert(aa .* mask, zeros(5), 2e-8); +%! assert(q * b * z, bb, 2e-8); +%! assert(bb .* mask, zeros(5), 2e-8); + +%!error qzhess([0]); +%!error qzhess(); +
--- a/scripts/linear-algebra/rref.m +++ b/scripts/linear-algebra/rref.m @@ -86,3 +86,43 @@ k = find (used); endfunction + +%!test +%! a = [1]; +%! [r k] = rref(a); +%! assert(r, [1], 2e-8); +%! assert(k, [1], 2e-8); + +%!test +%! a = [1 3; 4 5]; +%! [r k] = rref(a); +%! assert(rank(a), rank(r), 2e-8); +%! assert(r, eye(2), 2e-8); +%! assert(k == [1, 2] || k == [2, 1]); + + +%!test +%! a = [1 3; 4 5; 7 9]; +%! [r k] = rref(a); +%! assert(rank(a), rank(r), 2e-8); +%! assert(r, eye(3)(:,1:2), 2e-8); +%! assert(k, [1 2], 2e-8); + +%!test +%! a = [1 2 3; 2 4 6; 7 2 0]; +%! [r k] = rref(a); +%! assert(rank(a), rank(r), 2e-8); +%! assert(r, [1 0 (3-7/2); 0 1 (7/4); 0 0 0], 2e-8); +%! assert(k, [1 2], 2e-8); + +%!test +%! a = [1 2 1; 2 4 2.01; 2 4 2.1]; +%! tol = 0.02; +%! [r k] = rref(a, tol); +%! assert(rank(a, tol), rank(r, tol), 2e-8); +%! tol = 0.2; +%! [r k] = rref(a, tol); +%! assert(rank(a, tol), rank(r, tol), 2e-8); + +%!error rref(); +
--- a/scripts/miscellaneous/mkoctfile.m +++ b/scripts/miscellaneous/mkoctfile.m @@ -75,26 +75,30 @@ ## Print the configuration variable VAR@. Recognized variables are: ## ## @example -## ALL_CFLAGS FFTW_LIBS +## ALL_CFLAGS FFTW3F_LIBS ## ALL_CXXFLAGS FLIBS ## ALL_FFLAGS FPICFLAG ## ALL_LDFLAGS INCFLAGS -## BLAS_LIBS LDFLAGS -## CC LD_CXX -## CFLAGS LD_STATIC_FLAG -## CPICFLAG LFLAGS -## CPPFLAGS LIBCRUFT -## CXX LIBOCTAVE -## CXXFLAGS LIBOCTINTERP -## CXXPICFLAG LIBREADLINE +## BLAS_LIBS LAPACK_LIBS +## CC LDFLAGS +## CFLAGS LD_CXX +## CPICFLAG LD_STATIC_FLAG +## CPPFLAGS LFLAGS +## CXX LIBCRUFT +## CXXFLAGS LIBOCTAVE +## CXXPICFLAG LIBOCTINTERP ## DEPEND_EXTRA_SED_PATTERN LIBS ## DEPEND_FLAGS OCTAVE_LIBS -## DL_LD RDYNAMIC_FLAG -## DL_LDFLAGS RLD_FLAG -## F2C SED -## F2CFLAGS XTRA_CFLAGS -## F77 XTRA_CXXFLAGS -## FFLAGS +## DL_LD OCTAVE_LINK_DEPS +## DL_LDFLAGS OCT_LINK_DEPS +## EXEEXT RDYNAMIC_FLAG +## F77 READLINE_LIBS +## F77_INTEGER_8_FLAG SED +## FFLAGS XTRA_CFLAGS +## FFTW3_LDFLAGS XTRA_CXXFLAGS +## FFTW3_LIBS +## FFTW3F_LDFLAGS +## ## @end example ## ## @item --link-stand-alone
--- a/scripts/miscellaneous/tempdir.m +++ b/scripts/miscellaneous/tempdir.m @@ -37,3 +37,19 @@ endif endfunction + + +%!assert (ischar (tempdir ())) + +%!test +%! old_wstate = warning ("query"); +%! warning ("off"); +%! old_tmpdir = getenv ("TMPDIR"); +%! unwind_protect +%! setenv ("TMPDIR", "__MY_TMP_DIR__"); +%! assert (tempdir (), ["__MY_TMP_DIR__" filesep()]); +%! unwind_protect_cleanup +%! setenv ("TMPDIR", old_tmpdir); +%! warning (old_wstate); +%! end_unwind_protect +
--- a/scripts/miscellaneous/tempname.m +++ b/scripts/miscellaneous/tempname.m @@ -29,3 +29,7 @@ filename = tmpnam (varargin{:}); endfunction + + +%% No tests needed for alias. +%!assert (1)
--- a/scripts/optimization/__all_opts__.m +++ b/scripts/optimization/__all_opts__.m @@ -67,3 +67,7 @@ endfunction + +## No test needed for internal helper function. +%!assert (1) +
--- a/scripts/optimization/fminbnd.m +++ b/scripts/optimization/fminbnd.m @@ -49,7 +49,8 @@ ## This is patterned after opt/fmin.f from Netlib, which in turn is taken from ## Richard Brent: Algorithms For Minimization Without Derivatives, Prentice-Hall (1973) -## PKG_ADD: __all_opts__ ("fminbnd"); +## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup. +## PKG_ADD: [~] = __all_opts__ ("fminbnd"); function [x, fval, info, output] = fminbnd (fun, xmin, xmax, options = struct ())
--- a/scripts/optimization/fminunc.m +++ b/scripts/optimization/fminunc.m @@ -77,7 +77,8 @@ ## @seealso{fminbnd, optimset} ## @end deftypefn -## PKG_ADD: __all_opts__ ("fminunc"); +## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup. +## PKG_ADD: [~] = __all_opts__ ("fminunc"); function [x, fval, info, output, grad, hess] = fminunc (fcn, x0, options = struct ())
--- a/scripts/optimization/fsolve.m +++ b/scripts/optimization/fsolve.m @@ -127,7 +127,8 @@ ## @end example ## @end deftypefn -## PKG_ADD: __all_opts__ ("fsolve"); +## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup. +## PKG_ADD: [~] = __all_opts__ ("fsolve"); function [x, fvec, info, output, fjac] = fsolve (fcn, x0, options = struct ())
--- a/scripts/optimization/fzero.m +++ b/scripts/optimization/fzero.m @@ -93,7 +93,8 @@ ## the need for external functions and error handling. The algorithm has ## also been slightly modified. -## PKG_ADD: __all_opts__ ("fzero"); +## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup. +## PKG_ADD: [~] = __all_opts__ ("fzero"); function [x, fval, info, output] = fzero (fun, x0, options = struct ())
--- a/scripts/optimization/lsqnonneg.m +++ b/scripts/optimization/lsqnonneg.m @@ -63,7 +63,8 @@ ## @seealso{optimset, pqpnonneg} ## @end deftypefn -## PKG_ADD: __all_opts__ ("lsqnonneg"); +## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup. +## PKG_ADD: [~] = __all_opts__ ("lsqnonneg"); ## This is implemented from Lawson and Hanson's 1973 algorithm on page ## 161 of Solving Least Squares Problems.
--- a/scripts/optimization/pqpnonneg.m +++ b/scripts/optimization/pqpnonneg.m @@ -58,7 +58,8 @@ ## @seealso{optimset, lsqnonneg, qp} ## @end deftypefn -## PKG_ADD: __all_opts__ ("pqpnonneg"); +## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup. +## PKG_ADD: [~] = __all_opts__ ("pqpnonneg"); ## This is analogical to the lsqnonneg implementation, which is ## implemented from Lawson and Hanson's 1973 algorithm on page
--- a/scripts/optimization/qp.m +++ b/scripts/optimization/qp.m @@ -108,7 +108,8 @@ ## @end table ## @end deftypefn -## PKG_ADD: __all_opts__ ("qp"); +## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup. +## PKG_ADD: [~] = __all_opts__ ("qp"); function [x, obj, INFO, lambda] = qp (x0, H, varargin)
--- a/scripts/plot/__gnuplot_drawnow__.m +++ b/scripts/plot/__gnuplot_drawnow__.m @@ -386,3 +386,7 @@ endif endif endfunction + + +## No test needed for internal helper function. +%!assert (1)
--- a/scripts/plot/__go_close_all__.m +++ b/scripts/plot/__go_close_all__.m @@ -26,3 +26,7 @@ function __go_close_all__ () close ("all", "hidden"); endfunction + + +## No test needed for internal helper function. +%!assert (1)
--- a/scripts/plot/__plt_get_axis_arg__.m +++ b/scripts/plot/__plt_get_axis_arg__.m @@ -76,3 +76,7 @@ narg = length (varargin); endfunction + + +## No test needed for internal helper function. +%!assert (1)
--- a/scripts/plot/allchild.m +++ b/scripts/plot/allchild.m @@ -48,3 +48,12 @@ end_unwind_protect endfunction + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! l = line; +%! assert(get(allchild(hf),'type'),{'axes'; 'uimenu'; 'uimenu'; 'uimenu'}) +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/ancestor.m +++ b/scripts/plot/ancestor.m @@ -74,3 +74,13 @@ endif endfunction + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! l = line; +%! assert (ancestor (l, "axes"), gca); +%! assert (ancestor (l, "figure"), hf); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/clf.m +++ b/scripts/plot/clf.m @@ -75,3 +75,14 @@ delete (hc); endfunction + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! l = line; +%! assert (!isempty (get (gcf, "children"))); +%! clf; +%! assert (isempty (get (gcf, "children"))); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/findall.m +++ b/scripts/plot/findall.m @@ -42,3 +42,13 @@ end_unwind_protect endfunction + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! h = findall; +%! all_handles = {"uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "root"; "figure"}; +%! assert (get (h, 'type'), all_handles) +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/findobj.m +++ b/scripts/plot/findobj.m @@ -242,3 +242,18 @@ h = h (keepers != 0); h = reshape (h, [numel(h), 1]); endfunction + +%!test +%! fign = 1232; +%! hf = figure (fign, "visible", "off"); +%! unwind_protect +%! l = line; +%! obj = findobj ("type", "line"); +%! assert (l, obj); +%! assert (gca, findobj ("type", "axes")); +%! assert (fign, findobj ("type", "figure")); +%! assert (0, findobj ("type", "root")); +%! assert (isempty (findobj ("type", "xyzxyz"))); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/gcf.m +++ b/scripts/plot/gcf.m @@ -53,3 +53,13 @@ endif endfunction + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! line; +%! clf; +%! assert (isempty (get (gcf, "children"))); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/line.m +++ b/scripts/plot/line.m @@ -42,3 +42,17 @@ endif endfunction + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! h = line; +%! assert (get (h, "xdata"), [0 1], eps); +%! assert (get (h, "ydata"), [0 1], eps); +%! assert (get (h, "type"), "line"); +%! assert (get (h, "color"), [0 0 0]); +%! assert (get (h, "linestyle"), "-"); +%! assert (get (h, "linewidth"), 0.5, eps); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/loglog.m +++ b/scripts/plot/loglog.m @@ -60,3 +60,11 @@ endfunction +%!demo +%! t = 1:0.01:10; +%! x = sort ((t .* (1 + rand (size (t)))) .^ 2); +%! y = ((t .* (1 + rand (size (t)))) .^ 2); +%! loglog (x, y); + +## Remove from test statistics. No real tests possible. +%!assert (1)
--- a/scripts/plot/private/__print_parse_opts__.m +++ b/scripts/plot/private/__print_parse_opts__.m @@ -570,7 +570,7 @@ case "inches" value = value * 72; case "centimeters" - value = value * 72 / 25.4; + value = value * 72 / 2.54; case "normalized" error ("print:customnormalized", "print.m: papersize=='<custom>' and paperunits='normalized' may not be combined");
--- a/scripts/plot/semilogx.m +++ b/scripts/plot/semilogx.m @@ -59,3 +59,11 @@ end_unwind_protect endfunction + +%!demo +%! x = 1:0.01:10; +%! y = (x .* (1 + rand (size (x)))) .^ 2; +%! semilogx (y, x); + +## Remove from test statistics. No real tests possible. +%!assert (1)
--- a/scripts/plot/semilogy.m +++ b/scripts/plot/semilogy.m @@ -60,3 +60,11 @@ end_unwind_protect endfunction + +%!demo +%! x = 1:0.01:10; +%! y = (x .* (1 + rand (size (x)))) .^ 2; +%! semilogy (x, y); + +## Remove from test statistics. No real tests possible. +%!assert (1)
--- a/scripts/plot/title.m +++ b/scripts/plot/title.m @@ -37,3 +37,20 @@ endif endfunction + +%!demo +%! clf (); +%! ax=axes(); +%! xl = get(ax,"title"); +%! title("Testing title") +%! assert(get(xl,"string"),"Testing title") + +%!demo +%! clf (); +%! plot3 ([0,1], [0,1], [0,1]); +%! xl = get(gca (), "title"); +%! title("Testing title") +%! assert(get(xl,"string"),"Testing title") + +## Remove from test statistics. No real tests possible. +%!assert (1)
--- a/scripts/plot/view.m +++ b/scripts/plot/view.m @@ -93,3 +93,34 @@ endif endfunction + +%!test +%! fign = 1232; +%! hf = figure (fign, "visible", "off"); +%! unwind_protect +%! plot3 ([0,1], [0,1], [0,1]); +%! [az, el] = view; +%! assert ([az, el], [-37.5, 30], eps); +%! view (2); +%! [az, el] = view; +%! assert ([az, el], [0, 90], eps); +%! view ([1 1 0]); +%! [az, el] = view; +%! assert ([az, el], [135, 0], eps); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test +%! fign = 1232; +%! hf = figure (fign, "visible", "off"); +%! unwind_protect +%! line; +%! [az, el] = view; +%! assert ([az, el], [0, 90], eps); +%! view (3); +%! [az, el] = view; +%! assert ([az, el], [-37.5, 30], eps); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/whitebg.m +++ b/scripts/plot/whitebg.m @@ -143,3 +143,21 @@ endif endif endfunction + +%!test +%! set (0, "defaultaxescolor", [1 1 1]); +%! set (0, "defaultfigurecolor", [1 1 1]); +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! l = line; +%! assert (get (hf, "color"), [1 1 1]); +%! assert (get (gca, "color"), [1 1 1]); +%! whitebg; +%! assert (get (hf, "color"), [0 0 0]); +%! assert (get (gca, "color"), [0 0 0]); +%! whitebg([0.2 0.2 0.2]) +%! assert (get (hf, "color"), [0 0 0]); +%! assert (get (gca, "color"), [0.2 0.2 0.2]); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/xlim.m +++ b/scripts/plot/xlim.m @@ -44,3 +44,53 @@ retval = ret; endif endfunction + +%!demo +%! clf (); +%! line (); +%! xlim ([0.2, 0.8]); +%! title ("xlim is [0.2, 0.8]"); +%! assert (xlim (), [0.2, 0.8]); + +%!demo +%! clf (); +%! line (); +%! xlim ('auto'); +%! title ("xlim is auto"); +%! assert (xlim ("mode"), "auto"); + +%!demo +%! clf (); +%! plot3 ([0,1], [0,1], [0,1]); +%! xlim ([0.2, 0.8]); +%! title ("xlim is [0.2, 0.8]"); +%! assert (xlim (), [0.2, 0.8]); + +%!demo +%! clf (); +%! plot3 ([0,1], [0,1], [0,1]); +%! xlim ('auto'); +%! title ("xlim is auto"); +%! assert (xlim ("mode"), "auto"); + + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! plot3 ([0,1], [0,1], [0,1]); +%! xlim ([0, 1.1]); +%! assert (get (gca, "xlim"), [0, 1.1], eps); +%! assert (xlim ("mode"), "manual"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! h = plot3 ([0,1.1], [0,1], [0, 1]); +%! assert (get (gca, "xlim"), [0, 1.4], eps); +%! assert (xlim ("mode"), "auto"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/ylim.m +++ b/scripts/plot/ylim.m @@ -44,3 +44,53 @@ retval = ret; endif endfunction + +%!demo +%! clf (); +%! line (); +%! ylim ([0.2, 0.8]); +%! title ("ylim is [0.2, 0.8]"); +%! assert (ylim (), [0.2, 0.8]); + +%!demo +%! clf (); +%! line (); +%! ylim ('auto'); +%! title ("ylim is auto"); +%! assert (ylim ("mode"), "auto"); + +%!demo +%! clf (); +%! plot3 ([0,1], [0,1], [0,1]); +%! ylim ([0.2, 0.8]); +%! title ("ylim is [0.2, 0.8]"); +%! assert (ylim (), [0.2, 0.8]); + +%!demo +%! clf (); +%! plot3 ([0,1], [0,1], [0,1]); +%! ylim ('auto'); +%! title ("ylim is auto"); +%! assert (ylim ("mode"), "auto"); + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! limy = [0, 1.1]; +%! plot3 ([0,1], [0,1], [0,1]); +%! ylim (limy); +%! assert (get (gca, "ylim"), limy, eps); +%! assert (ylim ("mode"), "manual"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! plot3 ([0,1], [0,1.1], [0, 1]); +%! assert (get (gca, "ylim"), [0, 1.4], eps); +%! assert (ylim ("mode"), "auto"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/plot/zlim.m +++ b/scripts/plot/zlim.m @@ -44,3 +44,53 @@ retval = ret; endif endfunction + +%!demo +%! clf (); +%! line (); +%! zlim ([0.2, 0.8]); +%! title ("zlim is [0.2, 0.8]"); +%! assert (zlim (), [0.2, 0.8]); + +%!demo +%! clf (); +%! line (); +%! zlim ('auto'); +%! title ("zlim is auto"); +%! assert (zlim ("mode"), "auto"); + +%!demo +%! clf (); +%! plot3 ([0,1], [0,1], [0,1]); +%! zlim ([0.2, 0.8]); +%! title ("zlim is [0.2, 0.8]"); +%! assert (zlim (), [0.2, 0.8]); + +%!demo +%! clf (); +%! plot3 ([0,1], [0,1], [0,1]); +%! zlim ('auto'); +%! title ("zlim is auto"); +%! assert (zlim ("mode"), "auto"); + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! limz = [0, 1.1]; +%! plot3 ([0,1], [0,1], [0,1]); +%! zlim (limz); +%! assert (get (gca, "zlim"), limz, eps); +%! assert (zlim ("mode"), "manual"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect + +%!test +%! hf = figure (1232, "visible", "off"); +%! unwind_protect +%! plot3 ([0,1], [0,1], [0, 1.1]); +%! assert (get (gca, "zlim"), [0, 1.4], eps); +%! assert (zlim ("mode"), "auto"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect
--- a/scripts/polynomial/polygcd.m +++ b/scripts/polynomial/polygcd.m @@ -81,3 +81,24 @@ endif endfunction + + +%!test +%! poly1 = [1 6 11 6]; % (x+1)(x+2)(x+3) +%! poly2 = [1 3 2]; % (x+1)(x+2) +%! poly3 = polygcd (poly1, poly2); +%! assert (poly3, poly2, sqrt (eps)) + +%!test +%! assert (polygcd (poly(1:8), poly(3:12)), poly(3:8), sqrt (eps)) + +%!test +%! assert (deconv (poly(1:8), polygcd (poly(1:8), poly(3:12))), poly(1:2), sqrt (eps)) + +%!test +%! for ii=1:10 +%! p = (unique (randn (10, 1)) * 10).'; +%! p1 = p(3:end); +%! p2 = p(1:end-2); +%! assert (polygcd (poly (-p1), poly (-p2)), poly (- intersect (p1, p2)), sqrt (eps)) +%! endfor
--- a/scripts/polynomial/ppjumps.m +++ b/scripts/polynomial/ppjumps.m @@ -56,3 +56,29 @@ rlim = shiftdim (ppval (pp, x(2:end-1)), nd - 1); jumps = shiftdim (rlim - llim, 1); endfunction + + +%!test +%! p = [1 6 11 6]; +%! x = linspace (5, 6, 4); +%! y = polyval (p, x); +%! pp = spline (x, y); +%! jj = ppjumps (pp); +%! assert (jj, [0 0], eps) + +%!test +%! +%! breaks = [0 1 2]; +%! pp1 = poly (-[1 2 3]); +%! pp2 = poly (-([1 2 3]+1)); +%! pp = mkpp (breaks, [pp1;pp2]); +%! assert (ppjumps (pp), 0, eps) + +%!test +%! +%! breaks = [0 1 2]; +%! pp1 = poly (-[1 2 3]); +%! pp2 = poly (([1 2 3]+1)); +%! pp = mkpp (breaks, [pp1;pp2]); +%! j = - 2 * polyval (pp1, 1); +%! assert (ppjumps (pp), j, eps)
--- a/scripts/signal/bartlett.m +++ b/scripts/signal/bartlett.m @@ -47,3 +47,17 @@ endif endfunction + +%!assert (bartlett (1), 1); +%!assert (bartlett (2), zeros (2,1)); +%!assert (bartlett (16), fliplr (bartlett (16))); +%!assert (bartlett (15), fliplr (bartlett (15))); +%!test +%! N = 9; +%! A = bartlett (N); +%! assert (A (ceil (N/2)), 1); + +%!error bartlett (); +%!error bartlett (0.5); +%!error bartlett (-1); +%!error bartlett (ones(1,4)); \ No newline at end of file
--- a/scripts/signal/blackman.m +++ b/scripts/signal/blackman.m @@ -46,3 +46,18 @@ endif endfunction + +%!assert (blackman (1), 1); +%!assert (blackman (2), zeros(2,1), 1e-6); +%!assert (blackman (16), fliplr (blackman (16))); +%!assert (blackman (15), fliplr (blackman (15))); +%!test +%! N = 9; +%! A = blackman (N); +%! assert (A (ceil (N/2)), 1, 1e-6); +%! assert ([A(1), A(length (A))], zeros (1, 2), 1e-6); + +%!error blackman (); +%!error blackman (0.5); +%!error blackman (-1); +%!error blackman (ones(1,4));
--- a/scripts/signal/fftfilt.m +++ b/scripts/signal/fftfilt.m @@ -54,8 +54,12 @@ [r_x, c_x] = size (x); [r_b, c_b] = size (b); - if min ([r_b, c_b]) != 1 - error ("fftfilt: B should be a vector"); + if (! isvector (b)) + error ("fftfilt: B must be a vector"); + endif + + if (ndims (x) != 2) + error ("fftfilt: X must be a 1-D or 2-D array"); endif l_b = r_b * c_b; @@ -64,18 +68,18 @@ if (nargin == 2) ## Use FFT with the smallest power of 2 which is >= length (x) + ## length (b) - 1 as number of points ... - n = 2 ^ (ceil (log (r_x + l_b - 1) / log (2))); + n = 2 ^ nextpow2 (r_x + l_b - 1); B = fft (b, n); - y = ifft (fft (x, n) .* B(:,ones (1, c_x))); + y = ifft (fft (x, n) .* B(:, ones (1, c_x))); else ## Use overlap-add method ... if (! (isscalar (n))) error ("fftfilt: N has to be a scalar"); endif - n = 2 ^ (ceil (log (max ([n, l_b])) / log (2))); + n = 2 ^ nextpow2 (max ([n, l_b])); L = n - l_b + 1; B = fft (b, n); - B = B(:,ones (c_x,1)); + B = B(:, ones (c_x,1)); R = ceil (r_x / L); y = zeros (r_x, c_x); for r = 1:R; @@ -89,20 +93,59 @@ endfor endif - y = y(1:r_x,:); + y = y(1:r_x, :); if (transpose) y = y.'; endif - ## Final cleanups: if both x and b are real respectively integer, y - ## should also be + ## Final cleanups: If both x and b are real, y should be real. + ## If both x and b are integer, y should be integer. if (isreal (b) && isreal (x)) y = real (y); endif - if (! any (b - round (b))) - idx = !any (x - round (x)); - y(:,idx) = round (y(:,idx)); + if (! any (b - fix (b))) + idx = !any (x - fix (x)); + y(:, idx) = round (y(:, idx)); endif endfunction + + +%!shared b, x, r +%!test +%! b = [1 1]; +%! x = [1, zeros(1,9)]; +%! assert(fftfilt(b, x ), [1 1 0 0 0 0 0 0 0 0] , eps); +%! assert(fftfilt(b, x.'), [1 1 0 0 0 0 0 0 0 0].', eps); +%! assert(fftfilt(b.',x ), [1 1 0 0 0 0 0 0 0 0] , eps); +%! assert(fftfilt(b.',x.'), [1 1 0 0 0 0 0 0 0 0].', eps); + +%!test +%! r = sqrt(1/2) * (1+i); +%! b = b*r; +%! assert(fftfilt(b, x ), r*[1 1 0 0 0 0 0 0 0 0] , eps); +%! assert(fftfilt(b, r*x), r*r*[1 1 0 0 0 0 0 0 0 0], eps); +%! assert(fftfilt(b, x.'), r*[1 1 0 0 0 0 0 0 0 0].', eps); + +%!test +%! b = [1 1]; +%! x = zeros (10,3); x(1,1)=-1; x(1,2)=1; +%! y0 = zeros (10,3); y0(1:2,1)=-1; y0(1:2,2)=1; +%! y = fftfilt (b, x); +%! assert (y,y0); + +%!test +%! b = rand (10, 1); +%! x = rand (10, 1); +%! y0 = filter (b, 1, x); +%! y = filter (b, 1, x); +%! assert (y, y0); + +%% Test input validation +%!error fftfilt (1) +%!error fftfilt (1, 2, 3, 4) +%!error fftfilt (ones (2), 1) +%!error fftfilt (2, ones (3,3,3)) +%!error fftfilt (2, 1, ones (2)) +
--- a/scripts/signal/hamming.m +++ b/scripts/signal/hamming.m @@ -45,3 +45,17 @@ endif endfunction + +%!assert (hamming (1), 1); +%!assert (hamming (2), (0.54 - 0.46)*ones(2,1)); +%!assert (hamming (16), fliplr (hamming (16))); +%!assert (hamming (15), fliplr (hamming (15))); +%!test +%! N = 15; +%! A = hamming (N); +%! assert (A (ceil (N/2)), 1); + +%!error hamming (); +%!error hamming (0.5); +%!error hamming (-1); +%!error hamming (ones(1,4));
--- a/scripts/signal/hanning.m +++ b/scripts/signal/hanning.m @@ -45,3 +45,17 @@ endif endfunction + +%!assert (hanning (1), 1); +%!assert (hanning (2), zeros(2,1)); +%!assert (hanning (16), fliplr (hanning (16))); +%!assert (hanning (15), fliplr (hanning (15))); +%!test +%! N = 15; +%! A = hanning (N); +%! assert (A (ceil (N/2)), 1); + +%!error hanning (); +%!error hanning (0.5); +%!error hanning (-1); +%!error hanning (ones(1,4));
new file mode 100644 --- /dev/null +++ b/scripts/sparse/bicg.m @@ -0,0 +1,254 @@ +## Copyright (C) 2006 Sylvain Pelissier <sylvain.pelissier@gmail.com> +## Copyright (C) 2011 Carlo de Falco +## +## 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 2 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/>. + +## -*- texinfo -*- +## +## @deftypefn {Function File} {@var{x} =} bicg (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0}) +## @deftypefnx {Function File} {@var{x} =} bicg (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{P}) +## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} bicg (@var{A}, @var{b}, ...) +## Solve @code{A x = b} using the Bi-conjugate gradient iterative method. +## +## @itemize @minus +## @item @var{rtol} is the relative tolerance, if not given +## or set to [] the default value 1e-6 is used. +## @item @var{maxit} the maximum number of outer iterations, +## if not given or set to [] the default value +## @code{min (20, numel (b))} is used. +## @item @var{x0} the initial guess, if not given or set to [] +## the default value @code{zeros (size (b))} is used. +## @end itemize +## +## @var{A} can be passed as a matrix or as a function handle or +## inline function @code{f} such that @code{f(x, "notransp") = A*x} +## and @code{f(x, "transp") = A'*x}. +## +## The preconditioner @var{P} is given as @code{P = M1 * M2}. +## Both @var{M1} and @var{M2} can be passed as a matrix or as +## a function handle or inline function @code{g} such that +## @code{g(x, 'notransp') = M1 \ x} or @code{g(x, 'notransp') = M2 \ x} and +## @code{g(x, 'transp') = M1' \ x} or @code{g(x, 'transp') = M2' \ x}. +## +## If colled with more than one output parameter +## +## @itemize @minus +## @item @var{flag} indicates the exit status: +## @itemize @minus +## @item 0: iteration converged to the within the chosen tolerance +## @item 1: the maximum number of iterations was reached before convergence +## @item 3: the algorithm reached stagnation +## @end itemize +## (the value 2 is unused but skipped for compatibility). +## @item @var{relres} is the final value of the relative residual. +## @item @var{iter} is the number of iterations performed. +## @item @var{resvec} is a vector containing the relative residual at each iteration. +## @end itemize +## +## @seealso{bicgstab,cgs,gmres,pcg} +## +## @end deftypefn + + +function [x, flag, res1, k, resvec] = bicg (A, b, tol, maxit, M1, M2, x0) + + if (nargin >= 2 && isvector (full (b))) + + if (ischar (A)) + fun = str2func (A); + Ax = @(x) feval (fun, x, "notransp"); + Atx = @(x) feval (fun, x, "transp"); + elseif (ismatrix (A)) + Ax = @(x) A * x; + Atx = @(x) A' * x; + elseif (isa (A, "function_handle")) + Ax = @(x) feval (A, x, "notransp"); + Atx = @(x) feval (A, x, "transp"); + else + error (["bicg: first argument is expected to " ... + "be a function or a square matrix"]); + endif + + if (nargin < 3 || isempty (tol)) + tol = 1e-6; + endif + + if (nargin < 4 || isempty (maxit)) + maxit = min (rows (b), 20); + endif + + if (nargin < 5 || isempty (M1)) + M1m1x = @(x, ignore) x; + M1tm1x = M1m1x; + elseif (ischar (M1)) + fun = str2func (M1); + M1m1x = @(x) feval (fun, x, "notransp"); + M1tm1x = @(x) feval (fun, x, "transp"); + elseif (ismatrix (M1)) + M1m1x = @(x) M1 \ x; + M1tm1x = @(x) M1' \ x; + elseif (isa (M1, "function_handle")) + M1m1x = @(x) feval (M1, x, "notransp"); + M1tm1x = @(x) feval (M1, x, "transp"); + else + error (["bicg: preconditioner is expected to " ... + "be a function or matrix"]); + endif + + if (nargin < 6 || isempty (M2)) + M2m1x = @(x, ignore) x; + M2tm1x = M2m1x; + elseif (ischar (M2)) + fun = str2func (M2); + M2m1x = @(x) feval (fun, x, "notransp"); + M2tm1x = @(x) feval (fun, x, "transp"); + elseif (ismatrix (M2)) + M2m1x = @(x) M2 \ x; + M2tm1x = @(x) M2' \ x; + elseif (isa (M2, "function_handle")) + M2m1x = @(x) feval (M2, x, "notransp"); + M2tm1x = @(x) feval (M2, x, "transp"); + else + error (["bicg: preconditioner is expected to " ... + "be a function or matrix"]); + endif + + Pm1x = @(x) M2m1x (M1m1x (x)); + Ptm1x = @(x) M1tm1x (M2tm1x (x)); + + if (nargin < 7 || isempty (x0)) + x0 = zeros (size (b)); + endif + + y = x = x0; + c = b; + + r0 = b - Ax (x); + s0 = c - Atx (y); + + d = Pm1x (r0); + f = Ptm1x (s0); + + bnorm = norm (b); + res0 = Inf; + + if (any (r0 != 0)) + + for k = 1:maxit + + a = (s0' * Pm1x (r0)) ./ (f' * Ax (d)); + + x += a * d; + y += conj (a) * f; + + r1 = r0 - a * Ax (d); + s1 = s0 - conj (a) * Atx (f); + + beta = (s1' * Pm1x (r1)) ./ (s0' * Pm1x (r0)); + + d = Pm1x (r1) + beta * d; + f = Ptm1x (s1) + conj (beta) * f; + + r0 = r1; + s0 = s1; + + res1 = norm (b - Ax (x)) / bnorm; + if (res1 < tol) + flag = 0; + if (nargout < 2) + printf ("bicg converged at iteration %i ", k); + printf ("to a solution with relative residual %e\n", res1); + endif + break; + endif + + if (res0 <= res1) + flag = 3; + printf ("bicg stopped at iteration %i ", k); + printf ("without converging to the desired tolerance %e\n", tol); + printf ("because the method stagnated.\n"); + printf ("The iterate returned (number %i) ", k-1); + printf ("has relative residual %e\n", res0); + break + endif + res0 = res1; + if (nargout > 4) + resvec(k) = res0; + endif + endfor + + if (k == maxit) + flag = 1; + printf ("bicg stopped at iteration %i ", maxit); + printf ("without converging to the desired tolerance %e\n", tol); + printf ("because the maximum number of iterations was reached. "); + printf ("The iterate returned (number %i) has ", maxit); + printf ("relative residual %e\n", res1); + endif + + else + flag = 0; + if (nargout < 2) + printf ("bicg converged after 0 interations\n"); + endif + endif + + else + print_usage (); + endif + +endfunction; + + +%!test +%! n = 100; +%! A = spdiags ([-2*ones(n,1) 4*ones(n,1) -ones(n,1)], -1:1, n, n); +%! b = sum (A, 2); +%! tol = 1e-8; +%! maxit = 15; +%! M1 = spdiags ([ones(n,1)/(-2) ones(n,1)],-1:0, n, n); +%! M2 = spdiags ([4*ones(n,1) -ones(n,1)], 0:1, n, n); +%! [x, flag, relres, iter, resvec] = bicg (A, b, tol, maxit, M1, M2); +%! assert (x, ones (size (b)), 1e-7); +%! +%!test +%! n = 100; +%! A = spdiags ([-2*ones(n,1) 4*ones(n,1) -ones(n,1)], -1:1, n, n); +%! b = sum (A, 2); +%! tol = 1e-8; +%! maxit = 15; +%! M1 = spdiags ([ones(n,1)/(-2) ones(n,1)],-1:0, n, n); +%! M2 = spdiags ([4*ones(n,1) -ones(n,1)], 0:1, n, n); +%! +%! function y = afun (x, t, a) +%! switch t +%! case "notransp" +%! y = a * x; +%! case "transp" +%! y = a' * x; +%! endswitch +%! endfunction +%! +%! [x, flag, relres, iter, resvec] = bicg (@(x, t) afun (x, t, A), +%! b, tol, maxit, M1, M2); +%! assert (x, ones (size (b)), 1e-7); + +%!test +%! n = 100; +%! tol = 1e-8; +%! a = sprand (n, n, .1); +%! A = a' * a + 100 * eye (n); +%! b = sum (A, 2); +%! [x, flag, relres, iter, resvec] = bicg (A, b, tol, [], diag (diag (A))); +%! assert (x, ones (size (b)), 1e-7);
--- a/scripts/sparse/bicgstab.m +++ b/scripts/sparse/bicgstab.m @@ -1,4 +1,5 @@ ## Copyright (C) 2008-2011 Radek Salac +## Copyright (C) 2011 Carlo de Falco ## ## This file is part of Octave. ## @@ -17,155 +18,181 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} bicgstab (@var{A}, @var{b}) -## @deftypefnx {Function File} {} bicgstab (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0}) -## This procedure attempts to solve a system of linear equations A*x = b for x. -## The @var{A} must be square, symmetric and positive definite real matrix N*N. -## The @var{b} must be a one column vector with a length of N. -## The @var{tol} specifies the tolerance of the method, the default value is -## 1e-6. -## The @var{maxit} specifies the maximum number of iterations, the default value -## is min(20,N). -## The @var{M1} specifies a preconditioner, can also be a function handler which -## returns M\X. -## The @var{M2} combined with @var{M1} defines preconditioner as -## preconditioner=M1*M2. -## The @var{x0} is the initial guess, the default value is zeros(N,1). +## +## @deftypefn {Function File} {@var{x} =} bicgstab (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0}) +## @deftypefnx {Function File} {@var{x} =} bicgstab (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{P}) +## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} bicgstab (@var{A}, @var{b}, ...) +## Solve @code{A x = b} using the stabilizied Bi-conjugate gradient iterative method. +## +## @itemize @minus +## @item @var{rtol} is the relative tolerance, if not given or set to +## [] the default value 1e-6 is used. +## @item @var{maxit} the maximum number of outer iterations, if not +## given or set to [] the default value @code{min (20, numel (b))} is +## used. +## @item @var{x0} the initial guess, if not given or set to [] the +## default value @code{zeros (size (b))} is used. +## @end itemize +## +## @var{A} can be passed as a matrix or as a function handle or +## inline function @code{f} such that @code{f(x) = A*x}. ## -## The value @var{x} is a computed result of this procedure. -## The value @var{flag} can be 0 when we reach tolerance in @var{maxit} -## iterations, 1 when -## we don't reach tolerance in @var{maxit} iterations and 3 when the procedure -## stagnates. -## The value @var{relres} is a relative residual - norm(b-A*x)/norm(b). -## The value @var{iter} is an iteration number in which x was computed. -## The value @var{resvec} is a vector of @var{relres} for each iteration. +## The preconditioner @var{P} is given as @code{P = M1 * M2}. +## Both @var{M1} and @var{M2} can be passed as a matrix or as a function handle or +## inline function @code{g} such that @code{g(x) = M1 \ x} or @code{g(x) = M2 \ x}. +## +## If called with more than one output parameter +## +## @itemize @minus +## @item @var{flag} indicates the exit status: +## @itemize @minus +## @item 0: iteration converged to the within the chosen tolerance +## @item 1: the maximum number of iterations was reached before convergence +## @item 3: the algorithm reached stagnation +## @end itemize +## (the value 2 is unused but skipped for compatibility). +## @item @var{relres} is the final value of the relative residual. +## @item @var{iter} is the number of iterations performed. +## @item @var{resvec} is a vector containing the relative residual at each iteration. +## @end itemize +## +## @seealso{bicg,cgs,gmres,pcg} ## ## @end deftypefn -function [x, flag, relres, iter, resvec] = bicgstab (A, b, tol, maxit, M1, M2, x0) +function [x, flag, relres, iter, resvec] = bicgstab (A, b, tol, maxit, + M1, M2, x0) - if (nargin < 2 || nargin > 7 || nargout > 5) - print_usage (); - elseif (!(isnumeric (A) && issquare (A))) - error ("bicgstab: A must be a square numeric matrix"); - elseif (!isvector (b)) - error ("bicgstab: B must be a vector"); - elseif (!any (b)) - error ("bicgstab: B must not be a vector of all zeros"); - elseif (rows (A) != rows (b)) - error ("bicgstab: A and B must have the same number of rows"); - elseif (nargin > 2 && !isscalar (tol)) - error ("bicgstab: TOL must be a scalar"); - elseif (nargin > 3 && !isscalar (maxit)) - error ("bicgstab: MAXIT must be a scalar"); - elseif (nargin > 4 && ismatrix (M1) && (rows (M1) != rows (A) || columns (M1) != columns (A))) - error ("bicgstab: M1 must have the same number of rows and columns as A"); - elseif (nargin > 5 && (!ismatrix (M2) || rows (M2) != rows (A) || columns (M2) != columns (A))) - error ("bicgstab: M2 must have the same number of rows and columns as A"); - elseif (nargin > 6 && !isvector (x0)) - error ("bicgstab: X0 must be a vector"); - elseif (nargin > 6 && rows (x0) != rows (b)) - error ("bicgstab: X0 must have the same number of rows as B"); - endif + if (nargin >= 2 && nargin <= 7 && isvector (full (b))) + + if (ischar (A)) + A = str2func (A); + elseif (ismatrix (A)) + Ax = @(x) A * x; + elseif (isa (A, "function_handle")) + Ax = @(x) feval (A, x); + else + error (["bicgstab: first argument is expected " ... + "to be a function or a square matrix"]); + endif + + if (nargin < 3 || isempty (tol)) + tol = 1e-6; + endif - ## Default tolerance. - if (nargin < 3) - tol = 1e-6; - endif - - ## Default maximum number of iteration. - if (nargin < 4) - maxit = min (rows (b), 20); - endif + if (nargin < 4 || isempty (maxit)) + maxit = min (rows (b), 20); + endif - ## Left preconditioner. - if (nargin == 5) - if (isnumeric (M1)) - precon = @(x) M1 \ x; + if (nargin < 5 || isempty (M1)) + M1m1x = @(x) x; + elseif (ischar (M1)) + M1m1x = str2func (M1); + elseif (ismatrix (M1)) + M1m1x = @(x) M1 \ x; + elseif (isa (M1, "function_handle")) + M1m1x = @(x) feval (M1, x); + else + error (["bicgstab: preconditioner is " ... + "expected to be a function or matrix"]); endif - elseif (nargin > 5) - if (issparse (M1) && issparse (M2)) - precon = @(x) M2 \ (M1 \ x); + + if (nargin < 6 || isempty (M2)) + M2m1x = @(x) x; + elseif (ischar (M2)) + M2m1x = str2func (M2); + elseif (ismatrix (M2)) + M2m1x = @(x) M2 \ x; + elseif (isa (M2, "function_handle")) + M2m1x = @(x) feval (M2, x); else - M = M1*M2; - precon = @(x) M \ x; + error (["bicgstab: preconditioner is "... + "expected to be a function or matrix"]); endif - else - precon = @(x) x; - endif - ## specifies initial estimate x0 - if (nargin < 7) - x = zeros (rows (b), 1); - else - x = x0; - endif - - norm_b = norm (b); - - res = b - A*x; - rr = res; + precon = @(x) M2m1x (M1m1x (x)); - ## Vector of the residual norms for each iteration. - resvec = [norm(res)/norm_b]; - - ## Default behaviour we don't reach tolerance tol within maxit iterations. - flag = 1; - - for iter = 1:maxit - rho_1 = res' * rr; - - if (iter == 1) - p = res; + if (nargin < 7 || isempty (x0)) + x0 = zeros (size (b)); + endif + + ## specifies initial estimate x0 + if (nargin < 7) + x = zeros (rows (b), 1); else - beta = (rho_1 / rho_2) * (alpha / omega); - p = res + beta * (p - omega * v); + x = x0; endif - phat = precon (p); + norm_b = norm (b); + + res = b - Ax (x); + rr = res; - v = A * phat; - alpha = rho_1 / (rr' * v); - s = res - alpha * v; + ## Vector of the residual norms for each iteration. + resvec = norm(res) / norm_b; - shat = precon (s); + ## Default behaviour we don't reach tolerance tol within maxit iterations. + flag = 1; + + for iter = 1:maxit + rho_1 = res' * rr; - t = A * shat; - omega = (t' * s) / (t' * t); - x = x + alpha * phat + omega * shat; - res = s - omega * t; - rho_2 = rho_1; + if (iter == 1) + p = res; + else + beta = (rho_1 / rho_2) * (alpha / omega); + p = res + beta * (p - omega * v); + endif + + phat = precon (p); - relres = norm (res) / norm_b; - resvec = [resvec; relres]; + v = Ax (phat); + alpha = rho_1 / (rr' * v); + s = res - alpha * v; + + shat = precon (s); + + t = Ax (shat); + omega = (t' * s) / (t' * t); + x = x + alpha * phat + omega * shat; + res = s - omega * t; + rho_2 = rho_1; - if (relres <= tol) - ## We reach tolerance tol within maxit iterations. - flag = 0; - break; - elseif (resvec (end) == resvec (end - 1)) - ## The method stagnates. - flag = 3; - break; - endif - endfor + relres = norm (res) / norm_b; + resvec = [resvec; relres]; + + if (relres <= tol) + ## We reach tolerance tol within maxit iterations. + flag = 0; + break; + elseif (resvec(end) == resvec(end - 1)) + ## The method stagnates. + flag = 3; + break; + endif + endfor - if (nargout < 2) - if (flag == 0) - printf (["bicgstab converged at iteration %i ", - "to a solution with relative residual %e\n"],iter,relres); - elseif (flag == 3) - printf (["bicgstab stopped at iteration %i ", - "without converging to the desired tolerance %e\n", - "because the method stagnated.\n", - "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres); - else - printf (["bicgstab stopped at iteration %i ", - "without converging to the desired toleranc %e\n", - "because the maximum number of iterations was reached.\n", - "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres); + if (nargout < 2) + if (flag == 0) + printf ("bicgstab converged at iteration %i ", iter); + printf ("to a solution with relative residual %e\n", relres); + elseif (flag == 3) + printf ("bicgstab stopped at iteration %i ", iter); + printf ("without converging to the desired tolerance %e\n", tol); + printf ("because the method stagnated.\n"); + printf ("The iterate returned (number %i) ", iter); + printf ("has relative residual %e\n", relres); + else + printf ("bicgstab stopped at iteration %i ", iter); + printf ("without converging to the desired toleranc %e\n", tol); + printf ("because the maximum number of iterations was reached.\n"); + printf ("The iterate returned (number %i) ", iter); + printf ("has relative residual %e\n", relres); + endif endif + + else + print_usage (); endif endfunction @@ -176,3 +203,36 @@ %! b = [7;-1;4] %! [x, flag, relres, iter, resvec] = bicgstab(A, b) +%!shared A, b, n, M1, M2 +%! +%!test +%! n = 100; +%! A = spdiags ([-2*ones(n,1) 4*ones(n,1) -ones(n,1)], -1:1, n, n); +%! b = sum (A, 2); +%! tol = 1e-8; +%! maxit = 15; +%! M1 = spdiags ([ones(n,1)/(-2) ones(n,1)],-1:0, n, n); +%! M2 = spdiags ([4*ones(n,1) -ones(n,1)], 0:1, n, n); +%! [x, flag, relres, iter, resvec] = bicgstab (A, b, tol, maxit, M1, M2); +%! assert (x, ones (size (b)), 1e-7); +%! +%!test +%! tol = 1e-8; +%! maxit = 15; +%! +%! function y = afun (x, a) +%! y = a * x; +%! endfunction +%! +%! [x, flag, relres, iter, resvec] = bicgstab (@(x) afun (x, A), b, +%! tol, maxit, M1, M2); +%! assert (x, ones (size (b)), 1e-7); + +%!test +%! n = 100; +%! tol = 1e-8; +%! a = sprand (n, n, .1); +%! A = a'*a + 100 * eye (n); +%! b = sum (A, 2); +%! [x, flag, relres, iter, resvec] = bicgstab (A, b, tol, [], diag (diag (A))); +%! assert (x, ones (size (b)), 1e-7);
--- a/scripts/sparse/cgs.m +++ b/scripts/sparse/cgs.m @@ -1,4 +1,5 @@ ## Copyright (C) 2008-2011 Radek Salac +## Copyright (C) 2011 Carlo de Falco ## ## This file is part of Octave. ## @@ -17,134 +18,165 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} cgs (@var{A}, @var{b}) -## @deftypefnx {Function File} {} cgs (@var{A}, @var{b}, @var{tol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0}) -## This procedure attempts to solve a system of linear equations A*x = b for x. -## The @var{A} must be square, symmetric and positive definite real matrix N*N. -## The @var{b} must be a one column vector with a length of N. -## The @var{tol} specifies the tolerance of the method, default value is 1e-6. -## The @var{maxit} specifies the maximum number of iteration, default value is -## MIN(20,N). -## The @var{M1} specifies a preconditioner, can also be a function handler which -## returns M\X. -## The @var{M2} combined with @var{M1} defines preconditioner as -## preconditioner=M1*M2. -## The @var{x0} is initial guess, default value is zeros(N,1). +## +## @deftypefn {Function File} {@var{x} =} cgs (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0}) +## @deftypefnx {Function File} {@var{x} =} cgs (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{P}) +## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} cgs (@var{A}, @var{b}, ...) +## Solve @code{A x = b}, where @var{A} is a square matrix, using the +## Conjugate Gradients Squared method. +## +## @itemize @minus +## @item @var{rtol} is the relative tolerance, if not given or set to [] +## the default value 1e-6 is used. +## @item @var{maxit} the maximum number of outer iterations, if not +## given or set to [] the default value @code{min (20, numel (b))} is +## used. +## @item @var{x0} the initial guess, if not given or set to [] the +## default value @code{zeros (size (b))} is used. +## @end itemize +## +## @var{A} can be passed as a matrix or as a function handle or +## inline function @code{f} such that @code{f(x) = A*x}. ## +## The preconditioner @var{P} is given as @code{P = M1 * M2}. +## Both @var{M1} and @var{M2} can be passed as a matrix or as a function +## handle or inline function @code{g} such that @code{g(x) = M1 \ x} or +## @code{g(x) = M2 \ x}. +## +## If called with more than one output parameter +## +## @itemize @minus +## @item @var{flag} indicates the exit status: +## @itemize @minus +## @item 0: iteration converged to the within the chosen tolerance +## @item 1: the maximum number of iterations was reached before convergence +## @item 3: the algorithm reached stagnation +## @end itemize +## (the value 2 is unused but skipped for compatibility). +## @item @var{relres} is the final value of the relative residual. +## @item @var{iter} is the number of iterations performed. +## @item @var{resvec} is a vector containing the relative residual at +## each iteration. +## @end itemize +## +## @seealso{pcg,bicgstab,bicg,gmres} ## @end deftypefn function [x, flag, relres, iter, resvec] = cgs (A, b, tol, maxit, M1, M2, x0) - if (nargin < 2 || nargin > 7 || nargout > 5) - print_usage (); - elseif (!(isnumeric (A) && issquare (A))) - error ("cgs: A must be a square numeric matrix"); - elseif (!isvector (b)) - error ("cgs: B must be a vector"); - elseif (rows (A) != rows (b)) - error ("cgs: A and B must have the same number of rows"); - elseif (nargin > 2 && !isscalar (tol)) - error ("cgs: TOL must be a scalar"); - elseif (nargin > 3 && !isscalar (maxit)) - error ("cgs: MAXIT must be a scalar"); - elseif (nargin > 4 && ismatrix (M1) && (rows (M1) != rows (A) || columns (M1) != columns (A))) - error ("cgs: M1 must have the same number of rows and columns as A"); - elseif (nargin > 5 && (!ismatrix (M2) || rows (M2) != rows (A) || columns (M2) != columns (A))) - error ("cgs: M2 must have the same number of rows and columns as A"); - elseif (nargin > 6 && !isvector (x0)) - error ("cgs: X0 must be a vector"); - elseif (nargin > 6 && rows (x0) != rows (b)) - error ("cgs: X0 must have the same number of rows as B"); - endif - - ## Default tolerance. - if (nargin < 3) - tol = 1e-6; - endif + if (nargin >= 2 && nargin <= 7 && isvector (full (b))) + + if (ischar (A)) + A = str2func (A); + elseif (ismatrix (A)) + Ax = @(x) A * x; + elseif (isa (A, "function_handle")) + Ax = @(x) feval (A, x); + else + error (["cgs: first argument is expected to "... + "be a function or a square matrix"]); + endif + + if (nargin < 3 || isempty (tol)) + tol = 1e-6; + endif + + if (nargin < 4 || isempty (maxit)) + maxit = min (rows (b), 20); + endif + + if (nargin < 5 || isempty (M1)) + M1m1x = @(x) x; + elseif (ischar (M1)) + M1m1x = str2func (M1); + elseif (ismatrix (M1)) + M1m1x = @(x) M1 \ x; + elseif (isa (M1, "function_handle")) + M1m1x = @(x) feval (M1, x); + else + error ("cgs: preconditioner is expected to be a function or matrix"); + endif + + if (nargin < 6 || isempty (M2)) + M2m1x = @(x) x; + elseif (ischar (M2)) + M2m1x = str2func (M2); + elseif (ismatrix (M2)) + M2m1x = @(x) M2 \ x; + elseif (isa (M2, "function_handle")) + M2m1x = @(x) feval (M2, x); + else + error ("cgs: preconditioner is expected to be a function or matrix"); + endif - ## Default maximum number of iteration. - if (nargin < 4) - maxit = min (rows (b),20); - endif + precon = @(x) M2m1x (M1m1x (x)); - ## Left preconditioner. - if (nargin == 5) - if (isnumeric (M1)) - precon = @(x) M1 \ x; + if (nargin < 7 || isempty (x0)) + x0 = zeros (size (b)); endif - elseif (nargin > 5) - if (issparse (M1) && issparse (M2)) - precon = @(x) M2 \ (M1 \ x); - else - M = M1*M2; - precon = @(x) M \ x; - endif - else - precon = @(x) x; - endif - - ## Specifies initial estimate x0. - if (nargin < 7) - x = zeros (rows (b), 1); - else - x = x0; - endif - res = b - A * x; - norm_b = norm (b); - ## Vector of the residual norms for each iteration. - resvec = [ norm(res)/norm_b ]; - ro = 0; - ## Default behavior we don't reach tolerance tol within maxit iterations. - flag = 1; - for iter = 1 : maxit + + x = x0; + + res = b - Ax (x); + norm_b = norm (b); + ## Vector of the residual norms for each iteration. + resvec = norm (res) / norm_b; + ro = 0; + ## Default behavior we don't reach tolerance tol within maxit iterations. + flag = 1; + for iter = 1:maxit - z = precon (res); + z = precon (res); - ## Cache. - ro_old = ro; - ro = res' * z; - if (iter == 1) - p = z; - else - beta = ro / ro_old; - p = z + beta * p; - endif - ## Cache. - q = A * p; - alpha = ro / (p' * q); - x = x + alpha * p; + ## Cache. + ro_old = ro; + ro = res' * z; + if (iter == 1) + p = z; + else + beta = ro / ro_old; + p = z + beta * p; + endif + ## Cache. + q = Ax (p); + alpha = ro / (p' * q); + x = x + alpha * p; - res = res - alpha * q; - relres = norm(res) / norm_b; - resvec = [resvec;relres]; + res = res - alpha * q; + relres = norm (res) / norm_b; + resvec = [resvec; relres]; - if (relres <= tol) - ## We reach tolerance tol within maxit iterations. - flag = 0; - break; - elseif (resvec (end) == resvec (end - 1)) - ## The method stagnates. - flag = 3; - break; - endif - endfor; + if (relres <= tol) + ## We reach tolerance tol within maxit iterations. + flag = 0; + break + elseif (resvec (end) == resvec (end - 1)) + ## The method stagnates. + flag = 3; + break + endif + endfor - if (nargout < 1) - if ( flag == 0 ) - printf (["cgs converged at iteration %i ", - "to a solution with relative residual %e\n"],iter,relres); - elseif (flag == 3) - printf (["cgs stopped at iteration %i ", - "without converging to the desired tolerance %e\n", - "because the method stagnated.\n", - "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres); - else - printf (["cgs stopped at iteration %i ", - "without converging to the desired tolerance %e\n", - "because the maximum number of iterations was reached.\n", - "The iterate returned (number %i) has relative residual %e\n"],iter,tol,iter,relres); + if (nargout < 1) + if (flag == 0) + printf ("cgs converged at iteration %i to a solution with relative residual %e\n", + iter, relres); + elseif (flag == 3) + printf (["cgs stopped at iteration %i without converging to the desired tolerance %e\n", + "because the method stagnated.\n", + "The iterate returned (number %i) has relative residual %e\n"], + iter, tol, iter, relres); + else + printf (["cgs stopped at iteration %i without converging to the desired tolerance %e\n", + "because the maximum number of iterations was reached.\n", + "The iterate returned (number %i) has relative residual %e\n"], + iter, tol, iter, relres); + endif endif + + else + print_usage (); endif endfunction @@ -156,3 +188,31 @@ %! A=[5 -1 3;-1 2 -2;3 -2 3] %! b=[7;-1;4] %! [a,b,c,d,e]=cgs(A,b) + +%!shared A, b, n, M +%! +%!test +%! n = 100; +%! A = spdiags ([-ones(n,1) 4*ones(n,1) -ones(n,1)], -1:1, n, n); +%! b = sum (A, 2); +%! tol = 1e-8; +%! maxit = 1000; +%! M = 4*eye (n); +%! [x, flag, relres, iter, resvec] = cgs (A, b, tol, maxit, M); +%! assert (x, ones (size (b)), 1e-7); +%! +%!test +%! tol = 1e-8; +%! maxit = 15; +%! +%! [x, flag, relres, iter, resvec] = cgs (@(x) A * x, b, tol, maxit, M); +%! assert (x, ones (size (b)), 1e-7); + +%!test +%! n = 100; +%! tol = 1e-8; +%! a = sprand (n, n, .1); +%! A = a'*a + 100 * eye (n); +%! b = sum (A, 2); +%! [x, flag, relres, iter, resvec] = cgs (A, b, tol, [], diag (diag (A))); +%! assert (x, ones (size (b)), 1e-7);
--- a/scripts/sparse/gmres.m +++ b/scripts/sparse/gmres.m @@ -49,30 +49,23 @@ ## ## @itemize @minus ## @item @var{flag} indicates the exit status: -## ## @table @asis -## @item 0 : iteration converged to within the specified tolerance -## -## @item 1 : maximum number of iterations exceeded -## -## @item 2 : unused, but skipped for compatibility -## -## @item 3 : algorithm reached stagnation +## @item 0 : iteration converged to within the specified tolerance +## @item 1 : maximum number of iterations exceeded +## @item 2 : unused, but skipped for compatibility +## @item 3 : algorithm reached stagnation ## @end table -## ## @item @var{relres} is the final value of the relative residual. -## ## @item @var{iter} is a vector containing the number of outer iterations and ## total iterations performed. -## ## @item @var{resvec} is a vector containing the relative residual at each ## iteration. ## @end itemize ## -## @seealso{pcg, cgs, bicgstab} +## @seealso{bicg, bicgstab, cgs, pcg} ## @end deftypefn -function [x, flag, prec_res_norm, itcnt] = gmres (A, b, restart, rtol, maxit, M1, M2, x0) +function [x, flag, presn, it] = gmres (A, b, restart, rtol, maxit, M1, M2, x0) if (nargin < 2 || nargin > 8) print_usage (); @@ -133,7 +126,7 @@ x_old = x0; x = x_old; prec_res = Pm1x (b - Ax (x_old)); - prec_res_norm = norm (prec_res, 2); + presn = norm (prec_res, 2); B = zeros (restart + 1, 1); V = zeros (rows (x), restart); @@ -143,49 +136,54 @@ iter = 1; restart_it = restart + 1; resids = zeros (maxit, 1); - resids(1) = prec_res_norm; + resids(1) = presn; prec_b_norm = norm (Pm1x (b), 2); flag = 1; - while ((iter <= maxit * restart) && (prec_res_norm > rtol * prec_b_norm)) + while (iter <= maxit * restart && presn > rtol * prec_b_norm) ## restart if (restart_it > restart) restart_it = 1; x_old = x; prec_res = Pm1x (b - Ax (x_old)); - prec_res_norm = norm (prec_res, 2); - B(1) = prec_res_norm; + presn = norm (prec_res, 2); + B(1) = presn; H(:) = 0; - V(:, 1) = prec_res / prec_res_norm; + V(:, 1) = prec_res / presn; endif ## basic iteration tmp = Pm1x (Ax (V(:, restart_it))); - [V(:,restart_it+1), H(1:restart_it+1, restart_it)] = mgorth (tmp, V(:,1:restart_it)); + [V(:,restart_it+1), H(1:restart_it+1, restart_it)] = ... + mgorth (tmp, V(:,1:restart_it)); Y = (H(1:restart_it+1, 1:restart_it) \ B (1:restart_it+1)); - little_res = B(1:restart_it+1) - H(1:restart_it+1, 1:restart_it) * Y(1:restart_it); - prec_res_norm = norm (little_res, 2); + little_res = B(1:restart_it+1) - ... + H(1:restart_it+1, 1:restart_it) * Y(1:restart_it); + + presn = norm (little_res, 2); x = x_old + V(:, 1:restart_it) * Y(1:restart_it); - resids(iter) = prec_res_norm ; + resids(iter) = presn; if (norm (x - x_old, inf) <= eps) flag = 3; break endif - restart_it++ ; iter++; + restart_it++ ; + iter++; endwhile - if (prec_res_norm > rtol * prec_b_norm) + if (presn > rtol * prec_b_norm) flag = 0; endif resids = resids(1:iter-1); - itcnt = [floor(maxit/restart), rem(maxit, restart)]; + it = [floor(maxit/restart), rem(maxit, restart)]; + endfunction
--- a/scripts/sparse/gplot.m +++ b/scripts/sparse/gplot.m @@ -54,3 +54,31 @@ endif endfunction + + +%!demo +%! ## Binary Tree Representation +%! A = [0 1 0 0 0 0 0 +%! 1 0 1 1 0 0 0 +%! 0 1 0 0 0 0 0 +%! 0 1 0 0 1 0 0 +%! 0 0 0 1 0 1 1 +%! 0 0 0 0 1 0 0 +%! 0 0 0 0 1 0 0]; +%! +%! xy = [1, 0 +%! 1.5, 1 +%! 2, 0 +%! 2.5, 2 +%! 3.5, 1 +%! 3, 0 +%! 4, 0]; +%! +%! clf; +%! gplot (A, xy, "o-"); +%! set (get (gca, ("children")), "markersize", 12); +%! title ("gplot() of Binary Tree Adjacency matrix"); + +%% Mark graphical function as tested by demo block +%!assert (1); +
--- a/scripts/sparse/module.mk +++ b/scripts/sparse/module.mk @@ -1,6 +1,7 @@ FCN_FILE_DIRS += sparse sparse_FCN_FILES = \ + sparse/bicg.m \ sparse/bicgstab.m \ sparse/cgs.m \ sparse/colperm.m \
--- a/scripts/sparse/spconvert.m +++ b/scripts/sparse/spconvert.m @@ -43,3 +43,25 @@ endif endfunction + + +%!test +%! i = [1; 3; 5]; +%! j = [2; 4; 6]; +%! v = [7; 8; 9]; +%! s = spconvert ([i, j, v]); +%! assert (issparse (s)); +%! [fi, fj, fv] = find (s); +%! assert (isequal (i, fi) && isequal (j, fj) && isequal (v, fv)); +%! s = spconvert ([i, j, v, j]); +%! [fi, fj, fv] = find (s); +%! assert (isequal (i, fi) && isequal (j, fj) && isequal (complex (v, j), fv)); +%! assert (size (spconvert ([1, 1, 3; 5, 15, 0])), [5, 15]); + +%% Test input validation +%!error spconvert () +%!error spconvert (1, 2) +%!error spconvert ({[1 2 3]}) +%!error spconvert ([1 2]) +%!error spconvert ([1 2 3i]) +%!error spconvert ([1 2 3 4 5])
--- a/scripts/sparse/sprand.m +++ b/scripts/sparse/sprand.m @@ -52,9 +52,9 @@ endif if (nargin == 1) - [i, j, v] = find (m); + [i, j] = find (m); [nr, nc] = size (m); - S = sparse (i, j, rand (size (v)), nr, nc); + S = sparse (i, j, rand (size (i)), nr, nc); return; endif @@ -92,3 +92,30 @@ endfunction +## FIXME: Test for density can't happen until code of sprand is improved +%!test +%! s = sprand (4, 10, 0.1); +%! assert (size (s), [4, 10]); +##%! assert (nnz (s) / numel (s), 0.1, .01); + +%% Test 1-input calling form +%!test +%! s = sprand (sparse ([1 2 3], [3 2 3], [2 2 2])); +%! [i, j, v] = find (s); +%! assert (sort (i), [1 2 3]'); +%! assert (sort (j), [2 3 3]'); +%! assert (all (v > 0 & v < 1)); + +%% Test input validation +%!error sprand () +%!error sprand (1, 2) +%!error sprand (1, 2, 3, 4) +%!error sprand (ones(3), 3, 0.5) +%!error sprand (3.5, 3, 0.5) +%!error sprand (0, 3, 0.5) +%!error sprand (3, ones(3), 0.5) +%!error sprand (3, 3.5, 0.5) +%!error sprand (3, 0, 0.5) +%!error sprand (3, 3, -1) +%!error sprand (3, 3, 2) +
--- a/scripts/sparse/sprandn.m +++ b/scripts/sparse/sprandn.m @@ -38,30 +38,75 @@ ## Author: Paul Kienzle <pkienzle@users.sf.net> function S = sprandn (m, n, d) - if (nargin == 1) - [i, j, v] = find (m); - [nr, nc] = size (m); - S = sparse (i, j, randn (size (v)), nr, nc); - elseif (nargin == 3) - mn = m*n; - k = round (d*mn); - idx = unique (fix (rand (min (k*1.01, k+10), 1) * mn)) + 1; - ## idx contains random numbers in [1,mn] - ## generate 1% or 10 more random values than necessary in order to - ## reduce the probability that there are less than k distinct - ## values; maybe a better strategy could be used but I don't think - ## it's worth the price. - ## actual number of entries in S - k = min (length (idx), k); - j = floor ((idx(1:k)-1)/m); - i = idx(1:k) - j*m; - if (isempty (i)) - S = sparse (m, n); - else - S = sparse (i, j+1, randn (k, 1), m, n); - endif - else + if (nargin != 1 && nargin != 3) print_usage (); endif + + if (nargin == 1) + [i, j] = find (m); + [nr, nc] = size (m); + S = sparse (i, j, randn (size (i)), nr, nc); + return; + endif + + if (!(isscalar (m) && m == fix (m) && m > 0)) + error ("sprand: M must be an integer greater than 0"); + endif + + if (!(isscalar (n) && n == fix (n) && n > 0)) + error ("sprand: N must be an integer greater than 0"); + endif + + if (d < 0 || d > 1) + error ("sprand: density D must be between 0 and 1"); + endif + + mn = m*n; + k = round (d*mn); + idx = unique (fix (rand (min (k*1.01, k+10), 1) * mn)) + 1; + ## idx contains random numbers in [1,mn] + ## generate 1% or 10 more random values than necessary in order to + ## reduce the probability that there are less than k distinct + ## values; maybe a better strategy could be used but I don't think + ## it's worth the price. + + ## actual number of entries in S + k = min (length (idx), k); + j = floor ((idx(1:k)-1)/m); + i = idx(1:k) - j*m; + if (isempty (i)) + S = sparse (m, n); + else + S = sparse (i, j+1, randn (k, 1), m, n); + endif + endfunction + + +## FIXME: Test for density can't happen until code of sprandn is improved +%!test +%! s = sprandn (4, 10, 0.1); +%! assert (size (s), [4, 10]); +##%! assert (nnz (s) / numel (s), 0.1, .01); + +%% Test 1-input calling form +%!test +%! s = sprandn (sparse ([1 2 3], [3 2 3], [2 2 2])); +%! [i, j] = find (s); +%! assert (sort (i), [1 2 3]'); +%! assert (sort (j), [2 3 3]'); + +%% Test input validation +%!error sprandn () +%!error sprandn (1, 2) +%!error sprandn (1, 2, 3, 4) +%!error sprandn (ones(3), 3, 0.5) +%!error sprandn (3.5, 3, 0.5) +%!error sprandn (0, 3, 0.5) +%!error sprandn (3, ones(3), 0.5) +%!error sprandn (3, 3.5, 0.5) +%!error sprandn (3, 0, 0.5) +%!error sprandn (3, 3, -1) +%!error sprandn (3, 3, 2) +
--- a/scripts/sparse/sprandsym.m +++ b/scripts/sparse/sprandsym.m @@ -34,44 +34,83 @@ ## @end deftypefn function S = sprandsym (n, d) - if (nargin == 1) - [i, j, v] = find (tril (n)); - [nr, nc] = size (n); - S = sparse (i, j, randn (size (v)), nr, nc); - S = S + tril (S, -1)'; - elseif (nargin == 2) - m1 = floor (n/2); - n1 = m1 + rem (n, 2); - mn1 = m1*n1; - k1 = round (d*mn1); - idx1 = unique (fix (rand (min (k1*1.01, k1+10), 1) * mn1)) + 1; - ## idx contains random numbers in [1,mn] generate 1% or 10 more - ## random values than necessary in order to reduce the probability - ## that there are less than k distinct values; maybe a better - ## strategy could be used but I don't think it's worth the price. - ## Actual number of entries in S. - k1 = min (length (idx1), k1); - j1 = floor ((idx1(1:k1)-1)/m1); - i1 = idx1(1:k1) - j1*m1; - - n2 = ceil (n/2); - nn2 = n2*n2; - k2 = round (d*nn2); - idx2 = unique (fix (rand (min (k2*1.01, k1+10), 1) * nn2)) + 1; - k2 = min (length (idx2), k2); - j2 = floor ((idx2(1:k2)-1)/n2); - i2 = idx2(1:k2) - j2*n2; - - if (isempty (i1) && isempty (i2)) - S = sparse (n, n); - else - S1 = sparse (i1, j1+1, randn (k1, 1), m1, n1); - S = [tril(S1), sparse(m1,m1); ... - sparse(i2,j2+1,randn(k2,1),n2,n2), triu(S1,1)']; - S = S + tril (S, -1)'; - endif - else + if (nargin != 1 && nargin != 2) print_usage (); endif + + if (nargin == 1) + [i, j] = find (tril (n)); + [nr, nc] = size (n); + S = sparse (i, j, randn (size (i)), nr, nc); + S = S + tril (S, -1)'; + return; + endif + + if (!(isscalar (n) && n == fix (n) && n > 0)) + error ("sprand: N must be an integer greater than 0"); + endif + + if (d < 0 || d > 1) + error ("sprand: density D must be between 0 and 1"); + endif + + m1 = floor (n/2); + n1 = m1 + rem (n, 2); + mn1 = m1*n1; + k1 = round (d*mn1); + idx1 = unique (fix (rand (min (k1*1.01, k1+10), 1) * mn1)) + 1; + ## idx contains random numbers in [1,mn] generate 1% or 10 more + ## random values than necessary in order to reduce the probability + ## that there are less than k distinct values; maybe a better + ## strategy could be used but I don't think it's worth the price. + + ## Actual number of entries in S. + k1 = min (length (idx1), k1); + j1 = floor ((idx1(1:k1)-1)/m1); + i1 = idx1(1:k1) - j1*m1; + + n2 = ceil (n/2); + nn2 = n2*n2; + k2 = round (d*nn2); + idx2 = unique (fix (rand (min (k2*1.01, k1+10), 1) * nn2)) + 1; + k2 = min (length (idx2), k2); + j2 = floor ((idx2(1:k2)-1)/n2); + i2 = idx2(1:k2) - j2*n2; + + if (isempty (i1) && isempty (i2)) + S = sparse (n, n); + else + S1 = sparse (i1, j1+1, randn (k1, 1), m1, n1); + S = [tril(S1), sparse(m1,m1); ... + sparse(i2,j2+1,randn(k2,1),n2,n2), triu(S1,1)']; + S = S + tril (S, -1)'; + endif + endfunction + + +## FIXME: Test for density can't happen until code of sprandsym is improved +%!test +%! s = sprandsym (10, 0.1); +%! assert (issparse (s)); +%! assert (issymmetric (s)); +%! assert (size (s), [10, 10]); +##%! assert (nnz (s) / numel (s), 0.1, .01); + +%% Test 1-input calling form +%!test +%! s = sprandsym (sparse ([1 2 3], [3 2 3], [2 2 2])); +%! [i, j] = find (s); +%! assert (sort (i), [2 3]'); +%! assert (sort (j), [2 3]'); + +%% Test input validation +%!error sprandsym () +%!error sprandsym (1, 2, 3) +%!error sprandsym (ones(3), 0.5) +%!error sprandsym (3.5, 0.5) +%!error sprandsym (0, 0.5) +%!error sprandsym (3, -1) +%!error sprandsym (3, 2) +
--- a/scripts/sparse/spy.m +++ b/scripts/sparse/spy.m @@ -61,3 +61,11 @@ axis ([0, n+1, 0, m+1], "ij"); endfunction + + +%!demo +%! clf; +%! spy (sprand (10,10, 0.2)); + +%% Mark graphical function as tested by demo block +%!assert (1);
--- a/scripts/sparse/treelayout.m +++ b/scripts/sparse/treelayout.m @@ -202,10 +202,26 @@ endif endfunction -%!demo +%!test %! % Compute a simple tree layout -%! [x,y,h,s]=treelayout([0 1 2 2]) +%! [x, y, h, s] = treelayout ([0, 1, 2, 2]); +%! assert (x, [1.5, 1.5, 2, 1]); +%! assert (y, [3, 2, 1, 1]); +%! assert (h, 2); +%! assert (s, 2); -%!demo +%!test %! % Compute a simple tree layout with defined postorder permutation -%! [x,y,h,s]=treelayout([0 1 2 2],[1 2 3 4]) +%! [x, y, h, s] = treelayout ([0, 1, 2, 2], [1, 2, 4, 3]); +%! assert (x, [1.5, 1.5, 1, 2]); +%! assert (y, [3, 2, 1, 1]); +%! assert (h, 2); +%! assert (s, 2); + +%!test +%! % Compute a simple tree layout with defined postorder permutation +%! [x, y, h, s] = treelayout ([0, 1, 2, 2], [4, 2, 3, 1]); +%! assert (x, [0, 0, 0, 1]); +%! assert (y, [0, 0, 0, 3]); +%! assert (h, 0); +%! assert (s, 1);
--- a/scripts/testfun/demo.m +++ b/scripts/testfun/demo.m @@ -141,3 +141,6 @@ %! plot (t,x) %! %------------------------------------------------- %! % the figure window shows one cycle of a sine wave + +%!error demo (); +%!error demo (1, 2, 3);
--- a/scripts/testfun/fail.m +++ b/scripts/testfun/fail.m @@ -129,15 +129,16 @@ endfunction -%!fail ('[1,2]*[2,3]','nonconformant') -%!fail ("fail('[1,2]*[2;3]','nonconformant')","expected error <nonconformant> but got none") -%!fail ("fail('[1,2]*[2,3]','usage:')","expected error <usage:>\nbut got.*nonconformant") -%!fail ("warning('test warning')",'warning','test warning'); + +%!fail ('[1,2]*[2,3]', 'nonconformant') +%!fail ("fail('[1,2]*[2;3]', 'nonconformant')", "expected error <nonconformant> but got none") +%!fail ("fail('[1,2]*[2,3]','usage:')", "expected error <usage:>\nbut got.*nonconformant") +%!fail ("warning('test warning')", 'warning','test warning'); -%!# fail ("warning('next test')",'warning','next test'); ## only allowed one warning test?!? +##% !fail ("warning('next test')",'warning','next test'); ## only allowed one warning test?!? -## Comment out the following tests if you don't want to see what -## errors look like -% !fail ('a*[2;3]', 'nonconformant') -% !fail ('a*[2,3]', 'usage:') -% !fail ("warning('warning failure')", 'warning', 'success') +%% Test that fail() itself will generate an error +%!error fail ("1"); +%!error <undefined> fail ('a*[2;3]', 'nonconformant') +%!error <expected error> fail ('a*[2,3]', 'usage:') +%!error <warning failure> fail ("warning('warning failure')", 'warning', 'success')
--- a/scripts/testfun/rundemos.m +++ b/scripts/testfun/rundemos.m @@ -81,3 +81,5 @@ retval = findstr (str, "%!demo"); endif endfunction + +%!error rundemos ("foo", 1);
--- a/scripts/testfun/speed.m +++ b/scripts/testfun/speed.m @@ -25,7 +25,8 @@ ## each @var{n}, an initialization expression (@var{init}) is computed to ## create any data needed for the test. If a second expression (@var{f2}) is ## given then the execution times of the two expressions are compared. When -## called without output arguments the results are displayed graphically. +## called without output arguments the results are printed to stdout and +## displayed graphically. ## ## @table @code ## @item @var{f} @@ -115,7 +116,7 @@ ## ## @example ## @group -## speed ("v = sum (x)", "", [10000, 100000], ... +## speed ("sum (x)", "", [10000, 100000], ... ## "v = 0; for i = 1:length (x), v += x(i); end") ## @end group ## @end example @@ -127,10 +128,10 @@ ## ## @example ## @group -## speed ("v = xcorr (x, n)", "x = rand (128, 1);", 100, -## "v2 = xcorr_orig (x, n)", -100*eps) -## speed ("v = xcorr (x, 15)", "x = rand (20+n, 1);", 100, -## "v2 = xcorr_orig (x, n)", -100*eps) +## speed ("xcorr (x, n)", "x = rand (128, 1);", 100, +## "xcorr_orig (x, n)", -100*eps) +## speed ("xcorr (x, 15)", "x = rand (20+n, 1);", 100, +## "xcorr_orig (x, n)", -100*eps) ## @end group ## @end example ## @@ -191,7 +192,12 @@ __torig = __tnew = zeros (size (__test_n)); - disp (cstrcat ("testing ", __f1, "\ninit: ", __init)); + ## Print and plot the data if no output is requested. + do_display = (nargout == 0); + + if (do_display) + disp (cstrcat ("testing ", __f1, "\ninit: ", __init)); + endif ## Make sure the functions are freshly loaded by evaluating them at ## test_n(1); first have to initialize the args though. @@ -208,8 +214,10 @@ n = __test_n(k); eval (cstrcat (__init, ";")); - printf ("n%i = %i ",k, n); - fflush (stdout); + if (do_display) + printf ("n%i = %i ",k, n); + fflush (stdout); + endif eval (cstrcat ("__t = time();", __f1, "; __v1=ans; __t = time()-__t;")); if (__t < 0.25) eval (cstrcat ("__t2 = time();", __f1, "; __t2 = time()-__t2;")); @@ -251,14 +259,12 @@ __order.a = exp (p(2)); endif - ## Plot the data if no output is requested. - doplot = (nargout == 0); - - if (doplot) + if (do_display) figure; endif - if (doplot && ! isempty (__f2)) + if (do_display && ! isempty (__f2)) + subplot (1, 2, 1); semilogx (__test_n, __torig./__tnew, cstrcat ("-*r;", strrep (__f1, ";", "."), "/", @@ -284,7 +290,7 @@ printf ("\n\nMean runtime ratio = %.3g for '%s' vs '%s'\n", ratio, __f2, __f1); - elseif (doplot) + elseif (do_display) loglog (__test_n, __tnew*1000, "*-g;execution time;"); xlabel ("test length"); @@ -293,7 +299,7 @@ endif - if (doplot) + if (do_display) ## Plot time complexity approximation (using milliseconds). order = sprintf ("O(n^%g)", round (10*p(1))/10); @@ -314,10 +320,12 @@ time = sprintf ("%g ns", dt*1e9); endif - ## Display nicely formatted complexity. - printf ("\nFor %s:\n", __f1); - printf (" asymptotic power: %s\n", order); - printf (" approximate time per operation: %s\n", time); + if (do_display) + ## Display nicely formatted complexity. + printf ("\nFor %s:\n", __f1); + printf (" asymptotic power: %s\n", order); + printf (" approximate time per operation: %s\n", time); + endif endif @@ -378,3 +386,30 @@ %! disp("This time, the for loop is done away with entirely."); %! disp("Notice how much bigger the speedup is than in example 1."); %! endif + +%!error speed (); +%!error speed (1, 2, 3, 4, 5, 6, 7); + +%!test +%! [order, n, T_f1, T_f2] = speed ("airy (x)", "x = rand (n, 10)", [100, 1000]); +%! assert (isstruct (order)); +%! assert (size (order), [1, 1]); +%! assert (fieldnames (order), {"p"; "a"}); +%! assert (isnumeric (n)); +%! assert (size (n), [1, 15]); +%! assert (isnumeric (T_f1)); +%! assert (size (T_f1), [1, 15]); +%! assert (isnumeric (T_f1)); +%! assert (size (T_f2), [1, 15]); + +%!test +%! [order, n, T_f1, T_f2] = speed ("sum (x)", "", [100, 1000], "v = 0; for i = 1:length (x), v += x(i); end"); +%! assert (isstruct (order)); +%! assert (size (order), [1, 1]); +%! assert (fieldnames (order), {"p"; "a"}); +%! assert (isnumeric (n)); +%! assert (size (n), [1, 15]); +%! assert (isnumeric (T_f1)); +%! assert (size (T_f1), [1, 15]); +%! assert (isnumeric (T_f1)); +%! assert (size (T_f2), [1, 15]);
--- a/scripts/time/datetick.m +++ b/scripts/time/datetick.m @@ -67,6 +67,9 @@ %! datetick(2,'keepticks') %! set(ax,'ytick',12:16) +## Remove from test statistics. No real tests possible. +%!assert (1) + function __datetick__ (varargin) keeplimits = false;
--- a/src/DLD-FUNCTIONS/__magick_read__.cc +++ b/src/DLD-FUNCTIONS/__magick_read__.cc @@ -670,8 +670,7 @@ octave_idx_type rows = m.rows (); octave_idx_type columns = m.columns (); - // FIXME -- maybe simply using bit shifting would be better? - unsigned int div_factor = pow (2.0, static_cast<int> (bitdepth)) - 1; + unsigned int div_factor = (1 << bitdepth) - 1; for (unsigned int ii = 0; ii < nframes; ii++) { @@ -760,7 +759,7 @@ } im.quantizeColorSpace (Magick::GRAYColorspace); - im.quantizeColors (pow (2, bitdepth)); + im.quantizeColors (1 << bitdepth); im.quantize (); }
--- a/src/DLD-FUNCTIONS/bsxfun.cc +++ b/src/DLD-FUNCTIONS/bsxfun.cc @@ -769,4 +769,45 @@ %!assert (bsxfun (@max, a, b), max (aa, bb)); %!assert (bsxfun (@and, a > 0, b > 0), (aa > 0) & (bb > 0)); %!assert (bsxfun (@or, a > 0, b > 0), (aa > 0) | (bb > 0)); + +%% Test automatic bsxfun +% +%!test +%! funs = {@plus, @minus, @times, @rdivide, @ldivide, @power, @max, @min, \ +%! @rem, @mod, @atan2, @hypot, @eq, @ne, @lt, @le, @gt, @ge, \ +%! @and, @or, @xor }; +%! +%! float_types = {@single, @double}; +%! int_types = {@int8, @int16, @int32, @int64, \ +%! @uint8, @uint16, @uint32, @uint64}; +%! +%! x = rand (3)*10-5; +%! y = rand (3,1)*10-5; +%! +%! for i=1:length (funs) +%! for j = 1:length(float_types) +%! for k = 1:length(int_types) +%! +%! fun = funs{i}; +%! f_type = float_types{j}; +%! i_type = int_types{k}; +%! +%! assert (bsxfun (fun, f_type (x), i_type (y)), \ +%! fun (f_type(x), i_type (y))); +%! assert (bsxfun (fun, f_type (y), i_type (x)), \ +%! fun (f_type(y), i_type (x))); +%! +%! assert (bsxfun (fun, i_type (x), i_type (y)), \ +%! fun (i_type (x), i_type (y))); +%! assert (bsxfun (fun, i_type (y), i_type (x)), \ +%! fun (i_type (y), i_type (x))); +%! +%! assert (bsxfun (fun, f_type (x), f_type (y)), \ +%! fun (f_type (x), f_type (y))); +%! assert (bsxfun (fun, f_type(y), f_type(x)), \ +%! fun (f_type (y), f_type (x))); +%! endfor +%! endfor +%! endfor +%! */
--- a/src/DLD-FUNCTIONS/config-module.awk +++ b/src/DLD-FUNCTIONS/config-module.awk @@ -1,4 +1,7 @@ BEGIN { + FS = "|"; + nfiles = 0; + print "## DO NOT EDIT -- generated from module-files by config-module.awk"; print "" print "EXTRA_DIST += \\" @@ -6,9 +9,14 @@ print " DLD-FUNCTIONS/config-module.awk \\" print " DLD-FUNCTIONS/module-files" print "" - nfiles = 0; -} { - files[++nfiles] = $1; +} +/^#.*/ { next; } +{ + nfiles++; + files[nfiles] = $1; + cppflags[nfiles] = $2; + ldflags[nfiles] = $3; + libraries[nfiles] = $4; } END { sep = " \\\n"; print "DLD_FUNCTIONS_SRC = \\"; @@ -22,9 +30,9 @@ sep = " \\\n"; print "DLD_FUNCTIONS_LIBS = $(DLD_FUNCTIONS_SRC:.cc=.la)"; print ""; - print "octlib_LTLIBRARIES += $(DLD_FUNCTIONS_LIBS)"; + print "if AMCOND_ENABLE_DYNAMIC_LINKING"; print ""; - print "if AMCOND_ENABLE_DYNAMIC_LINKING"; + print "octlib_LTLIBRARIES += $(DLD_FUNCTIONS_LIBS)"; print ""; print "## Use stamp files to avoid problems with checking timestamps"; print "## of symbolic links"; @@ -41,18 +49,28 @@ print "\t touch $(@F)"; print ""; } + print "else"; + print ""; + print "noinst_LTLIBRARIES = $(DLD_FUNCTIONS_LIBS)"; + print ""; print "endif"; - print ""; for (i = 1; i <= nfiles; i++) { basename = files[i]; sub (/\.cc$/, "", basename); + print ""; printf ("DLD_FUNCTIONS_%s_la_SOURCES = DLD-FUNCTIONS/%s\n", basename, files[i]); - printf ("DLD_FUNCTIONS_%s_la_LDFLAGS = @NO_UNDEFINED_LDFLAG@ -module\n", - basename); - printf ("DLD_FUNCTIONS_%s_la_LIBADD = $(OCT_LINK_DEPS)\n", basename); + if (cppflags[i]) + { + printf ("DLD-FUNCTIONS/%s.df: CPPFLAGS += %s\n", + basename, cppflags[i]); + printf ("DLD_FUNCTIONS_%s_la_CPPFLAGS = $(AM_CPPFLAGS) %s\n", + basename, cppflags[i]); + } + printf ("DLD_FUNCTIONS_%s_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED_LDFLAG) %s $(OCT_LINK_OPTS)\n", + basename, ldflags[i]); + printf ("DLD_FUNCTIONS_%s_la_LIBADD = liboctinterp.la ../liboctave/liboctave.la ../libcruft/libcruft.la %s $(OCT_LINK_DEPS)\n", + basename, libraries[i]); } - print ""; - }
--- a/src/DLD-FUNCTIONS/luinc.cc +++ b/src/DLD-FUNCTIONS/luinc.cc @@ -110,7 +110,7 @@ bool udiag = false; Matrix thresh; double droptol = -1.; - bool vecout; + bool vecout = false; if (args(1).is_string ()) { @@ -236,7 +236,7 @@ if (vecout) retval(2) = fact.Pr_vec (); else - retval(2) = fact.Pr (); + retval(2) = fact.Pr_mat (); retval(1) = octave_value (fact.U (), MatrixType (MatrixType::Upper)); retval(0) = octave_value (fact.L (), @@ -260,8 +260,8 @@ } else { - retval(3) = fact.Pc (); - retval(2) = fact.Pr (); + retval(3) = fact.Pc_mat (); + retval(2) = fact.Pr_mat (); } retval(1) = octave_value (fact.U (), MatrixType (MatrixType::Upper)); @@ -319,7 +319,7 @@ if (vecout) retval(2) = fact.Pr_vec (); else - retval(2) = fact.Pr (); + retval(2) = fact.Pr_mat (); retval(1) = octave_value (fact.U (), MatrixType (MatrixType::Upper)); retval(0) = octave_value (fact.L (), @@ -343,8 +343,8 @@ } else { - retval(3) = fact.Pc (); - retval(2) = fact.Pr (); + retval(3) = fact.Pc_mat (); + retval(2) = fact.Pr_mat (); } retval(1) = octave_value (fact.U (), MatrixType (MatrixType::Upper));
--- a/src/DLD-FUNCTIONS/module-files +++ b/src/DLD-FUNCTIONS/module-files @@ -1,40 +1,41 @@ +# FILE|CPPFLAGS|LDFLAGS|LIBRARIES __contourc__.cc -__delaunayn__.cc +__delaunayn__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS) __dispatch__.cc __dsearchn__.cc -__fltk_uigetfile__.cc -__glpk__.cc -__init_fltk__.cc +__fltk_uigetfile__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS) +__glpk__.cc|$(GLPK_CPPFLAGS)|$(GLPK_LDFLAGS)|$(GLPK_LIBS) +__init_fltk__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS) __lin_interpn__.cc -__magick_read__.cc +__magick_read__.cc|$(MAGICK_CPPFLAGS)|$(MAGICK_LDFLAGS)|$(MAGICK_LIBS) __pchip_deriv__.cc __qp__.cc -__voronoi__.cc -amd.cc +__voronoi__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS) +amd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) balance.cc besselj.cc betainc.cc bsxfun.cc -ccolamd.cc +ccolamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) cellfun.cc -chol.cc -colamd.cc +chol.cc|$(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(QRUPDATE_LDFLAGS) $(SPARSE_XLDFLAGS)|$(QRUPDATE_LIBS) $(SPARSE_XLIBS) +colamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) colloc.cc conv2.cc -convhulln.cc +convhulln.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS) daspk.cc dasrt.cc dassl.cc det.cc dlmread.cc -dmperm.cc +dmperm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) dot.cc eig.cc -eigs.cc -fft.cc -fft2.cc -fftn.cc -fftw.cc +eigs.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS) +fft.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS) +fft2.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS) +fftn.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS) +fftw.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS) filter.cc find.cc gammainc.cc @@ -58,13 +59,13 @@ nproc.cc onCleanup.cc pinv.cc -qr.cc +qr.cc|$(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(QRUPDATE_LDFLAGS) $(SPARSE_XLDFLAGS)|$(QRUPDATE_LIBS) $(SPARSE_XLIBS) quad.cc quadcc.cc -qz.cc +qz.cc|||$(LAPACK_LIBS) $(BLAS_LIBS) rand.cc rcond.cc -regexp.cc +regexp.cc|$(REGEX_CPPFLAGS)|$(REGEX_LDFLAGS)|$(REGEX_LIBS) schur.cc spparms.cc sqrtm.cc @@ -73,10 +74,10 @@ sub2ind.cc svd.cc syl.cc -symbfact.cc -symrcm.cc +symbfact.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) +symrcm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS) time.cc tril.cc tsearch.cc typecast.cc -urlwrite.cc +urlwrite.cc|$(CURL_CPPFLAGS)|$(CURL_LDFLAGS)|$(CURL_LIBS)
--- a/src/DLD-FUNCTIONS/onCleanup.cc +++ b/src/DLD-FUNCTIONS/onCleanup.cc @@ -274,3 +274,19 @@ return retval; } + +/* + +%!test +%! old_wstate = warning ("query"); +%! unwind_protect +%! trigger = onCleanup (@() warning ("on", "__MY_WARNING__")); +%! warning ("off", "__MY_WARNING__"); +%! assert ((warning ("query", "__MY_WARNING__")).state, "off"); +%! clear trigger +%! assert ((warning ("query", "__MY_WARNING__")).state, "on"); +%! unwind_protect_cleanup +%! warning (old_wstate); +%! end_unwind_protect + +*/
--- a/src/DLD-FUNCTIONS/pinv.cc +++ b/src/DLD-FUNCTIONS/pinv.cc @@ -169,3 +169,23 @@ return retval; } + +/* +%!shared a, b, tol, hitol, d, u, x, y +%! a = reshape (rand*[1:16], 4, 4); ## Rank 2 matrix +%! b = pinv (a); +%! tol = 1e-14; +%! hitol = 15*sqrt(eps); +%! d = diag ([rand, rand, hitol, hitol]); +%! u = rand (4); ## Could be singular by freak accident +%! x = inv (u)*d*u; +%! y = pinv (x, sqrt(eps)); +%!assert(a*b*a, a, tol); +%!assert(b*a*b, b, tol); +%!assert((b*a)', b*a, tol); +%!assert((a*b)', a*b, tol); +%!assert(x*y*x, x, -hitol); +%!assert(y*x*y, y, -hitol); +%!assert((x*y)', x*y, hitol); +%!assert((y*x)', y*x, hitol); +*/
--- a/src/DLD-FUNCTIONS/qz.cc +++ b/src/DLD-FUNCTIONS/qz.cc @@ -287,6 +287,9 @@ return (fabs (p) >= 1 ? 1 : -1); } + +//FIXME: Matlab does not produce lambda as the first output argument. +// Compatibility problem? DEFUN_DLD (qz, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{lambda} =} qz (@var{A}, @var{B})\n\ @@ -1236,3 +1239,30 @@ return retval; } + +/* +%!shared a, b, c +%! a = [1 2; 0 3]; +%! b = [1 0; 0 0]; +%! c = [0 1; 0 0]; +%!assert(qz (a,b), 1); +%!assert(isempty (qz (a,c))); + +%% Exaple 7.7.3 in Golub & Van Loan +%!test +%! a = [ 10 1 2; +%! 1 2 -1; +%! 1 1 2]; +%! b = reshape(1:9,3,3); +%! [aa, bb, q, z, v, w, lambda] = qz (a, b); +%! sz = length(lambda); +%! observed = (b * v * diag ([lambda;0])) (:, 1:sz); +%! assert ( (a*v) (:, 1:sz), observed, norm (observed) * 1e-14); +%! observed = (diag ([lambda;0]) * w' * b) (1:sz, :); +%! assert ( (w'*a) (1:sz, :) , observed, norm (observed) * 1e-13); +%! assert (q * a * z, aa, norm (aa) * 1e-14); +%! assert (q * b * z, bb, norm (bb) * 1e-14); + +%% FIXME: Still need a test for third form of calling qz + +*/
--- a/src/DLD-FUNCTIONS/rand.cc +++ b/src/DLD-FUNCTIONS/rand.cc @@ -177,7 +177,6 @@ octave_idx_type base = NINTbig (r.base ()); octave_idx_type incr = NINTbig (r.inc ()); - octave_idx_type lim = NINTbig (r.limit ()); for (octave_idx_type i = 0; i < n; i++) {
--- a/src/DLD-FUNCTIONS/spparms.cc +++ b/src/DLD-FUNCTIONS/spparms.cc @@ -136,7 +136,7 @@ { double val = octave_sparse_params::get_key (str); if (xisnan (val)) - error ("spparams: KEY not recognized"); + error ("spparms: KEY not recognized"); else retval (0) = val; } @@ -148,7 +148,7 @@ if (error_state) error ("spparms: input must be a string or a vector"); else if (vals.numel () > OCTAVE_SPARSE_CONTROLS_SIZE) - error ("spparams: too many elements in vector VALS"); + error ("spparms: too many elements in vector VALS"); else octave_sparse_params::set_vals (vals); } @@ -176,3 +176,33 @@ return retval; } + +/* + +%!test +%! old_vals = spparms (); # save state +%! spparms ("defaults"); +%! vals = spparms (); +%! assert (vals, [0 1 1 0 3 3 0.5 1.0 1.0 0.1 0.5 1.0 0.001]'); +%! [keys, vals] = spparms (); +%! assert (rows (keys), 13); +%! assert (keys(2,:), "ths_rel"); +%! assert (vals, [0 1 1 0 3 3 0.5 1.0 1.0 0.1 0.5 1.0 0.001]'); +%! spparms ([3 2 1]); +%! assert (spparms ()(1:3), [3, 2, 1]'); +%! assert (spparms ("ths_rel"), 2); +%! spparms ("exact_d", 5); +%! assert (spparms ("exact_d"), 5); +%! spparms (old_vals); # restore state + +%% Test input validation +%!error (spparms (1, 2, 3)) +%!error ([x, y, z] = spparms ()) +%!error (spparms ("UNKNOWN_KEY")) +%!error (spparms ({1, 2, 3})) +%!error (spparms (ones (14, 1))) +%!error (spparms (1, 1)) +%!error (spparms ("ths_rel", "hello")) +%!error (spparms ("UNKNOWN_KEY", 1)) + +*/
--- a/src/Makefile.am +++ b/src/Makefile.am @@ -480,20 +480,15 @@ include TEMPLATE-INST/module.mk if AMCOND_ENABLE_DYNAMIC_LINKING - DLD_DYNAMIC_SRC = $(DLD_FUNCTIONS_SRC) - DLD_STATIC_SRC = OCT_FILES = $(DLD_FUNCTIONS_LIBS:.la=.oct) OCT_STAMP_FILES = $(subst DLD-FUNCTIONS/,DLD-FUNCTIONS/$(am__leading_dot),$(DLD_FUNCTIONS_LIBS:.la=.oct-stamp)) else - DLD_DYNAMIC_SRC = - DLD_STATIC_SRC = $(DLD_FUNCTIONS_SRC) OCT_FILES = OCT_STAMP_FILES = endif liboctinterp_la_SOURCES = \ $(DIST_SRC) \ - $(DLD_STATIC_SRC) \ $(OPERATORS_SRC) \ $(TEMPLATE_INST_SRC) @@ -508,87 +503,14 @@ version.h \ $(OPT_INC) +liboctinterp_la_CPPFLAGS = @OCTINTERP_DLL_DEFS@ $(AM_CPPFLAGS) -if AMCOND_ENABLE_DYNAMIC_LINKING - OCTAVE_LIBS = \ - ./liboctinterp.la \ - ../liboctave/liboctave.la \ - ../libcruft/libcruft.la \ - ../libcruft/libranlib.la \ - ../libgnu/libgnu.la \ - $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) \ - $(QRUPDATE_LDFLAGS) $(QRUPDATE_LIBS) \ - $(FFTW_XLDFLAGS) $(FFTW_XLIBS) \ - $(LAPACK_LIBS) $(BLAS_LIBS) \ - $(GRAPHICS_LDFLAGS) $(GRAPHICS_LIBS) \ - $(FT2_LDFLAGS) $(FT2_LIBS) \ - $(HDF5_LDFLAGS) $(HDF5_LIBS) $(Z_LDFLAGS) $(Z_LIBS) \ - $(OPENGL_LIBS) $(X11_LIBS) $(CARBON_LIBS) \ - $(READLINE_LIBS) $(TERM_LIBS) \ - $(LIBGLOB) \ - $(REGEX_LDFLAGS) $(REGEX_LIBS) \ - $(LAPACK_LIBS) $(BLAS_LIBS) \ - $(DL_LIBS) $(PTHREAD_LIBS) \ - $(LIBS) \ - $(FLIBS) -else - ## FIXME -- this list is probably not complete now. It may not even - ## be possible to build a statically linked copy of Octave that is - ## fully functional. - OCTAVE_LIBS = \ - ./liboctinterp.la \ - ../liboctave/liboctave.la \ - ../libcruft/libcruft.la \ - ../libcruft/libranlib.la \ - ../libgnu/libgnu.la \ - $(FFTW_XLDFLAGS) $(FFTW_XLIBS) \ - $(QHULL_LDFLAGS) $(QHULL_LIBS) \ - $(QRUPDATE_LDFLAGS) $(QRUPDATE_LIBS) \ - $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) \ - $(REGEX_LDFLAGS) $(REGEX_LIBS) \ - $(CURL_LDFLAGS) $(CURL_LIBS) \ - $(GLPK_LDFLAGS) $(GLPK_LIBS) \ - $(MAGICK_LDFLAGS) $(MAGICK_LIBS) \ - $(GRAPHICS_LDFLAGS) $(GRAPHICS_LIBS) \ - $(FT2_LDFLAGS) $(FT2_LIBS) \ - $(HDF5_LDFLAGS) $(HDF5_LIBS) $(Z_LDFLAGS) $(Z_LIBS) \ - $(OPENGL_LIBS) $(X11_LIBS) $(CARBON_LIBS) \ - $(READLINE_LIBS) $(TERM_LIBS) \ - $(LIBGLOB) \ - $(LAPACK_LIBS) $(BLAS_LIBS) \ - $(DL_LIBS) $(PTHREAD_LIBS) \ - $(LIBS) \ - $(FLIBS) -endif +include link-deps.mk -OCTINTERP_LINK_DEPS = \ - $(RLD_FLAG) \ +liboctinterp_la_LIBADD = \ ../liboctave/liboctave.la \ ../libcruft/libcruft.la \ - ../libcruft/libranlib.la \ - ../libgnu/libgnu.la \ - $(FFTW_XLDFLAGS) $(FFTW_XLIBS) \ - $(FT2_LDFLAGS) $(FT2_LIBS) \ - $(HDF5_LDFLAGS) $(HDF5_LIBS) $(Z_LDFLAGS) $(Z_LIBS) \ - $(OPENGL_LIBS) $(X11_LIBS) $(CARBON_LIBS) \ - $(READLINE_LIBS) $(TERM_LIBS) \ - $(LIBGLOB) \ - $(LAPACK_LIBS) $(BLAS_LIBS) \ - $(LIBS) \ - $(FLIBS) - -liboctinterp_la_LIBADD = $(OCTINTERP_LINK_DEPS) - -## Additional library dependencies used by module.mk files -OCT_LINK_DEPS = \ - $(RLD_FLAG) $(LDFLAGS) \ - ./liboctinterp.la \ - ../liboctave/liboctave.la \ - ../libcruft/libcruft.la \ - ../libcruft/libranlib.la \ - ../libgnu/libgnu.la - -liboctinterp_la_CPPFLAGS = @OCTINTERP_DLL_DEFS@ $(AM_CPPFLAGS) + $(LIBOCTINTERP_LINK_DEPS) # Increment these as needed and according to the rules in the libtool manual: liboctinterp_current = 0 @@ -600,120 +522,39 @@ liboctinterp_la_LDFLAGS = \ -version-info $(liboctinterp_version_info) \ $(NO_UNDEFINED_LDFLAG) \ - -bindir $(bindir) + -bindir $(bindir) \ + $(LIBOCTINTERP_LINK_OPTS) display.df display.lo: CPPFLAGS += $(X11_FLAGS) -DLD-FUNCTIONS/__magick_read__.df: CPPFLAGS += $(MAGICK_CPPFLAGS) -DLD_FUNCTIONS___magick_read___la_CPPFLAGS = $(AM_CPPFLAGS) $(MAGICK_CPPFLAGS) -DLD_FUNCTIONS___magick_read___la_LIBADD += $(MAGICK_LDFLAGS) $(MAGICK_LIBS) - -DLD-FUNCTIONS/convhulln.df: CPPFLAGS += $(QHULL_CPPFLAGS) -DLD_FUNCTIONS_convhulln_la_CPPFLAGS = $(AM_CPPFLAGS) $(QHULL_CPPFLAGS) -DLD_FUNCTIONS_convhulln_la_LIBADD += $(QHULL_LDFLAGS) $(QHULL_LIBS) - -DLD-FUNCTIONS/__delaunayn__.df: CPPFLAGS += $(QHULL_CPPFLAGS) -DLD_FUNCTIONS___delaunayn___la_CPPFLAGS = $(AM_CPPFLAGS) $(QHULL_CPPFLAGS) -DLD_FUNCTIONS___delaunayn___la_LIBADD += $(QHULL_LDFLAGS) $(QHULL_LIBS) - -DLD-FUNCTIONS/__voronoi__.df: CPPFLAGS += $(QHULL_CPPFLAGS) -DLD_FUNCTIONS___voronoi___la_CPPFLAGS = $(AM_CPPFLAGS) $(QHULL_CPPFLAGS) -DLD_FUNCTIONS___voronoi___la_LIBADD += $(QHULL_LDFLAGS) $(QHULL_LIBS) - -DLD-FUNCTIONS/eigs.df: CPPFLAGS += $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_eigs_la_CPPFLAGS = $(AM_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_eigs_la_LIBADD += $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS) - -#DLD-FUNCTIONS/qz.df DLD-FUNCTIONS/qz.lo: -DLD_FUNCTIONS_qz_la_LIBADD += $(LAPACK_LIBS) $(BLAS_LIBS) - -DLD-FUNCTIONS/qr.df: CPPFLAGS += $(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_qr_la_CPPFLAGS = $(AM_CPPFLAGS) $(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_qr_la_LIBADD += $(QRUPDATE_LDFLAGS) $(QRUPDATE_LIBS) $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/chol.df: CPPFLAGS += $(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_chol_la_CPPFLAGS = $(AM_CPPFLAGS) $(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_chol_la_LIBADD += $(QRUPDATE_LDFLAGS) $(QRUPDATE_LIBS) $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/regexp.df: CPPFLAGS += $(REGEX_CPPFLAGS) -DLD_FUNCTIONS_regexp_la_CPPFLAGS = $(AM_CPPFLAGS) $(REGEX_CPPFLAGS) -DLD_FUNCTIONS_regexp_la_LIBADD += $(REGEX_LDFLAGS) $(REGEX_LIBS) - -DLD-FUNCTIONS/urlwrite.df: CPPFLAGS += $(CURL_CPPFLAGS) -DLD_FUNCTIONS_urlwrite_la_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CPPFLAGS) -DLD_FUNCTIONS_urlwrite_la_LIBADD += $(CURL_LDFLAGS) $(CURL_LIBS) - -DLD-FUNCTIONS/__fltk_uigetfile__.df: CPPFLAGS += $(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS) -DLD_FUNCTIONS___fltk_uigetfile___la_CPPFLAGS = $(AM_CPPFLAGS) $(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS) -DLD_FUNCTIONS___fltk_uigetfile___la_LIBADD += $(GRAPHICS_LDFLAGS) $(GRAPHICS_LIBS) $(FT2_LDFLAGS) $(FT2_LIBS) - -DLD-FUNCTIONS/__glpk__.df: CPPFLAGS += $(GLPK_CPPFLAGS) -DLD_FUNCTIONS___glpk___la_CPPFLAGS = $(AM_CPPFLAGS) $(GLPK_CPPFLAGS) -DLD_FUNCTIONS___glpk___la_LIBADD += $(GLPK_LDFLAGS) $(GLPK_LIBS) - -DLD-FUNCTIONS/__init_fltk__.df: CPPFLAGS += $(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS) -DLD_FUNCTIONS___init_fltk___la_CPPFLAGS = $(AM_CPPFLAGS) $(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS) -DLD_FUNCTIONS___init_fltk___la_LIBADD += $(GRAPHICS_LDFLAGS) $(GRAPHICS_LIBS) $(FT2_LDFLAGS) $(FT2_LIBS) - -DLD-FUNCTIONS/amd.df: CPPFLAGS += $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_amd_la_CPPFLAGS = $(AM_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_amd_la_LIBADD += $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/colamd.df: CPPFLAGS += $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_colamd_la_CPPFLAGS = $(AM_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_colamd_la_LIBADD += $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/ccolamd.df: CPPFLAGS += $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_ccolamd_la_CPPFLAGS = $(AM_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_ccolamd_la_LIBADD += $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/symbfact.df: CPPFLAGS += $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_symbfact_la_CPPFLAGS = $(AM_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_symbfact_la_LIBADD += $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/dmperm.df: CPPFLAGS += $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_dmperm_la_CPPFLAGS = $(AM_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_dmperm_la_LIBADD += $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/symrcm.df: CPPFLAGS += $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_symrcm_la_CPPFLAGS = $(AM_CPPFLAGS) $(SPARSE_XCPPFLAGS) -DLD_FUNCTIONS_symrcm_la_LIBADD += $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) - -DLD-FUNCTIONS/fft.df: CPPFLAGS += $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fft_la_CPPFLAGS = $(AM_CPPFLAGS) $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fft_la_LIBADD += $(FFTW_XLDFLAGS) $(FFTW_XLIBS) - -DLD-FUNCTIONS/fft2.df: CPPFLAGS += $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fft2_la_CPPFLAGS = $(AM_CPPFLAGS) $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fft2_la_LIBADD += $(FFTW_XLDFLAGS) $(FFTW_XLIBS) - -DLD-FUNCTIONS/fftn.df: CPPFLAGS += $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fftn_la_CPPFLAGS = $(AM_CPPFLAGS) $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fftn_la_LIBADD += $(FFTW_XLDFLAGS) $(FFTW_XLIBS) - -DLD-FUNCTIONS/fftw.df: CPPFLAGS += $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fftw_la_CPPFLAGS = $(AM_CPPFLAGS) $(FFTW_XCPPFLAGS) -DLD_FUNCTIONS_fftw_la_LIBADD += $(FFTW_XLDFLAGS) $(FFTW_XLIBS) - - octave_SOURCES = main.c -octave_LDADD = $(OCTAVE_LIBS) +octave_LDADD = \ + liboctinterp.la \ + ../liboctave/liboctave.la \ + ../libcruft/libcruft.la \ + $(OCTAVE_LINK_DEPS) +octave_LDFLAGS = \ + $(NO_UNDEFINED_LDFLAG) \ + $(OCTAVE_LINK_OPTS) ## Section for defining and creating DEF_FILES SRC_DEF_FILES := $(shell $(srcdir)/find-defun-files.sh "$(srcdir)" $(DIST_SRC)) -DLD_STATIC_DEF_FILES = $(DLD_STATIC_SRC:.cc=.df) -DLD_DYNAMIC_DEF_FILES = $(DLD_DYNAMIC_SRC:.cc=.df) +DLD_FUNCTIONS_DEF_FILES = $(DLD_FUNCTIONS_SRC:.cc=.df) ## builtins.cc depends on $(DEF_FILES), so DEF_FILES should only include ## .df files that correspond to sources included in liboctave. -DEF_FILES = $(SRC_DEF_FILES) $(DLD_STATIC_DEF_FILES) +if AMCOND_ENABLE_DYNAMIC_LINKING + DEF_FILES = $(SRC_DEF_FILES) +else + DEF_FILES = $(SRC_DEF_FILES) $(DLD_FUNCTIONS_DEF_FILES) +endif -ALL_DEF_FILES = $(DEF_FILES) $(DLD_DYNAMIC_DEF_FILES) +ALL_DEF_FILES = $(SRC_DEF_FILES) $(DLD_FUNCTIONS_DEF_FILES) -$(DEF_FILES) $(DYNAMIC_DLD_DEF_FILES): mkdefs Makefile +$(SRC_DEF_FILES): mkdefs Makefile $(DEF_FILES): $(OPT_HANDLERS) $(OPT_INC) @@ -796,9 +637,13 @@ $(OPT_INC) : %.h : %.in $(MAKE) -C $(@D) $(@F) -DLD-FUNCTIONS/PKG_ADD: $(DLD_DYNAMIC_DEF_FILES) mk-pkg-add - $(srcdir)/mk-pkg-add $(DLD_DYNAMIC_DEF_FILES) > $@-t +if AMCOND_ENABLE_DYNAMIC_LINKING +DLD_FUNCTIONS_PKG_ADD_FILE = DLD-FUNCTIONS/PKG_ADD + +DLD-FUNCTIONS/PKG_ADD: $(DLD_FUNCTIONS_DEF_FILES) mk-pkg-add + $(srcdir)/mk-pkg-add $(DLD_FUNCTIONS_DEF_FILES) > $@-t mv $@-t $@ +endif lex.lo lex.o oct-parse.lo oct-parse.o: \ AM_CXXFLAGS := $(filter-out -Wold-style-cast, $(AM_CXXFLAGS)) @@ -830,8 +675,7 @@ gendoc$(BUILD_EXEEXT): gendoc.cc $(BUILD_CXX) $(BUILD_CXXFLAGS) -o $@ $^ $(BUILD_LDFLAGS) - -all-local: $(OCT_STAMP_FILES) DLD-FUNCTIONS/PKG_ADD .DOCSTRINGS +all-local: $(OCT_STAMP_FILES) $(DLD_FUNCTIONS_PKG_ADD_FILE) .DOCSTRINGS if AMCOND_BUILD_COMPILED_AUX_PROGRAMS octave-config.cc: octave-config.cc.in Makefile @@ -884,8 +728,8 @@ if AMCOND_ENABLE_DYNAMIC_LINKING install-oct: $(top_srcdir)/build-aux/mkinstalldirs $(DESTDIR)$(octfiledir) - if [ -n "`cat DLD-FUNCTIONS/PKG_ADD`" ]; then \ - $(INSTALL_DATA) DLD-FUNCTIONS/PKG_ADD $(DESTDIR)$(octfiledir)/PKG_ADD; \ + if [ -n "`cat $(DLD_FUNCTIONS_PKG_ADD_FILE)`" ]; then \ + $(INSTALL_DATA) $(DLD_FUNCTIONS_PKG_ADD_FILE) $(DESTDIR)$(octfiledir)/PKG_ADD; \ fi cd $(DESTDIR)$(octlibdir) && \ for ltlib in $(DLD_FUNCTIONS_LIBS); do \ @@ -913,7 +757,7 @@ CLEANFILES = \ $(bin_SCRIPTS) \ - DLD-FUNCTIONS/PKG_ADD \ + $(DLD_FUNCTIONS_PKG_ADD_FILE) \ doc-files \ gendoc.cc \ gendoc$(BUILD_EXEEXT) \
--- a/src/OPERATORS/op-int.h +++ b/src/OPERATORS/op-int.h @@ -732,7 +732,7 @@ { \ if (is_valid_bsxfun (a_dims, b_dims)) \ { \ - return bsxfun_pow (a, static_cast<T1 ## NDArray> (b)); \ + return bsxfun_pow (a, b); \ } \ else \ { \ @@ -758,7 +758,7 @@ { \ if (is_valid_bsxfun (a_dims, b_dims)) \ { \ - return bsxfun_pow (static_cast<T2 ## NDArray> (a), b); \ + return bsxfun_pow (a, b); \ } \ else \ { \ @@ -784,7 +784,7 @@ { \ if (is_valid_bsxfun (a_dims, b_dims)) \ { \ - return bsxfun_pow (a, static_cast<T1 ## NDArray> (b)); \ + return bsxfun_pow (a, b); \ } \ else \ { \ @@ -810,7 +810,7 @@ { \ if (is_valid_bsxfun (a_dims, b_dims)) \ { \ - return bsxfun_pow (static_cast<T1 ## NDArray> (a), b); \ + return bsxfun_pow (a, b); \ } \ else \ { \
--- a/src/OPERATORS/op-pm-sm.cc +++ b/src/OPERATORS/op-pm-sm.cc @@ -32,6 +32,49 @@ #include "ov-perm.h" #include "ov-re-sparse.h" +#include "ov-bool-sparse.h" + +// Unary permutation ops, some cast to sparse + +//Avoid casting to a full matrix +DEFUNOP_OP (uplus, perm_matrix, /* no-op */) + +// Not calling standard CAST_UNOP_ARG for these next two because a +// dynamic_cast would fail. +DEFUNOP (not, perm_matrix) +{ + // Obviously negation of a permutation matrix destroys sparsity + return octave_value ( ! a.bool_array_value ()); +} + +DEFUNOP (uminus, perm_matrix) +{ + return octave_value ( - a.sparse_matrix_value ()); +} + +// Most other logical operations cast to SparseBoolMatrix +DEFBINOP (eq_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return v1.sparse_bool_matrix_value () == v2.sparse_bool_matrix_value (); +} +DEFBINOP (ne_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return v1.sparse_bool_matrix_value () != v2.sparse_bool_matrix_value (); +} +DEFBINOP (el_and_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return mx_el_and(v1.sparse_bool_matrix_value (), + v2.sparse_bool_matrix_value ()); +} +DEFBINOP (el_or_pm, perm_matrix, perm_matrix) +{ + CAST_BINOP_ARGS (const octave_perm_matrix&, const octave_perm_matrix&); + return mx_el_or(v1.sparse_bool_matrix_value (), + v2.sparse_bool_matrix_value ()); +} // permutation matrix by sparse matrix ops @@ -86,6 +129,11 @@ void install_pm_sm_ops (void) { + INSTALL_UNOP (op_not, octave_perm_matrix, not); + INSTALL_UNOP (op_uplus, octave_perm_matrix, uplus); + INSTALL_UNOP (op_uminus, octave_perm_matrix, uminus); + + INSTALL_BINOP (op_mul, octave_perm_matrix, octave_sparse_matrix, mul_pm_sm); INSTALL_BINOP (op_ldiv, octave_perm_matrix, octave_sparse_matrix, @@ -94,4 +142,9 @@ mul_sm_pm); INSTALL_BINOP (op_div, octave_sparse_matrix, octave_perm_matrix, div_sm_pm); + + INSTALL_BINOP (op_eq, octave_perm_matrix, octave_perm_matrix, eq_pm); + INSTALL_BINOP (op_ne, octave_perm_matrix, octave_perm_matrix, ne_pm); + INSTALL_BINOP (op_el_and, octave_perm_matrix, octave_perm_matrix, el_and_pm); + INSTALL_BINOP (op_el_or, octave_perm_matrix, octave_perm_matrix, el_or_pm); }
--- a/src/data.cc +++ b/src/data.cc @@ -2032,7 +2032,7 @@ \n\ @example\n\ @group\n\ - ndims (ones (4, 1, 2, 1)\n\ + ndims (ones (4, 1, 2, 1))\n\ @result{} 3\n\ @end group\n\ @end example\n\
new file mode 100644 --- /dev/null +++ b/src/link-deps.mk @@ -0,0 +1,38 @@ +include ../liboctave/link-deps.mk + +if AMCOND_ENABLE_DYNAMIC_LINKING + LIBOCTINTERP_LINK_DEPS = +else + LIBOCTINTERP_LINK_DEPS = $(DLD_FUNCTIONS_LIBS) +endif + +LIBOCTINTERP_LINK_DEPS += \ + $(GRAPHICS_LIBS) \ + $(FT2_LIBS) \ + $(HDF5_LIBS) \ + $(Z_LIBS) \ + $(OPENGL_LIBS) \ + $(X11_LIBS) \ + $(CARBON_LIBS) + +LIBOCTINTERP_LINK_OPTS = \ + $(GRAPHICS_LDFLAGS) \ + $(FT2_LDFLAGS) \ + $(HDF5_LDFLAGS) \ + $(Z_LDFLAGS) \ + $(REGEX_LDFLAGS) + +OCT_LINK_DEPS = + +OCT_LINK_OPTS = $(LDFLAGS) + +if AMCOND_LINK_ALL_DEPS + LIBOCTINTERP_LINK_DEPS += $(LIBOCTAVE_LINK_DEPS) + LIBOCTINTERP_LINK_OPTS += $(LIBOCTAVE_LINK_OPTS) + + OCTAVE_LINK_DEPS = $(LIBOCTINTERP_LINK_DEPS) + OCTAVE_LINK_OPTS = $(LIBOCTINTERP_LINK_OPTS) + + OCT_LINK_DEPS += $(LIBOCTINTERP_LINK_DEPS) + OCT_LINK_OPTS += $(LIBOCTINTERP_LINK_OPTS) +endif
--- a/src/load-save.cc +++ b/src/load-save.cc @@ -664,7 +664,8 @@ bool list_only = false; bool verbose = false; - for (i; i < argc; i++) + //for (i; i < argc; i++) + for (; i < argc; i++) { if (argv[i] == "-force" || argv[i] == "-f") {
--- a/src/mappers.cc +++ b/src/mappers.cc @@ -212,7 +212,13 @@ %!assert(arg (single(1)), single(0)); %!assert(arg (single(i)), single(pi/2)); -%!assert(arg (single(-1)), single(pi)); +%!test +%! if (ismac ()) +%! ## Avoid failing for a MacOS feature +%! assert(arg (single(-1)), single(pi), 2*eps(single(1))); +%! else +%! assert(arg (single(-1)), single(pi)); +%! endif %!assert(arg (single(-i)), single(-pi/2)); %!assert(arg (single([1, i; -1, -i])), single([0, pi/2; pi, -pi/2]), 2e1*eps('single'));
--- a/src/mkoctfile.cc.in +++ b/src/mkoctfile.cc.in @@ -219,7 +219,6 @@ vars["DL_LD"] = get_variable ("DL_LD", %OCTAVE_CONF_DL_LD%); vars["DL_LDFLAGS"] = get_variable ("DL_LDFLAGS", %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%); - vars["RLD_FLAG"] = get_variable ("RLD_FLAG", %OCTAVE_CONF_RLD_FLAG%); vars["RDYNAMIC_FLAG"] = get_variable ("RDYNAMIC_FLAG", %OCTAVE_CONF_RDYNAMIC_FLAG%); vars["LIBOCTAVE"] = "-loctave"; vars["LIBOCTINTERP"] = "-loctinterp"; @@ -233,6 +232,10 @@ vars["FFTW3F_LIBS"] = get_variable ("FFTW3F_LIBS", %OCTAVE_CONF_FFTW3F_LIBS%); vars["LIBS"] = get_variable ("LIBS", %OCTAVE_CONF_LIBS%); vars["FLIBS"] = get_variable ("FLIBS", %OCTAVE_CONF_FLIBS%); + vars["OCTAVE_LINK_DEPS"] = get_variable ("FLIBS", %OCTAVE_CONF_OCTAVE_LINK_DEPS%); + vars["OCT_LINK_DEPS"] = get_variable ("FLIBS", %OCTAVE_CONF_OCT_LINK_DEPS%); + vars["FLIBS"] = get_variable ("FLIBS", %OCTAVE_CONF_FLIBS%); + vars["LD_CXX"] = get_variable ("LD_CXX", %OCTAVE_CONF_LD_CXX%); vars["LDFLAGS"] = get_variable ("LDFLAGS", %OCTAVE_CONF_LDFLAGS%); vars["LD_STATIC_FLAG"] = get_variable ("LD_STATIC_FLAG", %OCTAVE_CONF_LD_STATIC_FLAG%); @@ -296,25 +299,30 @@ " -p VAR, --print VAR Print configuration variable VAR. Recognized\n" " variables are:\n" "\n" -" ALL_CFLAGS FLIBS\n" -" ALL_CXXFLAGS FPICFLAG\n" -" ALL_FFLAGS INCFLAGS\n" -" ALL_LDFLAGS LAPACK_LIBS\n" -" BLAS_LIBS LDFLAGS\n" -" CC LD_CXX\n" -" CFLAGS LD_STATIC_FLAG\n" -" CPICFLAG LFLAGS\n" -" CPPFLAGS LIBCRUFT\n" -" CXX LIBOCTAVE\n" -" CXXFLAGS LIBOCTINTERP\n" -" CXXPICFLAG LIBS\n" -" DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS\n" -" DEPEND_FLAGS RDYNAMIC_FLAG\n" -" DL_LD READLINE_LIBS\n" -" DL_LDFLAGS RLD_FLAG\n" -" F77 SED\n" -" FFLAGS XTRA_CFLAGS\n" -" FFTW_LIBS XTRA_CXXFLAGS\n" +" ALL_CFLAGS FLIBS\n" +" ALL_CXXFLAGS FPICFLAG\n" +" ALL_FFLAGS INCFLAGS\n" +" ALL_LDFLAGS LAPACK_LIBS\n" +" BLAS_LIBS LDFLAGS\n" +" CC LD_CXX\n" +" CFLAGS LD_STATIC_FLAG\n" +" CPICFLAG LFLAGS\n" +" CPPFLAGS LIBCRUFT\n" +" CXX LIBOCTAVE\n" +" CXXFLAGS LIBOCTINTERP\n" +" CXXPICFLAG LIBS\n" +" DEPEND_EXTRA_SED_PATTERN OCTAVE_LIBS\n" +" DEPEND_FLAGS OCTAVE_LINK_DEPS\n" +" DL_LD OCTAVE_LINK_OPTS\n" +" DL_LDFLAGS OCT_LINK_DEPS\n" +" EXEEXT OCT_LINK_OPTS\n" +" F77 RDYNAMIC_FLAG\n" +" F77_INTEGER_8_FLAG READLINE_LIBS\n" +" FFLAGS SED\n" +" FFTW3_LDFLAGS XTRA_CFLAGS\n" +" FFTW3_LIBS XTRA_CXXFLAGS\n" +" FFTW3F_LDFLAGS\n" +" FFTW3F_LIBS\n" "\n" " --link-stand-alone Link a stand-alone executable file.\n" "\n" @@ -742,11 +750,10 @@ + vars["ALL_CXXFLAGS"] + " " + vars["RDYNAMIC_FLAG"] + " " + vars["ALL_LDFLAGS"] + " " + pass_on_options + " " + output_option + " " + objfiles + " " + libfiles - + " " + ldflags + " " + vars["LFLAGS"] + " " - + vars["RLD_FLAG"] + " " + vars["OCTAVE_LIBS"] + " " - + vars["LAPACK_LIBS"] + " " + vars["BLAS_LIBS"] + " " - + vars["FFTW_LIBS"] + " " + vars["READLINE_LIBS"] + " " - + vars["LIBS"] + " " + vars["FLIBS"]; + + " " + ldflags + " " + vars["LFLAGS"] + + " -loctinterp -loctave -lcruft " + + " " + vars["OCT_LINK_OPTS"] + + " " + vars["OCTAVE_LINK_DEPS"]; result = run_command (cmd); } else @@ -758,12 +765,11 @@ } else { - string LINK_DEPS = vars["LFLAGS"] + " " + vars["OCTAVE_LIBS"] - + " " + vars["LDFLAGS"] + " " + vars["BLAS_LIBS"] + " " - + vars["FFTW_LIBS"] + " " + vars["LIBS"] + " " + vars["FLIBS"]; string cmd = vars["DL_LD"] + " " + vars["DL_LDFLAGS"] + " " + pass_on_options + " -o " + octfile + " " + objfiles + " " - + libfiles + " " + ldflags + " " + LINK_DEPS; + + libfiles + " " + ldflags + " " + vars["LFLAGS"] + + " -loctinterp -loctave -lcruft " + + vars["OCT_LINK_OPTS"] + " " + vars["OCT_LINK_DEPS"]; result = run_command (cmd); }
--- a/src/mkoctfile.in +++ b/src/mkoctfile.in @@ -85,7 +85,6 @@ : ${DL_LD=%OCTAVE_CONF_DL_LD%} : ${DL_LDFLAGS=%OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%} -: ${RLD_FLAG=%OCTAVE_CONF_RLD_FLAG%} : ${RDYNAMIC_FLAG=%OCTAVE_CONF_RDYNAMIC_FLAG%} : ${LIBOCTAVE=-loctave} : ${LIBOCTINTERP=-loctinterp} @@ -99,6 +98,10 @@ : ${FFTW3F_LIBS=%OCTAVE_CONF_FFTW3F_LIBS%} : ${LIBS=%OCTAVE_CONF_LIBS%} : ${FLIBS=%OCTAVE_CONF_FLIBS%} +: ${OCTAVE_LINK_DEPS=%OCTAVE_CONF_OCTAVE_LINK_DEPS%} +: ${OCTAVE_LINK_DEPS=%OCTAVE_CONF_OCTAVE_LINK_OPTS%} +: ${OCT_LINK_DEPS=%OCTAVE_CONF_MKOCTFILE_OCT_LINK_DEPS%} +: ${OCT_LINK_DEPS=%OCTAVE_CONF_MKOCTFILE_OCT_LINK_OPTS%} : ${LD_CXX=%OCTAVE_CONF_LD_CXX%} : ${LDFLAGS=%OCTAVE_CONF_LDFLAGS%} : ${LD_STATIC_FLAG=%OCTAVE_CONF_LD_STATIC_FLAG%} @@ -221,7 +224,7 @@ -s, --strip Strip output file. - --mex Create a MEX file. + --mex Create a MEX file. Set the default output extension to ".mex". -o FILE, --output FILE Output file name. Default extension is .oct @@ -231,28 +234,29 @@ -p VAR, --print VAR Print configuration variable VAR. Recognized variables are: - ALL_CFLAGS FFTW3F_LDFLAGS - ALL_CXXFLAGS FFTW3F_LIBS - ALL_FFLAGS FLIBS - ALL_LDFLAGS FPICFLAG - BLAS_LIBS INCFLAGS - CC LAPACK_LIBS - CFLAGS LDFLAGS - CPICFLAG LD_CXX - CPPFLAGS LD_STATIC_FLAG - CXX LFLAGS - CXXFLAGS LIBCRUFT - CXXPICFLAG LIBOCTAVE - DEPEND_EXTRA_SED_PATTERN LIBOCTINTERP - DEPEND_FLAGS LIBS - DL_LD OCTAVE_LIBS - DL_LDFLAGS RDYNAMIC_FLAG - EXEEXT READLINE_LIBS - F77 RLD_FLAG + ALL_CFLAGS FFTW3F_LIBS + ALL_CXXFLAGS FLIBS + ALL_FFLAGS FPICFLAG + ALL_LDFLAGS INCFLAGS + BLAS_LIBS LAPACK_LIBS + CC LDFLAGS + CFLAGS LD_CXX + CPICFLAG LD_STATIC_FLAG + CPPFLAGS LFLAGS + CXX LIBCRUFT + CXXFLAGS LIBOCTAVE + CXXPICFLAG LIBOCTINTERP + DEPEND_EXTRA_SED_PATTERN LIBS + DEPEND_FLAGS OCTAVE_LIBS + DL_LD OCTAVE_LINK_DEPS + DL_LDFLAGS OCT_LINK_DEPS + EXEEXT RDYNAMIC_FLAG + F77 READLINE_LIBS F77_INTEGER_8_FLAG SED FFLAGS XTRA_CFLAGS FFTW3_LDFLAGS XTRA_CXXFLAGS FFTW3_LIBS + FFTW3F_LDFLAGS -v, --verbose Echo commands as they are executed. @@ -529,7 +533,7 @@ if $link && [ -n "$objfiles" ]; then if $link_stand_alone; then if [ -n "$LD_CXX" ]; then - cmd="$LD_CXX $CPPFLAGS $ALL_CXXFLAGS $RDYNAMIC_FLAG $ALL_LDFLAGS $pass_on_options $output_option $objfiles $libfiles $ldflags $LFLAGS $RLD_FLAG $OCTAVE_LIBS $LAPACK_LIBS $BLAS_LIBS $FFTW_LIBS $READLINE_LIBS $LIBS $FLIBS" + cmd="$LD_CXX $CPPFLAGS $ALL_CXXFLAGS $RDYNAMIC_FLAG $ALL_LDFLAGS $pass_on_options $output_option $objfiles $libfiles $ldflags $LFLAGS -loctinterp -loctave -lcruft $OCTAVE_LINK_OPTS $OCTAVE_LINK_DEPS" $dbg $cmd eval $cmd else @@ -537,8 +541,7 @@ exit 1 fi else - LINK_DEPS="$LFLAGS $OCTAVE_LIBS $LDFLAGS $LAPACK_LIBS $BLAS_LIBS $FFTW_LIBS $LIBS $FLIBS" - cmd="$DL_LD $DL_LDFLAGS $pass_on_options -o $octfile $objfiles $libfiles $ldflags $LINK_DEPS" + cmd="$DL_LD $DL_LDFLAGS $pass_on_options -o $octfile $objfiles $libfiles $ldflags $LFLAGS -loctinterp -loctave -lcruft $OCT_LINK_OPTS $OCT_LINK_DEPS" $dbg $cmd eval $cmd fi
--- a/src/oct-conf.h.in +++ b/src/oct-conf.h.in @@ -376,6 +376,14 @@ #define OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS% #endif +#ifndef OCTAVE_CONF_OCTAVE_LINK_DEPS +#define OCTAVE_CONF_OCTAVE_LINK_DEPS %OCTAVE_CONF_OCTAVE_LINK_DEPS% +#endif + +#ifndef OCTAVE_CONF_OCTAVE_LINK_OPTS +#define OCTAVE_CONF_OCTAVE_LINK_OPTS %OCTAVE_CONF_OCTAVE_LINK_OPTS% +#endif + #ifndef OCTAVE_CONF_OCTINCLUDEDIR #define OCTAVE_CONF_OCTINCLUDEDIR %OCTAVE_CONF_OCTINCLUDEDIR% #endif @@ -384,6 +392,14 @@ #define OCTAVE_CONF_OCTLIBDIR %OCTAVE_CONF_OCTLIBDIR% #endif +#ifndef OCTAVE_CONF_OCT_LINK_DEPS +#define OCTAVE_CONF_OCT_LINK_DEPS %OCTAVE_CONF_OCT_LINK_DEPS% +#endif + +#ifndef OCTAVE_CONF_OCT_LINK_OPTS +#define OCTAVE_CONF_OCT_LINK_OPTS %OCTAVE_CONF_OCT_LINK_OPTS% +#endif + #ifndef OCTAVE_CONF_OPENGL_LIBS #define OCTAVE_CONF_OPENGL_LIBS %OCTAVE_CONF_OPENGL_LIBS% #endif @@ -440,10 +456,6 @@ #define OCTAVE_CONF_REGEX_LIBS %OCTAVE_CONF_REGEX_LIBS% #endif -#ifndef OCTAVE_CONF_RLD_FLAG -#define OCTAVE_CONF_RLD_FLAG %OCTAVE_CONF_RLD_FLAG% -#endif - #ifndef OCTAVE_CONF_SED #define OCTAVE_CONF_SED %OCTAVE_CONF_SED% #endif
--- a/src/ov-perm.cc +++ b/src/ov-perm.cc @@ -217,6 +217,12 @@ return SparseMatrix (matrix); } +SparseBoolMatrix +octave_perm_matrix::sparse_bool_matrix_value (bool) const +{ + return SparseBoolMatrix (matrix); +} + SparseComplexMatrix octave_perm_matrix::sparse_complex_matrix_value (bool) const {
--- a/src/ov-perm.h +++ b/src/ov-perm.h @@ -160,6 +160,8 @@ SparseMatrix sparse_matrix_value (bool = false) const; + SparseBoolMatrix sparse_bool_matrix_value (bool = false) const; + SparseComplexMatrix sparse_complex_matrix_value (bool = false) const; int8NDArray
--- a/src/ov-typeinfo.cc +++ b/src/ov-typeinfo.cc @@ -595,7 +595,7 @@ @deftypefnx {Built-in Function} {} typeinfo (@var{expr})\n\ \n\ Return the type of the expression @var{expr}, as a string. If\n\ -@var{expr} is omitted, return an array of strings containing all the\n\ +@var{expr} is omitted, return an cell array of strings containing all the\n\ currently installed data types.\n\ @end deftypefn") { @@ -612,3 +612,74 @@ return retval; } + +/* +%!error typeinfo ("foo", 1); + +%!assert (iscellstr (typeinfo ())); + +%!assert (typeinfo (false), "bool"); +%!assert (typeinfo ([true, false]), "bool matrix"); + +%!assert (typeinfo (1:2), "range"); + +%!assert (typeinfo ("string"), "string"); +%!assert (typeinfo ('string'), "sq_string"); + +%!assert (typeinfo (diag ([1, 2])), "diagonal matrix") +%!assert (typeinfo (diag ([i, 2])), "complex diagonal matrix") +%!assert (typeinfo (single (diag ([1, 2]))), "float diagonal matrix") +%!assert (typeinfo (single (diag ([i, 2]))), "float complex diagonal matrix") +%!assert (typeinfo (diag (single ([1, 2]))), "float diagonal matrix") +%!assert (typeinfo (diag (single ([i, 2]))), "float complex diagonal matrix") + +%!assert (typeinfo ([]), "null_matrix"); +%!assert (typeinfo (""), "null_string"); +%!assert (typeinfo (''), "null_sq_string"); + +%!assert (typeinfo (1), "scalar"); +%!assert (typeinfo (double (1)), "scalar"); +%!assert (typeinfo ([1, 2]), "matrix"); +%!assert (typeinfo (double ([1, 2])), "matrix"); + +%!assert (typeinfo (i), "complex scalar"); +%!assert (typeinfo ([i, 2]), "complex matrix"); + +%!assert (typeinfo (single (1)), "float scalar"); +%!assert (typeinfo (single ([1, 2])), "float matrix"); + +%!assert (typeinfo (single (i)), "float complex scalar"); +%!assert (typeinfo (single ([i, 2])), "float complex matrix"); + +%!assert (typeinfo (sparse (eye (10))), "sparse matrix"); +%!assert (typeinfo (sparse (i * eye (10))), "sparse complex matrix"); +%!assert (typeinfo (logical (sparse (i * eye (10)))), "sparse bool matrix"); + +%!assert (typeinfo (int8 (1)), "int8 scalar"); +%!assert (typeinfo (int16 (1)), "int16 scalar"); +%!assert (typeinfo (int32 (1)), "int32 scalar"); +%!assert (typeinfo (int64 (1)), "int64 scalar"); +%!assert (typeinfo (uint8 (1)), "uint8 scalar"); +%!assert (typeinfo (uint16 (1)), "uint16 scalar"); +%!assert (typeinfo (uint32 (1)), "uint32 scalar"); +%!assert (typeinfo (uint64 (1)), "uint64 scalar"); + +%!test +%! s.a = 1; +%! assert (typeinfo (s), "scalar struct"); + +%!test +%! s(2).a = 1; +%! assert (typeinfo (s), "struct"); + +%!assert (typeinfo ({"cell"}), "cell"); + +%!assert (typeinfo (@sin), "function handle"); +%!assert (typeinfo (@(x) x), "function handle"); + +%!assert (typeinfo (inline ('x^2')), "inline function"); + +%!test +%! [l, u, p] = lu (rand (3)); +%! assert (typeinfo (p), "permutation matrix"); +*/
--- a/src/profiler.cc +++ b/src/profiler.cc @@ -174,7 +174,7 @@ } assert (i == n); - Octave_map retval; + octave_map retval; retval.assign ("Index", rv_indices); retval.assign ("SelfTime", rv_times); @@ -290,37 +290,61 @@ octave_value profile_data_accumulator::get_flat (void) const { + octave_value retval; + const octave_idx_type n = known_functions.size (); flat_profile flat (n); - assert (call_tree); - call_tree->build_flat (flat); - Cell rv_names (n, 1); - Cell rv_times (n, 1); - Cell rv_calls (n, 1); - Cell rv_recursive (n, 1); - Cell rv_parents (n, 1); - Cell rv_children (n, 1); - - for (octave_idx_type i = 0; i != n; ++i) + if (call_tree) { - rv_names(i) = octave_value (known_functions[i]); - rv_times(i) = octave_value (flat[i].time); - rv_calls(i) = octave_value (flat[i].calls); - rv_recursive(i) = octave_value (flat[i].recursive); - rv_parents(i) = stats::function_set_value (flat[i].parents); - rv_children(i) = stats::function_set_value (flat[i].children); - } + call_tree->build_flat (flat); + + Cell rv_names (n, 1); + Cell rv_times (n, 1); + Cell rv_calls (n, 1); + Cell rv_recursive (n, 1); + Cell rv_parents (n, 1); + Cell rv_children (n, 1); + + for (octave_idx_type i = 0; i != n; ++i) + { + rv_names(i) = octave_value (known_functions[i]); + rv_times(i) = octave_value (flat[i].time); + rv_calls(i) = octave_value (flat[i].calls); + rv_recursive(i) = octave_value (flat[i].recursive); + rv_parents(i) = stats::function_set_value (flat[i].parents); + rv_children(i) = stats::function_set_value (flat[i].children); + } + + octave_map m; - Octave_map retval; + m.assign ("FunctionName", rv_names); + m.assign ("TotalTime", rv_times); + m.assign ("NumCalls", rv_calls); + m.assign ("IsRecursive", rv_recursive); + m.assign ("Parents", rv_parents); + m.assign ("Children", rv_children); - retval.assign ("FunctionName", rv_names); - retval.assign ("TotalTime", rv_times); - retval.assign ("NumCalls", rv_calls); - retval.assign ("IsRecursive", rv_recursive); - retval.assign ("Parents", rv_parents); - retval.assign ("Children", rv_children); + retval = m; + } + else + { + static const char *fn[] = + { + "FunctionName", + "TotalTime", + "NumCalls", + "IsRecursive", + "Parents", + "Children", + 0 + }; + + static octave_map m (dim_vector (0, 1), string_vector (fn)); + + retval = m; + } return retval; } @@ -328,8 +352,27 @@ octave_value profile_data_accumulator::get_hierarchical (void) const { - assert (call_tree); - return call_tree->get_hierarchical (); + octave_value retval; + + if (call_tree) + retval = call_tree->get_hierarchical (); + else + { + static const char *fn[] = + { + "Index", + "SelfTime", + "NumCalls", + "Children", + 0 + }; + + static octave_map m (dim_vector (0, 1), string_vector (fn)); + + retval = m; + } + + return retval; } double
old mode 100644 new mode 100755 --- a/src/profiler.h +++ b/src/profiler.h @@ -31,7 +31,7 @@ class octave_value; class -OCTAVE_API +OCTINTERP_API profile_data_accumulator { public: @@ -173,7 +173,7 @@ }; // The instance used. -extern profile_data_accumulator profiler; +extern OCTINTERP_API profile_data_accumulator profiler; // Helper macro to profile a block of code. #define BEGIN_PROFILER_BLOCK(name) \
--- a/src/symtab.cc +++ b/src/symtab.cc @@ -1463,7 +1463,9 @@ { octave_value retval; - if (nargout > 0) + int nargin = args.length (); + + if (nargout > 0 || nargin == 0) { switch (Vignore_function_time_stamp) { @@ -1481,8 +1483,6 @@ } } - int nargin = args.length (); - if (nargin == 1) { std::string sval = args(0).string_value (); @@ -1507,6 +1507,25 @@ return retval; } +/* +%!shared old_state +%! old_state = ignore_function_time_stamp (); +%!test +%! state = ignore_function_time_stamp ("all"); +%! assert (state, old_state); +%! assert (ignore_function_time_stamp (), "all"); +%! state = ignore_function_time_stamp ("system"); +%! assert (state, "all"); +%! assert (ignore_function_time_stamp (), "system"); +%! ignore_function_time_stamp (old_state); + +%% Test input validation +%!error (ignore_function_time_stamp ("all", "all")) +%!error (ignore_function_time_stamp ("UNKNOWN_VALUE")) +%!error (ignore_function_time_stamp (42)) + +*/ + DEFUN (__current_scope__, , , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{scope}, @var{context}]} __dump_symtab_info__ ()\n\
--- a/src/toplev.cc +++ b/src/toplev.cc @@ -1300,6 +1300,10 @@ { false, "MAGICK_LDFLAGS", OCTAVE_CONF_MAGICK_LDFLAGS }, { false, "MAGICK_LIBS", OCTAVE_CONF_MAGICK_LIBS }, { false, "MKOCTFILE_DL_LDFLAGS", OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS }, + { false, "OCTAVE_LINK_DEPS", OCTAVE_CONF_OCTAVE_LINK_DEPS }, + { false, "OCTAVE_LINK_OPTS", OCTAVE_CONF_OCTAVE_LINK_OPTS }, + { false, "OCT_LINK_DEPS", OCTAVE_CONF_OCT_LINK_DEPS }, + { false, "OCT_LINK_OPTS", OCTAVE_CONF_OCT_LINK_OPTS }, { false, "OPENGL_LIBS", OCTAVE_CONF_OPENGL_LIBS }, { false, "PTHREAD_CFLAGS", OCTAVE_CONF_PTHREAD_CFLAGS }, { false, "PTHREAD_LIBS", OCTAVE_CONF_PTHREAD_LIBS }, @@ -1313,7 +1317,6 @@ { false, "RDYNAMIC_FLAG", OCTAVE_CONF_RDYNAMIC_FLAG }, { false, "READLINE_LIBS", OCTAVE_CONF_READLINE_LIBS }, { false, "REGEX_LIBS", OCTAVE_CONF_REGEX_LIBS }, - { false, "RLD_FLAG", OCTAVE_CONF_RLD_FLAG }, { false, "SED", OCTAVE_CONF_SED }, { false, "SHARED_LIBS", OCTAVE_CONF_SHARED_LIBS }, { false, "SHLEXT", OCTAVE_CONF_SHLEXT },
--- a/src/utils.cc +++ b/src/utils.cc @@ -114,6 +114,17 @@ return retval; } +/* +%!error isvarname (); +%!error isvarname ("foo", "bar"); + +%!assert (isvarname ("foo"), true); +%!assert (isvarname ("_foo"), true); +%!assert (isvarname ("_1"), true); +%!assert (isvarname ("1foo"), false); +%!assert (isvarname (""), false); +*/ + // Return TRUE if F and G are both names for the same file. bool @@ -325,6 +336,24 @@ return retval; } +/* +%!error file_in_loadpath (); +%!error file_in_loadpath ("foo", "bar", 1); + +%!test +%! f = file_in_loadpath ("plot.m"); +%! assert (ischar (f)); +%! assert (! isempty (f)); + +%!test +%! f = file_in_loadpath ("$$probably_!!_not_&&_a_!!_file$$"); +%! assert (f, ""); + +%!test +%! lst = file_in_loadpath ("$$probably_!!_not_&&_a_!!_file$$", "all"); +%! assert (lst, {}); +*/ + DEFUN (file_in_path, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} file_in_path (@var{path}, @var{file})\n\ @@ -390,6 +419,25 @@ return retval; } +/* +%!error file_in_path (); +%!error file_in_path ("foo"); +%!error file_in_path ("foo", "bar", "baz", 1); + +%!test +%! f = file_in_path (path (), "plot.m"); +%! assert (ischar (f)); +%! assert (! isempty (f)); + +%!test +%! f = file_in_path (path (), "$$probably_!!_not_&&_a_!!_file$$"); +%! assert (f, ""); + +%!test +%! lst = file_in_path (path (), "$$probably_!!_not_&&_a_!!_file$$", "all"); +%! assert (lst, {}); +*/ + std::string file_in_path (const std::string& name, const std::string& suffix) { @@ -623,6 +671,20 @@ return retval; } +/* +%!error do_string_escapes (); +%!error do_string_escapes ("foo", "bar"); + +%!assert (do_string_escapes ('foo\nbar'), "foo\nbar"); +%!assert (do_string_escapes ("foo\\nbar"), "foo\nbar"); +%!assert (do_string_escapes ("foo\\nbar"), ["foo", char(10), "bar"]); + +%!assert (do_string_escapes ('\a\b\f\n\r\t\v'), "\a\b\f\n\r\t\v"); +%!assert (do_string_escapes ("\\a\\b\\f\\n\\r\\t\\v"), "\a\b\f\n\r\t\v"); +%!assert (do_string_escapes ("\\a\\b\\f\\n\\r\\t\\v"), +%! char ([7, 8, 12, 10, 13, 9, 11])); +*/ + const char * undo_string_escape (char c) { @@ -729,6 +791,20 @@ return retval; } +/* +%!error undo_string_escapes (); +%!error undo_string_escapes ("foo", "bar"); + +%!assert (undo_string_escapes ("foo\nbar"), 'foo\nbar'); +%!assert (undo_string_escapes ("foo\nbar"), "foo\\nbar"); +%!assert (undo_string_escapes (["foo", char(10), "bar"]), "foo\\nbar"); + +%!assert (undo_string_escapes ("\a\b\f\n\r\t\v"), '\a\b\f\n\r\t\v'); +%!assert (undo_string_escapes ("\a\b\f\n\r\t\v"), "\\a\\b\\f\\n\\r\\t\\v"); +%!assert (undo_string_escapes (char ([7, 8, 12, 10, 13, 9, 11])), +%! "\\a\\b\\f\\n\\r\\t\\v"); +*/ + DEFUN (is_absolute_filename, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} is_absolute_filename (@var{file})\n\ @@ -747,6 +823,13 @@ return retval; } +/* +%!error is_absolute_filename (); +%!error is_absolute_filename ("foo", "bar"); + +FIXME -- we need system-dependent tests here. +*/ + DEFUN (is_rooted_relative_filename, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} is_rooted_relative_filename (@var{file})\n\ @@ -765,6 +848,13 @@ return retval; } +/* +%!error is_rooted_relative_filename (); +%!error is_rooted_relative_filename ("foo", "bar"); + +FIXME -- we need system-dependent tests here. +*/ + DEFUN (make_absolute_filename, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} make_absolute_filename (@var{file})\n\ @@ -789,6 +879,13 @@ return retval; } +/* +%!error make_absolute_filename (); +%!error make_absolute_filename ("foo", "bar"); + +FIXME -- we need system-dependent tests here. +*/ + DEFUN (find_dir_in_path, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} find_dir_in_path (@var{dir})\n\ @@ -829,6 +926,13 @@ return retval; } +/* +%!error find_dir_in_path (); +%!error find_dir_in_path ("foo", "bar", 1); + +FIXME -- need to create tests using current path, pathsep, and dirsep. +*/ + DEFUNX ("errno", Ferrno, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{err} =} errno ()\n\ @@ -873,6 +977,21 @@ return retval; } +/* +%!error errno ("foo", 1); + +%!assert (isnumeric (errno ())); + +%!test +%! lst = errno_list (); +%! fns = fieldnames (lst); +%! oldval = errno (fns{1}); +%! assert (isnumeric (oldval)); +%! errno (oldval); +%! newval = errno (); +%! assert (oldval, newval); +*/ + DEFUN (errno_list, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} errno_list ()\n\ @@ -889,6 +1008,12 @@ return retval; } +/* +%!error errno_list ("foo"); + +%!assert (isstruct (errno_list ())); +*/ + static void check_dimensions (octave_idx_type& nr, octave_idx_type& nc, const char *warnfor) { @@ -1352,6 +1477,14 @@ return retval; } +/* +%!error isindex (); + +%!assert (isindex ([1, 2, 3])); +%!assert (isindex (1:3)); +%!assert (isindex ([1, 2, -3]), false); +*/ + octave_value_list do_simple_cellfun (octave_value_list (*fun) (const octave_value_list&, int), const char *fun_name, const octave_value_list& args,
--- a/src/xpow.cc +++ b/src/xpow.cc @@ -2598,8 +2598,21 @@ if (a_dims != b_dims) { - gripe_nonconformant ("operator .^", a_dims, b_dims); - return octave_value (); + if (is_valid_bsxfun (a_dims, b_dims)) + { + //Potentially complex results + FloatNDArray xa = octave_value_extract<FloatNDArray> (a); + FloatNDArray xb = octave_value_extract<FloatNDArray> (b); + if (! xb.all_integers () && xa.any_element_is_negative ()) + return octave_value (bsxfun_pow (FloatComplexNDArray (xa), xb)); + else + return octave_value (bsxfun_pow (xa, xb)); + } + else + { + gripe_nonconformant ("operator .^", a_dims, b_dims); + return octave_value (); + } } int len = a.length (); @@ -2673,8 +2686,15 @@ if (a_dims != b_dims) { - gripe_nonconformant ("operator .^", a_dims, b_dims); - return octave_value (); + if (is_valid_bsxfun (a_dims, b_dims)) + { + return bsxfun_pow (a, b); + } + else + { + gripe_nonconformant ("operator .^", a_dims, b_dims); + return octave_value (); + } } FloatComplexNDArray result (a_dims); @@ -2765,8 +2785,15 @@ if (a_dims != b_dims) { - gripe_nonconformant ("operator .^", a_dims, b_dims); - return octave_value (); + if (is_valid_bsxfun (a_dims, b_dims)) + { + return bsxfun_pow (a, b); + } + else + { + gripe_nonconformant ("operator .^", a_dims, b_dims); + return octave_value (); + } } FloatComplexNDArray result (a_dims); @@ -2808,8 +2835,15 @@ if (a_dims != b_dims) { - gripe_nonconformant ("operator .^", a_dims, b_dims); - return octave_value (); + if (is_valid_bsxfun (a_dims, b_dims)) + { + return bsxfun_pow (a, b); + } + else + { + gripe_nonconformant ("operator .^", a_dims, b_dims); + return octave_value (); + } } FloatComplexNDArray result (a_dims);
--- a/test/fntests.m +++ b/test/fntests.m @@ -91,7 +91,7 @@ if (fid >= 0) str = fread (fid, "*char")'; fclose (fid); - retval = ! isempty (regexp (str, '^%!(test|assert|error|warning)', "lineanchors")); + retval = ! isempty (regexp (str, '^%!(assert|error|fail|test|warning)', "lineanchors")); else error ("fopen failed: %s", f); endif @@ -124,8 +124,8 @@ [p, n, xf, sk] = test (nm(1:(end-2)), "quiet", fid); print_pass_fail (n, p); files_with_tests(end+1) = ffnm; - elseif (has_demos (ffnm)) - files_with_tests(end+1) = ffnm; + ##elseif (has_demos (ffnm)) + ## files_with_tests(end+1) = ffnm; else files_with_no_tests(end+1) = ffnm; endif @@ -177,8 +177,8 @@ dxf += xf; dsk += sk; files_with_tests(end+1) = f; - elseif (has_demos (f)) - files_with_tests(end+1) = f; + ##elseif (has_demos (f)) + ## files_with_tests(end+1) = f; elseif (has_functions (f)) ## To reduce the list length, only mark .cc files that contain ## DEFUN definitions. @@ -215,7 +215,7 @@ n_with = num_elts_matching_pattern (with, pat); n_without = num_elts_matching_pattern (without, pat); n_tot = n_with + n_without; - printf ("\n%d (of %d) %s files have no tests or demos.\n", n_without, n_tot, typ); + printf ("\n%d (of %d) %s files have no tests.\n", n_without, n_tot, typ); endfunction pso = page_screen_output ();