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
next prev parent 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).