Skip to main content

list manipulation - Equivalent Nested Loop Structure


Consider the following examples:


Flatten @ Table[ f[a, b, c], {a, 1, 3}, {b, 1, 3}, {c, 1, 3}] ==
f @@@ Tuples[ Range[3], 3]

Flatten @ Table[ If[ a != b != c, f[a, b, c], Unevaluated[]],
{a, 1, 3}, {b, 1, 3}, {c, 1, 3}] ==
f @@@ Permutations[ Range[3], {3}]


Flatten @ Table[ f[a, b, c], {a, 1, 5}, {b, a + 1, 5}, {c, b + 1, 5}] ==
f @@@ Subsets[ Range[5], {3}]


True
True
True

Is there a similar built-in function performing this:



Flatten @ Table[ f[a, b, c], {a, 1, 5}, {b, a, 5}, {c, b, 5}]

in a simpler way?



Answer



Here a two more ways, neither of them built-in.
f @@ (# - {0,1,2})& /@ Subsets[Range@7,{3}]
f @@@ Transpose[Transpose@Subsets[Range@7,{3}] - {0,1,2}]


EDIT - The question is related to a long and somewhat tangled MathGroup thread generating submultisets with repeated elements. "sms" below stands for for "submultisets".


sms[n_, k_, f_:List] := With[{i = Table[Unique[],{k}]}, Flatten[Table[f@@i,
Evaluate[Sequence@@Transpose@{i,Prepend[Most@i,1],Table[n,{k}]}]],k-1]]


sms[5, 3]
sms[5, 3, f]


{{1,1,1}, {1,1,2}, {1,1,3}, {1,1,4}, {1,1,5}, {1,2,2}, {1,2,3}, {1,2,4}, {1,2,5}, {1,3,3}, {1,3,4}, {1,3,5}, {1,4,4}, {1,4,5}, {1,5,5}, {2,2,2}, {2,2,3}, {2,2,4}, {2,2,5}, {2,3,3}, {2,3,4}, {2,3,5}, {2,4,4}, {2,4,5}, {2,5,5}, {3,3,3}, {3,3,4}, {3,3,5}, {3,4,4}, {3,4,5}, {3,5,5}, {4,4,4}, {4,4,5}, {4,5,5}, {5,5,5}}


{f[1,1,1], f[1,1,2], f[1,1,3], f[1,1,4], f[1,1,5], f[1,2,2], f[1,2,3], f[1,2,4], f[1,2,5], f[1,3,3], f[1,3,4], f[1,3,5], f[1,4,4], f[1,4,5], f[1,5,5], f[2,2,2], f[2,2,3], f[2,2,4], f[2,2,5], f[2,3,3], f[2,3,4], f[2,3,5], f[2,4,4], f[2,4,5], f[2,5,5], f[3,3,3], f[3,3,4], f[3,3,5], f[3,4,4], f[3,4,5], f[3,5,5], f[4,4,4], f[4,4,5], f[4,5,5], f[5,5,5]}



sms[data_List, k_, f_:List] := With[{i = Table[Unique[],{k}]}, Flatten[Table[f@@data[[i]],
Evaluate[Sequence@@Transpose@{i,Prepend[Most@i,1],Table[Length@data,{k}]}]],k-1]]


data = {a,b,c,d,e};
sms[data, 3]
sms[data, 3, f]


{{a,a,a}, {a,a,b}, {a,a,c}, {a,a,d}, {a,a,e}, {a,b,b}, {a,b,c}, {a,b,d}, {a,b,e}, {a,c,c}, {a,c,d}, {a,c,e}, {a,d,d}, {a,d,e}, {a,e,e}, {b,b,b}, {b,b,c}, {b,b,d}, {b,b,e}, {b,c,c}, {b,c,d}, {b,c,e}, {b,d,d}, {b,d,e}, {b,e,e}, {c,c,c}, {c,c,d}, {c,c,e}, {c,d,d}, {c,d,e}, {c,e,e}, {d,d,d}, {d,d,e}, {d,e,e}, {e,e,e}}


{f[a,a,a], f[a,a,b], f[a,a,c], f[a,a,d], f[a,a,e], f[a,b,b], f[a,b,c], f[a,b,d], f[a,b,e], f[a,c,c], f[a,c,d], f[a,c,e], f[a,d,d], f[a,d,e], f[a,e,e], f[b,b,b], f[b,b,c], f[b,b,d], f[b,b,e], f[b,c,c], f[b,c,d], f[b,c,e], f[b,d,d], f[b,d,e], f[b,e,e], f[c,c,c], f[c,c,d], f[c,c,e], f[c,d,d], f[c,d,e], f[c,e,e], f[d,d,d], f[d,d,e], f[d,e,e], f[e,e,e]}



Comments

Popular posts from this blog

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...