Converting XGBoost tree structure dump file to MQL4 (C like language) code - python

I have a dump file of XGBoost tree structure trained in Python. The structure has 377 trees, and file has approximately 50,000 lines. I would like to convert this structure to MQL4 code, or C code so to say. The text file looks something like this:
booster[0]:
0:[inp0<6.85417] yes=1,no=2,missing=1
1:[inp10<1.00054] yes=3,no=4,missing=3
3:[inp21<0.974632] yes=7,no=8,missing=7
7:[inp22<1.01021] yes=15,no=16,missing=15
15:[inp15<0.994931] yes=31,no=32,missing=31
31:[inp12<0.999151] yes=63,no=64,missing=63
63:[inp23<0.957624] yes=111,no=112,missing=111
111:leaf=0.163636
112:leaf=-0.36
64:leaf=0.323077
32:[inp19<0.993949] yes=65,no=66,missing=65
65:[inp23<0.931146] yes=113,no=114,missing=113
113:leaf=-0
114:[inp23<0.972193] yes=161,no=162,missing=161
161:leaf=-0.421782
162:leaf=-0.133333
66:[inp2<61] yes=115,no=116,missing=115
115:leaf=0.381818
116:leaf=-0.388235
16:[inp17<0.985065] yes=33,no=34,missing=33
33:leaf=-0.381818
34:[inp23<0.946341] yes=67,no=68,missing=67
67:leaf=-0.36
68:[inp12<1.00121] yes=117,no=118,missing=117
117:[inp19<0.989751] yes=163,no=164,missing=163
163:leaf=0.367742
164:leaf=-0.0666667
118:[inp0<4.29167] yes=165,no=166,missing=165
165:leaf=-0
166:leaf=-0.3
8:[inp11<0.999875] yes=17,no=18,missing=17
17:[inp7<134] yes=35,no=36,missing=35
35:[inp9<62] yes=69,no=70,missing=69
69:[inp8<26] yes=119,no=120,missing=119
119:[inp23<0.993382] yes=167,no=168,missing=167
167:leaf=-0.211765
168:leaf=0.27
120:[inp21<0.989946] yes=169,no=170,missing=169
169:leaf=-0.392308
170:leaf=-0.161421
70:[inp17<0.997] yes=121,no=122,missing=121
121:[inp13<0.999021] yes=171,no=172,missing=171
171:leaf=-0.0378947
172:leaf=-0.340541
122:[inp11<0.9986] yes=173,no=174,missing=173
173:leaf=-0.2
174:leaf=0.0857143
36:[inp8<154] yes=71,no=72,missing=71
71:[inp8<132] yes=123,no=124,missing=123
123:[inp2<123] yes=175,no=176,missing=175
175:leaf=0.0277635
176:leaf=-0.132584
124:[inp4<170] yes=177,no=178,missing=177
177:leaf=0.269725
178:leaf=0.0618557
72:[inp2<26] yes=125,no=126,missing=125
125:[inp9<123] yes=179,no=180,missing=179
179:leaf=-0.224742
180:leaf=-0
126:[inp2<60] yes=181,no=182,missing=181
181:leaf=0.0330435
182:leaf=-0.0703448
18:[inp15<0.999742] yes=37,no=38,missing=37
37:[inp14<1.00044] yes=73,no=74,missing=73
73:[inp2<73] yes=127,no=128,missing=127
127:[inp16<1.00107] yes=183,no=184,missing=183
183:leaf=-0.36
184:leaf=0.0666667
128:[inp11<0.999936] yes=185,no=186,missing=185
185:leaf=0.4
186:leaf=-0.0666667
74:[inp3<371] yes=129,no=130,missing=129
129:leaf=0.494118
130:leaf=0.12
38:[inp23<0.997023] yes=75,no=76,missing=75
75:[inp20<1.00221] yes=131,no=132,missing=131
131:leaf=0.163636
132:[inp13<1.00015] yes=187,no=188,missing=187
187:leaf=-0.371429
188:leaf=0.0666667
76:leaf=0.3
4:[inp19<0.978746] yes=9,no=10,missing=9
9:[inp6<260] yes=19,no=20,missing=19
19:[inp3<405] yes=39,no=40,missing=39
39:[inp20<0.998759] yes=77,no=78,missing=77
77:leaf=0.0545455
78:[inp2<206] yes=133,no=134,missing=133
133:[inp9<217] yes=189,no=190,missing=189
189:leaf=-0.485714
190:leaf=-0.12
134:[inp0<5.39583] yes=191,no=192,missing=191
191:leaf=-0.24
192:leaf=0.3
40:[inp0<5.875] yes=79,no=80,missing=79
79:leaf=0.36
80:leaf=-0.15
20:[inp9<87] yes=41,no=42,missing=41
41:[inp15<0.99573] yes=81,no=82,missing=81
81:[inp4<272] yes=135,no=136,missing=135
135:leaf=0.381818
136:leaf=-0
82:[inp13<0.999781] yes=137,no=138,missing=137
137:leaf=-0.42
138:leaf=0.0545455
42:[inp3<199] yes=83,no=84,missing=83
83:leaf=0.458824
84:leaf=-0.0666667
10:[inp18<1.01862] yes=21,no=22,missing=21
21:[inp16<1.00397] yes=43,no=44,missing=43
43:[inp22<1.03335] yes=85,no=86,missing=85
85:[inp5<474] yes=139,no=140,missing=139
139:[inp19<0.998419] yes=193,no=194,missing=193
193:leaf=0.0538108
194:leaf=0.190909
140:[inp4<164] yes=195,no=196,missing=195
195:leaf=0.1125
196:leaf=-0.278351
86:[inp17<0.994249] yes=141,no=142,missing=141
141:[inp5<154] yes=197,no=198,missing=197
197:leaf=-0.0568421
198:leaf=-0.377778
142:[inp22<1.03873] yes=199,no=200,missing=199
199:leaf=-0.135484
200:leaf=0.1584
44:[inp15<0.999235] yes=87,no=88,missing=87
87:[inp21<0.9739] yes=143,no=144,missing=143
143:[inp3<106] yes=201,no=202,missing=201
201:leaf=-0.272727
202:leaf=0.410526
144:[inp14<1.00351] yes=203,no=204,missing=203
203:leaf=-0.0146652
204:leaf=0.155556
88:[inp21<0.999884] yes=145,no=146,missing=145
145:[inp22<1.04426] yes=205,no=206,missing=205
205:leaf=-0.0905588
206:leaf=0.105263
146:[inp4<313] yes=207,no=208,missing=207
207:leaf=0.182927
208:leaf=-0.253846
22:[inp18<1.01903] yes=45,no=46,missing=45
45:[inp0<3.60417] yes=89,no=90,missing=89
89:leaf=-0
90:leaf=0.471429
46:[inp18<1.01953] yes=91,no=92,missing=91
91:[inp2<32] yes=147,no=148,missing=147
147:[inp21<0.997154] yes=209,no=210,missing=209
209:leaf=-0.3
210:leaf=0.333333
148:[inp21<0.99536] yes=211,no=212,missing=211
211:leaf=-0.0666667
212:leaf=-0.45
92:[inp16<1.01109] yes=149,no=150,missing=149
149:[inp2<137] yes=213,no=214,missing=213
213:leaf=0.305085
214:leaf=-0.0923077
150:[inp4<117] yes=215,no=216,missing=215
215:leaf=0.294118
216:leaf=-0.0375
2:[inp5<183] yes=5,no=6,missing=5
5:[inp6<187] yes=11,no=12,missing=11
11:[inp13<1.00025] yes=23,no=24,missing=23
23:[inp18<1.0069] yes=47,no=48,missing=47
47:[inp20<1.00403] yes=93,no=94,missing=93
93:[inp23<0.975704] yes=151,no=152,missing=151
151:leaf=-0
152:leaf=-0.45
94:[inp23<0.990095] yes=153,no=154,missing=153
153:[inp2<28] yes=217,no=218,missing=217
217:leaf=-0
218:leaf=0.4
154:leaf=-0.2
48:leaf=-0.485714
24:[inp3<205] yes=49,no=50,missing=49
49:leaf=0.3
50:leaf=-0
12:[inp6<258] yes=25,no=26,missing=25
25:[inp10<1.00079] yes=51,no=52,missing=51
51:[inp22<1.03732] yes=95,no=96,missing=95
95:leaf=0.5
96:leaf=-0
52:leaf=-0.0666667
26:[inp9<52] yes=53,no=54,missing=53
53:leaf=0.375
54:[inp15<0.998562] yes=97,no=98,missing=97
97:leaf=-0.410526
98:[inp9<92] yes=155,no=156,missing=155
155:[inp3<120] yes=219,no=220,missing=219
219:leaf=-0
220:leaf=-0.428571
156:[inp8<275] yes=221,no=222,missing=221
221:leaf=0.44
222:leaf=-0.0545455
6:[inp10<1.00118] yes=13,no=14,missing=13
13:[inp4<366] yes=27,no=28,missing=27
27:[inp23<0.998109] yes=55,no=56,missing=55
55:[inp15<0.999976] yes=99,no=100,missing=99
99:[inp17<0.994571] yes=157,no=158,missing=157
157:[inp12<1.00049] yes=223,no=224,missing=223
223:leaf=-0.458824
224:leaf=-0.128571
158:[inp3<33] yes=225,no=226,missing=225
225:leaf=-0.12
226:leaf=-0.552381
100:[inp11<0.999604] yes=159,no=160,missing=159
159:leaf=0.12
160:leaf=-0.36
56:[inp18<1.00668] yes=101,no=102,missing=101
101:leaf=0.333333
102:leaf=-0.342857
28:[inp7<81] yes=57,no=58,missing=57
57:leaf=0.3
58:[inp9<20] yes=103,no=104,missing=103
103:leaf=0.0666667
104:leaf=-0.388235
14:[inp19<0.992859] yes=29,no=30,missing=29
29:[inp11<0.999532] yes=59,no=60,missing=59
59:leaf=0.415385
60:[inp1<5] yes=105,no=106,missing=105
105:leaf=-0.2
106:leaf=0.15
30:[inp3<227] yes=61,no=62,missing=61
61:[inp2<126] yes=107,no=108,missing=107
107:leaf=-0.461538
108:leaf=-0
62:[inp0<6.9375] yes=109,no=110,missing=109
109:leaf=0.272727
110:leaf=-0.15
booster[1]:
0:[...
There are 24 inputs as inp0, inp1, ..., inp23.
On conditions of these inputs being smaller than some thresholds a booster[0] probability is set.
There are 377 booster trees ( booster[0], ... , booster[376] ).
The condition numbers do not follow the same sequence in different boosters.
Missing parameter is irrelevant as I do not have any missing input values.
I would like to get all 377 booster probabilities and sum them up to get an overall sum, and then feed it to a logistic function to calculate the final output probability. Logistic function is:
1 / ( 1 + exp( -sum ) )
The C code I would like to get is something like that:
if ( inp0 < 6.85417 && inp10 < 1.00054 ... ) booster[0] = 0.163636;
if ( ...
Does anyone have any idea on how to get this text file and output as C code as easily as possible, either in Python or C++?

Good news is that it is now possible to turn your sklearn models (including XGBoost) to popular programming languages' native code with m2cgen – Model To Code Generator library in Python. The advantage here is that you can deploy your ML model on any platform because it would consist of basic if statements, mathematical operations or functions which are available in every programming language. Platform independent deployment of ML models is a very strong capability for a data scientist.
In our case it is as easy as:
import m2cgen as m2c
code = m2c.export_to_c(xgb_model) #xgb_model is your trained XGBoost model with .fit method
#write the code to a text file
text_file = open("xgb_c.txt", "w")
text_file.write("C code for the XGB structure: %s" % code)
text_file.close()
And the converted C code looks something like this:
void score(double * input, double * output) {
double var0;
if ((input[0]) >= (6.8125)) {
if ((input[15]) >= (1.00002789)) {
if ((input[8]) >= (127)) {
if ((input[11]) >= (0.999750614)) {
if ((input[7]) >= (252)) {
var0 = -0.226666674;
.
.
.
} else {
var376 = -0.0343097448;
}
double var377;
var377 = (1) / ((1) + (exp((0) - ((((((((-0.0) + ((((((((((((((((((((((((((((((((((((((((var0) + (var1)) + (var2)) + (var3)) + (var4)) + (var5)) + (var6)) + (var7)) + (var8)) + (var9)) + (var10)) + (var11)) + (var12)) + (var13)) + (var14)) + (var15)) + (var16)) + (var17)) + (var18)) + (var19)) + (var20)) + (var21)) + (var22)) + (var23)) + (var24)) + (var25)) + (var26)) + (var27)) + (var28)) + (var29)) + (var30)) + (var31)) + (var32)) + (var33)) + (var34)) + (var35)) + (var36)) + (var37)) + (var38)) + (var39))) + ((((((((((((((((((((((((((((((((((((((((((var40) + (var41)) + (var42)) + (var43)) + (var44)) + (var45)) + (var46)) + (var47)) + (var48)) + (var49)) + (var50)) + (var51)) + (var52)) + (var53)) + (var54)) + (var55)) + (var56)) + (var57)) + (var58)) + (var59)) + (var60)) + (var61)) + (var62)) + (var63)) + (var64)) + (var65)) + (var66)) + (var67)) + (var68)) + (var69)) + (var70)) + (var71)) + (var72)) + (var73)) + (var74)) + (var75)) + (var76)) + (var77)) + (var78)) + (var79)) + (var80)) + (var81))) + (((((((((((((((((((((((((((((((((((((((((((((((((((((((var82) + (var83)) + (var84)) + (var85)) + (var86)) + (var87)) + (var88)) + (var89)) + (var90)) + (var91)) + (var92)) + (var93)) + (var94)) + (var95)) + (var96)) + (var97)) + (var98)) + (var99)) + (var100)) + (var101)) + (var102)) + (var103)) + (var104)) + (var105)) + (var106)) + (var107)) + (var108)) + (var109)) + (var110)) + (var111)) + (var112)) + (var113)) + (var114)) + (var115)) + (var116)) + (var117)) + (var118)) + (var119)) + (var120)) + (var121)) + (var122)) + (var123)) + (var124)) + (var125)) + (var126)) + (var127)) + (var128)) + (var129)) + (var130)) + (var131)) + (var132)) + (var133)) + (var134)) + (var135)) + (var136))) + ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((var137) + (var138)) + (var139)) + (var140)) + (var141)) + (var142)) + (var143)) + (var144)) + (var145)) + (var146)) + (var147)) + (var148)) + (var149)) + (var150)) + (var151)) + (var152)) + (var153)) + (var154)) + (var155)) + (var156)) + (var157)) + (var158)) + (var159)) + (var160)) + (var161)) + (var162)) + (var163)) + (var164)) + (var165)) + (var166)) + (var167)) + (var168)) + (var169)) + (var170)) + (var171)) + (var172)) + (var173)) + (var174)) + (var175)) + (var176)) + (var177)) + (var178)) + (var179)) + (var180)) + (var181)) + (var182)) + (var183)) + (var184)) + (var185)) + (var186)) + (var187)) + (var188)) + (var189)) + (var190)) + (var191)) + (var192)) + (var193)) + (var194))) + ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((var195) + (var196)) + (var197)) + (var198)) + (var199)) + (var200)) + (var201)) + (var202)) + (var203)) + (var204)) + (var205)) + (var206)) + (var207)) + (var208)) + (var209)) + (var210)) + (var211)) + (var212)) + (var213)) + (var214)) + (var215)) + (var216)) + (var217)) + (var218)) + (var219)) + (var220)) + (var221)) + (var222)) + (var223)) + (var224)) + (var225)) + (var226)) + (var227)) + (var228)) + (var229)) + (var230)) + (var231)) + (var232)) + (var233)) + (var234)) + (var235)) + (var236)) + (var237)) + (var238)) + (var239)) + (var240)) + (var241)) + (var242)) + (var243)) + (var244)) + (var245)) + (var246)) + (var247)) + (var248)) + (var249)) + (var250)) + (var251)) + (var252)) + (var253)) + (var254)) + (var255)) + (var256)) + (var257)) + (var258)) + (var259)) + (var260)) + (var261)) + (var262))) + (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((var263) + (var264)) + (var265)) + (var266)) + (var267)) + (var268)) + (var269)) + (var270)) + (var271)) + (var272)) + (var273)) + (var274)) + (var275)) + (var276)) + (var277)) + (var278)) + (var279)) + (var280)) + (var281)) + (var282)) + (var283)) + (var284)) + (var285)) + (var286)) + (var287)) + (var288)) + (var289)) + (var290)) + (var291)) + (var292)) + (var293)) + (var294)) + (var295)) + (var296)) + (var297)) + (var298)) + (var299)) + (var300)) + (var301)) + (var302)) + (var303)) + (var304)) + (var305)) + (var306)) + (var307)) + (var308)) + (var309)) + (var310)) + (var311)) + (var312)) + (var313)) + (var314)) + (var315)) + (var316)) + (var317)) + (var318)) + (var319)) + (var320)) + (var321)) + (var322)) + (var323)) + (var324)) + (var325)) + (var326)) + (var327)) + (var328)) + (var329)) + (var330)) + (var331)) + (var332)) + (var333)) + (var334)) + (var335)) + (var336)) + (var337)) + (var338)) + (var339)) + (var340)) + (var341)) + (var342)) + (var343))) + (((((((((((((((((((((((((((((((((var344) + (var345)) + (var346)) + (var347)) + (var348)) + (var349)) + (var350)) + (var351)) + (var352)) + (var353)) + (var354)) + (var355)) + (var356)) + (var357)) + (var358)) + (var359)) + (var360)) + (var361)) + (var362)) + (var363)) + (var364)) + (var365)) + (var366)) + (var367)) + (var368)) + (var369)) + (var370)) + (var371)) + (var372)) + (var373)) + (var374)) + (var375)) + (var376))))));
memcpy(output, (double[]){(1) - (var377), var377}, 2 * sizeof(double));
}
Which can be translated into MQL4 language fairly easily.

