From maintainers-request at octave dot org Thu Feb 10 10:03:40 2005 Subject: Re: Moving code from octave-forge to octave [Was: polyderiv problem?] From: Michael Creel To: maintainers at octave dot org Cc: Paul Kienzle , Joe Koski Date: Thu, 10 Feb 2005 16:59:34 +0100 On Thursday 10 February 2005 16:00, you wrote: > On  9-Feb-2005, Michael Creel wrote: > | On Wednesday 09 February 2005 16:50, David Bateman wrote: > | > The only > | > remaining patch to consider is M-v-ops-2.1.31.patch that allows the > | > extension of ./, .*, etc to allow Matrix by vector arguments. > | > | I sent this message to David, but I meant to send it to all, so here it > | is: > | > | This is a behavior that I have found very useful in languages like Gauss > | and Ox. > > Do these languages have special syntax for these operations? No, .* gives the functionality that the function I hacked together provides. The same .* will do ordinary element-by-element multiplication. > > Although it has been discussed before, and I have probably even > suggested implementing it in the past, I now hesitate to overload > operators like .* for this purpose because (as David mentioned) it > means that a dimensioning error can lead to bad results with no > warning.  As another example, you might mean to multiply elements of > M1 by elements of M2, but M2 accidentally becomes a vector, so > suddenly you are scaling columns instead of seeing an error about > non-conforming operands.  That seems bad to me.  But it would be > useful to have this capability implemented efficiently, even if we do > not have special operators for it. I agree, this opens the door for unpredictable results due to errors. > > | Maybe it would be possible to allow it only for matrices and vectors, but > | not NDArrays? > > There is probably some way to generalize to N-d arrays when the > dimension of one operand is one less than the dimension of the other. > > | Or maybe a function would do the job. I attach a quck hack for > | consideration. Michael > | m_x_v.m > | function result = m_x_v(m,v) > |  if !ismatrix(m) > |   error("m_x_v: first arg must be a matrix"); > |  endif > |  if !isvector(v) > |   error("m_x_v: second arg must be a vector"); > |  endif > | > |  [rm, cm] = size(m); > |  [rv, cv] = size(v); > | > |  if (rm == rv) > |   v = kron(v, ones(1,cm)); > |   result = m .* v; > |  elseif (cm == cv) > |   v = kron(v, ones(rm, 1)); > |   result = m .* v; > |  else > |   error("m_x_v: dimension of vector must match one of the dimensions of > | the matr ix"); > |  endif > | endfunction > > This kind of approach will work, but it will use a lot of memory, so > it would be better to do this in a built-in function where we could > use loops and not sacrifice speed or memory efficiency. The thing I like about this is that a user must explicitly call a function by name to get the behavior, rather than type ".*" which may or may not give the desired results. The function gives an error message if the second argument is not a vector. As to memory and speed, one could write an .oct version if desired. The function is just to point out that the behavior can be obtained easily without changing .* Michael