guile-devel
[Top][All Lists]
Advanced

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

Re: propose deprecation of generalized-vector-*


From: Daniel Llorens
Subject: Re: propose deprecation of generalized-vector-*
Date: Wed, 19 Sep 2012 19:20:49 +0200

On Sep 19, 2012, at 18:00, address@hidden wrote:

> Date: Wed, 19 Sep 2012 13:02:25 +0100
> From: Peter TB Brett <address@hidden>
> To: address@hidden
> Subject: Re: propose deprecation of generalized-vector-*

 ...

> It seems to me that array-length should return the first non-unity
> dimension. This is the approach taken by e.g. MATLAB's length()
> function. It would give it a distinct utility compared to
> array-dimensions (which is analogous to MATLAB's size() function).
> 
> WDYT?
> 
>                        Peter

That is not exactly what length() does in Matlab:

> >> help length
>  LENGTH   Length of vector.
>     LENGTH(X) returns the length of vector X.  It is equivalent
>     to MAX(SIZE(X)) for non-empty arrays and 0 for empty ones.

The notion of rank in Matlab is rather sui generis. There are no rank 1 objects 
as such, only row or column vectors. Even size(0) gives [1 1]. So there's 
constant confusion when you want a simple vector X, because Matlab gives you a 
column or a row and you need to know which one you've got, even though the 
things you want to do with X don't depend on that at all. That leads to 
superfluous use of (:) and .'   .

The above definition of length() is meant to paper over the row/column 
distinction. Octave says:

> octave:1> help length
> `length' is a built-in function
> 
>  -- Built-in Function:  length (A)
>      Return the `length' of the object A.  For matrix objects, the
>      length is the number of rows or columns, whichever is greater (this
>      odd definition is used for compatibility with MATLAB).

Guile is strict about rank, so this problem doesn't exist. Wouldn't you agree?

----

Going back to the two definitions I proposed, and after giving it some thought, 
I favor the first

  (array-length a) = (car (array-dimensions a))

more strongly than before, for these reasons:

1. Utility. I do the equivalent of (car (array-dimensions a)) much more often 
than either (fold * 1 (array-dimensions a)) or what Matlab length() does. An 
array is often also a list of objects, e.g. a list of n points in R^m is an [n 
m] shape array, or a list of n transformation matrices is an [n m m] shape 
array [*].

Of course this is because of the way I use arrays in my own code. I'd be 
interested in reading about what other people do.
 
2. Efficiency. (car (array-dimensions a)) deserves a shortcut, since it's a 
waste to construct a list only to take its car. You can say that of the other 
axes, but the first axis is used more often.

[*] This is very common in J and K, the descendants of APL. In fact K's 
'arrays' don't even need to be rectangular. But I think J can be a good model 
for Guile arrays. J has an operator '#' (tally) which is basically what I 
propose for array-length. The only difference is that in J (# scalar) gives 1, 
and this seems irregular. It maybe better to make (array-length #0(0)) an error.

Here's an implementation with this behavior.

    SCM array_length(SCM a)
    {
        scm_t_array_handle h;
        scm_array_get_handle(a, &h);
        if (scm_array_handle_rank(&h)==0) {
            scm_array_handle_release(&h);
            scm_error_scm(scm_from_locale_symbol("out-of-range"), SCM_BOOL_F,
                          scm_from_locale_string("no items for rank 0 array"), 
SCM_EOL, a);
        }
        scm_t_array_dim const * dims = scm_array_handle_dims(&h);
        SCM l = scm_from_size_t(dims->ubnd-dims->lbnd+1);
        scm_array_handle_release(&h);
        return l;
    }




reply via email to

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