Karim Belabas on Wed, 02 Jul 2025 23:57:57 +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/