# How to create 31-tuples with nonnegative entries that sum to 1

Hello. I would like to know how to create all 31-tuples (sequence of 31 numbers) whose entries are real, nonnegative, and sum up to one. One such kind of tuple would be one where exactly one of the 31 entries is 1 and all of the other remaining 30 entries are 0.

How could I ask Sage to do this?

Thank you.

edit retag close merge delete

the "numbers" are in which ring?

( 2019-11-05 12:16:53 -0600 )edit

My apologies, I just edited my post. The entries are real and nonnegative.

( 2019-11-05 12:25:39 -0600 )edit
1

There are infinitely many such tuples if you do not pose additional constraints.As an example, note that $(1/n, 1-1/n,0,0, \dots, 0)$ is such a tuple for every positive integer $n$.

( 2019-11-05 13:04:48 -0600 )edit

You could pick a random number x between 0 and 1 for the first slot, then a random number between 0 and 1-x for the second slot, etc.

( 2019-11-05 17:17:02 -0600 )edit

Sort by » oldest newest most voted

If you want to consider all the points satisfying some properties, i guess the best way it to consider those points as forming a set. In your case, the set of points is a polytope. By convenience, you can construct it from a linear program as follows:

sage: p = MixedIntegerLinearProgram()
sage: x = p.new_variable(real=True, nonnegative=True)
sage: p.add_constraint(sum(x[i] for i in range(31)) == 1)
sage: P = p.polyhedron() ; P
A 30-dimensional polyhedron in RDF^31 defined as the convex hull of 31 vertices


Then you can do things like:

sage: P.contains([1/2,1/2,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
True
sage: P.contains([1/2,1/3,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
False

sage: P.random_integral_point()
(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

sage: P.integral_points_count()
31

sage: P.dim()
30

sage: P.is_simplex()
True

sage: P.vertices_list()
...

more

Clapclapclapclapclap ! Very nice (much more general than my ad hoc solution...).

( 2019-11-06 04:45:55 -0600 )edit

As already pointed out by commenters, there are infinitely many such tuples. One way to generate them is:

def R31S1():
A=[random() for u in range(31)]
S=sum(A)
return tuple([u/S for u in A])


Let's check:

sage: T=R31S1()
sage: type(T)
<class 'tuple'>
sage: len(T)
31
sage: sum(T)
1.0
sage: all([u>=0 and u<1 for u in T])
True
sage: T
(0.006089037356475367,
0.02653861505103852,
0.048525911647988376,
0.030844994609170905,
0.02700793870208519,
0.07872299394844966,
0.015087636977883111,
0.06309180347147934,
0.05423637336235927,
0.052700158885111356,
0.06602701660767711,
0.0363743838933233,
0.013134222937337785,
0.04594966379579753,
0.025102035013684295,
0.04519431764115383,
0.002292718973017283,
0.012639236364503856,
0.030852444551295627,
0.07184775173604117,
0.04969543126517173,
0.03573006205560776,
0.01675001424706971,
0.0061099530976978155,
0.04987299807905701,
0.015149928406498115,
0.0027994609852037985,
0.013127271433974403,
0.0011150285848061565,
0.05054156008030657,
0.00684903623873419)


All of this is basic Python, nothing Sage-specific...

HTH,

more

2

Note that this random generation is not uniform on the simplex, as it comes from the projection of an hypercube (think of a square projected on its diagonal).

( 2019-11-06 04:44:07 -0600 )edit

Indeed. But the uniformity wasn't specified in the problem statement... and i'm lazy :-). Generating a simplex q=with uniform density isn't that simple...

( 2019-11-07 13:38:32 -0600 )edit