5
$\begingroup$

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!

$\endgroup$
  • 1
    $\begingroup$ It's better if you provide some simple sample data for people to try. $\endgroup$ – IPoiler Dec 19 '15 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 '15 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 '15 at 22:46
  • $\begingroup$ @bills Yes, I have try Moment, but it doesn't seem like doing what I trying to do here. $\endgroup$ – Jane Potter Dec 19 '15 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$ – Patrick Stevens Dec 19 '15 at 23:22
12
$\begingroup$

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; 
$\endgroup$
  • $\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$ – Jane Potter Dec 20 '15 at 14:54
  • $\begingroup$ I have try your code, and it is about 40 times faster than mine. That is amazing!! $\endgroup$ – Jane Potter Dec 20 '15 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$ – Jane Potter Dec 20 '15 at 15:44
  • $\begingroup$ @JanePotter Then simply use reimg = u\[Transpose].Unm.u; $\endgroup$ – xzczd Dec 20 '15 at 15:46
  • $\begingroup$ it works!! Now it is 50 times faster!! Thanks so much!! $\endgroup$ – Jane Potter Dec 20 '15 at 15:52

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.