Could somebody teach me how to compile this code?

Do[uu = Outer[Times, u[[n1]], u[[m1]]];
   Unm[[n1, m1]] = Flatten[uu].Flatten[data], {n1, n}, {m1,  n}]; 
Do[uuu = Outer[Times, u[[All, s]], u[[All, t]]];
   reimg[[s, t]] = Flatten[uuu].Flatten[Unm], {s, sz}, {t,  sz}]; 

This part of code calculates image moment. data is image data with size sz*sz. Unm is a table of moment which I try to get. u is a table size of n*sz. usually n=sz. My code runs hours to get the reconstruction image, reimg. How could I compile this code? All of the arguments are tables of list, that is what confuse me the most. This code is upgrade from this Original code:

Do[Unm[[n1, m1]] = 
    Sum[Sum[u[[n1, s]] u[[m1, t]] data[[s, t]], {s, sz}], {t, 
      sz}], {n1, n}, {m1, n}]; 
Do[reimg[[s, t]] = 
    Sum[Sum[ Unm[[n1, m]] u[[n1, s]] u[[m, t]], {n1, n}], {m, n}], {s,
     sz}, {t, sz}];

The first code is 2 times faster than the original one, but still not fast enough.Please Help!!!

I try to compile the Unm part like this:

fc = Compile[{{list1, _Real, 1}, {list2, _Real, 1}}, Unm = list1.list2, 
             Parallelization -> True, RuntimeAttributes -> {Listable}];
Do[list1 = Flatten[Outer[Times, u[[n1]], u[[m1]]]]; list2 = Flatten[data];
  Unm = fc[list1, list2], {n1, n}, {m1, n}];

It says:

Flatten::normal: "Nonatomic expression expected at position 1 in Flatten[1.38595258992021`].

What does it mean?

Based on answers below, here is the update code:

Unm = u.data.u\[Transpose]; 
reimg1 = u\[Transpose].Unm.u;

It's simple. It's elegant. It runs like lightning. Love it. Thanks for helping out!

  • 1
    $\begingroup$ It's better if you provide some simple sample data for people to try. $\endgroup$
    – IPoiler
    Commented Dec 19, 2015 at 22:27
  • $\begingroup$ You might also want to try Unm=Table[Sum[...],{n1,n},{m1,n}] as opposed to Do[Unm ...] and likewise for the second Do loop you've defined for reimg. $\endgroup$
    – IPoiler
    Commented Dec 19, 2015 at 22:31
  • $\begingroup$ Have you looked at Moments and/or CentralMoments? It looks like you are reproducing built in function. $\endgroup$
    – bill s
    Commented Dec 19, 2015 at 22:46
  • $\begingroup$ @bills Yes, I have try Moment, but it doesn't seem like doing what I trying to do here. $\endgroup$ Commented Dec 19, 2015 at 23:06
  • $\begingroup$ As far as I can tell, Map[Flatten, Transpose /@ Outer[Times, u, u], {2}].data is your Unm. Is that a) doing what you want, and b) faster? $\endgroup$ Commented Dec 19, 2015 at 23:22

1 Answer 1


Compile is the toy of experienced Mathematica user. You'd better improve your understanding for the core language first. As to your specific question, your attempt can be achieved simply with

reimg = u\[Transpose].u.data.u\[Transpose].u; 
  • $\begingroup$ Thanks. That is exactly what I think I should do. The results of compile don't have enough precision in my case anyway, so I think I should try paralize or something else. $\endgroup$ Commented Dec 20, 2015 at 14:54
  • $\begingroup$ I have try your code, and it is about 40 times faster than mine. That is amazing!! $\endgroup$ Commented Dec 20, 2015 at 15:33
  • $\begingroup$ But, there is one problem, reimg is supposed to be construct by Unm, instead of data. data is the original image. $\endgroup$ Commented Dec 20, 2015 at 15:44
  • $\begingroup$ @JanePotter Then simply use reimg = u\[Transpose].Unm.u; $\endgroup$
    – xzczd
    Commented Dec 20, 2015 at 15:46
  • $\begingroup$ it works!! Now it is 50 times faster!! Thanks so much!! $\endgroup$ Commented Dec 20, 2015 at 15:52

Your Answer

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

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