Method A: MQL4 asks a python XGBOOST instance to .predict()
This is a natural way, to use a distributed system, communicating under a common messaging / signalling framework based on ZeroMQ.
MQL4 side sends zmq_send( ASK_XGBOOST_TO_PREDICT, anInputStateVECTOR_BLOB ) to the python side.
Python side decodesthe _BLOB elements anInputStateVECTOR = demap( anInputStateVECTOR_BLOB )
and sends back a ANSWER.send( xgboost.predict( anInputStateVECTOR ) )
and finally MQL4 side reads string s_recv( GET_XGBOOST_ANSWER, ZMQ_NOBLOCK );
Most of my advanced distributed trading solutions use this sort of integration approach, as it provides means for both performance-scaling and for service fault-tolerance to be added.
Method B: extend MQL4 to parse and compute ::XGBOOST_PREDICT()
The easiest possible approach will go into a New-MQL4 class XGBOOST_in_MQL4{ ... };,where public methods will expose methods to manipulate internal, principally private, collection-of-trees representation and allow to update it from a fileXGBOOST_in_MQL4::XGBOOST_LOAD_TXT( aFileNameToLOAD );and get predictions fromXGBOOST_in_MQL4::XGBOOST_PREDICT( anInputStateVECTOR ); as sketched below:
class XGBOOST_in_MQL4 {
private: // instance-hidden
int XGB_trees = 0;
struct XGB_tree_node
{ int INPidN_or_LEAF = EMPTY;
double INPcmp_or_LEAF_VALUE = 0.0;
int JMPcmpLT = 0;
int JMPcmpGE = 0;
// int JMPcmpMISSING; // N/A
};
XGB_tree_node XGBOOST_TREE[]; // a tree-holder array[]
XGBOOST_TREE XGBOOST_TREES[]; // a collection of trees
public: // published-methods
XGBOOST_in_MQL4( void ){ // default class-constructor
}
void XGBOOST_LOAD_TXT( string aFileNAME ){ // importer + parser
// LOAD_TXT into parser-process
// STORE into XGBOOST_TREES[]
// UPDATE XGB_trees
XGB_trees = ArrayRange( XGBOOST_TREES, 0 );
}
double XGBOOST_PREDICT( double INPUT[] ){ // .predictor
// PREDICT
int tree;
double sum = 0.;
for ( tree = 0; tree < XGB_trees; tree++ ){
sum += XGBOOST_compute_TREE( tree, INPUT );
}
return ( 1. / ( 1. + MathExp( -sum ) ) );
}
double XGBOOST_compute_TREE( int aTree, double INPUT[] ){
// COMPUTE one TREE
return( RECURSIVE_traverse_TREE( aTree, 0, INPUT ) );
}
double RECURSIVE_traverse_TREE( int aTree, int aNode, double INPUT[] ){
// TRAVERSE TREE recursively
if ( XGBOOST_TREES[aTree, aNode].INPidN_or_LEAF == EMPTY ) return( XGBOOST_TREES[aTree, aNode].INPcmp_or_LEAF_VALUE );
return( ( XGBOOST_TREES[aTree, aNode].INPcmp_or_LEAF_VALUE < INPUT[XGBOOST_TREES[aTree, aNode].INPidN_or_LEAF] )
? RECURSIVE_traverse_TREE( aTree,
XGBOOST_TREES[aTree, aNode].JMPcmpLT,
INPUT
)
: RECURSIVE_traverse_TREE( aTree,
XGBOOST_TREES[aTree, aNode].JMPcmpGE,
INPUT
)
);
}
}
For a low-number of a collection-of-trees' updates per unit of time, this could be a funny way to go :o)
Epilogue:
Why to pay any single nanosecond longer time, than needed - the more in FOREX environment? There are many FOREX-events taking place within the very same millisecond, whereas one might want to respond to such, before any other 3rd-party does. That is the core rudimentary logic, since the trading meetings took place in the living room of the Bourses family.
While contemporary CPU-architectures provide about some 10 ~ 40 operations / 5 [ns], it is possible to cut-through the throat of the code much smarter, than to evaluate a vast SEQ of if(){...}else{...} instruction sections
FOREX industry major players can benefit from much faster processing approach and can receive the result in about 50~100 ns time. During the same amount of time, the smartest C-code can process just a fraction of the "list". Enclosed one can see the compiled C-code span in symbolic assembler, so as to better sense the run-time accumulation.
The example produced about 120 assembly instructions ( + not each taking just one CPU_CLK time to execute ( but forget about this fact as a "detail" for not loosing the Big Picture ) )covering just the first 6 input_FeatureVECTOR_STATE[] cells for just the first XGB-Tree, so scale those about 50 [ns] further, to expand the code run-time to cover all those 377-trees, altogether having some 50.000 lines in the dump-file.
If one's guess is around 50 [ns] * 10.000 ~ about half a millisecond ( in case indeed a smart coding had taken place ), one ought be interested to know, that during that amount of time the FX-Market has moved a few tens times from the original Ask-Bid price-levels and thus a truly professional solution is due to be put in place, once there are ways to get response within those given ~ 100 [ns]
Would you risk waiting 5.000x longer for making a decision that was ready after the first 100[ns]?
Why?

