Skip to main content
Rollback to Revision 1
Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

Critique of Leonid's method

This has now been fixed. I shall preserve the timings below using Leonid's old method simply as a reference and an example of the large effects of relatively small changes.

I think it needs to be pointed out that while Leonid's meta-programming method is quite convenient it has an extremely high overhead in the case of low complexity recursion (iteration).

Consider these timings:

ClearAll[f, g] def[ f[1] := 1 ] def[ f[n_] := n + f[n - 1] ] g[n_] := g[n, 0] g[0, tot_] := tot g[n_, tot_] := g[n - 1, n + tot] $IterationLimit = 1*^6; SetAttributes[timeAvg, HoldFirst] timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] Table[ {n, g[n] // timeAvg, f[n] // timeAvg}, {n, 5^Range[0, 7]} ] // TableForm[#, TableHeadings -> {None, {"n", "Manual", "Meta-programming"}}] & 

Mathematica graphics

Most troubling is the apparent computational complexity of the meta-programming method:

Mathematica graphics

(Note the logarithmic scale.)

Again, this complexity problem has been corrected.

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

Critique of Leonid's method

This has now been fixed. I shall preserve the timings below using Leonid's old method simply as a reference and an example of the large effects of relatively small changes.

I think it needs to be pointed out that while Leonid's meta-programming method is quite convenient it has an extremely high overhead in the case of low complexity recursion (iteration).

Consider these timings:

ClearAll[f, g] def[ f[1] := 1 ] def[ f[n_] := n + f[n - 1] ] g[n_] := g[n, 0] g[0, tot_] := tot g[n_, tot_] := g[n - 1, n + tot] $IterationLimit = 1*^6; SetAttributes[timeAvg, HoldFirst] timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] Table[ {n, g[n] // timeAvg, f[n] // timeAvg}, {n, 5^Range[0, 7]} ] // TableForm[#, TableHeadings -> {None, {"n", "Manual", "Meta-programming"}}] & 

Mathematica graphics

Most troubling is the apparent computational complexity of the meta-programming method:

Mathematica graphics

(Note the logarithmic scale.)

Again, this complexity problem has been corrected.

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 
added 37 characters in body
Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

Critique of Leonid's method

This has now been fixed. I shall preserve the timings below using Leonid's old method simply as a reference and an example of the large effects of relatively small changes.

I think it needs to be pointed out that while Leonid's meta-programming method is quite convenient it has an extremely high overhead in the case of low complexity recursion (iteration). The overhead is so high in fact that I question the validity of the method as it is written.

Consider these timings:

ClearAll[f, g] def[ f[1] := 1 ] def[ f[n_] := n + f[n - 1] ] g[n_] := g[n, 0] g[0, tot_] := tot g[n_, tot_] := g[n - 1, n + tot] $IterationLimit = 1*^6; SetAttributes[timeAvg, HoldFirst] timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] Table[ {n, g[n] // timeAvg, f[n] // timeAvg}, {n, 5^Range[0, 7]} ] // TableForm[#, TableHeadings -> {None, {"n", "Manual", "Meta-programming"}}] & 

Mathematica graphics

Most troubling is the apparent computational complexity of the meta-programming method:

Mathematica graphics

(Note the logarithmic scale.)

The meta-programming method, as it is written, is simply unsuitable where performance is a priority.Again, this complexity problem has been corrected.

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

Critique of Leonid's method

I think it needs to be pointed out that while Leonid's meta-programming method is quite convenient it has an extremely high overhead in the case of low complexity recursion (iteration). The overhead is so high in fact that I question the validity of the method as it is written.

Consider these timings:

ClearAll[f, g] def[ f[1] := 1 ] def[ f[n_] := n + f[n - 1] ] g[n_] := g[n, 0] g[0, tot_] := tot g[n_, tot_] := g[n - 1, n + tot] $IterationLimit = 1*^6; SetAttributes[timeAvg, HoldFirst] timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] Table[ {n, g[n] // timeAvg, f[n] // timeAvg}, {n, 5^Range[0, 7]} ] // TableForm[#, TableHeadings -> {None, {"n", "Manual", "Meta-programming"}}] & 

Mathematica graphics

Most troubling is the apparent computational complexity of the meta-programming method:

Mathematica graphics

(Note the logarithmic scale.)

The meta-programming method, as it is written, is simply unsuitable where performance is a priority.

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

Critique of Leonid's method

This has now been fixed. I shall preserve the timings below using Leonid's old method simply as a reference and an example of the large effects of relatively small changes.

I think it needs to be pointed out that while Leonid's meta-programming method is quite convenient it has an extremely high overhead in the case of low complexity recursion (iteration).

Consider these timings:

ClearAll[f, g] def[ f[1] := 1 ] def[ f[n_] := n + f[n - 1] ] g[n_] := g[n, 0] g[0, tot_] := tot g[n_, tot_] := g[n - 1, n + tot] $IterationLimit = 1*^6; SetAttributes[timeAvg, HoldFirst] timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] Table[ {n, g[n] // timeAvg, f[n] // timeAvg}, {n, 5^Range[0, 7]} ] // TableForm[#, TableHeadings -> {None, {"n", "Manual", "Meta-programming"}}] & 

Mathematica graphics

Most troubling is the apparent computational complexity of the meta-programming method:

Mathematica graphics

(Note the logarithmic scale.)

Again, this complexity problem has been corrected.

added 1228 characters in body
Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

Critique of Leonid's method

I think it needs to be pointed out that while Leonid's meta-programming method is quite convenient it has an extremely high overhead in the case of low complexity recursion (iteration). The overhead is so high in fact that I question the validity of the method as it is written.

Consider these timings:

ClearAll[f, g] def[ f[1] := 1 ] def[ f[n_] := n + f[n - 1] ] g[n_] := g[n, 0] g[0, tot_] := tot g[n_, tot_] := g[n - 1, n + tot] $IterationLimit = 1*^6; SetAttributes[timeAvg, HoldFirst] timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] Table[ {n, g[n] // timeAvg, f[n] // timeAvg}, {n, 5^Range[0, 7]} ] // TableForm[#, TableHeadings -> {None, {"n", "Manual", "Meta-programming"}}] & 

Mathematica graphics

Most troubling is the apparent computational complexity of the meta-programming method:

Mathematica graphics

(Note the logarithmic scale.)

The meta-programming method, as it is written, is simply unsuitable where performance is a priority.

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

As a point of reference it's not hard to make Times iterative, you just need to put everything inside a single function call:

ClearAll[g] g[0, total_] := total; g[n_, total_] := g[n - 1, total*n] g[n_] := g[n, 1] Block[{$IterationLimit = 30000}, g[5000] === 5000! ] 
True 

Critique of Leonid's method

I think it needs to be pointed out that while Leonid's meta-programming method is quite convenient it has an extremely high overhead in the case of low complexity recursion (iteration). The overhead is so high in fact that I question the validity of the method as it is written.

Consider these timings:

ClearAll[f, g] def[ f[1] := 1 ] def[ f[n_] := n + f[n - 1] ] g[n_] := g[n, 0] g[0, tot_] := tot g[n_, tot_] := g[n - 1, n + tot] $IterationLimit = 1*^6; SetAttributes[timeAvg, HoldFirst] timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}] Table[ {n, g[n] // timeAvg, f[n] // timeAvg}, {n, 5^Range[0, 7]} ] // TableForm[#, TableHeadings -> {None, {"n", "Manual", "Meta-programming"}}] & 

Mathematica graphics

Most troubling is the apparent computational complexity of the meta-programming method:

Mathematica graphics

(Note the logarithmic scale.)

The meta-programming method, as it is written, is simply unsuitable where performance is a priority.

Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k
Loading