Попробуйте Compile
. Здесь я определяю 3 функции: f
, как вы ее определили, fc
, скомпилированные (для какого-то байт-кода) и fcc
, скомпилированные в C (посмотрите документацию о том, как исследовать сгенерированный код).
Сначала заставьте mma сообщить нам, если что-то не может быть скомпилировано:
SetSystemOptions["CompileOptions"->"CompileReportExternal"->True]
тогда функции:
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"
];
ошибок нет, так что все в порядке. А теперь протестируйте (это на macbook с 2,4 ГГц Core 2 Duo, работающим от батареи):
ell=400;
e=RandomInteger[{0,1},2*ell];
f[ell,e];//Timing
fc[ell,e];//Timing
fcc[ell,e];//Timing
дает
{2.60925, Null}
{0.092022, Null}
{0.022709, Null}
так что версия, скомпилированная в C, здесь на два порядка быстрее.
Если вы изменили типы и получили ошибки компиляции, спросите.
РЕДАКТИРОВАТЬ: Если e
содержит реалов, попробуйте
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"
];
вместо.
О том, как это работает, можно почувствовать, сказав
Needs["CompiledFunctionTools`"]
CompilePrint[fc]
и получение
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
с именами регистров, указывающими их тип и т. Д. Вы также можете посмотреть на сгенерированный код C, если используете опцию "C" (но это немного сложнее для чтения).