3
$\begingroup$

Here is an example of what I want to do:

Suppose I have a collection of samples S = {s1, s2, s3, ...}. I want to construct the correlation matrix (and yes, this might already be built in, but this is just an example). The obvious way of doing this is by doing Outer[Correlation, S, S], but obviously this does (slightly more than) twice the amount of work necessary. There are ugly ways to fix this, for example, defining a function

 corr[i_, j_]:= If[i>j, Correlation[S[[i]], S[[j]]], 0]

but this does not appeal (and it is also space-wasteful). Is there an elegant solution?

$\endgroup$
7
  • $\begingroup$ In other words, are you trying to more efficiently implement Outer[ #1, #2, #2]&? Or is your question more specific? $\endgroup$
    – jjc385
    Apr 29, 2017 at 18:28
  • $\begingroup$ @jjc385 I am trying to do things more efficiently when the function is symmetric in the arguments, so one does not do the computation twice over. $\endgroup$
    – Igor Rivin
    Apr 29, 2017 at 18:39
  • $\begingroup$ @IgorRivin does my answer work. If not let me know so that i can delete it ! $\endgroup$
    – Ali Hashmi
    Apr 29, 2017 at 18:40
  • $\begingroup$ @Igor Ah, yes, of course the function needs to be symmetric in the arguments. Is it possible Outer does this automatically when its first argument is Orderless? $\endgroup$
    – jjc385
    Apr 29, 2017 at 18:41
  • 1
    $\begingroup$ @AliHashmi Yes, that does work, but it is not so different from what I suggest Maybe there is only one real way to do this.... $\endgroup$
    – Igor Rivin
    Apr 29, 2017 at 19:35

1 Answer 1

4
$\begingroup$
S = {s1, s2, s3, s4};
ls = SparseArray[{i_, j_} :> Correlation[S[[i]], S[[j]]] /; i > j,
ConstantArray[Length@S,2]] // Quiet;

ls//Normal

(* {{0, 0, 0, 0}, {Correlation[s2, s1], 0, 0, 0}, {Correlation[s3, s1], 
Correlation[s3, s2], 0, 0}, {Correlation[s4, s1], 
Correlation[s4, s2], Correlation[s4, s3], 0}} *)

this is same as:

ls = Outer[Correlation, S, S] // Quiet;
Do[If[i <= j, ls[[i, j]] = 0], {i, 4}, {j, 4}];
ls
(* {{0, 0, 0, 0}, {Correlation[s2, s1], 0, 0, 0}, {Correlation[s3, s1], 
Correlation[s3, s2], 0, 0}, {Correlation[s4, s1], 
Correlation[s4, s2], Correlation[s4, s3], 0}} *)
$\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.