From bug-octave-request at bevo dot che dot wisc dot edu Thu Oct 5 16:00:54 2000 Subject: M-v ops From: Paul Kienzle To: bug-octave at bevo dot che dot wisc dot edu, pkienzle@kienzle.powernet.co.uk Date: Thu, 05 Oct 2000 11:27:38 +0100 To: bug-octave at bevo dot che dot wisc dot edu Cc: pkienzle Subject: M-v ops Bug report for Octave 2.1.31 configured for %OCTAVE_CANONICAL_HOST_TYPE% Description: ----------- Octave's element-wise binary operations .*,./,.\,+,- can be extended to handle the case where one of the operands is a row or column vector with the same length as the corresponding dimension of the matrix M. The vector operation is simply repeated as many times as necessary to match the dimensions of M. The same extension should be done for .^ (in src/xpow.cc) and for the boolean and comparison operators (in mx-op-defs.h). The same concept applies for N-dimensional matrices, with the lengths of each dimension of v either being 1 or matching the length of the corresponding dimension of M. The concept could be extended to compute outer products as well, if you allow M to have dimensions of length 1 while the corresponding dimension of v has dimension greater than 1. I don't know if you would want to though. The convenience of generating outer products needs to be weighed against the convenience of debugging errors in the shape of your vectors (e.g., when you are applying a window to your data, you don't want to accidentally create 1024x1024 arrays). Repeat-By: --------- octave:6> rand(3).*[1:3] error: product: nonconformant arguments (op1 is 3x3, op2 is 1x3) error: evaluating assignment expression near line 6, column 8 Fix: --- *** MArray2.cc 2000/10/05 09:33:32 1.1 --- MArray2.cc 2000/10/04 08:47:13 *************** *** 149,158 **** int b_nr = b.rows (); \ int b_nc = b.cols (); \ if (a_nr != b_nr || a_nc != b_nc) \ ! { \ ! gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \ ! return MArray2 (); \ ! } \ if (a_nr == 0 || a_nc == 0) \ return MArray2 (a_nr, a_nc); \ int l = a.length (); \ --- 149,205 ---- int b_nr = b.rows (); \ int b_nc = b.cols (); \ if (a_nr != b_nr || a_nc != b_nc) \ ! if (a_nr == b_nr && a_nc == 1) \ ! { \ ! MArray2 result (a_nr, b_nc); \ ! T *r = result.fortran_vec (); \ ! const T *x = a.data (); \ ! const T *y = b.data (); \ ! int k=0; \ ! for (int j=0; j < b_nc; j++) \ ! for (int i=0; i < a_nr; i++, k++) \ ! r[k] = x[i] OP y[k]; \ ! return result; \ ! } \ ! else if (a_nr == b_nr && b_nc == 1) \ ! { \ ! MArray2 result (a_nr, a_nc); \ ! T *r = result.fortran_vec (); \ ! const T *x = a.data (); \ ! const T *y = b.data (); \ ! int k=0; \ ! for (int j=0; j < a_nc; j++) \ ! for (int i=0; i < a_nr; i++, k++) \ ! r[k] = x[k] OP y[i]; \ ! return result; \ ! } \ ! else if (a_nc == b_nc && b_nr == 1) \ ! { \ ! MArray2 result (a_nr, a_nc); \ ! T *r = result.fortran_vec (); \ ! const T *x = a.data (); \ ! const T *y = b.data (); \ ! for (int i=0; i < a_nr; i++) \ ! for (int j=0, k=i; j < a_nc; j++, k+=a_nr) \ ! r[k] = x[k] OP y[j]; \ ! return result; \ ! } \ ! else if (a_nc == b_nc && a_nr == 1) \ ! { \ ! MArray2 result (b_nr, a_nc); \ ! T *r = result.fortran_vec (); \ ! const T *x = a.data (); \ ! const T *y = b.data (); \ ! for (int i=0; i < b_nr; i++) \ ! for (int j=0, k=i; j < a_nc; j++, k+=b_nr) \ ! r[k] = x[j] OP y[k]; \ ! return result; \ ! } \ ! else \ ! { \ ! gripe_nonconformant (#FCN, a_nr, a_nc, b_nr, b_nc); \ ! return MArray2 (); \ ! } \ if (a_nr == 0 || a_nc == 0) \ return MArray2 (a_nr, a_nc); \ int l = a.length (); \ *** mx-op-defs.h 2000/10/05 09:33:32 1.1 --- mx-op-defs.h 2000/10/04 07:41:06 *************** *** 23,28 **** --- 23,29 ---- #if !defined (octave_mx_op_defs_h) #define octave_mx_op_defs_h 1 + #include "lo-error.h" #include "mx-inlines.cc" #define BIN_OP_DECL(R, OP, X, Y) \ *************** *** 353,359 **** BIN_OP_DECL (R, product, M1, M2); \ BIN_OP_DECL (R, quotient, M1, M2); ! #define MM_BIN_OP(R, OP, M1, M2, F) \ R \ OP (const M1& m1, const M2& m2) \ { \ --- 354,360 ---- BIN_OP_DECL (R, product, M1, M2); \ BIN_OP_DECL (R, quotient, M1, M2); ! #define MM_BIN_OP(R, OP, M1, M2, F, OPSYM) \ R \ OP (const M1& m1, const M2& m2) \ { \ *************** *** 366,372 **** int m2_nc = m2.cols (); \ \ if (m1_nr != m2_nr || m1_nc != m2_nc) \ ! gripe_nonconformant (#OP, m1_nr, m1_nc, m2_nr, m2_nc); \ else \ { \ r.resize (m1_nr, m1_nc); \ --- 367,402 ---- int m2_nc = m2.cols (); \ \ if (m1_nr != m2_nr || m1_nc != m2_nc) \ ! if (m1_nr == m2_nr && m1_nc == 1) \ ! { \ ! r.resize (m1_nr, m2_nc); \ ! for (int j = 0; j < m2_nc; j++) \ ! for (int i = 0; i < m1_nr; i++) \ ! r.elem(i, j) = m1.elem(i, 0) OPSYM m2.elem(i, j); \ ! } \ ! else if (m1_nr == m2_nr && m2_nc == 1) \ ! { \ ! r.resize (m1_nr, m1_nc); \ ! for (int j = 0; j < m1_nc; j++) \ ! for (int i = 0; i < m1_nr; i++) \ ! r.elem(i, j) = m1.elem(i, j) OPSYM m2.elem(i, 0); \ ! } \ ! else if (m1_nc == m2_nc && m2_nr == 1) \ ! { \ ! r.resize (m1_nr, m1_nc); \ ! for (int j = 0; j < m1_nc; j++) \ ! for (int i = 0; i < m1_nr; i++) \ ! r.elem(i, j) = m1.elem(i, j) OPSYM m2.elem(0, j); \ ! } \ ! else if (m1_nc == m2_nc && m1_nr == 1) \ ! { \ ! r.resize (m2_nr, m1_nc); \ ! for (int j = 0; j < m1_nc; j++) \ ! for (int i = 0; i < m2_nr; i++) \ ! r.elem(i, j) = m1.elem(0, j) OPSYM m2.elem(i, j); \ ! } \ ! else \ ! gripe_nonconformant (#OP, m1_nr, m1_nc, m2_nr, m2_nc); \ else \ { \ r.resize (m1_nr, m1_nc); \ *************** *** 379,388 **** } #define MM_BIN_OPS(R, M1, M2) \ ! MM_BIN_OP (R, operator +, M1, M2, add) \ ! MM_BIN_OP (R, operator -, M1, M2, subtract) \ ! MM_BIN_OP (R, product, M1, M2, multiply) \ ! MM_BIN_OP (R, quotient, M1, M2, divide) #define MM_CMP_OP_DECLS(M1, M2) \ CMP_OP_DECL (mx_el_lt, M1, M2); \ --- 409,418 ---- } #define MM_BIN_OPS(R, M1, M2) \ ! MM_BIN_OP (R, operator +, M1, M2, add, +) \ ! MM_BIN_OP (R, operator -, M1, M2, subtract, -) \ ! MM_BIN_OP (R, product, M1, M2, multiply, *) \ ! MM_BIN_OP (R, quotient, M1, M2, divide, /) #define MM_CMP_OP_DECLS(M1, M2) \ CMP_OP_DECL (mx_el_lt, M1, M2); \ Configuration (please do not edit this section): ----------------------------------------------- uname output: Linux kienzle 2.2.17 #1 Sun Sep 10 17:51:52 BST 2000 i586 unknown configure opts: --prefix=/usr --datadir=/usr/share --libdir=/usr/lib --libexecdir=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --with-g77 --with-fastblas --enable-dl --enable-shared --enable-lite-kernel --disable-static --host i386-linux Fortran compiler: g77 FFLAGS: -O2 F2C: F2CFLAGS: FLIBS: -lg2c -lm -L/usr/lib/gcc-lib/i386-linux/2.95.2 -lm CPPFLAGS: INCFLAGS: -I. -I. -I./liboctave -I./src -I./libcruft/misc -I./glob -I./glob C compiler: gcc, version 2.95.2 20000220 (Debian GNU/Linux) CFLAGS: -O2 CPICFLAG: -fPIC C++ compiler: c++, version 2.95.2 20000220 (Debian GNU/Linux) CXXFLAGS: -O2 CXXPICFLAG: -fPIC LDFLAGS: -s LIBFLAGS: -L. RLD_FLAG: -Xlinker -rpath -Xlinker /usr/lib/octave-2.1.31 TERMLIBS: -lncurses LIBS: LEXLIB: LIBPLPLOT: LIBDLFCN: LIBGLOB: ./glob/glob.o ./glob/fnmatch.o DEFS: -DOCTAVE_SOURCE=1 -DSEPCHAR=':' -DSEPCHAR_STR=":" -DUSE_READLINE=1 -D__NO_MATH_INLINES=1 -DCXX_NEW_FRIEND_TEMPLATE_DECL=1 -DHAVE_LIBM=1 -DHAVE_LIBZ=1 -DF77_APPEND_UNDERSCORE=1 -DOCTAVE_LITE=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DNPOS=std::string::npos -DSTDC_HEADERS=1 -DHAVE_DIRENT_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_ASSERT_H=1 -DHAVE_CURSES_H=1 -DHAVE_DLFCN_H=1 -DHAVE_FCNTL_H=1 -DHAVE_FLOAT_H=1 -DHAVE_FNMATCH_H=1 -DHAVE_GLOB_H=1 -DHAVE_GRP_H=1 -DHAVE_LIMITS_H=1 -DHAVE_MEMORY_H=1 -DHAVE_NCURSES_H=1 -DHAVE_POLL_H=1 -DHAVE_PWD_H=1 -DHAVE_SGTTY_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_POLL_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_UTSNAME_H=1 -DHAVE_TERMCAP_H=1 -DHAVE_TERMIO_H=1 -DHAVE_UNISTD_H=1 -DHAVE_VARARGS_H=1 -DHAVE_ATEXIT=1 -DHAVE_BCOPY=1 -DHAVE_BZERO=1 -DHAVE_DUP2=1 -DHAVE_ENDGRENT=1 -DHAVE_ENDPWENT=1 -DHAVE_EXECVP=1 -DHAVE_FCNTL=1 -DHAVE_FORK=1 -DHAVE_GETCWD=1 -DHAVE_GETEGID=1 -DHAVE_GETEUID=1 -DHAVE_GETGID=1 -DHAVE_GETGRENT=1 -DHAVE_GETGRGID=1 -DHAVE_GETGRNAM=1 -DHAVE_GETHOSTNAME=1 -DHAVE_GETPGRP=1 -DHAVE_GETPID=1 -DHAVE_GETPPID=1 -DHAVE_GETPWENT=1 -DHAVE_GETPWNAM=1 -DHAVE_GETPWUID=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_GETUID=1 -DHAVE_GETWD=1 -DHAVE_LOCALTIME_R=1 -DHAVE_LSTAT=1 -DHAVE_MEMMOVE=1 -DHAVE_MKDIR=1 -DHAVE_MKFIFO=1 -DHAVE_ON_EXIT=1 -DHAVE_PIPE=1 -DHAVE_POLL=1 -DHAVE_PUTENV=1 -DHAVE_RENAME=1 -DHAVE_RINDEX=1 -DHAVE_RMDIR=1 -DHAVE_SELECT=1 -DHAVE_SETGRENT=1 -DHAVE_SETPWENT=1 -DHAVE_SETVBUF=1 -DHAVE_SIGACTION=1 -DHAVE_SIGPENDING=1 -DHAVE_SIGPROCMASK=1 -DHAVE_SIGSUSPEND=1 -DHAVE_STAT=1 -DHAVE_STRCASECMP=1 -DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRFTIME=1 -DHAVE_STRNCASECMP=1 -DHAVE_STRPTIME=1 -DHAVE_TEMPNAM=1 -DHAVE_UMASK=1 -DHAVE_UNLINK=1 -DHAVE_USLEEP=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1 -DHAVE_VSNPRINTF=1 -DHAVE_WAITPID=1 -DHAVE_LIBDL=1 -DHAVE_DLOPEN=1 -DHAVE_DLSYM=1 -DHAVE_DLERROR=1 -DHAVE_DLCLOSE=1 -DWITH_DL=1 -DWITH_DYNAMIC_LINKING=1 -DHAVE_TIMEVAL=1 -DHAVE_FINITE=1 -DHAVE_ISNAN=1 -DHAVE_ISINF=1 -DHAVE_ACOSH=1 -DHAVE_ASINH=1 -DHAVE_ATANH=1 -DHAVE_ERF=1 -DHAVE_ERFC=1 -DHAVE_ST_BLKSIZE=1 -DHAVE_ST_BLOCKS=1 -DHAVE_ST_RDEV=1 -DHAVE_TM_ZONE=1 -DHAVE_GR_PASSWD=1 -DEXCEPTION_IN_MATH=1 -DRETSIGTYPE=void -DSYS_SIGLIST_DECLARED=1 -DHAVE_SYS_SIGLIST=1 -DHAVE_POSIX_SIGNALS=1 -DHAVE_GETRUSAGE=1 -DHAVE_TIMES=1 -DGNUPLOT_HAS_MULTIPLOT=1 -DGNUPLOT_HAS_FRAMES=1 User-preferences (please do not edit this section): -------------------------------------------------- EDITOR = "vi" EXEC_PATH = "/home/pkienzle/octave/audio::/scratch/programs/audio/package/pipewave.1.3/bin:/scratch/programs/audio/pitch/POWERpv1.1G/bin:/home/pkienzle/pantome/bin:/home/pkienzle/sfs/bin:/home/pkienzle/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games" IMAGEPATH = ".:/usr/local/share/octave/2.1.31/imagelib//" INFO_FILE = "/usr/local/info/octave.info" INFO_PROGRAM = "info" LOADPATH = "/home/pkienzle/matcompat//:/home/pkienzle/octave//::/usr/lib/octave/2.1.31/oct/:/usr/share/octave/2.1.31//" PAGER = "less" PS1 = "\\s:\\#> " PS2 = "> " PS4 = "+ " automatic_replot = 0 beep_on_error = 0 completion_append_char = " " default_eval_print_flag = 1 # default_global_variable_value = default_return_value = [] default_save_format = "ascii" define_all_return_values = 0 do_fortran_indexing = 0 echo_executing_commands = 0 empty_list_elements_ok = "warn" fixed_point_format = 0 gnuplot_binary = "gnuplot" gnuplot_command_end = "\n" gnuplot_command_plot = "pl" gnuplot_command_replot = "rep" gnuplot_command_splot = "sp" gnuplot_command_title = "t" gnuplot_command_using = "u" gnuplot_command_with = "w" gnuplot_has_frames = 1 gnuplot_has_multiplot = 1 history_file = "/home/pkienzle/.octave_hist" history_size = 1024 ignore_function_time_stamp = "system" implicit_num_to_str_ok = 0 implicit_str_to_num_ok = 0 initialize_global_variables = 0 max_recursion_depth = 256 ok_to_lose_imaginary_part = "warn" output_max_field_width = 10 output_precision = 5 page_output_immediately = 0 page_screen_output = 1 prefer_column_vectors = 1 print_answer_id_name = 1 print_empty_dimensions = 1 print_rhs_assign_val = 0 propagate_empty_matrices = 1 resize_on_range_error = 1 return_last_computed_value = 0 save_precision = 15 saving_history = 1 silent_functions = 0 split_long_rows = 1 string_fill_char = " " struct_levels_to_print = 2 suppress_verbose_help_message = 1 treat_neg_dim_as_zero = 0 warn_assign_as_truth_value = 1 warn_divide_by_zero = 1 warn_function_name_clash = 1 warn_future_time_stamp = 1 warn_missing_semicolon = 0 warn_variable_switch_label = 0 whitespace_in_literal_matrix = ----------------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.che.wisc.edu/octave/octave.html How to fund new projects: http://www.che.wisc.edu/octave/funding.html Subscription information: http://www.che.wisc.edu/octave/archive.html -----------------------------------------------------------------------