# HG changeset patch # User jwe # Date 909616271 0 # Node ID 3ac3e8edc25850671f1e9becb5051bbb08936424 # Parent 7a5a5da64756e676655bc655928a31bdce8859a0 [project @ 1998-10-28 23:04:39 by jwe] diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -1,6 +1,21 @@ Summary of changes for version 2.1.x: ------------------------------------ + * The built-in variable argv is now a list of strings instead of a + string vector. + + * The value of LOADPATH set by the environment variable + OCTAVE_PATH, the -p or --path command line options, or on the + command line is no longer modified to include the default path. + Instead it is left as specified. Its default value is now ":", + which tells Octave to search the default path, and the new + built-in variable DEFAULT_LOADPATH contains the default list of + directories to search. + + * The function file_in_path no longer does any special processing of + its PATH argument. To search LOADPATH for files, it is now + generally better to use the new function file_in_loadpath. + * If fread is given a skip parameter, the skip is performed after the read instead of before (for compatibility with Matlab). diff --git a/doc/interpreter/basics.texi b/doc/interpreter/basics.texi --- a/doc/interpreter/basics.texi +++ b/doc/interpreter/basics.texi @@ -198,7 +198,7 @@ @end example @noindent -@code{argv} would be a string vector with the elements +@code{argv} would be a list of strings with the elements @code{--no-line-editing} and @code{--silent}. If you write an executable Octave script, @code{argv} will contain the @@ -229,7 +229,7 @@ @example printf ("%s", program_name); for i = 1:nargin - printf (" %s", argv(i,:)); + printf (" %s", argv(i)); endfor printf ("\n"); @end example diff --git a/doc/interpreter/linalg.texi b/doc/interpreter/linalg.texi --- a/doc/interpreter/linalg.texi +++ b/doc/interpreter/linalg.texi @@ -380,6 +380,102 @@ @code{span (a)}. @end deftypefn + +@deftypefn {Function File} {@var{lambda} =} qz (@var{a}, @var{b}) +Generalized eigenvalue problem @math{A x = s B x}, +@var{QZ} decomposition. Three ways to call: +@enumerate +@item @code{lambda = qz(A,B)} + +Computes the generalized eigenvalues @var{lambda} of @math{(A - sB)}. + +@item @code{[AA, BB, Q, Z @{, V, W, lambda@}] = qz (A, B)} + +Computes qz decomposition, generalized eigenvectors, and + generalized eigenvalues of @math{(A - sB)} +@example +@group + A V = B V diag(lambda) + W' A = diag(lambda) W' B + AA = Q'*A*Z, BB = Q'*B*Z with Q, Z orthogonal (unitary)= I +@end group +@end example + +@item @code{[AA,BB,Z@{,lambda@}] = qz(A,B,opt)} + +As in form [2], but allows ordering of generalized eigenpairs + for (e.g.) solution of discrete time algebraic Riccati equations. + Form 3 is not available for complex matrices and does not compute + the generalized eigenvectors V, W, nor the orthogonal matrix Q. +@table @var +@item opt + for ordering eigenvalues of the GEP pencil. The leading block + of the revised pencil contains all eigenvalues that satisfy: +@table @code +@item "N" + = unordered (default) + +@item "S" += small: leading block has all |lambda| <=1 + +@item "B" + = big: leading block has all |lambda >= 1 + +@item "-" + = negative real part: leading block has all eigenvalues + in the open left half-plant + +@item "+" + = nonnegative real part: leading block has all eigenvalues + in the closed right half-plane +@end table +@end table +@end enumerate + +Note: qz performs permutation balancing, but not scaling (see balance). + Order of output arguments was selected for compatibility with MATLAB + +See also: balance, dare, eig, schur +@end deftypefn + +@deftypefn {Function File} {[@var{aa}, @var{bb}, @var{q}, @var{z}] =} qzhess (@var{a}, @var{b}) +Compute the Hessenberg-triangular decomposition of the matrix pencil +@code{(@var{a}, @var{b})}, returning +@code{@var{aa} = @var{q} * @var{a} * @var{z}}, +@code{@var{bb} = @var{q} * @var{b} * @var{z}}, with @var{q} and @var{z} +orthogonal. For example, + +@example +@group +[aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8]) + @result{} aa = [ -3.02244, -4.41741; 0.92998, 0.69749 ] + @result{} bb = [ -8.60233, -9.99730; 0.00000, -0.23250 ] + @result{} q = [ -0.58124, -0.81373; -0.81373, 0.58124 ] + @result{} z = [ 1, 0; 0, 1 ] +@end group +@end example + +The Hessenberg-triangular decomposition is the first step in +Moler and Stewart's QZ decomposition algorithm. + +Algorithm taken from Golub and Van Loan, @cite{Matrix Computations, 2nd +edition}. +@end deftypefn + +@deftypefn {Loadable Function} {} qzval (@var{a}, @var{b}) +Compute generalized eigenvalues of the matrix pencil +@iftex +@tex +$a - \lambda b$. +@end tex +@end iftex +@ifinfo +@code{@var{a} - lambda @var{b}}. +@end ifinfo + +The arguments @var{a} and @var{b} must be real matrices. +@end deftypefn + @deftypefn {Loadable Function} {@var{s} =} schur (@var{a}) @deftypefnx {Loadable Function} {[@var{u}, @var{s}] =} schur (@var{a}, @var{opt}) @cindex Schur decomposition @@ -784,44 +880,6 @@ @end example @end deftypefn -@deftypefn {Function File} {[@var{aa}, @var{bb}, @var{q}, @var{z}] =} qzhess (@var{a}, @var{b}) -Compute the Hessenberg-triangular decomposition of the matrix pencil -@code{(@var{a}, @var{b})}, returning -@code{@var{aa} = @var{q} * @var{a} * @var{z}}, -@code{@var{bb} = @var{q} * @var{b} * @var{z}}, with @var{q} and @var{z} -orthogonal. For example, - -@example -@group -[aa, bb, q, z] = qzhess ([1, 2; 3, 4], [5, 6; 7, 8]) - @result{} aa = [ -3.02244, -4.41741; 0.92998, 0.69749 ] - @result{} bb = [ -8.60233, -9.99730; 0.00000, -0.23250 ] - @result{} q = [ -0.58124, -0.81373; -0.81373, 0.58124 ] - @result{} z = [ 1, 0; 0, 1 ] -@end group -@end example - -The Hessenberg-triangular decomposition is the first step in -Moler and Stewart's QZ decomposition algorithm. - -Algorithm taken from Golub and Van Loan, @cite{Matrix Computations, 2nd -edition}. -@end deftypefn - -@deftypefn {Loadable Function} {} qzval (@var{a}, @var{b}) -Compute generalized eigenvalues of the matrix pencil -@iftex -@tex -$a - \lambda b$. -@end tex -@end iftex -@ifinfo -@code{@var{a} - lambda @var{b}}. -@end ifinfo - -The arguments @var{a} and @var{b} must be real matrices. -@end deftypefn - @deftypefn {Loadable Function} {@var{x} =} syl (@var{a}, @var{b}, @var{c}) Solve the Sylvester equation @iftex diff --git a/kpathsea/ChangeLog b/kpathsea/ChangeLog --- a/kpathsea/ChangeLog +++ b/kpathsea/ChangeLog @@ -1,3 +1,8 @@ +Fri Oct 23 22:05:46 1998 John W. Eaton + + * kdefault.c (kpse_expand_default): Always return newly allocated + storage. + Fri Sep 25 13:28:54 1998 John W. Eaton * elt-dirs.c (kpse_clear_dir_cache): New function. diff --git a/kpathsea/kdefault.c b/kpathsea/kdefault.c --- a/kpathsea/kdefault.c +++ b/kpathsea/kdefault.c @@ -38,12 +38,12 @@ assert (fallback); if (path == NULL) - expansion = (string) fallback; + expansion = xstrdup (fallback); /* Solitary or leading :? */ else if (IS_ENV_SEP (*path)) { - expansion = path[1] == 0 ? (string) fallback : concat (fallback, path); + expansion = path[1] == 0 ? xstrdup (fallback) : concat (fallback, path); } /* Sorry about the assignment in the middle of the expression, but @@ -60,7 +60,7 @@ const_string loc; /* What we'll return if we find none. */ - expansion = (string) path; + expansion = xstrdup (path); for (loc = path; *loc && expansion == path; loc++) { diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,10 @@ +Fri Oct 23 21:46:20 1998 John W. Eaton + + * pathsearch.h (dir_path::default_path): New data member. + * pathsearch.cc (dir_path::init): Use it. + + * Makefile.in: Avoid optmization when compiling lo-ieee.cc. + Fri Oct 16 01:08:30 1998 John W. Eaton * chMatrix.cc (charMatrix::extract): New function. diff --git a/liboctave/pathsearch.cc b/liboctave/pathsearch.cc --- a/liboctave/pathsearch.cc +++ b/liboctave/pathsearch.cc @@ -39,6 +39,8 @@ // or otherwise cause trouble... #define string kpse_string +#include +#include #include #include @@ -161,11 +163,24 @@ kpse_clear_dir_cache (); - char *tmp = kpse_path_expand (p_orig.c_str ()); - if (tmp) + char *t1 = 0; + + if (p_default.empty ()) + t1 = kpse_path_expand (p_orig.c_str ()); + else { - p = tmp; - free (tmp); + char *t2 = kpse_expand_default (p_orig.c_str (), p_default.c_str ()); + + t1 = kpse_path_expand (t2); + + if (t2) + free (t2); + } + + if (t1) + { + p = t1; + free (t1); } else p = string (); diff --git a/liboctave/pathsearch.h b/liboctave/pathsearch.h --- a/liboctave/pathsearch.h +++ b/liboctave/pathsearch.h @@ -32,20 +32,22 @@ { public: - dir_path (const string& s = string ()) - : p_orig (s), initialized (false) + dir_path (const string& s = string (), const string& d = string ()) + : p_orig (s), p_default (d), initialized (false) { if (! p_orig.empty ()) init (); } dir_path (const dir_path& dp) - : p_orig (dp.p_orig), initialized (dp.initialized), p (dp.p), pv (dp.pv) + : p_orig (dp.p_orig), p_default (dp.p_default), + initialized (dp.initialized), p (dp.p), pv (dp.pv) { } dir_path& operator = (const dir_path& dp) { p_orig = dp.p_orig; + p_default = dp.p_default; initialized = dp.initialized; p = dp.p; pv = dp.pv; @@ -82,11 +84,15 @@ // The colon separated list that we were given. string p_orig; + // The default path. If specified, replaces leading, trailing, or + // doubled colons in p_orig. + string p_default; + // TRUE means we've unpacked p. bool initialized; // A version of the colon separate list on which we have performed - // tilde and variable expansion. + // tilde, variable, and possibly default path expansion. string p; // The elements of the list. diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,7 @@ +Wed Oct 28 11:51:14 1998 John W. Eaton + + * general/length.m: Delete. + Fri Oct 23 00:21:55 1998 John W. Eaton * configure.in: Add finance/Makefile, statistics/base/Makefile, diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,85 @@ +Wed Oct 28 11:01:37 1998 John W. Eaton + + * OPERATORS/op-list.cc: New file. + * Makefile.in (OP_XSRC): Add it to the list. + + * ov-list.cc (octave_list::assign): New function. + + * ov-typeinfo.h (octave_value_typeinfo::assignany_ops): + New data member. + * ov-typeinfo.cc (octave_value_info::register_assignany_op, + octave_value_info::do_register_assignany_op, + octave_value_info::lookup_assignany_op, + octave_value_info::do_lookup_assignany_op): + New functions. + * ov.cc (octave_value::try_assignment (octave_value::assign_op, + const octave_value_list&, const octave_value&)): If no assignment + operator for particular RHS type exists, try finding one for + generic octave_value as RHS type. + * ops.h (DEFASSIGNANYOP_FN): New macro. + + * ov-list.cc (Fsplice): New function. + * oct-obj.cc (octave_value_list::splice): New function. + + * ov.cc (Vresize_on_range_error): No longer static. + * ov.h (Vresize_on_range_error): Provide extern declaration. + + * oct-procbuf.cc (symbols_of_oct_procbuf): Don't declare static. + + * data.cc (Flength): New function. + * ov.h (octave_value::length): New virtual function. + * ov-base.cc (octave_base_value::length): New function. + (octave_base_value::rows, octave_base_value::columns): Move + definitions here, from ov-base.h. Don't return -1. Instead, + gripe about wrong argument type. + * ov-bool-mat.h (octave_bool_matrix::length): New function. + * ov-bool.h (octave_bool::length): Ditto. + * ov-ch-mat.h (octave_char_matrix::length): Ditto. + * ov-complex.h (octave_complex::length): Ditto. + * ov-cx-mat.h (octave_complex_matrix::length): Ditto. + * ov-list.h (octave_list::length): Ditto. + * ov-range.h (octave_range::length): Ditto. + * ov-re-mat.h (octave_matrix::length): Ditto. + * ov-scalar.h (octave_scalar::length): Ditto. + +Tue Oct 27 22:19:24 1998 John W. Eaton + + * ov-list.cc (octave_list::print_raw): Handle case of empty list. + (octave_list::print_name_tag): Likewise. + + * octave.cc (intern_argv): Built-in variable argv is now a list of + strings instead of a string vector. + Always bind argv, making it an empty list if there are no args. + +Mon Oct 26 08:41:46 1998 John W. Eaton + + * xdiv.cc (mx_leftdiv_conform): Explicitly declare args to be + passed as references to const objects. Fix explicit instantiation + requests to match. + (mx_div_conform): Likewise. + + * pt-unop.h (tree_prefix_expression): Reorder constructor args to + put those with default values last. + (tree_postfix_expression): Likewise. + * parse.y: Change all callers. + Fri Oct 23 12:07:32 1998 John W. Eaton + * utils.cc (Ffile_in_loadpath): New function. + + * defaults.cc (Vload_path, Vdefault_load_path): Now static. + + * help.cc (simple_help): Use Vload_path_dir_path here instead of + trying to reconstruct it from Vload_path. + * fn-cache.cc (octave_fcn_file_name_cache::do_list): Likewise. + (octave_fcn_file_name_cache::update): Likewise. + + * defaults.cc (octave_loadpath): Construct Vload_path_dir_path + using Vdefault_load_path. + (set_default_path): Likewise. + + * defaults.h, defaults.cc (maybe_add_default_load_path): Delete. + * defaults.cc (Vdefault_load_path): New static variable. (set_default_path): Set it. (maybe_add_default_load_path): Use it. diff --git a/src/ov-list.cc b/src/ov-list.cc --- a/src/ov-list.cc +++ b/src/ov-list.cc @@ -80,6 +80,34 @@ } void +octave_list::assign (const octave_value_list& idx, const octave_value& rhs) +{ + if (idx.length () == 1) + { + double d = idx(0).double_value (); + + if (! error_state) + { + if (D_NINT (d) == d) + { + int n = lst.length (); + + int i = static_cast (d); + + if (i > 0 && (Vresize_on_range_error || i <= n)) + lst(i) = rhs; + else + error ("list index = %d out of range", i); + } + else + error ("list index must be an integer"); + } + } + else + error ("lists may only be indexed by a single scalar"); +} + +void octave_list::print (ostream& os, bool) const { print_raw (os); @@ -90,31 +118,37 @@ { unwind_protect::begin_frame ("octave_list_print"); - indent (os); - os << "("; - newline (os); - - increment_indent_level (); - int n = lst.length (); - for (int i = 0; i < n; i++) + if (n > 0) { - ostrstream buf; - buf << "[" << i+1 << "]" << ends; - const char *nm = buf.str (); + indent (os); + os << "("; + newline (os); + + increment_indent_level (); - octave_value val = lst(i); + for (int i = 0; i < n; i++) + { + ostrstream buf; + buf << "[" << i+1 << "]" << ends; + const char *nm = buf.str (); - val.print_with_name (os, nm); + octave_value val = lst(i); - delete [] nm; - } + val.print_with_name (os, nm); + + delete [] nm; + } - decrement_indent_level (); + decrement_indent_level (); - indent (os); - os << ")"; + indent (os); + os << ")"; + } + else + os << "()"; + newline (os); unwind_protect::run_frame ("octave_list_print"); @@ -124,8 +158,13 @@ octave_list::print_name_tag (ostream& os, const string& name) const { indent (os); - os << name << " ="; - newline (os); + if (lst.length () == 0) + os << name << " = "; + else + { + os << name << " ="; + newline (os); + } return false; } @@ -186,6 +225,82 @@ return retval; } +DEFUN (splice, args, , + "splice (LIST_1, OFFSET, LENGTH, LIST_2)\n\ +splice (LIST_1, OFFSET, LENGTH, LIST_2)\n\ +splice (LIST_1, OFFSET, LENGTH)\n\ +splice (LIST_1, OFFSET)\n\ +\n\ +Replace LENGTH elements of LIST_1 beginning at OFFSET with the +contents of LIST_2 (if any). If LENGTH is omitted, ") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin > 1 && nargin < 5) + { + octave_value_list list_1 = args(0).list_value (); + + if (! error_state) + { + double d_offset = args(1).double_value (); + + if (! error_state) + { + if (D_NINT (d_offset) == d_offset) + { + int offset = static_cast (d_offset) - 1; + + int length = 0; + + if (nargin < 3) + length = list_1.length () - offset; + else + { + double d_length = args(2).double_value (); + + if (error_state) + return retval; + else + { + if (D_NINT (d_length) == d_length) + length = static_cast (d_length); + else + error ("splice: LENGTH must be an integer"); + } + } + + octave_value_list list_2; + + if (nargin == 4) + { + list_2 = args(3).list_value (); + + if (error_state) + { + error ("splice: fourth argument must be a list"); + return retval; + } + } + + retval = list_1.splice (offset, length, list_2); + } + else + error ("splice: OFFSET must be an integer"); + } + else + error ("splice: OFFSET must be an integer"); + } + else + error ("splice: first argument must be a list"); + } + else + print_usage ("splice"); + + return retval; +} + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/src/ov-list.h b/src/ov-list.h --- a/src/ov-list.h +++ b/src/ov-list.h @@ -72,6 +72,10 @@ octave_value do_index_op (const octave_value_list& idx); + void assign (const octave_value_list& idx, const octave_value& rhs); + + int length (void) const { return lst.length (); } + bool is_defined (void) const { return true; } bool is_constant (void) const { return true; } diff --git a/src/ov-typeinfo.cc b/src/ov-typeinfo.cc --- a/src/ov-typeinfo.cc +++ b/src/ov-typeinfo.cc @@ -98,6 +98,14 @@ } bool +octave_value_typeinfo::register_assignany_op (octave_value::assign_op op, + int t_lhs, assign_op_fcn f) +{ + return (instance_ok ()) + ? instance->do_register_assignany_op (op, t_lhs, f) : -1; +} + +bool octave_value_typeinfo::register_pref_assign_conv (int t_lhs, int t_rhs, int t_result) { @@ -136,6 +144,9 @@ assign_ops.resize (static_cast (octave_value::num_assign_ops), len, len, static_cast (0)); + assignany_ops.resize (static_cast (octave_value::num_assign_ops), + len, static_cast (0)); + pref_assign_conv.resize (len, len, -1); widening_ops.resize (len, len, static_cast (0)); @@ -169,6 +180,15 @@ } bool +octave_value_typeinfo::do_register_assignany_op (octave_value::assign_op op, + int t_lhs, assign_op_fcn f) +{ + assignany_ops.checkelem (static_cast (op), t_lhs) = f; + + return false; +} + +bool octave_value_typeinfo::do_register_pref_assign_conv (int t_lhs, int t_rhs, int t_result) { @@ -202,6 +222,13 @@ return assign_ops.checkelem (static_cast (op), t_lhs, t_rhs); } +assign_op_fcn +octave_value_typeinfo::do_lookup_assignany_op (octave_value::assign_op op, + int t_lhs) +{ + return assignany_ops.checkelem (static_cast (op), t_lhs); +} + int octave_value_typeinfo::do_lookup_pref_assign_conv (int t_lhs, int t_rhs) { diff --git a/src/ov-typeinfo.h b/src/ov-typeinfo.h --- a/src/ov-typeinfo.h +++ b/src/ov-typeinfo.h @@ -52,6 +52,9 @@ static bool register_assign_op (octave_value::assign_op, int, int, assign_op_fcn); + static bool register_assignany_op (octave_value::assign_op, int, + assign_op_fcn); + static bool register_pref_assign_conv (int, int, int); static bool register_widening_op (int, int, type_conv_fcn); @@ -68,6 +71,12 @@ return instance->do_lookup_assign_op (op, t_lhs, t_rhs); } + static assign_op_fcn + lookup_assignany_op (octave_value::assign_op op, int t_lhs) + { + return instance->do_lookup_assignany_op (op, t_lhs); + } + static int lookup_pref_assign_conv (int t_lhs, int t_rhs) { @@ -93,6 +102,8 @@ init_tab_sz, (binary_op_fcn) 0), assign_ops (octave_value::num_assign_ops, init_tab_sz, init_tab_sz, (assign_op_fcn) 0), + assignany_ops (octave_value::num_assign_ops, init_tab_sz, + (assign_op_fcn) 0), pref_assign_conv (init_tab_sz, init_tab_sz, -1), widening_ops (init_tab_sz, init_tab_sz, (type_conv_fcn) 0) { } @@ -110,6 +121,8 @@ Array3 assign_ops; + Array2 assignany_ops; + Array2 pref_assign_conv; Array2 widening_ops; @@ -122,6 +135,9 @@ bool do_register_assign_op (octave_value::assign_op, int, int, assign_op_fcn); + bool do_register_assignany_op (octave_value::assign_op, int, + assign_op_fcn); + bool do_register_pref_assign_conv (int, int, int); bool do_register_widening_op (int, int, type_conv_fcn); @@ -132,6 +148,9 @@ assign_op_fcn do_lookup_assign_op (octave_value::assign_op, int, int); + assign_op_fcn + do_lookup_assignany_op (octave_value::assign_op, int); + int do_lookup_pref_assign_conv (int, int); type_conv_fcn do_lookup_widening_op (int, int); diff --git a/src/ov.cc b/src/ov.cc --- a/src/ov.cc +++ b/src/ov.cc @@ -115,7 +115,7 @@ // If TRUE, resize matrices when performing and indexed assignment and // the indices are outside the current bounds. -static bool Vresize_on_range_error; +bool Vresize_on_range_error; // XXX FIXME XXX @@ -846,6 +846,17 @@ retval = (! error_state); } + else + { + f = octave_value_typeinfo::lookup_assignany_op (op, t_lhs); + + if (f) + { + f (*rep, idx, rhs); + + retval = (! error_state); + } + } return retval; }