unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Daniel Llorens <daniel.llorens@bluewin.ch>
To: Andy Wingo <wingo@pobox.com>
Cc: ludo@gnu.org, guile-devel@gnu.org
Subject: Re: propose deprecation of generalized-vector-*
Date: Wed, 23 Jan 2013 13:20:43 +0100	[thread overview]
Message-ID: <2D31D517-08F8-4D07-84DB-098E335AE0AD@bluewin.ch> (raw)
In-Reply-To: <87mww0nu8l.fsf@pobox.com>


On Jan 23, 2013, at 10:06, Andy Wingo wrote:

> For C, that makes sense.  Something should be done for Scheme as well,
> but it's not terribly urgent.  Perhaps make scm_array_ref not be bound
> to "array-ref", and instead bind "array-ref" to some function that takes
> two optional arguments and a rest argument.  A poor man's case-lambda...

Just saying…

I have written a general rectangular selector for arrays as in APL.

It depends on having a prefix-selection operator. Here's an example from numpy:

In [1]: import numpy as np

In [2]: a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

In [3]: a
Out[3]:
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

In [4]: a[1]
Out[4]: array([4, 5, 6])

In [5]: a[1, 1]
Out[5]: 5

array-ref can be extended very simply to do that. It accumulates on the position as it is done now, but if the index list comes up short it makes a shared array with the remaining axes instead of giving a rank error. So it shouldn't be any slower than array_ref.

This cannot be done properly from user code with current Guile because scm_i_make_array() and friends are internal. The only option is make-shared-array. Now, this is a nice interface for general slicing, but it requires creating a closure that is only going to be used rank+1 times, plus a bunch of lists. Let's say that I want to iterate through the rows of a [100000 x 3] array. Moving from row to row is fundamentally just moving a pointer. make-shared-array is not a practical way to do it.

The extension of array-ref below isn't a real fix for this use case, because we're still creating a array descriptor for each iteration. But it's way faster than make-shared-array and it is a natural extension. I'm proposing a patch for this.

The only wart is what happens with arrays of rank 0. The function below doesn't return views of rank 0, but the element instead, just as array-ref does. The only advantage of returning a rank 0 view is that one could in principle modify the array through it, but they are a pain to deal with otherwise. My ‘solution’ is to treat the result of array-ref as read-only.

In APL/J there's no difference between an array of rank 0 and a scalar, so this problem doesn't exist. We may have a similar extension to (array-set! array obj . idxlist) where obj is an array of rank (rank(obj)-length(idxlist)) but an element if this gives 0. This would be just a wrapper over array-copy(array-ref) or the current array-set!.

Otherwise I think it should be possible to manipulate SCM_I_ARRAY_DIMS directly, at least from C. Unless there is a way already and I didn't realize, that would be great.

// Generalization of array-ref where the number of indices may be smaller than the rank of a.

    SCM from_(SCM a, SCM i_)
    {
        SCM i = i_;
        scm_t_array_handle ah;
        scm_array_get_handle(a, &ah);
        scm_t_array_dim * as = scm_array_handle_dims(&ah);
        int arank = scm_array_handle_rank(&ah);
        int k = arank;
        ssize_t pos = 0;
        for (; k>0 && scm_is_pair(i); --k, ++as, i=scm_cdr(i)) {
            ssize_t ik = scm_to_ssize_t(scm_car(i));
            if (ik<as->lbnd || ik>as->ubnd) {
                scm_array_handle_release(&ah);
                scm_error_scm(scm_from_locale_symbol("out-of-range"), SCM_BOOL_F,
                              scm_from_locale_string("indices out of range"),
                              SCM_EOL, i_);
            }
            pos += (ik-as->lbnd)*as->inc;
        }
        SCM o;
        if (k>0) {
            if (k==arank) {
                o = a;
            } else {
                o = scm_i_make_array(k);
                SCM_I_ARRAY_V(o) = SCM_I_ARRAY_V(a);
                SCM_I_ARRAY_BASE(o) = pos + SCM_I_ARRAY_BASE(a); // since arank>1.
                scm_t_array_dim * os = SCM_I_ARRAY_DIMS(o);
                for (; k>0; --k, ++as, ++os) {
                    os->ubnd = as->ubnd;
                    os->lbnd = as->lbnd;
                    os->inc = as->inc;
                }
            }
        } else if (scm_is_null(i)) {
            o = scm_array_handle_ref(&ah, pos); // these may be non-arrays.
        } else {
            scm_array_handle_release(&ah);
            scm_error_scm(scm_from_locale_symbol("out-of-range"), SCM_BOOL_F,
                          scm_from_locale_string("too many indices"), SCM_EOL, i_);
        }
        scm_array_handle_release(&ah);
        return o;
    }


