2
$\begingroup$

I have a list of lists with different lengthes:

{{a1,a2},{b1,b2},{c1,c2,c3},...}

Now I want to create a matrix the following way:

{{       0,        0, f[b1,a1], f[b2,a1], f[c1,a1], f[c2,a1], f[c3,a1],...},
 {       0,        0, f[b1,a2], f[b2,a2], f[c1,a2], f[c2,a2], f[c3,a2],...},
 {f[a1,b1], f[a2,b1], 0       , 0       , f[c1,b1], f[c2,b1], f[c3,b1],...},
 {f[a1,b2], f[a2,b2], 0       , 0       , f[c1,b2], f[c2,b2], f[c3,b2],...},
 {f[a1,c1], f[a2,c1], f[b1,c1], f[b2,c1], 0       , 0       , 0       ,...},
 {f[a1,c2], f[a2,c2], f[b1,c2], f[b2,c2], 0       , 0       , 0       ,...},
 {f[a1,c3], f[a2,c3], f[b1,c3], f[b2,c3], 0       , 0       , 0       ,...},
 {                                   ...                                  }}

If it weren't for those zero-blocks I could simplify use flatten on my nested list, but I somehow need to "remember" the structure it. Note that a1,.. are just placeholders to better show what I mean. In reality a1 could be equal to b2 for example. Maybe one could do this in two steps and set the zeros in the second one. But I'm not sure how to do this without for-loops either.

$\endgroup$

2 Answers 2

2
$\begingroup$
blocks[l_List, f_] := Module[{m},
  m = Transpose@Outer[f, #, #] &@Flatten[l];
  (m[[#, #]] = 0) & /@ 
   Span @@@ (# + {1, 0} & /@ Partition[{0}~Join~Accumulate[Length /@ l], 2, 1]);
  m
  ]

blocks[{{a1, a2}, {b1, b2}, {c1, c2, c3}}, f] // MatrixForm

enter image description here


blocks[{{a1, a2, a3}, {b1}, {c1, c2}}, f] // MatrixForm

enter image description here

$\endgroup$
0
$\begingroup$
blocks[l_List, f_] := Map[f @@ # &,
Module[{m = 0, F = Flatten[l], Q},
ReplacePart[Table[Q[i, j], {j, F}, {i, F}],
Flatten[Tuples[#, 2] & /@ Map[++m &, l, {2}], 1] -> 0]], {2}]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.