You should probably check the possibility to compile the python code to C using cython or even implementing the xgboost in C or use something even faster like Fortran https://www.stat.berkeley.edu/~breiman/RandomForests/cc_graphicsdoc.htm good luck seems to be an interesting project

Related

What transformation does `simplify` apply when both `powsimp` and `collect` do nothing?

I have the following expression and want to group it by powers of the variable e:
from sympy import symbols
e = symbols('e')
expr = (
0.363635891123757*e
+ 1.27444227529689*(0.006290933064*e + 0.526290933064)*(0.12408152*e + 0.12408152)
+ 2.76494336639746*(0.0483917928*e + 1.0483917928)*(0.12408152*e + 0.12408152)
+ 1.27444227529689*(0.12408152*e + 0.12408152)*(
0.012581866128*e
+ 0.39*(0.006290933064*e + 0.526290933064)*(0.12408152*e + 0.12408152)
+ 0.922581866128
)
+ 2.76494336639746*(0.12408152*e + 0.12408152)*(
0.0967835856*e
+ 0.39*(0.0483917928*e + 1.0483917928)*(0.12408152*e + 0.12408152)
+ 1.0967835856
)
+ 1.63807816642065
)
From their descriptions both powsimp and collect should work, however they return the expression unmodified. When I apply simplify then the expression gets simplified as expected. So I'm wondering what other type of transformation gets applied during the call to simplify?
from sympy.simplify import simplify, powsimp, collect
print(f'{powsimp(expr) = }')
print(f'{collect(expr, e) = }')
print(f'{simplify(expr) = }')
This produces the following output:
powsimp(expr) = 0.363635891123757*e + (0.0080174310478246*e + 0.670727414202207)*(0.12408152*e + 0.12408152) + (0.12408152*e + 0.12408152)*(0.13380056649044*e + 2.8987439328879) + (0.158134734671097*e + 0.158134734671097)*(0.012581866128*e + (0.00245346389496*e + 0.20525346389496)*(0.12408152*e + 0.12408152) + 0.922581866128) + (0.343078375616514*e + 0.343078375616514)*(0.0967835856*e + (0.018872799192*e + 0.408872799192)*(0.12408152*e + 0.12408152) + 1.0967835856) + 1.63807816642065
collect(expr, e) = 0.363635891123757*e + (0.0080174310478246*e + 0.670727414202207)*(0.12408152*e + 0.12408152) + (0.12408152*e + 0.12408152)*(0.13380056649044*e + 2.8987439328879) + (0.158134734671097*e + 0.158134734671097)*(0.012581866128*e + (0.00245346389496*e + 0.20525346389496)*(0.12408152*e + 0.12408152) + 0.922581866128) + (0.343078375616514*e + 0.343078375616514)*(0.0967835856*e + (0.018872799192*e + 0.408872799192)*(0.12408152*e + 0.12408152) + 1.0967835856) + 1.63807816642065
simplify(expr) = 0.000851550024540092*e**3 + 0.0759270659579648*e**2 + 1.42522479477876*e + 2.62459155414223
P.S.: For my use case, this expression is part of a larger expression which I cannot transform via simplify because I get the error described here.
$ conda list | grep sympy
sympy 1.8 py39hf3d152e_0 conda-forge
In general you need to use expand before collect although in this case expand is enough:
In [7]: expr.expand()
Out[7]:
3 2
0.000851550024540092⋅e + 0.0759270659579648⋅e + 1.42522479477876⋅e + 2.62459155414223

