Lower conditions as well as the whole job can be done by brute force up to a certain n
In[41]:= With[{b = 7, n = 5, a = 1},
If[a < 0 || n < 0 || b < 1 || b - n < a, Print["You will get the empty set!"]];
If[a < n, Print["Your conditions run empty on lower boundary!"]];
Union[Flatten[
DeleteMissing[
Table[If[a <= Plus @@ {a1, a2, a3, a4, a5} <= b,
X[a1, a2, a3, a4, a5], Missing[]],
{a1, 1, b - 1}, {a2, 1, b - 1}, {a3, 1, b - 1}, {a4, 1,
b - 1}, {a5, 1, b - 1}], n]]] /. X -> List
]
During evaluation of In[41]:= Your conditions run empty on lower boundary!
Out[41]= {{1, 1, 1, 1, 1}, {1, 1, 1, 1, 2}, {1, 1, 1, 1, 3}, {1, 1, 1, 2, 1}, {1, 1, 1, 2, 2}, {1, 1, 1, 3, 1},
{1, 1, 2, 1, 1}, {1, 1, 2, 1, 2}, {1, 1, 2, 2, 1}, {1, 1, 3, 1, 1}, {1, 2, 1, 1, 1}, {1, 2, 1, 1, 2},
{1, 2, 1, 2, 1}, {1, 2, 2, 1, 1}, {1, 3, 1, 1, 1}, {2, 1, 1, 1, 1}, {2, 1, 1, 1, 2}, {2, 1, 1, 2, 1},
{2, 1, 2, 1, 1}, {2, 2, 1, 1, 1}, {3, 1, 1, 1, 1}}
if you want multi-indices disregarding the order, it is simply
In[42]:= With[{b = 7, n = 5, a = 1},
If[a < 0 || n < 0 || b < 1 || b - n < a, Print["You will get the empty set!"]];
If[a < n, Print["Your conditions run empty on lower boundary!"]];
Union[Sort /@
Flatten[DeleteMissing[
Table[If[a <= Plus @@ {a1, a2, a3, a4, a5} <= b,
X[a1, a2, a3, a4, a5], Missing[]],
{a1, 1, b - 1}, {a2, 1, b - 1}, {a3, 1, b - 1}, {a4, 1,
b - 1}, {a5, 1, b - 1}], n]]] /. X -> List
]
During evaluation of In[42]:= Your conditions run empty on lower boundary!
Out[42]= {{1, 1, 1, 1, 1}, {1, 1, 1, 1, 2}, {1, 1, 1, 1, 3}, {1, 1, 1, 2, 2}}
this last thing brings you to an efficient way to do it: Start with the trivial allowed lower bound multiindex {1,1,1,..., Max[1,a-n+1]}
, raise the last position until the limit b is reached ({1,1,1,...,b-n+1}
) now distribute the IntegerPartitions/@ Range[Max[1,a-n+1],b-n+1-Max[1,a-n+1]]
over the trivial allowed lower bound multiindex, with other words
In[51]:= With[{b = 7, n = 5, a = 1},
If[a < 0 || n < 0 || b < 1 || b - n < a, Print["You will get the empty set!"]];
If[a < n, Print["Your conditions run empty on lower boundary!"]];
Join[{{1, 1, 1, 1, Max[1, a - n + 1]}},
{1, 1, 1, 1, Max[1, a - n + 1]} + PadLeft[#, n] & /@
Flatten[IntegerPartitions /@
Range[Max[1, a - n + 1], b - n + 1 - Max[1, a - n + 1]], 1]]
]
During evaluation of In[51]:= Your conditions run empty on lower boundary!
Out[51]= {{1, 1, 1, 1, 1}, {1, 1, 1, 1, 2}, {1, 1, 1, 1, 3}, {1, 1, 1, 2, 2}}
if they are needed with respect to order, the result must be shuffled back to un-order.
Check for errors please, and find possibly other, even more efficient ways to do it!