Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6195813
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T03:32:02+00:00 2026-05-24T03:32:02+00:00

Verbeia opened up a rather interesting discussion on the performance of the functional programming

  • 0

Verbeia opened up a rather interesting discussion on the performance of the functional programming style in Mathematica. It can be found here: What is the most efficient way to construct large block matrices in Mathematica?)

I’m working on a problem, and after doing some timing of my code one particularly time consuming portion is where I calculate entries of a matrix through a recurrence relation:

c = Table[0, {2L+1}, {2L+1}];

c[[1, 1]] = 1;
Do[c[[i, i]] = e[[i - 1]] c[[i - 1, i - 1]], {i, 2, 2 L + 1}];
Do[c[[i, 1]] = (1 - e[[i - 1]]) c[[i - 1, 1]], {i, 2, 2 L + 1}];
Do[c[[i, j]] = (1 - e[[i - 1]]) c[[i - 1, j]] + 
    e[[i - 1]] c[[i - 1, j - 1]], {i, 2, 2 L + 1}, {j, 2, i - 1}];

Where e is some externally defined list. Is there any way I could write this in a more efficient manner? I can’t seem to find any obvious way of using the built in functions to accomplish this in a more idiomatic and efficient way.

I realize I can only do so much, since this code is O(n^2), but I have a series of matrix multiplications (About 6 in all) that, combined, take less time to run than this statement. Anything I can do to speed this up even slightly would make an appreciable difference in run times for me.

Update:
In line with what acl recommended, I tried using Compile to speed up my expressions. For a relatively small L = 600, I get 3.81 seconds on the naive Do[...], 1.54 seconds for plain old Compile, and 0.033 seconds for Compile[..., CompilationTarget->"C"].