How to convert symbolic expressions to float in Python?

Now i m trying to solve 6th order of nonlinear equations.
For solving this problem, 'fsolve' is the best module for my situation.
But i have a problem for using this 'fsolve'.
My Equations below : eq1, eq2, eq3, eq4, eq5, eq6
U = (E*h/32)*(pi**4*K3+8*pi**2*K4+16*J2-pi**4/b*K1**2-8*pi**2/b*K1*J1)+pi**2/2*D*((K1*K2)**0.5+(1-v)*K5-v*K6)+F/(4*b)*pi**2*K1
eq1 = diff(U,b_1)
eq2 = diff(U,b_2)
eq3 = diff(U,b_3)
eq4 = diff(U,b_4)
eq5 = diff(U,b_5)
eq6 = diff(U,b_6)
Now i m gonna try to define functions:
def functions(v):
b_1 = v[0]
b_2 = v[1]
b_3 = v[2]
b_4 = v[3]
b_5 = v[4]
b_6 = v[5]
return eq1,eq2,eq3,eq4,eq5,eq6
Until now, all of code is perfectly completed.
But next, I got a error code for 'fsolve'
x0 = [0.1,0.1,0.1,0.1,0.1,0.1]
solutions = fsolve(functions,x0)
Traceback (most recent call last):
File "C:\Users\user\AppData\Roaming\Python\Python37\site-packages\sympy\core\expr.py", line 327, in __float__
raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
Traceback (most recent call last):
File "C:\Users\user\Desktop\-----\trial.py", line 97, in <module>
solutions = fsolve(functions,x0)
File "C:\Users\user\anaconda3\lib\site-packages\scipy\optimize\minpack.py", line 147, in fsolve
res = _root_hybr(func, x0, args, jac=fprime, **options)
File "C:\Users\user\anaconda3\lib\site-packages\scipy\optimize\minpack.py", line 225, in _root_hybr
ml, mu, epsfcn, factor, diag)
error: Result from function call is not a proper array of floats.
Actually i don't know exactly meaning about 'array of floats'.
The eq1~eq6 is really complicated expressions. For example (eq1):
519749583.393768*b_1**3 + 519749583.393768*b_1**2*b_2 + 311849750.036261*b_1**2*b_3 + 222749821.454472*b_1**2*b_4 + 173249861.131256*b_1**2*b_5 + 141749886.380119*b_1**2*b_6 + 589049527.846271*b_1*b_2**2 + 920699262.011818*b_1*b_2*b_3 + 742499404.84824*b_1*b_2*b_4 + 619499503.439037*b_1*b_2*b_5 + 530653420.807624*b_1*b_2*b_6 + 395009683.379264*b_1*b_3**2 + 672299461.117134*b_1*b_3*b_4 + 581053380.409443*b_1*b_3*b_5 + 510299590.968427*b_1*b_3*b_6 + 296183828.527375*b_1*b_4**2 + 524699579.42609*b_1*b_4*b_5 + 469323153.224931*b_1*b_4*b_6 + 236661575.009363*b_1*b_5**2 + 429394392.660243*b_1*b_5*b_6 + 196977114.839905*b_1*b_6**2 + 39642.9110110422*b_1 + 193049845.260542*b_2**3 + 482129613.548124*b_2**2*b_3 + 406949673.808743*b_2**2*b_4 + 350618949.729969*b_2**2*b_5 + 307488215.070719*b_2**2*b_6 + 420149663.228267*b_2*b_3**2 + 732095017.5835*b_2*b_3*b_4 + 645437944.186494*b_2*b_3*b_5 + 575987321.121736*b_2*b_3*b_6 + 326318969.207663*b_2*b_4**2 + 585464236.60242*b_2*b_4*b_5 + 529609601.687166*b_2*b_4*b_6 + 266189415.118358*b_2*b_5**2 + 486862510.0121*b_2*b_5*b_6 + 224616040.694387*b_2*b_6**2 - 29192.3833775011*b_2 + 125272976.510293*b_3**3 + 334349732.001359*b_3**2*b_4 + 299655189.675087*b_3**2*b_5 + 270932940.727941*b_3**2*b_6 + 302393649.018531*b_3*b_4**2 + 549176644.826696*b_3*b_4*b_5 + 501838635.183477*b_3*b_4*b_6 + 252001834.206563*b_3*b_5**2 + 464613445.578031*b_3*b_5*b_6 + 215729827.081362*b_3*b_6**2 - 28558.195613361*b_3 + 92286363.2746599*b_4**3 + 253972873.350655*b_4**2*b_5 + 234063996.922265*b_4**2*b_6 + 234970783.525745*b_4*b_5**2 + 436229928.976872*b_4*b_5*b_6 + 203716223.26551*b_4*b_6**2 - 24903.5955817128*b_4 + 72968765.0411644*b_5**3 + 204424758.743579*b_5**2*b_6 + 191897759.069662*b_5*b_6**2 - 21706.6337724143*b_5 + 60314467.7838601*b_6**3 - 19178.52782655*b_6 + 52.9828871992195*((35.720610813872*b_2**2 + 142.882443255488*b_2*b_3 + 214.323664883232*b_2*b_4 + 285.764886510976*b_2*b_5 + 357.20610813872*b_2*b_6 + 257.188397859878*b_3**2 + 918.529992356708*b_3*b_4 + 1333.56947038455*b_3*b_5 + 1753.55725813553*b_3*b_6 + 893.0152703468*b_4**2 + 2727.7557348775*b_4*b_5 + 3709.44804605594*b_4*b_6 + 2154.22760600582*b_5**2 + 6001.0626167305*b_5*b_6 + 4254.9551116524*b_6**2)*(0.482*b_1**2 + 0.321333333333333*b_1*b_2 + 0.1928*b_1*b_3 + 0.137714285714286*b_1*b_4 + 0.107111111111111*b_1*b_5 + 0.0876363636363637*b_1*b_6 + 0.0964*b_2**2 + 0.137714285714286*b_2*b_3 + 0.107111111111111*b_2*b_4 + 0.0876363636363637*b_2*b_5 + 0.0741538461538462*b_2*b_6 + 0.0535555555555556*b_3**2 + 0.0876363636363637*b_3*b_4 + 0.0741538461538462*b_3*b_5 + 0.0642666666666667*b_3*b_6 + 0.0370769230769231*b_4**2 + 0.0642666666666667*b_4*b_5 + 0.0567058823529412*b_4*b_6 + 0.0283529411764706*b_5**2 + 0.0507368421052632*b_5*b_6 + 0.022952380952381*b_6**2))**0.5*(0.964*b_1 + 0.321333333333333*b_2 + 0.1928*b_3 + 0.137714285714286*b_4 + 0.107111111111111*b_5 + 0.0876363636363637*b_6)/(0.482*b_1**2 + 0.321333333333333*b_1*b_2 + 0.1928*b_1*b_3 + 0.137714285714286*b_1*b_4 + 0.107111111111111*b_1*b_5 + 0.0876363636363637*b_1*b_6 + 0.0964*b_2**2 + 0.137714285714286*b_2*b_3 + 0.107111111111111*b_2*b_4 + 0.0876363636363637*b_2*b_5 + 0.0741538461538462*b_2*b_6 + 0.0535555555555556*b_3**2 + 0.0876363636363637*b_3*b_4 + 0.0741538461538462*b_3*b_5 + 0.0642666666666667*b_3*b_6 + 0.0370769230769231*b_4**2 + 0.0642666666666667*b_4*b_5 + 0.0567058823529412*b_4*b_6 + 0.0283529411764706*b_5**2 + 0.0507368421052632*b_5*b_6 + 0.022952380952381*b_6**2) + (-1.28102213260338e-7*b_2 - 3.20255533150846e-8*b_3 - 3.20255533150846e-8*b_4 - 1.60127766575423e-8*b_6)*(0.482*b_1**2 + 0.321333333333333*b_1*b_2 + 0.1928*b_1*b_3 + 0.137714285714286*b_1*b_4 + 0.107111111111111*b_1*b_5 + 0.0876363636363637*b_1*b_6 + 0.0964*b_2**2 + 0.137714285714286*b_2*b_3 + 0.107111111111111*b_2*b_4 + 0.0876363636363637*b_2*b_5 + 0.0741538461538462*b_2*b_6 + 0.0535555555555556*b_3**2 + 0.0876363636363637*b_3*b_4 + 0.0741538461538462*b_3*b_5 + 0.0642666666666667*b_3*b_6 + 0.0370769230769231*b_4**2 + 0.0642666666666667*b_4*b_5 + 0.0567058823529412*b_4*b_6 + 0.0283529411764706*b_5**2 + 0.0507368421052632*b_5*b_6 + 0.022952380952381*b_6**2) + (1.18477228028269e-9*b_1 + 6.14508444130024e-10*b_2 + 4.60881333097518e-10*b_3 + 1.53627111032506e-10*b_4 + 1.53627111032506e-10*b_5)*(78.9568352087149*b_1**2 + 52.6378901391433*b_1*b_2 + 31.582734083486*b_1*b_3 + 22.5590957739185*b_1*b_4 + 17.5459633797144*b_1*b_5 + 14.3557882197663*b_1*b_6 + 15.791367041743*b_2**2 + 22.5590957739185*b_2*b_3 + 17.5459633797144*b_2*b_4 + 14.3557882197663*b_2*b_5 + 12.1472054167254*b_2*b_6 + 8.77298168985721*b_3**2 + 14.3557882197663*b_3*b_4 + 12.1472054167254*b_3*b_5 + 10.5275780278287*b_3*b_6 + 6.07360270836269*b_4**2 + 10.5275780278287*b_4*b_5 + 9.2890394363194*b_4*b_6 + 4.6445197181597*b_5**2 + 8.31124581144368*b_5*b_6 + 3.75984929565309*b_6**2) + (0.964*b_1 + 0.321333333333333*b_2 + 0.1928*b_3 + 0.137714285714286*b_4 + 0.107111111111111*b_5 + 0.0876363636363637*b_6)*(-1.28102213260338e-7*b_1*b_2 - 3.20255533150846e-8*b_1*b_3 - 3.20255533150846e-8*b_1*b_4 - 1.60127766575423e-8*b_1*b_6 - 1.60127766575423e-8*b_2**2 - 3.20255533150846e-8*b_2*b_3 - 1.60127766575423e-8*b_2*b_5 - 8.00638832877115e-9*b_3**2 + 1.60127766575423e-8*b_3*b_4 - 8.00638832877115e-9*b_3*b_6 - 8.00638832877115e-9*b_4*b_5 + 8.00638832877115e-9*b_4*b_6 + 4.00319416438558e-9*b_5**2 - 8.00638832877115e-9*b_5*b_6 + 4.00319416438558e-9*b_6**2 + 41123.3516712057) - 129937395.848442*(4*b_1 + 1.33333333333333*b_2 + 0.8*b_3 + 0.571428571428572*b_4 + 0.444444444444445*b_5 + 0.363636363636364*b_6)*(b_1**2 + 0.666666666666667*b_1*b_2 + 0.4*b_1*b_3 + 0.285714285714286*b_1*b_4 + 0.222222222222222*b_1*b_5 + 0.181818181818182*b_1*b_6 + 0.2*b_2**2 + 0.285714285714286*b_2*b_3 + 0.222222222222222*b_2*b_4 + 0.181818181818182*b_2*b_5 + 0.153846153846154*b_2*b_6 + 0.111111111111111*b_3**2 + 0.181818181818182*b_3*b_4 + 0.153846153846154*b_3*b_5 + 0.133333333333333*b_3*b_6 + 0.076923076923077*b_4**2 + 0.133333333333333*b_4*b_5 + 0.117647058823529*b_4*b_6 + 0.0588235294117647*b_5**2 + 0.105263157894737*b_5*b_6 + 0.0476190476190477*b_6**2) + (157.91367041743*b_1 + 52.6378901391433*b_2 + 31.582734083486*b_3 + 22.5590957739185*b_4 + 17.5459633797144*b_5 + 14.3557882197663*b_6)*(5.92386140141343e-10*b_1**2 + 6.14508444130024e-10*b_1*b_2 + 4.60881333097518e-10*b_1*b_3 + 1.53627111032506e-10*b_1*b_4 + 1.53627111032506e-10*b_1*b_5 + 2.30440666548759e-10*b_2**2 + 1.53627111032506e-10*b_2*b_3 + 1.53627111032506e-10*b_2*b_4 + 1.53627111032506e-10*b_2*b_6 + 7.6813555516253e-11*b_3**2 - 7.6813555516253e-11*b_3*b_4 + 7.6813555516253e-11*b_3*b_6 + 7.6813555516253e-11*b_4*b_5 + 7.6813555516253e-11*b_4*b_6 + 3.84067777581265e-11*b_5**2 - 251.041666666667)
I must solve such theses 6 equations.
But " Result from function call is not a proper array of floats. " error message comes out.
Is there anyone who help my code?
I'm Python beginning, so Plz understane me

