octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Octave and GSOC'2008


From: Jaroslav Hajek
Subject: Re: Octave and GSOC'2008
Date: Thu, 28 Feb 2008 11:33:26 +0100

On Thu, Feb 28, 2008 at 10:55 AM, John W. Eaton <address@hidden> wrote:
> On 28-Feb-2008, Jaroslav Hajek wrote:
>
>  | 2. implement simple lazy evaluation for matrices. For instance, transpose,
>  | ones, zeros, or diag may output some kind of matrix expression that would 
> not
>  | be converted immediately to a matrix, but retained unevaluated until
>  | asked to do so.
>  | That would allow functions to use specialized code for things like
>  | A'*B or diag(A)*B,
>  | A' \ B, kron(ones(m,n),A) etc.
>  | My idea is that octave_value could hold a variable of class
>  | matrix_expr, which would
>  | maintain the expression in a "latent" form, but evaluate it whenever
>  | matrix_value, is_matrix_type or similar methods were called.
>  | There are certainly some problems, like what class() should output for
>  | these values,
>  | (and probably more that I don't see just now)
>
>  Some of these things could go in the NDArray/Matrix classes.  For
>  example, transpose.  However, if you implement it with a flag it means
>  slowing down the element access functions (each access must check the
>  flag) and if you do it by introducing new classes (tranposed_matrix,
>  transposed_ndarray, etc.) then we have many more classes to manage
>  (though maybe only a small number of functions in each would need to
>  be redefined).  I'm not sure the complexity is really worth it.
>

That's exactly why I thought more about using just a special type for
octave_value.
For instance, a common construct is A'*B, where the value of A' is not needed
anymore after the statement. Given that evaluating A'*B is typically
even slightly
faster than A*B, transposing  and then multiplying is really a waste
of time and memory.

So I was thinking about
DEFUN_DLD(times, ...
)

aA = args(0);
if (aA.is_matrix_expr())
{
  eA = aA.matrix_expr_value();
  switch (eA.expr_type())
  {
     case MatrixExpr::transpose:
        /* specialized code for transpose, possibly DGEMM('T'...) */
     case MatrixExpr::diag:
        /* just scale rows */
  }
} else if (aA.is_matrix())
{
  A = aA.matrix_value()
....


Once matrix_value() gets called, the lazy expression is evaluated and
substituted by the real thing. The problem is that matrix_value() now
affects the object for which it is called - I can imagine that causing
a lot of problems elsewhere...


>
>  | 3. variable handles, or something like that, that would allow passing
>  | by reference more
>  | graciously than using variable name and "evalin". This is suggested in
>  | the Octave's "wanted features" list, but is it really wanted?
>  | For instance:
>  | A = rand(3,3)
>  | set11tozero(@A)
>  |
>  | function set11tozero(x)
>  | if (isvarhandle(x))
>  |   assign_local_name("A",@x)
>  |   A(1,1) = 0
>  | endif
>
>  It might be better to have the parser/evaluator simply recognize
>
>   function x = f (x)
>     ...
>   endfunction
>
>  as a special case.  Doing this requires no new syntax.  Given Octave's
>  reference counting and copy-on-write semantics, some care might be
>  needed so that
>
>   a = b
>   a = f (a)
>
>  does not also modify b.  I think you'll also need to apply the
>  call-by-reference semantics only for calls like this:
>
>   a = f (a)
>
>  and not
>
>   b = f (a)
>
>
>  jwe
>

I strongly agree.

-- 
RNDr. Jaroslav Hajek
computing expert
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz


reply via email to

[Prev in Thread] Current Thread [Next in Thread]