For a more realistic size of L = 1200, the timings become 16.68, 0.605, and 0.132 for Do, Compile and Compile[.., CompilationTarget->"C"] respectively. I’m able to achieve the same 2 orders of magnitude speedup that acl mentioned in his post.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T03:32:02+00:00Added an answer on May 24, 2026 at 3:32 am

    Try Compile. Here I define 3 functions: f as you defined it, fc compiled (to some sort of bytecode) and fcc compiled to C (look up the documentation as to how to examine the generated code).

    First, make mma tell us if something can’t be compiled:

    SetSystemOptions["CompileOptions"->"CompileReportExternal"->True]
    

    then the functions:

    ClearAll[f];
    f=Function[{ell,e},
        Module[{c=Table[0,{2ell+1},{2ell+1}]},
            c[[1,1]]=1;
            Do[c[[i,i]]=e[[i-1]] c[[i-1,i-1]],{i,2,2 ell+1}];
            Do[c[[i,1]]=(1-e[[i-1]]) c[[i-1,1]],{i,2,2 ell+1}];
            Do[c[[i,j]]=(1-e[[i-1]]) c[[i-1,j]]+e[[i-1]] c[[i-1,j-1]],
                {i,2,2 ell+1},{j,2,i-1}];
            c
        ]
    ];
    
    
    ClearAll[fc];
    fc=Compile[{{ell,_Integer},{e,_Integer,1}},
        Module[{c},
            c=Table[0,{2ell+1},{2ell+1}];
            c[[1,1]]=1;
            Do[c[[i,i]]=e[[i-1]] c[[i-1,i-1]],{i,2,2 ell+1}];
            Do[c[[i,1]]=(1-e[[i-1]]) c[[i-1,1]],{i,2,2 ell+1}];
            Do[c[[i,j]]=(1-e[[i-1]]) c[[i-1,j]]+e[[i-1]] c[[i-1,j-1]],
                {i,2,2 ell+1},{j,2,i-1}];
            c
        ]
    ];
    
    ClearAll[fcc];
    fcc=Compile[{{ell,_Integer},{e,_Integer,1}},
        Module[{c},
            c=Table[0,{2ell+1},{2ell+1}];
            c[[1,1]]=1;
            Do[c[[i,i]]=e[[i-1]] c[[i-1,i-1]],{i,2,2 ell+1}];
            Do[c[[i,1]]=(1-e[[i-1]]) c[[i-1,1]],{i,2,2 ell+1}];
            Do[c[[i,j]]=(1-e[[i-1]]) c[[i-1,j]]+e[[i-1]] c[[i-1,j-1]],
                {i,2,2 ell+1},{j,2,i-1}];
            c
        ],
        CompilationTarget->"C",
        RuntimeOptions->"Speed"
    ];
    

    no errors, so it’s OK. And now test (these on a macbook with a 2.4GHz core 2 duo running on battery):

    ell=400;
    e=RandomInteger[{0,1},2*ell];
    f[ell,e];//Timing
    fc[ell,e];//Timing
    fcc[ell,e];//Timing
    

    giving

    {2.60925, Null}
    {0.092022, Null}
    {0.022709, Null}
    

    so the version compiled to C is two orders of magnitude faster here.

    If you change the types and get compilation errors, ask.

    EDIT: If e contains reals, try

    ClearAll[fc];
    fc=Compile[{{ell,_Integer},{e,_Real,1}},
        Module[{c},
            c=Table[0.,{2ell+1},{2ell+1}];
            c[[1,1]]=1;
            Do[c[[i,i]]=e[[i-1]] c[[i-1,i-1]],{i,2,2 ell+1}];
            Do[c[[i,1]]=(1-e[[i-1]]) c[[i-1,1]],{i,2,2 ell+1}];
            Do[c[[i,j]]=(1-e[[i-1]]) c[[i-1,j]]+e[[i-1]] c[[i-1,j-1]],
                {i,2,2 ell+1},{j,2,i-1}];
            c
        ]
    ];
    
    ClearAll[fcc];
    fcc=Compile[{{ell,_Integer},{e,_Real,1}},
        Module[{c},
            c=Table[0.,{2ell+1},{2ell+1}];
            c[[1,1]]=1;
            Do[c[[i,i]]=e[[i-1]] c[[i-1,i-1]],{i,2,2 ell+1}];
            Do[c[[i,1]]=(1-e[[i-1]]) c[[i-1,1]],{i,2,2 ell+1}];
            Do[c[[i,j]]=(1-e[[i-1]]) c[[i-1,j]]+e[[i-1]] c[[i-1,j-1]],
                {i,2,2 ell+1},{j,2,i-1}];
            c
        ],
        CompilationTarget\[Rule]"C",
        RuntimeOptions\[Rule]"Speed"
    ];
    

    instead.

    One can get a feel for how this works by saying

    Needs["CompiledFunctionTools`"]
    CompilePrint[fc]
    

    and obtaining

            2 arguments
            18 Integer registers
            6 Real registers
            3 Tensor registers
            Underflow checking off
            Overflow checking off
            Integer overflow checking on
            RuntimeAttributes -> {}
    
            I0 = A1
            T(R1)0 = A2
            I12 = 0
            I1 = 2
            I3 = 1
            I14 = -1
            R0 = 0.
            Result = T(R2)2
    
    1   I11 = I1 * I0
    2   I11 = I11 + I3
    3   I7 = I1 * I0
    4   I7 = I7 + I3
    5   I17 = I12
    6   T(R2)2 = Table[ I11, I7]
    7   I15 = I12
    8   goto 13
    9   I16 = I12
    10  goto 12
    11  Element[ T(R2)2, I17] = R0
    12  if[ ++ I16 < I7] goto 11
    13  if[ ++ I15 < I11] goto 9
    14  R1 = I3
    15  Part[ T(R2)2, I3, I3] = R1
    16  I4 = I1 * I0
    17  I4 = I4 + I3
    18  I5 = I3
    19  goto 26
    20  I10 = I5 + I14
    21  I8 = I10
    22  R4 = Part[ T(R1)0, I8]
    23  R5 = Part[ T(R2)2, I8, I8]
    24  R4 = R4 * R5
    25  Part[ T(R2)2, I5, I5] = R4
    26  if[ ++ I5 < I4] goto 20
    27  I4 = I1 * I0
    28  I4 = I4 + I3
    29  I5 = I3
    30  goto 40
    31  I10 = I5 + I14
    32  I13 = I10
    33  R4 = Part[ T(R1)0, I13]
    34  R5 = - R4
    35  R4 = I3
    36  R4 = R4 + R5
    37  R5 = Part[ T(R2)2, I13, I3]
    38  R4 = R4 * R5
    39  Part[ T(R2)2, I5, I3] = R4
    40  if[ ++ I5 < I4] goto 31
    41  I4 = I1 * I0
    42  I4 = I4 + I3
    43  I5 = I3
    44  goto 63
    45  I6 = I5 + I14
    46  I17 = I3
    47  goto 62
    48  I16 = I5 + I14
    49  I9 = I16
    50  R4 = Part[ T(R1)0, I9]
    51  R2 = R4
    52  R4 = - R2
    53  R5 = I3
    54  R5 = R5 + R4
    55  R4 = Part[ T(R2)2, I9, I17]
    56  R5 = R5 * R4
    57  I16 = I17 + I14
    58  R4 = Part[ T(R2)2, I9, I16]
    59  R3 = R2 * R4
    60  R5 = R5 + R3
    61  Part[ T(R2)2, I5, I17] = R5
    62  if[ ++ I17 < I6] goto 48
    63  if[ ++ I5 < I4] goto 45
    64  Return
    

    with the names of the registers indicating their type etc. You can also look at the generated C code if you use the “C” option (but that is a bit harder to read).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

If I have the following: $common = Amelia's sand verbena When I try to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.