Problems with incrementing location of widget creation when function is called

I am trying to make this function create a label and 2 buttons respectively, and each time this function is called, 3the widgets will be created on the next row(directly under the previous 3 widgets).
Howver, I am not sure why the items keep being created on the same row (effectively overlapping over the same one when the function is called) despite the counter being incremented.
def fetch_quick(self, entries):
for entry in entries:
text = entry[1].get()
print(text)
exec("app._framea" + str(self._qqq+7) + "= tk.Frame(app._master, bg='white')")
exec("app._framea" + str(self._qqq+7) + ".grid(row=" + str(self._qqq+6) + ")")
exec("self.queue_entry_quick" + str(self._qqq) + " = Label(app._framea" + str(self._qqq+7) + ", text='1 '+text +' 0 a few seconds ago')")
exec("self.queue_entry_quick" + str(self._qqq) + ".grid(row=" + str(self._qqq) + ")")
exec("self._Button" + str(self._qqq) + " = Button(app._framea" + str(self._qqq+7) + ", text = self._qqq, width = 2, command=app._framea" + str(self._qqq+7) + ".destroy, bg='red')")
exec("self._Buttonb" + str(self._qqq) + " = Button(app._framea" + str(self._qqq+7) + ", text = self._qqq, width = 2, command=app._framea" + str(self._qqq+7) + ".destroy, bg='green')")
exec("self._Button" + str(self._qqq) + ".grid(row=" + str(self._qqq) + ", column=1)")
exec("self._Button" + str(self._qqq) + ".bind('<Button-1>',self.call)")
exec("self._Buttonb" + str(self._qqq) + ".grid(row=" + str(self._qqq) + ", column=2)")
exec("self._Buttonb" + str(self._qqq) + ".bind('<Button-1>',self.call)")
abcd.append(text)
self._qqq += 1
print(self._qqq)
I think it might be the issue of the widgets' creation location(on the grid) being pre-set to row 0 for all of the widgets and thus it will not update self._qqq for each time the function is called. If this is the case, I am still unsure of what to do about it

