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
    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
    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
    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$ 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$ 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$ 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$ 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$ Dec 20, 2015 at 15:44
  • $\begingroup$ @JanePotter Then simply use reimg = u\[Transpose].Unm.u; $\endgroup$
    – xzczd
    Dec 20, 2015 at 15:46
  • $\begingroup$ it works!! Now it is 50 times faster!! Thanks so much!! $\endgroup$ Dec 20, 2015 at 15:52

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.