Hans L on Thu, 03 Jul 2025 03:53:48 +0200


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

Re: choosing k elements from a "set", and concat of vecsmall


Thanks for the thoughtful reply and explanation. 

On Wed, Jul 2, 2025, 4:57 PM Karim Belabas <Karim.Belabas@u-bordeaux.fr> wrote:
* Hans L [2025-07-02 22:33]:
> I often have a need to loop over all "n choose k" elements from a set.  The
> closest builtin functionality I have found for this  is to use forsubset,
> and then build a vector from that with vector as follows:
>
> forsubset([#S,k], s0,
>   my(s = vector(k, i, S[s0[i]]));
>   ...
> );
>
> Is there any more appropriate/efficient way to do such a thing?  It seems a
> little convoluted and odd to me that forsubset can't optionally accept a
> vector as input.

 forsubset([#S,k], s0,
   my(s = vecextract(S, s0));
   ...
 );

> Another somewhat related thing I noticed recently which feels like an
> oversight is when that concat is presented with a t_VEC and t_VECSMALL, it
> just inserts the t_VECSMALL as a single element.

It's not an oversight. There is an ambiguity about what "converting x to
a vector" means and I chose the simplest definition: not Vec(x) but
simply [x].

In particular, concat([1,2,3], 4*t + 5) returns concat([1,2,3, 4*t + 5])
and not [1,2,3,4,5] (N.B. Vec(4*t+5) = [4,5].)

The concat function is hard to describe completely and ??concat only
tells part of the story.

0)concat(x, y) works "as expected" when x and y have the same type.

It should probably have been left that way, requiring explicit type
coercions throughout to avoid ambiguities and surprising behavious.
Unfortunately, but in agreement with PARI philosophy, I have overloaded
it for convenience a long time ago, which made is somewhat "surprising".

1) There are special rules when either x or y is a t_MAT, t_LIST or t_STR:
we convert the other argument to the relevant type and concat as before.
(in particular, concat([1,2], "x") is "[1, 2]x" and not [1, 2,"x"] !)

We don't do this for t_VECSMALL: it's in general not possible to convert
the other element to a word-sized integer type fitting in a t_VECSMALL.

2) A "vector type" is defined as t_VEC or t_COL. concat(v, x), when v is
a vector type but x is not, converts x to the type of v in the above
sense ([x] or [x]~), then concatenates. More simply, it appends x to v.

It indeed follows that concat(v, t_VECSMALL) appends the t_VECSMALL to v.

Rationale for t_VECSMALL not being a vector type: a vector is either for
linear algebra or a collection of arbitrary objects. t_VECSMALL are
neither. In most cases, they arise as permutations or partitions, and
are viewed as an atomic object and not as a collection of integers.

3) concat(x, y) is just [x, y] when none of x,y are vector types.
In particular, concat(Vecsmall([1,2]), 3)  is  [Vecsmall([1, 2]), 3]

There are other rules but the above is complex enough already. I don't
want to add further special cases.

Cheers,

    K.B.
--
Pr. Karim Belabas, U. Bordeaux, Vice-président en charge du Numérique
Institut de Mathématiques de Bordeaux UMR 5251 - (+33) 05 40 00 29 77
http://www.math.u-bordeaux.fr/~kbelabas/