Let's start by defining a helper function that will find all of the partitions of an integer that contains exactly k components:
partitions[n_, k_] :=
Composition[Union, Permutations, PadRight[#, k]&] /@ IntegerPartitions[n, k] //
Flatten[#, 1]& //
Sort
We let IntegerPartitions do the heavy-lifting, but pad the results with zeroes so that there are always exactly k components. We permute each of the results and eliminate duplicates. Flatten is used to undo the extra list level introduced by Permutations. Finally, we Sort the result to impose a canonical order (this step is optional).
Here it is in action:
partitions[3, 3]
(*{{0,0,3},{0,1,2},{0,2,1},{0,3,0},{1,0,2},{1,1,1},{1,2,0},{2,0,1},{2,1,0},{3,0,0}}*)
We then use this helper function to define the main function:
setPartitions[a_, k_] :=
Module[{n = Length@a, z = 0 a}
, partitions[#, k]& /@ a //
Tuples //
Transpose[#, {1, 3, 2}]& //
Select[#, FreeQ[#, z]&]&
]
This invokes the helper function on each element of a. All possible combinations of the individual element partitions are then assembled using Tuples. Transpose generates the result vector sets. Finally, any combination involving the zero vector is removed.
Sample use:
setPartitions[{1, 2}, 2]
(*{{{0, 1}, {1, 1}}, {{0, 2}, {1, 0}}, {{1, 0}, {0, 2}}, {{1, 1}, {0, 1}}}*)
setPartitions[{3, 5, 7}, 2] generates the same 190 sets as the code exhibited in the question applied to the same parameters. On my machine, the original code took 1.89s to run whereas setPartitions was too fast to measure (0s reported). Notwithstanding this improvement, beware that this problem generates very large solution sets for even small increases in magnitude of k, n or the individual a[[i]]. For example, setPartitions[{3, 5, 7}, 5] took 9.08s to generate 856,985 solutions.
Edit
At the suggestion of @rasher, partitions can be expressed more concisely thus:
partitions[n_, k_] :=
Join @@ (Permutations /@ IntegerPartitions[n, {k}, Range[0, n]]) // Sort
Once again, the Sort is optional and is only there to obtain the same order of results as the code in the question. I would recommend removing the Sort if that order is not crucial.
IntegerPartitions... – ciao Mar 23 '14 at 03:31