> FWIW this is not the case.  Vectors hold SCM objects, whereas uniform
> vectors hold unpacked machine values.

Ok, I think I understand that. Still I don't see where the vref field for the srfi4 types is set. The conversions seem to be done in bytevector.c, can you point this out?

I've also noticed

scheme@(guile-user)> (f64vector-ref #s64(1 2 3) 0)
$1 = #.#
scheme@(guile-user)> (c64vector-ref #f64(1 2 3) 0)
$3 = 1.0+2.0i

(!)

Regards

	Daniel





  reply	other threads:[~2013-01-23 12:20 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <mailman.153.1351958430.10005.guile-devel@gnu.org>
2012-11-03 16:52 ` propose deprecation of generalized-vector-* Daniel Llorens
2012-11-03 21:10   ` Ludovic Courtès
2013-01-21 16:11     ` Andy Wingo
2013-01-22 14:31       ` Daniel Llorens
2013-01-22 18:31         ` Daniel Llorens
2013-01-22 20:52           ` Andy Wingo
2013-01-22 23:27             ` Daniel Llorens
2013-01-23  9:20               ` Andy Wingo
2013-01-23 14:55             ` Ludovic Courtès
2013-01-23  9:06         ` Andy Wingo
2013-01-23 12:20           ` Daniel Llorens [this message]
2013-02-18 15:55             ` Andy Wingo
2013-02-18 16:05               ` Noah Lavine
2013-02-18 16:25                 ` Mike Gran
2013-02-18 16:29                   ` Noah Lavine
2013-02-18 17:11                     ` David Pirotte
2013-02-18 17:17                       ` Mike Gran
2013-02-18 23:57                   ` Daniel Hartwig
2013-02-18 23:12               ` Problems with 'number->string' (was Re: propose deprecation of generalized-vector-*) Mark H Weaver
2013-02-21  1:13               ` propose deprecation of generalized-vector-* Daniel Llorens
2013-02-22  0:22                 ` Noah Lavine
2013-02-28 19:10                   ` Daniel Llorens
2013-03-01  2:42                     ` Noah Lavine
2013-03-01  3:46                       ` Noah Lavine
2013-03-01  9:01                       ` Daniel Llorens
2013-03-01  9:44                         ` Andy Wingo
2013-03-04  2:27                         ` Noah Lavine
2013-03-08 23:42                           ` array operations Daniel Llorens
2013-02-18 15:40           ` propose deprecation of generalized-vector-* Andy Wingo
2013-02-28 23:04 Nelson H. F. Beebe
2013-03-04 12:48 ` Aharon Robbins
     [not found] <mailman.191.1348070449.18828.guile-devel@gnu.org>
2012-09-19 17:20 ` Daniel Llorens
  -- strict thread matches above, loose matches on Subject: below --
2012-09-18 14:49 Daniel Llorens
2012-09-19 12:02 ` Peter TB Brett
2012-11-02 23:27 ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2D31D517-08F8-4D07-84DB-098E335AE0AD@bluewin.ch \
    --to=daniel.llorens@bluewin.ch \
    --cc=guile-devel@gnu.org \
    --cc=ludo@gnu.org \
    --cc=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).