# How to use Compile to generate an $n\times n$ array using $n$ vectors

Let's consider the following:

n = 1000; m=3;
p = RandomReal[{0, 9}, {n,m}];

f = Compile[{{ps, _Real, 2}},
Outer[
Which[
2 < Abs[#1[[1]] - #2[[1]]] < 3 && 2 < Abs[#1[[2]] - #2[[2]]] < 3,
Sin@Norm[#1 - #2],
2 < Abs[#1[[2]] - #2[[2]]] < 3 && 2 < Abs[#1[[3]] - #2[[3]]] < 3,
Cos@Norm[#1 - #2]
,True, 0]
&, ps, ps]];

f[p]


It gives the error message

Compile::part: Part specification CompileFunctionVariable\$41818[1] cannot be compiled since the argument is not a tensor of sufficient rank. Evaluation will use the uncompiled function. >>

because Outer doesn't combine vectors like it does elements (see f.e. Outer[h, {{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}] - the elements are not say h[{1,2},{5,6}] as you might think, which is what I want). How can I solve this? I left the Compile in because it is important to me that the solution is compilable.

The result should be a sparse array of numeric values.

This is basically an extension of my earlier question Faster use of Condition for a large array (see the example) which was answered by Pickett. As the code above shows, I don't know what to do when p is a two-dimensional list instead of a one-dimensional list.

• Please provide a rewritten version of my answer to the other question with Sin, Cos and the new conditions, and we can help you from there. Mathematica code is strongly preferred, when possible, over the math formulas. Jul 18, 2015 at 13:24
• Hi @Pickett, I added your earlier answer and answer of the present problem using Which and Table. Jul 18, 2015 at 16:26
• Do you mind if I edit your question (a big edit)? You can roll it back if you don't like the edit, but I want to show you how I think this question should be asked to increase the likelihood of getting an answer. Jul 19, 2015 at 0:04
• ok, there we go. When I asked you to modify my answer from the other question, this is what I was looking for. Even if you take out the part about Outer which you may not have been able to write, this question would still be very readable. Anyone can see from the code what you are trying to do etc. the math formulas etc. were mere distractions because they weren't what you had a problem with. The way your first question was written you would have us type the formulas into Mathematica before we could even begin to think about the problem. Jul 19, 2015 at 0:41
• Thanks for the guidance @Pickett. As I told you I am quite novice who just stars speaking mathematica. This example question would be really helpful. Jul 19, 2015 at 1:13

## 1 Answer

It is true that Outer cannot solve this problem inside Compile. Outside Compile it works to change the head p to something other than List, but Compile doesn't work with general heads. Instead you have to use another function to create the matrix. I suggest:

f = Compile[{{p, _Real, 2}},
Table[Which[
2 < Abs[#1[[1]] - #2[[1]]] < 3 && 2 < Abs[#1[[2]] - #2[[2]]] < 3, Sin@Norm[#1 - #2],
2 < Abs[#1[[2]] - #2[[2]]] < 3 && 2 < Abs[#1[[3]] - #2[[3]]] < 3, Cos@Norm[#1 - #2],
True, 0] &[x, y], {x, p}, {y, p}]
]
`