Import equation from text file in Python

I have a complex equation which is generated into a .txt file. I would like to import this equation (which is all the text in the .txt file) and make a function from it, which can be subsequently fit.
Does anybody know how I might go about this? The equation to be fitted is at the the very bottom. My feeble attempt to import is below...
myfile1= open("dummyfile.txt", 'r')
def fcn(J1,J2,T,k,g):
return myfile1.read()
"dummyfile.txt" contents:
B**2*N*(12.0*g**2*sp.exp(2.0*J2/(T*k)) + 60.0*g**2*sp.exp(6.0*J2/(T*k)) + 168.0*g**2*sp.exp(12.0*J2/(T*k)) + 360.0*g**2*sp.exp(20.0*J2/(T*k)) + 30.0*g**2*sp.exp((2.0*J1 + 4.0*J2)/(T*k)) + 168.0*g**2*sp.exp((4.0*J1 + 8.0*J2)/(T*k)) + 360.0*g**2*sp.exp((6.0*J1 + 14.0*J2)/(T*k)) + 180.0*g**2*sp.exp((8.0*J1 + 12.0*J2)/(T*k)) + 660.0*g**2*sp.exp((8.0*J1 + 22.0*J2)/(T*k)) + 660.0*g**2*sp.exp((12.0*J1 + 18.0*J2)/(T*k)) + 1092.0*g**2*sp.exp((16.0*J1 + 26.0*J2)/(T*k)) + 546.0*g**2*sp.exp((18.0*J1 + 24.0*J2)/(T*k)) + 1680.0*g**2*sp.exp((24.0*J1 + 32.0*J2)/(T*k)) + 1224.0*g**2*sp.exp((32.0*J1 + 40.0*J2)/(T*k)))/(3*T*k*(6*sp.exp(2.0*J2/(T*k)) + 10*sp.exp(6.0*J2/(T*k)) + 14*sp.exp(12.0*J2/(T*k)) + 18*sp.exp(20.0*J2/(T*k)) + 5*sp.exp((2.0*J1 + 4.0*J2)/(T*k)) + 14*sp.exp((4.0*J1 + 8.0*J2)/(T*k)) + 18*sp.exp((6.0*J1 + 14.0*J2)/(T*k)) + 9*sp.exp((8.0*J1 + 12.0*J2)/(T*k)) + 22*sp.exp((8.0*J1 + 22.0*J2)/(T*k)) + 22*sp.exp((12.0*J1 + 18.0*J2)/(T*k)) + 26*sp.exp((16.0*J1 + 26.0*J2)/(T*k)) + 13*sp.exp((18.0*J1 + 24.0*J2)/(T*k)) + 30*sp.exp((24.0*J1 + 32.0*J2)/(T*k)) + 17*sp.exp((32.0*J1 + 40.0*J2)/(T*k)) + 1))
You can do that with exec().
Code:
def build_function(filename):
with open(filename, 'rU') as f:
eqn = f.read().strip()
exec("def fcn(J1, J2, T, k, g):\n return ({})".format(eqn))
return locals()['fcn']
Test Code:
fcn = build_function('file1')
print(fcn(1, 2, 3, 4, 5))
File1:
J2 + T*k
Results:
14

integrate cos(x)*cos(2x)*...*cos(mx) via SAGE

I'm going to find $I_m=\int_0^{2\pi} \prod_{k=1}^m cos(kx){}dx$, where $m=1,2,3\ldots$
Simple SAGE code:
x=var('x')
f = lambda m,x : prod([cos(k*x) for k in range(1,m+1)])
for m in range(1,15+1):
print m, numerical_integral(f(m,x), 0, 2*pi)[0],integrate(f(m,x),x,0,2*pi).n()
Output:
1 -1.47676658757e-16 0.000000000000000
2 -5.27735962315e-16 0.000000000000000
3 1.57079632679 1.57079632679490
4 0.785398163397 0.785398163397448
5 -2.60536121164e-16 0.000000000000000
6 -1.81559273097e-16 0.000000000000000
7 0.392699081699 0.392699081698724
8 0.343611696486 0.147262155637022
9 -1.72448482421e-16 0.294524311274043
10 -1.8747663502e-16 0.196349540849362
11 0.214757310304 0.312932080728671
12 0.190213617698 0.177941771394734
13 -1.30355375996e-16 0.208621387152447
14 -1.25168280013e-16 0.0859029241215959
15 0.138441766107 0.134223318939994
As you can see numerical answer is right, but result of integrate(...) is right for $m=1,2,\ldots,7$ and then there is some bug.
We can print indefinite integral:
for m in range(7,11+1):
print 'm=',m
print 'Indef_I_m=',integrate(f(m,x),x)
And Output:
m = 7
Indef_I_m = 1/16*x + 1/16*sin(2*x) + 1/32*sin(4*x) + 7/384*sin(6*x) +
7/512*sin(8*x) + 3/320*sin(10*x) + 5/768*sin(12*x) + 5/896*sin(14*x) +
1/256*sin(16*x) + 1/384*sin(18*x) + 1/640*sin(20*x) + 1/704*sin(22*x) +
1/1536*sin(24*x) + 1/1664*sin(26*x) + 1/1792*sin(28*x)
m = 8
Indef_I_m = 3/128*x + 5/256*sin(2*x) + 1/32*sin(3*x) + 5/512*sin(4*x) +
5/768*sin(6*x) + 1/256*sin(8*x) + 1/256*sin(10*x) + 1/256*sin(12*x) +
1/256*sin(14*x) + 1/256*sin(16*x) + 7/2304*sin(18*x) + 3/1280*sin(20*x)
+ 5/2816*sin(22*x) + 1/768*sin(24*x) + 3/3328*sin(26*x) +
1/1792*sin(28*x) + 1/1920*sin(30*x) + 1/4096*sin(32*x) +
1/4352*sin(34*x) + 1/4608*sin(36*x) + 3/32*sin(x)
m = 9
Indef_I_m = 3/64*x + 3/128*sin(2*x) + 23/768*sin(3*x) + 3/256*sin(4*x) +
3/640*sin(5*x) + 1/128*sin(6*x) + 5/1792*sin(7*x) + 5/2304*sin(9*x) +
3/2816*sin(11*x) + 1/832*sin(13*x) + 1/1280*sin(15*x) + 3/4352*sin(17*x)
+ 5/4864*sin(19*x) + 1/1344*sin(21*x) + 3/2944*sin(23*x) +
7/6400*sin(25*x) + 1/1152*sin(27*x) + 3/3712*sin(29*x) +
5/7936*sin(31*x) + 1/2112*sin(33*x) + 3/8960*sin(35*x) +
1/4736*sin(37*x) + 1/4992*sin(39*x) + 1/10496*sin(41*x) +
1/11008*sin(43*x) + 1/11520*sin(45*x) + 23/256*sin(x)
m = 10
Indef_I_m = 1/32*x + 1/64*sin(2*x) + 17/512*sin(3*x) + 1/128*sin(4*x) +
7/2560*sin(5*x) + 1/192*sin(6*x) + 3/1792*sin(7*x) + 1/1152*sin(9*x) +
5/5632*sin(11*x) + 3/6656*sin(13*x) + 1/2560*sin(15*x) +
5/8704*sin(17*x) + 3/9728*sin(19*x) + 1/2688*sin(21*x) +
1/2944*sin(23*x) + 1/6400*sin(25*x) + 1/4608*sin(27*x) +
3/14848*sin(29*x) + 3/15872*sin(31*x) + 5/16896*sin(33*x) +
3/8960*sin(35*x) + 3/9472*sin(37*x) + 1/3328*sin(39*x) +
5/20992*sin(41*x) + 1/5504*sin(43*x) + 1/7680*sin(45*x) +
1/12032*sin(47*x) + 1/12544*sin(49*x) + 1/26112*sin(51*x) +
1/27136*sin(53*x) + 1/28160*sin(55*x) + 13/128*sin(x)
m = 11
Indef_I_m = 51/1024*x + 53/2048*sin(2*x) + 13/768*sin(3*x) + 53/4096*sin(4*x) +
13/1536*sin(6*x) + 1/2048*sin(8*x) + 1/2560*sin(10*x) + 1/3072*sin(12*x)
+ 5/14336*sin(14*x) + 1/4096*sin(16*x) + 5/18432*sin(18*x) +
1/4096*sin(20*x) + 1/5632*sin(22*x) + 5/24576*sin(24*x) +
5/26624*sin(26*x) + 5/28672*sin(28*x) + 1/5120*sin(30*x) +
3/16384*sin(32*x) + 5/34816*sin(34*x) + 1/9216*sin(36*x) +
5/38912*sin(38*x) + 1/10240*sin(40*x) + 1/10752*sin(42*x) +
3/22528*sin(44*x) + 3/23552*sin(46*x) + 1/8192*sin(48*x) +
3/25600*sin(50*x) + 5/53248*sin(52*x) + 1/13824*sin(54*x) +
3/57344*sin(56*x) + 1/29696*sin(58*x) + 1/30720*sin(60*x) +
1/63488*sin(62*x) + 1/65536*sin(64*x) + 1/67584*sin(66*x) +
13/256*sin(x)
so for $m=7$ answer is right compare with Indef_I_7 via WolframAlpha
and for $m=8$ answer is incorrect Indef_I_8 via WolframAlpha
There should be Indef_I_8=$\frac{7x}{128}+\ldots$ and no $\sin(x)$, $\sin(3x)$ in summation, only $\sin(2k)$ for $k=1,2,3,\ldots 18$
Sorry for volumetric calculations !
The question is - Am I right that it is the bug in the symbolic integration?
Well, apparently setting algorithm='mathematica_free' solved the issue; this is probably a bug in the default algorithm used bye SAGE ('maxima').
So the answer is - Yes. It is a bug in algorithm='maxima', so use algorithm='mathematica_free' (def new function to find definite integral) or simplify_full() for such product of cos(kx) and than integrate.
f(8,x).simplify_full().integral(x,0,2pi) == 7/64pi and
(7/64*pi).n() == 0.343611696486384 is correct

Categories

Resources