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 |
* 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/