3
$\begingroup$

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 Compile`FunctionVariable$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.

$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – C. E. Jul 18 '15 at 13:24
  • $\begingroup$ Hi @Pickett, I added your earlier answer and answer of the present problem using Which and Table. $\endgroup$ – Sumit Jul 18 '15 at 16:26
  • $\begingroup$ 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. $\endgroup$ – C. E. Jul 19 '15 at 0:04
  • 1
    $\begingroup$ 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. $\endgroup$ – C. E. Jul 19 '15 at 0:41
  • 1
    $\begingroup$ 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. $\endgroup$ – Sumit Jul 19 '15 at 1:13
4
$\begingroup$

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}]
  ]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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