Message Boards Message Boards

Make code faster and in C-compatible manner?

Posted 8 years ago

Hello,

I need to make the following code very fast:

B[a_, m_, t_] := Module[{n, p, q, seq, s, f, b},
   n = 1 - m; p = m/a; q = m (1 - 1/a);
   seq[i_, j_] := 
    Sequence @@ 
     Flatten[Table[{i == K || j == t - K, s[i, j, K]}, {K, 1, 
        Round[t/2]}], 1];
   s[i_, j_, K_] := 
    Sum[Binomial[i, i - k] Binomial[t - i, j - i + k] (p q)^
       k ((n + p) (n + q))^(K - k), {k, 0, K}];
   f[i_, j_] := 
    If[(t - i - j) >= 0, (n + p)^(t - i - j), (n + q)^-(t - i - j)];
   b[i_, j_] := Which[
     j == t, p^(j - i) f[i, j] Binomial[t, i],
     i == t, q^(i - j) f[i, j] Binomial[t, j],
     i <= j, 
     p^(j - i) f[i, j] Binomial[t, i] Which[Evaluate[seq[i, j]]],
     i > j, 
     q^(i - j) f[i, j] Binomial[t, j] Which[Evaluate[seq[j, i]]]];
   Return[Table[b[i, j], {i, 1, t}, {j, 1, t}]]];

It generates a t x t numerical matrix for an integer a and a real number m between 0 and 1. For low t it is fast enough but I need it for t=2000. I estimated that this would take years on a desktop computer... So I guess I need to compile the whole thing to C-code and possibly parallelize it. The problem is the seq function. It says that it cannot be compiled because the expression "Sequence" is not allowed. It generates a sequence of conditions of length t/2 and also uses the function s inside it. How can it be written in C-compatible manner? And is it possible to compile a function that uses another inside it? So I have a lot of questions. Unfortunately, my programming skills are only basic so any help would greatly be appreciated.

POSTED BY: Ulrich Utiger
Posted 8 years ago

In case anyone is interested: the main brake in the above code is the seq function. It creates useless redundancy because the list of conditions it generates can be integrated directly into Do-loops as follows:

B[a_, m_, t_] := Module[{n, p, q, s, f, b},
   n = 1 - m; p = m/a; q = m (1 - 1/a);
   s[i_, j_, K_] := 
    Sum[Binomial[i, i - k] Binomial[t - i, j - i + k] (p q)^
       k ((n + p) (n + q))^(K - k), {k, 0, K}];
   f[i_, j_] := 
    If[(t - i - j) >= 0, (n + p)^(t - i - j), (n + q)^-(t - i - j)];
   Do[b[i, j] = 
     p^(j - i) f[i, j] Binomial[t, i]/Binomial[t, j] s[i, j, i], {i, 
     1, Round[t/2] + 1}, {j, i, t - i}];
   Do[b[i, j] = 
     p^(j - i)
       f[i, j] Binomial[t, i]/Binomial[t, j] s[i, j, t - j], {j, 
     Round[t/2], t - 1}, {i, t - j + 1, j}];
   Do[b[i, t] = p^(t - i) f[i, t] Binomial[t, i], {i, 1, t}];
   Do[b[j, i] = (q/p)^(j - i)
       b[i, j] Binomial[t, j]/Binomial[t, i], {i, 1, t}, {j, i + 1, 
     t}];
   Return[Table[b[i, j], {i, 1, t}, {j, 1, t}]]];

This way it is possible to reduce the time for t=2000 from thousands of years to hours, still non-compiled...

POSTED BY: Ulrich Utiger
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract