1 /*
2 Qalculate (library)
3
4 Copyright (C) 2003-2007, 2008, 2016-2019 Hanna Knutsson (hanna.knutsson@protonmail.com)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 */
11
12 #include "support.h"
13
14 #include "BuiltinFunctions.h"
15 #include "MathStructure.h"
16 #include "Calculator.h"
17 #include "Number.h"
18 #include "Function.h"
19 #include "Variable.h"
20 #include "MathStructure-support.h"
21
22 using std::string;
23 using std::cout;
24 using std::vector;
25 using std::endl;
26
27 /* Collects x degree, coefficient, degree zero term. By default only one x term (a single exponent) is allowed.
28 If radunit is true all coefficient must be a multiple of the radian unit. The unit is then removed. Used for trigonometric functions.
29 If mexp_as_x2 is true, reuire a second degree polynomial and return second degree coefficient in mexp.
30 If mexp_as_fx is true allow x multipliers of any form (e.g. e^x or sin(x)) and return the the whole x multiplier in mexp.
31 */
integrate_info(const MathStructure & mstruct,const MathStructure & x_var,MathStructure & madd,MathStructure & mmul,MathStructure & mexp,bool radunit=false,bool mexp_as_x2=false,bool mexp_as_fx=false)32 bool integrate_info(const MathStructure &mstruct, const MathStructure &x_var, MathStructure &madd, MathStructure &mmul, MathStructure &mexp, bool radunit = false, bool mexp_as_x2 = false, bool mexp_as_fx = false) {
33 if(radunit && mstruct.isMultiplication() && mstruct.size() == 2 && mstruct[1] == CALCULATOR->getRadUnit()) return integrate_info(mstruct[0], x_var, madd, mmul, mexp, false, mexp_as_x2, mexp_as_fx);
34 madd.clear();
35 if(mexp_as_x2 || mexp_as_fx) mexp = m_zero;
36 else mexp = m_one;
37 mmul = m_zero;
38 if(!mexp_as_fx && mstruct == x_var) {
39 if(radunit) return false;
40 mmul = m_one;
41 return true;
42 } else if(mexp_as_x2 && mstruct.isPower()) {
43 if(radunit) return false;
44 if(mstruct[1].isNumber() && mstruct[1].number().isTwo() && mstruct[0] == x_var) {
45 mexp = m_one;
46 return true;
47 }
48 } else if(!mexp_as_fx && !mexp_as_x2 && mstruct.isPower() && mstruct[1].containsRepresentativeOf(x_var, true, true) == 0) {
49 if(radunit) return false;
50 if(mstruct[0] == x_var) {
51 mexp = mstruct[1];
52 mmul = m_one;
53 return true;
54 }
55 } else if(mstruct.isMultiplication() && mstruct.size() >= 2) {
56 bool b_x = false;
57 bool b_rad = false;
58 bool b2 = false;
59 size_t i_x = 0, i_rad = 0;
60 for(size_t i = 0; i < mstruct.size(); i++) {
61 if(!b_x && !mexp_as_fx && mstruct[i] == x_var) {
62 b_x = true;
63 i_x = i;
64 } else if(!b_x && mexp_as_x2 && mstruct[i].isPower() && mstruct[i][1].isNumber() && mstruct[i][1].number().isTwo() && mstruct[i][0] == x_var) {
65 b_x = true;
66 b2 = true;
67 i_x = i;
68 } else if(!b_x && !mexp_as_fx && !mexp_as_x2 && mstruct[i].isPower() && mstruct[i][0] == x_var && mstruct[i][1].containsRepresentativeOf(x_var, true, true) == 0) {
69 b_x = true;
70 i_x = i;
71 mexp = mstruct[i][1];
72 } else if(mstruct[i].containsRepresentativeOf(x_var, true, true) != 0) {
73 if(!b_x && mexp_as_fx && (mexp.isZero() || mexp == mstruct[i])) {
74 mexp = mstruct[i];
75 b_x = true;
76 i_x = i;
77 } else {
78 return false;
79 }
80 } else if(!b_rad && radunit && mstruct[i] == CALCULATOR->getRadUnit()) {
81 b_rad = true;
82 i_rad = i;
83 }
84 }
85 if(!b_x || (radunit && !b_rad)) return false;
86 if(mstruct.size() == 1 || (radunit && mstruct.size() == 2)) {
87 if(b2) mexp = m_one;
88 else mmul = m_one;
89 } else if(mstruct.size() == 2) {
90 if(b2) {
91 if(i_x == 1) mexp = mstruct[0];
92 else mexp = mstruct[1];
93 } else {
94 if(i_x == 1) mmul = mstruct[0];
95 else mmul = mstruct[1];
96 }
97 } else if(radunit && mstruct.size() == 3) {
98 if((i_x == 1 && i_rad == 2) || (i_x == 2 && i_rad == 1)) {
99 if(b2) mexp = mstruct[0];
100 else mmul = mstruct[0];
101 } else if((i_x == 0 && i_rad == 2) || (i_x == 2 && i_rad == 0)) {
102 if(b2) mexp = mstruct[1];
103 else mmul = mstruct[1];
104 } else {
105 if(b2) mexp = mstruct[2];
106 else mmul = mstruct[2];
107 }
108 } else {
109 if(b2) {
110 mexp = mstruct;
111 mexp.delChild(i_x + 1, true);
112 if(radunit) {
113 mexp.delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
114 }
115 } else {
116 mmul = mstruct;
117 mmul.delChild(i_x + 1, true);
118 if(radunit) {
119 mmul.delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
120 }
121 }
122 }
123 return true;
124 } else if(mstruct.isAddition()) {
125 mmul.setType(STRUCT_ADDITION);
126 if(mexp_as_x2) mexp.setType(STRUCT_ADDITION);
127 madd.setType(STRUCT_ADDITION);
128 for(size_t i = 0; i < mstruct.size(); i++) {
129 if(!mexp_as_fx && mstruct[i] == x_var) {
130 if(mexp_as_x2 || mexp.isOne()) mmul.addChild(m_one);
131 else return false;
132 } else if(mexp_as_x2 && mstruct[i].isPower() && mstruct[i][1].isNumber() && mstruct[i][1].number().isTwo() && mstruct[i][0] == x_var) {
133 mexp.addChild(m_one);
134 } else if(!mexp_as_fx && !mexp_as_x2 && mstruct[i].isPower() && mstruct[i][0] == x_var && mstruct[i][1].containsRepresentativeOf(x_var, true, true) == 0) {
135 if(mmul.size() == 0) {
136 mexp = mstruct[i][1];
137 } else if(mexp != mstruct[i][1]) {
138 return false;
139 }
140 mmul.addChild(m_one);
141 } else if(mstruct[i].isMultiplication()) {
142 bool b_x = false;
143 bool b_rad = false;
144 bool b2 = false;
145 size_t i_x = 0, i_rad = 0;
146 for(size_t i2 = 0; i2 < mstruct[i].size(); i2++) {
147 if(!b_x && !mexp_as_fx && mstruct[i][i2] == x_var) {
148 if(!mexp_as_x2 && !mexp.isOne()) return false;
149 i_x = i2;
150 b_x = true;
151 } else if(!b_x && mexp_as_x2 && mstruct[i][i2].isPower() && mstruct[i][i2][1].isNumber() && mstruct[i][i2][1].number().isTwo() && mstruct[i][i2][0] == x_var) {
152 b2 = true;
153 i_x = i2;
154 b_x = true;
155 } else if(!b_x && !mexp_as_fx && !mexp_as_x2 && mstruct[i][i2].isPower() && mstruct[i][i2][0] == x_var && mstruct[i][i2][1].containsRepresentativeOf(x_var, true, true) == 0) {
156 if(mmul.size() == 0) {
157 mexp = mstruct[i][i2][1];
158 } else if(mexp != mstruct[i][i2][1]) {
159 return false;
160 }
161 i_x = i2;
162 b_x = true;
163 } else if(mstruct[i][i2].containsRepresentativeOf(x_var, true, true) != 0) {
164 if(!b_x && mexp_as_fx && (mexp.isZero() || mexp == mstruct[i][i2])) {
165 mexp = mstruct[i][i2];
166 i_x = i2;
167 b_x = true;
168 } else {
169 return false;
170 }
171 } else if(!b_rad && radunit && mstruct[i][i2] == CALCULATOR->getRadUnit()) {
172 b_rad = true;
173 i_rad = i2;
174 }
175 }
176 if(radunit && !b_rad) return false;
177 if(b_x) {
178 if(mstruct[i].size() == 1) {
179 if(b2) mexp.addChild(m_one);
180 else mmul.addChild(m_one);
181 } else if(radunit && mstruct[i].size() == 2) {
182 if(b2) mexp.addChild(m_one);
183 else mmul.addChild(m_one);
184 } else {
185 if(b2) {
186 mexp.addChild(mstruct[i]);
187 mexp[mexp.size() - 1].delChild(i_x + 1, true);
188 if(radunit) mexp[mexp.size() - 1].delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
189 mexp.childUpdated(mexp.size());
190 } else {
191 mmul.addChild(mstruct[i]);
192 mmul[mmul.size() - 1].delChild(i_x + 1, true);
193 if(radunit) mmul[mmul.size() - 1].delChild(i_rad < i_x ? i_rad + 1 : i_rad, true);
194 mmul.childUpdated(mmul.size());
195 }
196 }
197 } else {
198 madd.addChild(mstruct[i]);
199 if(radunit) {
200 madd[madd.size() - 1].delChild(i_rad + 1, true);
201 }
202 }
203 } else if(radunit && mstruct[i] == CALCULATOR->getRadUnit()) {
204 madd.addChild(mstruct[i]);
205 } else if(radunit || mstruct[i].containsRepresentativeOf(x_var, true, true) != 0) {
206 if(!radunit && mexp_as_fx && (mexp.isZero() || mexp == mstruct[i])) {
207 mexp = mstruct[i];
208 mmul.addChild(m_one);
209 } else {
210 return false;
211 }
212 } else {
213 madd.addChild(mstruct[i]);
214 }
215 }
216 if(mmul.size() == 0 && (!mexp_as_x2 || mexp.size() == 0)) {
217 mmul.clear();
218 if(mexp_as_x2) mexp.clear();
219 return false;
220 }
221 if(mmul.size() == 0) mmul.clear();
222 else if(mmul.size() == 1) mmul.setToChild(1);
223 if(mexp_as_x2) {
224 if(mexp.size() == 0) mexp.clear();
225 else if(mexp.size() == 1) mexp.setToChild(1);
226 }
227 if(madd.size() == 0) madd.clear();
228 else if(madd.size() == 1) madd.setToChild(1);
229 return true;
230 } else if(!radunit && mexp_as_fx && mstruct.contains(x_var, true)) {
231 mexp = mstruct;
232 mmul = m_one;
233 return true;
234 }
235 return false;
236 }
237
238 /*bool test_absln_comp_cmplx(const MathStructure &mstruct) {
239 if(mstruct.number().isComplex() && (!mstruct.number().hasRealPart() || mstruct.number().hasPositiveSign()) && mstruct.number().internalImaginary()->isPositive()) return true;
240 if(mstruct.isPower() && mstruct[1].isNumber() && mstruct[1].number().numeratorIsOne() && mstruct[0].representsNonComplex(true)) return true;
241 if(mstruct.isMultiplication()) {
242 for(size_t i = 0; i < mstruct.size(); i++) {
243 if(!mstruct[i].representsNonNegative(true)) {
244 if(!test_absln_comp_cmplx(mstruct[i])) {
245 return false;
246 }
247 }
248 }
249 return true;
250 } else if(mstruct.isAddition()) {
251 for(size_t i = 0; i < mstruct.size(); i++) {
252 if(!mstruct[i].representsNonNegative(true)) {
253 if(!test_absln_comp_cmplx(mstruct[i])) {
254 return false;
255 }
256 }
257 }
258 return true;
259 }
260 return false;
261 }*/
262
263 /* Transform mstruct to logarithm (ln(mstruct)).
264 If use_abs != 0, logarithms of negative numbers are avoided. ln(abs(mstruct)) is used if signedness is unknown and mstruct is not complex. If abs > 0, mstruct is assumed real if it is not possible to determine if mstruct is complex or not.
265 */
transform_absln(MathStructure & mstruct,int use_abs,bool definite_integral,const MathStructure & x_var,const EvaluationOptions & eo)266 bool transform_absln(MathStructure &mstruct, int use_abs, bool definite_integral, const MathStructure &x_var, const EvaluationOptions &eo) {
267 if(use_abs != 0 && mstruct.representsNonComplex(true)) {
268 if(mstruct.representsNonPositive(true)) {
269 mstruct.negate();
270 } else if(!mstruct.representsNonNegative(true)) {
271 mstruct.transformById(FUNCTION_ID_ABS);
272 }
273 mstruct.transformById(FUNCTION_ID_LOG);
274 } else if(use_abs != 0 && !mstruct.representsComplex(true)) {
275 if(definite_integral) use_abs = -1;
276 CALCULATOR->beginTemporaryStopMessages();
277 MathStructure mtest(mstruct);
278 EvaluationOptions eo2 = eo;
279 eo2.expand = true;
280 eo2.approximation = APPROXIMATION_APPROXIMATE;
281 eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
282 mtest.eval(eo2);
283 CALCULATOR->endTemporaryStopMessages();
284 if(mtest.representsNonComplex(true)) {
285 if(mstruct.representsNonPositive(true)) {
286 mstruct.negate();
287 } else if(!mtest.representsNonNegative(true)) {
288 mstruct.transformById(FUNCTION_ID_ABS);
289 }
290 mstruct.transformById(FUNCTION_ID_LOG);
291 } else if(mtest.representsComplex(true)) {
292 mstruct.transformById(FUNCTION_ID_LOG);
293 } else {
294 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
295 CALCULATOR->beginTemporaryStopMessages();
296 KnownVariable *var = new KnownVariable("", format_and_print(x_var), ((UnknownVariable*) x_var.variable())->interval());
297 mtest.replace(x_var, var);
298 mtest.eval(eo2);
299 CALCULATOR->endTemporaryStopMessages();
300 if(mtest.representsNonComplex(true)) {
301 if(mstruct.representsNonPositive(true)) {
302 mstruct.negate();
303 } else if(!mtest.representsNonNegative(true)) {
304 mstruct.transformById(FUNCTION_ID_ABS);
305 }
306 mstruct.transformById(FUNCTION_ID_LOG);
307 } else if(use_abs > 0) {
308 CALCULATOR->error(false, "Integral assumed real", NULL);
309 mstruct.transformById(FUNCTION_ID_ABS);
310 mstruct.transformById(FUNCTION_ID_LOG);
311 } else {
312 mstruct.transformById(FUNCTION_ID_LOG);
313 }
314 var->destroy();
315 } else if(use_abs > 0) {
316 CALCULATOR->error(false, "Integral assumed real", NULL);
317 mstruct.transformById(FUNCTION_ID_ABS);
318 mstruct.transformById(FUNCTION_ID_LOG);
319 } else {
320 mstruct.transformById(FUNCTION_ID_LOG);
321 }
322 }
323 } else {
324 mstruct.transformById(FUNCTION_ID_LOG);
325 }
326 return true;
327 }
328
329 // Make sure that m does not contains division by zero. Used after differentiation.
check_zero_div(const MathStructure & m,const MathStructure & x_var,const EvaluationOptions & eo,bool top=true)330 bool check_zero_div(const MathStructure &m, const MathStructure &x_var, const EvaluationOptions &eo, bool top = true) {
331 if(top && (!x_var.isVariable() || x_var.variable()->isKnown() || ((UnknownVariable*) x_var.variable())->interval().isUndefined())) return true;
332 if(m.isPower() && m[1].compare(m_zero) == COMPARISON_RESULT_GREATER && m[0].contains(x_var, true) > 0 && COMPARISON_MIGHT_BE_EQUAL(m[0].compare(m_zero))) return false;
333 for(size_t i = 0; i < m.size(); i++) {
334 if(!check_zero_div(m[i], x_var, eo)) return false;
335 }
336 /*if(m.isFunction() && m.size() == 1 && (m.function()->id() == FUNCTION_ID_TAN || m.function()->id() == FUNCTION_ID_TANH) && m[0].contains(x_var, true) > 0) {
337 EvaluationOptions eo2 = eo;
338 eo2.approximation = APPROXIMATION_APPROXIMATE;
339 eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
340 eo2.assume_denominators_nonzero = false;
341 CALCULATOR->beginTemporaryStopMessages();
342 MathStructure mfunc(m);
343 mfunc.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
344 bool b = mfunc.calculateFunctions(eo2);
345 CALCULATOR->endTemporaryStopMessages();
346 if(!b) return false;
347 }*/
348 return true;
349 }
350
351 // 1/(ln(x)+5)=1/(ln(x*e^5)) if x>0
combine_ln(MathStructure & m,const MathStructure & x_var,const EvaluationOptions & eo,int depth=0)352 bool combine_ln(MathStructure &m, const MathStructure &x_var, const EvaluationOptions &eo, int depth = 0) {
353 if(m.isAddition() && depth > 0 && m.containsFunctionId(FUNCTION_ID_LOG)) {
354 size_t i_log = 0, i_mul_log = 0;
355 bool b = false;
356 MathStructure *mi = NULL;
357 for(size_t i = 0; i < m.size(); i++) {
358 if(!b && m[i].isMultiplication() && m[i].containsFunctionId(FUNCTION_ID_LOG) && m[i].contains(x_var, true)) {
359 for(size_t i2 = 0; i2 < m[i].size(); i2++) {
360 if(!b && m[i][i2].isFunction() && m[i][i2].function()->id() == FUNCTION_ID_LOG && m[i][i2].size() == 1 && m[i][i2][0].contains(x_var)) {
361 b = true;
362 i_log = i;
363 i_mul_log = i2;
364 } else if(m[i][i2].containsRepresentativeOf(x_var, true, true) != 0 || !m[i][i2].representsReal(true)) {
365 b = false;
366 break;
367 }
368 }
369 if(!b) break;
370 } else if(!b && m[i].isFunction() && m[i].function()->id() == FUNCTION_ID_LOG && m[i].size() == 1 && m[i][0].contains(x_var)) {
371 b = true;
372 i_log = i;
373 break;
374 } else if(!mi && m[i].isMultiplication() && m[i].size() == 2 && m[i][1].isVariable() && m[i][1].variable()->id() == VARIABLE_ID_PI && m[i][0].isNumber() && m[i][0].number().hasImaginaryPart() && !m[i][0].number().hasRealPart() && m[i][0].number().internalImaginary()->isReal()) {
375 mi = &m[i][0];
376 } else if(m[i].containsRepresentativeOf(x_var, true, true) != 0 || !m[i].representsReal(true)) {
377 b = false;
378 break;
379 }
380 }
381 if(b && ((m[i_log].isMultiplication() && m[i_log][i_mul_log][0].compare(m_zero) == COMPARISON_RESULT_LESS) || (m[i_log].isFunction() && m[i_log][0].compare(m_zero) == COMPARISON_RESULT_LESS))) {
382 MathStructure mmul(1, 1, 0);
383 if(mi) mmul = *mi->number().internalImaginary();
384 MathStructure *m_e = new MathStructure(CALCULATOR->getVariableById(VARIABLE_ID_E));
385 MathStructure *mpow = new MathStructure;
386 mpow->set_nocopy(m);
387 mpow->delChild(i_log + 1, true);
388 if(!mmul.isOne()) mpow->calculateDivide(mmul, eo);
389 m_e->raise_nocopy(mpow);
390 m_e->calculateRaiseExponent(eo);
391 m.setToChild(i_log + 1, true);
392 if(m.isMultiplication()) {
393 MathStructure *mexp = new MathStructure;
394 mexp->set_nocopy(m);
395 mexp->delChild(i_mul_log + 1, true);
396 if(!mmul.isOne()) mexp->calculateDivide(mmul, eo);
397 m.setToChild(i_mul_log + 1, true);
398 m[0].raise_nocopy(mexp);
399 m[0].calculateRaiseExponent(eo);
400 } else if(!mmul.isOne()) {
401 MathStructure *mexp = new MathStructure(mmul);
402 mexp->calculateInverse(eo);
403 m[0].raise_nocopy(mexp);
404 m[0].calculateRaiseExponent(eo);
405 }
406 m[0].multiply_nocopy(m_e);
407 m[0].calculateMultiplyLast(eo);
408 m.childUpdated(1);
409 if(!mmul.isOne()) {m.multiply(mmul); m.swapChildren(1, 2);}
410 return true;
411 }
412 }
413 bool b_ret = false;
414 for(size_t i = 0; i < m.size(); i++) {
415 if(combine_ln(m[i], x_var, eo, depth + 1)) {
416 m.childUpdated(i + 1);
417 b_ret = true;
418 }
419 }
420 if(b_ret) {
421 m.calculatesub(eo, eo, false);
422 }
423 return b_ret;
424 }
425
426 /* Determines the integral of mfac * ((mpowmul * mstruct) + mpowadd)^mpow, where mstruct is a function with x_var in argument.
427 */
integrate_function(MathStructure & mstruct,const MathStructure & x_var,const EvaluationOptions & eo,const MathStructure & mpow,const MathStructure & mfac,const MathStructure & mpowadd,const MathStructure & mpowmul,int use_abs,bool definite_integral,int max_part_depth,vector<MathStructure * > * parent_parts)428 int integrate_function(MathStructure &mstruct, const MathStructure &x_var, const EvaluationOptions &eo, const MathStructure &mpow, const MathStructure &mfac, const MathStructure &mpowadd, const MathStructure &mpowmul, int use_abs, bool definite_integral, int max_part_depth, vector<MathStructure*> *parent_parts) {
429 if(mpow.containsRepresentativeOf(x_var, true, true) != 0) return false;
430 // mpow != x
431 if(!mpowadd.isZero() || !mpowmul.isOne()) {
432 if(!mfac.isOne() || !mpow.isMinusOne()) return false;
433 // mpowadd != 0, mpowmul != 1, mfac = 1, mpow = -1: 1/((mpowmul*mstruct)+mpowadd)
434 if((mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_COS || mstruct.function()->id() == FUNCTION_ID_SINH || mstruct.function()->id() == FUNCTION_ID_COSH || mstruct.function()->id() == FUNCTION_ID_LOG) && mstruct.size() == 1) {
435 MathStructure mexp, mmul, madd;
436 if(integrate_info(mstruct[0], x_var, madd, mmul, mexp, (mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_COS))) {
437 if(mexp.isOne()) {
438 bool neg_equals = false;
439 if((mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_COS || mstruct.function()->id() == FUNCTION_ID_COSH) && mpowadd != mpowmul) {
440 MathStructure mpowaddneg(mpowadd);
441 mpowaddneg.calculateNegate(eo);
442 neg_equals = (mpowaddneg == mpowmul);
443 }
444 if(mstruct.function()->id() == FUNCTION_ID_SIN) {
445 if(mpowadd == mpowmul || neg_equals) {
446 //1/(c*sin(ax+b)+c): 2*sin((a x + b)/2)*(sin((a x + b)/2)+cos((a x + b)/2))/(a*(c*sin((a x + b))+c))
447 MathStructure mdiv(mstruct);
448 mstruct[0] *= nr_half;
449 MathStructure msin(mstruct);
450 MathStructure mcos(mstruct);
451 mcos.setFunctionId(FUNCTION_ID_COS);
452 mstruct *= nr_two;
453 if(mpowadd != mpowmul) msin.negate();
454 msin += mcos;
455 mstruct *= msin;
456 mdiv *= mpowmul;
457 mdiv += mpowadd;
458 if(!mmul.isOne()) mdiv *= mmul;
459 mstruct /= mdiv;
460 return true;
461 } else {
462 //1/(d*sin(ax+b)+c): (2 atan((c*tan((a x + b)/2)+d)/sqrt(c^2-d^2)))/(a*sqrt(c^2-d^2))
463 if(definite_integral && x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
464 MathStructure mtest(mstruct[0]);
465 mtest[0] /= CALCULATOR->getRadUnit();
466 mtest[0] /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
467 mtest[0] /= nr_two;
468 mtest[0].transformById(FUNCTION_ID_ABS);
469 mtest[0].transformById(FUNCTION_ID_FRAC);
470 if(COMPARISON_MIGHT_BE_EQUAL(mtest.compare(nr_half))) return -1;
471 }
472 mstruct.setFunctionId(FUNCTION_ID_TAN);
473 mstruct[0] *= nr_half;
474 mstruct *= mpowadd;
475 mstruct += mpowmul;
476 MathStructure msqrtc2md2(mpowadd);
477 if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
478 MathStructure mmpowmul2(mpowmul);
479 if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
480 mmpowmul2.negate();
481 msqrtc2md2 += mmpowmul2;
482 msqrtc2md2 ^= Number(-1, 2, 0);
483 mstruct *= msqrtc2md2;
484 mstruct.transformById(FUNCTION_ID_ATAN);
485 mstruct *= msqrtc2md2;
486 if(!mmul.isOne()) mstruct /= mmul;
487 mstruct *= nr_two;
488 return true;
489 }
490 } else if(mstruct.function()->id() == FUNCTION_ID_COS) {
491 if(mpowadd == mpowmul) {
492 //1/(c*cos(ax+b)+c): tan((a x + b)/2)/(ac)
493 mstruct[0] *= nr_half;
494 mstruct.setFunctionId(FUNCTION_ID_TAN);
495 if(!mpowadd.isOne()) mstruct /= mpowadd;
496 if(!mmul.isOne()) mstruct /= mmul;
497 return true;
498 } else if(neg_equals) {
499 //1/(c*cos(ax+b)-c): cos((a x + b)/2)/(ac*sin((a x + b)/2))
500 mstruct[0] *= nr_half;
501 MathStructure msin(mstruct);
502 msin.setFunctionId(FUNCTION_ID_SIN);
503 mstruct /= msin;
504 if(!mpowmul.isOne()) mstruct /= mpowmul;
505 if(!mmul.isOne()) mstruct /= mmul;
506 return true;
507 } else {
508 //1/(d*cos(ax+b)+c): -(2*atanh(((c-d)*tan((a x + b)/2))/sqrt(d^2-c^2)))/(a*sqrt(d^2-c^2))
509 if(definite_integral && x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
510 MathStructure mtest(mstruct[0]);
511 mtest[0] /= CALCULATOR->getRadUnit();
512 mtest[0] /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
513 mtest[0] /= nr_two;
514 mtest[0].transformById(FUNCTION_ID_ABS);
515 mtest[0].transformById(FUNCTION_ID_FRAC);
516 if(COMPARISON_MIGHT_BE_EQUAL(mtest.compare(nr_half))) return -1;
517 }
518 mstruct.setFunctionId(FUNCTION_ID_TAN);
519 mstruct[0] *= nr_half;
520 mstruct *= mpowadd;
521 mstruct.last() -= mpowmul;
522 mstruct.childUpdated(mstruct.size());
523 MathStructure msqrtc2md2(mpowadd);
524 if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
525 msqrtc2md2.negate();
526 MathStructure mmpowmul2(mpowmul);
527 if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
528 msqrtc2md2 += mmpowmul2;
529 msqrtc2md2 ^= Number(-1, 2, 0);
530 mstruct *= msqrtc2md2;
531 mstruct.transformById(FUNCTION_ID_ATANH);
532 mstruct *= msqrtc2md2;
533 if(!mmul.isOne()) mstruct /= mmul;
534 mstruct *= Number(-2, 1);
535 return true;
536 }
537 } else if(mstruct.function()->id() == FUNCTION_ID_SINH) {
538 //1/(d*sinh(ax+b)+c): (2 atan((-c*tan((a x + b)/2)+d)/sqrt(-c^2-d^2)))/(a*sqrt(-c^2-d^2))
539 mstruct.setFunctionId(FUNCTION_ID_TANH);
540 mstruct[0] *= nr_half;
541 mstruct *= mpowadd;
542 mstruct.negate();
543 mstruct += mpowmul;
544 MathStructure msqrtc2md2(mpowadd);
545 if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
546 msqrtc2md2.negate();
547 MathStructure mmpowmul2(mpowmul);
548 if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
549 mmpowmul2.negate();
550 msqrtc2md2 += mmpowmul2;
551 msqrtc2md2 ^= Number(-1, 2, 0);
552 mstruct *= msqrtc2md2;
553 mstruct.transformById(FUNCTION_ID_ATAN);
554 mstruct *= msqrtc2md2;
555 if(!mmul.isOne()) mstruct /= mmul;
556 mstruct *= nr_two;
557 return true;
558 } else if(mstruct.function()->id() == FUNCTION_ID_COSH) {
559 if(mpowadd == mpowmul) {
560 //1/(c*cosh(ax+b)+c): tanh((a x + b)/2)/(ac)
561 mstruct[0] *= nr_half;
562 mstruct.setFunctionId(FUNCTION_ID_TANH);
563 if(!mpowadd.isOne()) mstruct /= mpowadd;
564 if(!mmul.isOne()) mstruct /= mmul;
565 return true;
566 } else if(neg_equals) {
567 //1/(c*cosh(ax+b)-c): -cosh((a x + b)/2)/(ac*sinh((a x + b)/2))
568 mstruct[0] *= nr_half;
569 MathStructure msin(mstruct);
570 msin.setFunctionId(FUNCTION_ID_SINH);
571 mstruct.negate();
572 mstruct /= msin;
573 if(!mpowmul.isOne()) mstruct /= mpowmul;
574 if(!mmul.isOne()) mstruct /= mmul;
575 return true;
576 } else {
577 //1/(d*cos(ax+b)+c): -(2*atan(((c-d)*tanh((a x + b)/2))/sqrt(d^2-c^2)))/(a*sqrt(d^2-c^2))
578 mstruct.setFunctionId(FUNCTION_ID_TANH);
579 mstruct[0] *= nr_half;
580 mstruct *= mpowadd;
581 mstruct.last() -= mpowmul;
582 mstruct.childUpdated(mstruct.size());
583 MathStructure msqrtc2md2(mpowadd);
584 if(!mpowadd.isOne()) msqrtc2md2 ^= nr_two;
585 msqrtc2md2.negate();
586 MathStructure mmpowmul2(mpowmul);
587 if(!mpowmul.isOne()) mmpowmul2 ^= nr_two;
588 msqrtc2md2 += mmpowmul2;
589 msqrtc2md2 ^= Number(-1, 2, 0);
590 mstruct *= msqrtc2md2;
591 mstruct.transformById(FUNCTION_ID_ATAN);
592 mstruct *= msqrtc2md2;
593 if(!mmul.isOne()) mstruct /= mmul;
594 mstruct *= Number(-2, 1);
595 return true;
596 }
597 } else if(mstruct.function()->id() == FUNCTION_ID_LOG) {
598 //1/(d*ln(ax+b)+c): (e^(-c/d)*Ei(c/d+ln(ax+b)))/(a*d)
599 MathStructure mpadm(mpowadd);
600 if(!mpowmul.isOne()) mpadm /= mpowmul;
601 mstruct += mpadm;
602 mstruct.transformById(FUNCTION_ID_EXPINT);
603 mpadm.negate();
604 mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_E);
605 mstruct.last() ^= mpadm;
606 mstruct.childUpdated(mstruct.size());
607 if(!mmul.isOne()) mstruct /= mmul;
608 if(!mpowmul.isOne()) mstruct /= mpowmul;
609 return true;
610 }
611 } else if(mstruct.function()->id() == FUNCTION_ID_LOG && madd.isZero()) {
612 //1/(d*ln(ax^b)+c): (x*(ax^b)^(-1/b)*e^(-c/(bd))*Ei((c+d*ln(ax^b))/(bd)))/(bd)
613 MathStructure mem(mexp);
614 if(!mpowmul.isOne()) mem *= mpowmul;
615 mem.inverse();
616 MathStructure marg(mstruct[0]);
617 mexp.inverse();
618 mexp.negate();
619 marg ^= mexp;
620 MathStructure mexpe(CALCULATOR->getVariableById(VARIABLE_ID_E));
621 if(!mpowadd.isZero()) {
622 MathStructure mepow(mpowadd);
623 mepow.negate();
624 mepow *= mem;
625 mexpe ^= mepow;
626 }
627 if(!mpowmul.isOne()) mstruct *= mpowmul;
628 if(!mpowadd.isZero()) mstruct += mpowadd;
629 mstruct *= mem;
630 mstruct.transformById(FUNCTION_ID_EXPINT);
631 if(!mpowadd.isZero()) mstruct *= mexpe;
632 mstruct *= marg;
633 mstruct *= x_var;
634 mstruct *= mem;
635 return true;
636 }
637 }
638 }
639 return false;
640 }
641 // mpowadd=0 and mpowmul=1: mfac*mstruct^mpow
642
643 if(mstruct.function()->id() == FUNCTION_ID_LOG && mstruct.size() == 1) {
644 if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct[0]) && mpow.isOne() && mfac.isOne() && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
645 MathStructure mexp, mmul, madd;
646 if(integrate_info(mstruct[0][0], x_var, madd, mmul, mexp) && mexp.isOne()) {
647 if(madd.isZero()) {
648 if(mmul.isZero()) {
649 mstruct *= x_var;
650 mstruct += x_var;
651 mstruct.last().divide(mstruct[0][1]);
652 mstruct.childUpdated(mstruct.size());
653 mstruct.last().negate();
654 return true;
655 }
656 MathStructure mterm(mstruct[0]);
657 mterm ^= nr_two;
658 mterm *= mstruct[0];
659 mterm.inverse();
660 if(!mmul.isOne()) mterm *= mmul;
661 mterm *= x_var;
662 mterm.last() ^= nr_two;
663 mterm *= Number(-1, 3);
664 mstruct *= x_var;
665 mstruct += mterm;
666 return true;
667 }
668 MathStructure mterm1(x_var);
669 if(!mmul.isOne()) mterm1 *= mmul;
670 if(!madd.isOne()) mterm1 /= madd;
671 mterm1 += m_one;
672 if(!transform_absln(mterm1, use_abs, definite_integral, x_var, eo)) return -1;
673 if(!mmul.isOne()) mterm1 /= mmul;
674 if(!madd.isOne()) mterm1 *= madd;
675 mterm1 /= mstruct[0][1];
676 MathStructure mterm2(x_var);
677 mterm2 /= mstruct[0][1];
678 mstruct *= x_var;
679 mstruct += mterm1;
680 mstruct -= mterm2;
681 return true;
682 }
683 }
684 MathStructure mexp, mmul, madd;
685 if(integrate_info(mstruct[0], x_var, madd, mmul, mexp, false, false, true) && (mexp == x_var || (mexp.isPower() && mexp[0] == x_var && ((mexp[1] == x_var && madd.isZero() && mpow.isOne() && (!definite_integral || x_var.representsNonNegative(true))) || mexp[1].containsRepresentativeOf(x_var, true, true) == 0)) || (mpow.isOne() && madd.isZero() && mexp.isFunction() && mexp.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mexp) && mexp[0] == x_var) || (mpow.isOne() && madd.isZero() && mexp.isPower() && mexp[1].isInteger() && mexp[0].isFunction() && mexp[0].function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mexp[0]) && mexp[0][0] == x_var))) {
686 bool b_root = false;
687 if(mexp == x_var) mexp.set(1, 1, 0);
688 else if(mexp.isPower() && mexp[0] == x_var) mexp.setToChild(2);
689 else if(mexp.isPower()) {mexp[0].setToChild(2); mexp[0].number().recip(); mexp[0].number() *= mexp[1].number(); mexp.setToChild(1); b_root = true;}
690 else {mexp.setToChild(2); mexp.number().recip(); b_root = true;}
691 bool do_if = false;
692 // if mstruct[0]=0 for lower or upper limit do if(mstruct[0]=0,0,f(x))
693 if(definite_integral && x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
694 MathStructure mtest(((UnknownVariable*) x_var.variable())->interval());
695 mtest.eval(eo);
696 if(mtest.isNumber()) {
697 MathStructure mtest2(mstruct[0]);
698 mtest2.replace(x_var, mtest.number().lowerEndPoint());
699 mtest2.eval(eo);
700 do_if = (mtest2.isNumber() && !mtest2.number().isNonZero());
701 if(!do_if) {
702 mtest2 = mstruct[0];
703 mtest2.replace(x_var, mtest.number().upperEndPoint());
704 mtest2.eval(eo);
705 do_if = (mtest2.isNumber() && !mtest2.number().isNonZero());
706 }
707 }
708 }
709 MathStructure mif;
710 MathStructure marg(mstruct[0]);
711 bool b = false;
712 if(mexp == x_var) {
713 if(mfac.isOne()) {
714 // ln(x^x): x*ln(x^x)-x^2*(ln(x)*2+1)/4
715 mstruct *= x_var;
716 MathStructure mterm(x_var);
717 mterm.transformById(FUNCTION_ID_LOG);
718 mterm *= nr_two;
719 mterm += m_one;
720 mterm *= x_var;
721 mterm.last() ^= nr_two;
722 mterm *= Number(-1, 4);
723 mstruct += mterm;
724 b = true;
725 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
726 // ln(x^x)*x^a: -x(-(a+2)^2*ln(x^x)+(a+2)(x*ln(x))+(a+1)x)/((a+1)(a+2)^2)
727 if(mfac == x_var) mexp.set(1, 1, 0);
728 else mexp = mfac[1];
729 MathStructure mexpp1(mexp);
730 mexpp1 += m_one;
731 MathStructure mexpp2(mexp);
732 mexpp2 += nr_two;
733 MathStructure mterm1(x_var);
734 mterm1.transformById(FUNCTION_ID_LOG);
735 mterm1 *= x_var;
736 mterm1 *= mexpp2;
737 MathStructure mterm2(x_var);
738 mterm2 *= mexpp1;
739 mstruct.negate();
740 mexpp2 ^= nr_two;
741 mstruct *= mexpp2;
742 mstruct += mterm1;
743 mstruct += mterm2;
744 mstruct *= x_var;
745 mstruct.last() ^= mexpp1;
746 mexpp2 *= mexpp1;
747 mstruct /= mexpp2;
748 mstruct.negate();
749 b = true;
750 }
751 } else if(mfac.isOne() && (mexp.isOne() || madd.isZero())) {
752 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-1)) {
753 if(mpow.isOne()) {
754 if(madd.isZero()) {
755 // ln(ax^b): x(ln(ax^b)-b)
756 mstruct -= mexp;
757 mstruct.multiply(x_var);
758 b = true;
759 } else {
760 // ln(ax+b): (ax+b)(ln(ax)-1)/a
761 MathStructure marg(mstruct[0]);
762 mstruct *= marg;
763 mstruct -= marg;
764 if(!mmul.isOne()) mstruct.divide(mmul);
765 b = true;
766 }
767 } else if(mpow.number().isTwo()) {
768 // ln(ax+b)^2: (ln(ax+b)^2-2*ln(ax+b)+2)(ax+b)/a
769 // ln(ax^b)^2: x(ln(ax^b)^2-2*ln(ax^b)*b+2b^2)
770 MathStructure marg(mstruct[0]);
771 MathStructure mterm2(mstruct);
772 mstruct ^= mpow;
773 mterm2 *= Number(-2, 1);
774 if(mexp.isOne()) {
775 mterm2 += nr_two;
776 } else {
777 mterm2 *= mexp;
778 mterm2 += mexp;
779 mterm2.last() ^= nr_two;
780 mterm2.last() *= nr_two;
781 }
782 mstruct += mterm2;
783 if(madd.isZero()) {
784 mstruct.multiply(x_var);
785 } else {
786 mstruct *= marg;
787 if(!mmul.isOne()) mstruct /= mmul;
788 }
789 b = true;
790 } else if(mpow.number().isMinusOne()) {
791 if(mexp.isOne()) {
792 // ln(ax+b)^-1: li(ax+b)/a
793 if(!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0].compare(m_zero))) {
794 mstruct.setFunctionId(FUNCTION_ID_LOGINT);
795 if(!mmul.isOne()) mstruct /= mmul;
796 b = true;
797 do_if = false;
798 }
799 }
800 } else {
801 // ln(ax^b)^n: x*sum(ln(ax^b)^i*n!/i!*(-b)^(n-i), 0, n)
802 // ln(ax+b)^n: (ax+b)/a*sum(ln(ax+b)^i*n!/i!*(-1)^(n-i), 0, n)
803 unsigned long int n = mpow.number().uintValue();
804 MathStructure marg(mstruct[0]);
805 Number nfac(mpow.number());
806 nfac.factorial();
807 for(size_t i = 0; i <= n; i++) {
808 MathStructure mterm(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &marg, NULL);
809 mterm ^= Number(i);
810 mterm *= nfac;
811 Number ifac(i);
812 ifac.factorial();
813 mterm /= ifac;
814 MathStructure m1pow(mexp);
815 m1pow.negate();
816 m1pow ^= Number(n - i);
817 mterm *= m1pow;
818 if(i == 0) mstruct = mterm;
819 else mstruct += mterm;
820 }
821 if(madd.isZero()) {
822 mstruct.multiply(x_var);
823 } else {
824 mstruct *= marg;
825 if(!mmul.isOne()) mstruct /= mmul;
826 }
827 b = true;
828 }
829 }
830 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
831 MathStructure mfacexp(1, 1, 0);
832 if(mfac != x_var) mfacexp = mfac[1];
833 if(mfacexp.isMinusOne()) {
834 if(mpow.isMinusOne()) {
835 if(mexp.isOne() && madd.isZero()) {
836 mstruct.transformById(FUNCTION_ID_LOG);
837 b = true;
838 }
839 } else if(madd.isZero()) {
840 MathStructure mpowp1(mpow);
841 mpowp1 += m_one;
842 mstruct ^= mpowp1;
843 mstruct /= mpowp1;
844 if(!mexp.isOne()) mstruct /= mexp;
845 b = true;
846 } else if(mpow.isOne()) {
847 MathStructure m_axcb(x_var);
848 if(!mexp.isOne()) m_axcb ^= mexp;
849 if(!mmul.isOne()) m_axcb *= mmul;
850 if(!madd.isZero()) m_axcb /= madd;
851 mstruct *= m_axcb;
852 mstruct.last().negate();
853 mstruct.last().transformById(FUNCTION_ID_LOG);
854 MathStructure mterm2(m_axcb);
855 mterm2 += m_one;
856 mterm2.transformById(FUNCTION_ID_POLYLOG);
857 mterm2.insertChild(nr_two, 1);
858 mstruct += mterm2;
859 if(!mexp.isOne()) mstruct /= mexp;
860 b = true;
861 }
862 do_if = do_if && !madd.isZero();
863 } else if(madd.isZero()) {
864 if(mpow.isOne()) {
865 mfacexp += m_one;
866 mstruct *= mfacexp;
867 mstruct -= mexp;
868 mstruct *= x_var;
869 mstruct.last() ^= mfacexp;
870 mfacexp ^= Number(-2, 1);
871 mstruct *= mfacexp;
872 mstruct.childrenUpdated();
873 b = true;
874 } else if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100)) {
875 if(mpow.isMinusOne()) {
876 if(!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0].compare(m_zero))) {
877 if(mexp.isOne()) {
878 MathStructure mmulfac(mmul);
879 if(!mmul.isOne()) {
880 mmulfac *= x_var;
881 mmulfac ^= mfacexp;
882 mmulfac[1].negate();
883 mmulfac *= x_var;
884 mmulfac.last() ^= mfacexp;
885 mmulfac.childrenUpdated(true);
886 }
887 mfacexp += m_one;
888 mstruct *= mfacexp;
889 mstruct.transformById(FUNCTION_ID_EXPINT);
890 if(!mmul.isOne()) {
891 mstruct *= mmulfac;
892 mstruct /= mmul;
893 }
894 b = true;
895 } else {
896 MathStructure mepow(mstruct);
897 mfacexp += m_one;
898 mstruct *= mfacexp;
899 mstruct /= mexp;
900 mstruct.transformById(FUNCTION_ID_EXPINT);
901 mepow.negate();
902 mepow += x_var;
903 mepow.last().transformById(FUNCTION_ID_LOG);
904 mepow.last() *= mexp;
905 mepow *= mfacexp;
906 mepow /= mexp;
907 MathStructure memul(CALCULATOR->getVariableById(VARIABLE_ID_E));
908 memul ^= mepow;
909 mstruct *= memul;
910 mstruct /= mexp;
911 b = true;
912 }
913 }
914 } else if(mpow.number().isNegative()) {
915 if(mexp.isOne()) {
916 MathStructure mpowp1(mpow);
917 mpowp1 += m_one;
918 MathStructure mpowp1n(mpowp1);
919 mpowp1n.negate();
920 MathStructure mterm(mstruct);
921 mstruct ^= mpowp1;
922 mstruct *= x_var;
923 mstruct.last() ^= mfacexp;
924 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
925 mfacexp += m_one;
926 mstruct *= mfacexp;
927 mstruct /= mpowp1n;
928 mterm ^= mpowp1;
929 mterm *= x_var;
930 mterm.last() ^= mfacexp;
931 mterm /= mpowp1n;
932 mstruct -= mterm;
933 mstruct.childrenUpdated(true);
934 b = true;
935 }
936 } else {
937 MathStructure mterm(mstruct);
938 mstruct ^= mpow;
939 mstruct.last() += nr_minus_one;
940 mstruct *= x_var;
941 mstruct.last() ^= mfacexp;
942 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
943 mstruct *= mpow;
944 mfacexp += m_one;
945 mstruct /= mfacexp;
946 mstruct.negate();
947 mstruct *= mexp;
948 mterm ^= mpow;
949 mterm *= x_var;
950 mterm.last() ^= mfacexp;
951 mterm /= mfacexp;
952 mstruct += mterm;
953 mstruct.childrenUpdated(true);
954 b = true;
955 }
956 }
957 } else if(mfac == x_var && mexp.isOne()) {
958 if(mpow.isOne()) {
959 MathStructure mterm2(x_var);
960 if(!mmul.isOne()) mterm2 *= mmul;
961 mterm2 += madd;
962 mterm2.last() *= Number(-2, 1);
963 mterm2 *= x_var;
964 if(!mmul.isOne()) mterm2 /= mmul;
965 mterm2 *= Number(-1, 4);
966 MathStructure marg(x_var);
967 if(!mmul.isOne()) marg *= mmul;
968 marg += madd;
969 mstruct *= marg;
970 marg.last() *= nr_minus_one;
971 mstruct *= marg;
972 if(!mmul.isOne()) {
973 mstruct *= mmul;
974 mstruct.last() ^= Number(-2, 1);
975 }
976 mstruct *= nr_half;
977 mstruct += mterm2;
978 mstruct.childrenUpdated(true);
979 b = true;
980 if(do_if) mif = mterm2;
981 }
982 }
983 } else if(!b_root && mfac.isFunction() && mfac.function()->id() == FUNCTION_ID_LOG && mfac.size() == 1 && madd.isZero() && mpow.isOne()) {
984 MathStructure mexp2, mmul2, madd2;
985 if(integrate_info(mfac[0], x_var, madd2, mmul2, mexp2) && madd2.isZero()) {
986 MathStructure mterm2(mfac);
987 mterm2.negate();
988 mterm2 += nr_two;
989 if(!mexp2.isOne()) {
990 mterm2.last() *= mexp2;
991 mterm2.childUpdated(mterm2.size());
992 }
993 if(!mexp.isOne()) mterm2 *= mexp;
994 mstruct *= mfac;
995 mstruct.last() -= mexp2;
996 mstruct.childUpdated(mstruct.size());
997 mstruct += mterm2;
998 mstruct *= x_var;
999 b = true;
1000 }
1001 }
1002 if(b) {
1003 if(do_if) {
1004 mstruct.transformById(FUNCTION_ID_IF);
1005 mstruct.insertChild(mif, 1);
1006 mstruct.insertChild(marg, 1);
1007 mstruct.addChild(m_zero);
1008 mstruct[0].transform(COMPARISON_EQUALS, m_zero);
1009 }
1010 return true;
1011 }
1012 }
1013 } else if(mstruct.function()->id() == FUNCTION_ID_LAMBERT_W && mstruct.size() >= 1) {
1014 if(mfac == x_var && mpow.isOne() && mstruct[0] == x_var) {
1015 MathStructure mthis(mstruct);
1016 mstruct ^= nr_two;
1017 mstruct *= nr_two;
1018 mstruct += nr_one;
1019 mstruct *= mthis;
1020 mstruct.last() *= nr_two;
1021 mstruct.last() += nr_minus_one;
1022 mstruct *= x_var;
1023 mstruct.last() ^= nr_two;
1024 mstruct *= mthis;
1025 mstruct.last() ^= Number(-2, 1);
1026 mstruct *= Number(1, 8);
1027 return true;
1028 } else if(mfac.isPower() && mfac[0] == x_var && mfac[1].isMinusOne() && mpow.isOne() && mstruct[0] == x_var) {
1029 MathStructure mthis(mstruct);
1030 mstruct += nr_two;
1031 mstruct *= mthis;
1032 mstruct *= nr_half;
1033 return true;
1034 } else if((mpow.isOne() || (mpow.isNumber() && mpow.number().isTwo())) && mfac.isOne()) {
1035 MathStructure mexp, mmul, madd;
1036 if(integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1037 if(mpow.isOne()) {
1038 MathStructure mthis(mstruct);
1039 mstruct ^= nr_two;
1040 mstruct -= mthis;
1041 mstruct += m_one;
1042 mstruct *= mthis[0];
1043 mstruct /= mthis;
1044 if(!mmul.isOne()) mstruct /= mmul;
1045 return true;
1046 } else {
1047 MathStructure mthis(mstruct);
1048 mstruct ^= nr_three;
1049 mstruct += mthis;
1050 mstruct.last() ^= nr_two;
1051 mstruct.last() *= Number(-2, 1);
1052 mstruct += mthis;
1053 mstruct.last() *= Number(4, 1);
1054 mstruct += Number(-4, 1);
1055 mstruct *= mthis[0];
1056 mstruct /= mthis;
1057 if(!mmul.isOne()) mstruct /= mmul;
1058 return true;
1059 }
1060 }
1061 }
1062 return false;
1063 } else if(mstruct.function()->id() == FUNCTION_ID_SIGNUM && mstruct.size() == 2) {
1064 if(mstruct[0].representsNonComplex(true) && mpow.isNumber() && mpow.number().isRational() && mpow.number().isPositive()) {
1065 MathStructure minteg(x_var);
1066 if(!mfac.isOne()) {
1067 minteg = mfac;
1068 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1069 }
1070 if(!mpow.number().isInteger()) {
1071 MathStructure mmul(-1, 1, 0);
1072 Number nr_frac(mpow.number());
1073 Number nr_int(mpow.number());
1074 nr_frac.frac();
1075 nr_int.trunc();
1076 mmul ^= nr_frac;
1077 if(nr_int.isEven()) mmul += nr_minus_one;
1078 else mmul += m_one;
1079 mstruct *= mmul;
1080 mstruct -= mmul[0];
1081 if(nr_int.isEven()) mstruct += nr_minus_one;
1082 else mstruct += m_one;
1083 if(nr_int.isEven()) mstruct.negate();
1084 mstruct /= nr_two;
1085 } else if(mpow.number().isEven()) {
1086 mstruct ^= nr_two;
1087 mstruct += nr_three;
1088 mstruct *= Number(1, 4);
1089 }
1090 mstruct *= minteg;
1091 return true;
1092 }
1093 } else if(mstruct.function()->id() == FUNCTION_ID_DIRAC && mstruct.size() == 1 && mstruct[0].representsNonComplex(true)) {
1094 MathStructure mexp, mmul, madd;
1095 if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1096 if(mfac == x_var && madd.representsNonZero()) {
1097 mstruct.setFunctionId(FUNCTION_ID_HEAVISIDE);
1098 if(!mmul.isOne()) {
1099 mmul ^= nr_two;
1100 mstruct /= mmul;
1101 }
1102 mstruct *= madd;
1103 mstruct.negate();
1104 return true;
1105 } else if(mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0 && madd.representsNonZero()) {
1106 mstruct.setFunctionId(FUNCTION_ID_HEAVISIDE);
1107 madd.negate();
1108 madd ^= mfac[1];
1109 mstruct *= madd;
1110 if(mmul.isOne()) {
1111 mexp = mfac[1];
1112 mexp += m_one;
1113 mexp.negate();
1114 mmul ^= mexp;
1115 mstruct *= mmul;
1116 }
1117 return true;
1118 } else if(mfac.isOne()) {
1119 mstruct.setFunctionId(FUNCTION_ID_HEAVISIDE);
1120 if(!mmul.isOne()) mstruct /= mmul;
1121 return true;
1122 }
1123 }
1124 return false;
1125 } else if(mstruct.function()->id() == FUNCTION_ID_ARG && mstruct.size() == 1 && mstruct[0].representsNonComplex(true)) {
1126 MathStructure mexp, mmul, madd;
1127 if(mpow.representsPositive() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
1128 MathStructure minteg(x_var);
1129 if(!mfac.isOne()) {
1130 minteg = mfac;
1131 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1132 }
1133 mstruct.setFunctionId(FUNCTION_ID_SIGNUM);
1134 mstruct += nr_minus_one;
1135 mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1136 if(!mpow.isOne()) {
1137 mstruct.last() ^= mpow;
1138 mstruct.childUpdated(mstruct.size());
1139 }
1140 mstruct *= Number(-1, 2);
1141 mstruct *= minteg;
1142 return true;
1143 }
1144 return false;
1145 } else if(mstruct.function()->id() == FUNCTION_ID_HEAVISIDE && mstruct.size() == 1) {
1146 MathStructure mexp, mmul, madd;
1147 if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1148 if(mfac.isOne()) {
1149 if(mmul.representsNonNegative()) {
1150 MathStructure mfacn(x_var);
1151 if(!madd.isZero()) {
1152 if(!mmul.isOne()) madd /= mmul;
1153 mfacn += madd;
1154 }
1155 mstruct *= mfacn;
1156 return true;
1157 } else if(mmul.representsNegative()) {
1158 if(madd.isZero()) {
1159 mstruct[0] = x_var;
1160 mstruct *= x_var;
1161 mstruct.negate();
1162 mstruct += x_var;
1163 return true;
1164 }
1165 mstruct.setToChild(1);
1166 mmul.negate();
1167 madd.negate();
1168 mstruct /= mmul;
1169 MathStructure mfacn(x_var);
1170 mfacn *= mmul;
1171 mfacn += madd;
1172 mfacn.transformById(FUNCTION_ID_HEAVISIDE);
1173 mstruct *= mfacn;
1174 mstruct += x_var;
1175 return true;
1176 }
1177 }
1178 }
1179 return false;
1180 } else if(mstruct.function()->id() == FUNCTION_ID_SINC && mstruct.size() == 1) {
1181 MathStructure mexp, mmul, madd;
1182 if(mfac.isOne() && mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-2) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
1183 if(mpow.isOne()) {
1184 mstruct.setFunctionId(FUNCTION_ID_SININT);
1185 if(!mmul.isOne()) mstruct.divide(mmul);
1186 return true;
1187 }
1188 }
1189 } else if(mstruct.function()->id() == FUNCTION_ID_SIN && mstruct.size() == 1) {
1190 MathStructure mexp, mmul, madd;
1191 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp, true)) {
1192 if(mfac.isOne()) {
1193 if(mexp.isOne()) {
1194 if(mpow.isOne()) {
1195 mstruct.setFunctionId(FUNCTION_ID_COS);
1196 mstruct.multiply(m_minus_one);
1197 if(!mmul.isOne()) mstruct.divide(mmul);
1198 } else if(mpow.number().isTwo()) {
1199 if(!madd.isZero()) {
1200 mstruct[0] = x_var;
1201 mstruct[0] *= CALCULATOR->getRadUnit();
1202 }
1203 mstruct[0] *= nr_two;
1204 mstruct /= 4;
1205 if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
1206 mstruct.negate();
1207 MathStructure xhalf(x_var);
1208 xhalf *= nr_half;
1209 mstruct += xhalf;
1210 if(!madd.isZero()) {
1211 MathStructure marg(x_var);
1212 if(!mmul.isOne()) marg *= mmul;
1213 marg += madd;
1214 mstruct.replace(x_var, marg);
1215 if(!mmul.isOne()) mstruct.divide(mmul);
1216 }
1217 } else if(mpow.number().isMinusOne()) {
1218 MathStructure mcot(mstruct);
1219 mcot.setFunctionId(FUNCTION_ID_TAN);
1220 mcot.inverse();
1221 mstruct.inverse();
1222 mstruct += mcot;
1223 if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1224 if(!mmul.isOne()) mstruct.divide(mmul);
1225 mstruct.negate();
1226 } else if(mpow.number() == -2) {
1227 mstruct.setFunctionId(FUNCTION_ID_TAN);
1228 mstruct.inverse();
1229 mstruct.negate();
1230 if(!mmul.isOne()) mstruct.divide(mmul);
1231 } else if(mpow.number().isPositive()) {
1232 MathStructure mbak(mstruct);
1233 MathStructure nm1(mpow);
1234 nm1 += nr_minus_one;
1235 mstruct ^= nm1;
1236 MathStructure mcos(mbak);
1237 mcos.setFunctionId(FUNCTION_ID_COS);
1238 mstruct *= mcos;
1239 mstruct.negate();
1240 mmul *= mpow;
1241 mstruct /= mmul;
1242 MathStructure minteg(mbak);
1243 MathStructure nm2(mpow);
1244 nm2 += Number(-2, 1);
1245 minteg ^= nm2;
1246 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1247 minteg *= nm1;
1248 minteg /= mpow;
1249 mstruct += minteg;
1250 } else {
1251 MathStructure mbak(mstruct);
1252 MathStructure np1(mpow);
1253 np1 += m_one;
1254 mstruct ^= np1;
1255 MathStructure mcos(mbak);
1256 mcos.setFunctionId(FUNCTION_ID_COS);
1257 mstruct *= mcos;
1258 mstruct /= np1;
1259 mstruct /= mmul;
1260 MathStructure minteg(mbak);
1261 MathStructure np2(mpow);
1262 np2 += nr_two;
1263 minteg ^= np2;
1264 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1265 minteg *= np2;
1266 minteg /= np1;
1267 mstruct += minteg;
1268 }
1269 return true;
1270 } else if(mexp.isNumber() && mexp.number().isTwo() && madd.isZero() && mpow.isOne()) {
1271 mstruct = nr_two;
1272 mstruct /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1273 mstruct ^= nr_half;
1274 mstruct *= x_var;
1275 mstruct *= mmul;
1276 mstruct.last() ^= nr_half;
1277 mstruct.transformById(FUNCTION_ID_FRESNEL_S);
1278 mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1279 mstruct.last() *= nr_half;
1280 mstruct.last() ^= nr_half;
1281 mstruct *= mmul;
1282 mstruct.last() ^= Number(-1, 2);
1283 return true;
1284 }
1285 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
1286 MathStructure mfacexp(1, 1, 0);
1287 if(mfac != x_var) mfacexp = mfac[1];
1288 if(mfacexp.isMinusOne() && !mexp.isZero()) {
1289 if(madd.isZero()) {
1290 if(mpow.isOne()) {
1291 mstruct[0] /= CALCULATOR->getRadUnit();
1292 mstruct.setFunctionId(FUNCTION_ID_SININT);
1293 if(!mexp.isOne()) mstruct /= mexp;
1294 return true;
1295 } else if(mpow.number().isTwo()) {
1296 mstruct[0] *= nr_two;
1297 mstruct[0] /= CALCULATOR->getRadUnit();
1298 mstruct.setFunctionId(FUNCTION_ID_COSINT);
1299 if(!mexp.isOne()) mstruct /= mexp;
1300 mstruct.negate();
1301 mstruct += x_var;
1302 if(!transform_absln(mstruct.last(), use_abs, definite_integral, x_var, eo)) return -1;
1303 mstruct *= nr_half;
1304 return true;
1305 } else if(mpow.number() == 3) {
1306 mstruct[0] /= CALCULATOR->getRadUnit();
1307 mstruct.setFunctionId(FUNCTION_ID_SININT);
1308 MathStructure mterm2(mstruct);
1309 mstruct[0] *= nr_three;
1310 mterm2 *= Number(-3, 1);
1311 mstruct += mterm2;
1312 if(!mexp.isOne()) mstruct /= mexp;
1313 mstruct *= Number(-1, 4);
1314 return true;
1315 }
1316 } else if(mpow.isOne()) {
1317 MathStructure mterm2;
1318 mstruct = x_var;
1319 if(!mexp.isOne()) mstruct ^= mexp;
1320 if(!mmul.isOne()) mstruct *= mmul;
1321 mstruct.transformById(FUNCTION_ID_SININT);
1322 if(CALCULATOR->getRadUnit()) madd *= CALCULATOR->getRadUnit();
1323 mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COS), &madd, NULL);
1324 mterm2 = x_var;
1325 if(!mexp.isOne()) mterm2 ^= mexp;
1326 if(!mmul.isOne()) mterm2 *= mmul;
1327 mterm2.transformById(FUNCTION_ID_COSINT);
1328 mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIN), &madd, NULL);
1329 mstruct += mterm2;
1330 if(!mexp.isOne()) mstruct /= mexp;
1331 return true;
1332 }
1333 } else if(mexp.isOne() && mpow.isOne()) {
1334 if(mfacexp.isOne()) {
1335 MathStructure mterm2(mstruct);
1336 mterm2.setFunctionId(FUNCTION_ID_COS);
1337 mterm2 *= x_var;
1338 if(!mmul.isOne()) {
1339 mterm2 /= mmul;
1340 mmul ^= nr_two;
1341 mstruct /= mmul;
1342 }
1343 mstruct -= mterm2;
1344 return true;
1345 } else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
1346 mstruct.setFunctionId(FUNCTION_ID_COS);
1347 MathStructure mterm2(mstruct);
1348 mterm2 *= x_var;
1349 mterm2.last() ^= mfacexp;
1350 mterm2.childUpdated(mterm2.size());
1351 if(!mmul.isOne()) mterm2 /= mmul;
1352 mstruct *= x_var;
1353 mstruct.last() ^= mfacexp;
1354 mstruct.childUpdated(mstruct.size());
1355 mstruct.last().last() += nr_minus_one;
1356 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1357 mstruct *= mfacexp;
1358 if(!mmul.isOne()) mstruct /= mmul;
1359 mstruct -= mterm2;
1360 return true;
1361 } else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
1362 mfacexp += m_one;
1363 MathStructure mterm2(mstruct);
1364 mterm2 *= x_var;
1365 mterm2.last() ^= mfacexp;
1366 mterm2.childUpdated(mterm2.size());
1367 mterm2 /= mfacexp;
1368 mstruct.setFunctionId(FUNCTION_ID_COS);
1369 mstruct *= x_var;
1370 mstruct.last() ^= mfacexp;
1371 mstruct.childUpdated(mstruct.size());
1372 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1373 mstruct /= mfacexp;
1374 mstruct.negate();
1375 if(!mmul.isOne()) mstruct *= mmul;
1376 mstruct += mterm2;
1377 return true;
1378 }
1379 } else if(mexp.isOne() && mpow.number().isTwo()) {
1380 if(mfacexp.isOne()) {
1381 MathStructure mterm2(mstruct);
1382 MathStructure mterm3(x_var);
1383 mterm3 ^= nr_two;
1384 mterm3 *= Number(1, 4);
1385 mterm2[0] *= nr_two;
1386 mterm2 *= x_var;
1387 if(!mmul.isOne()) mterm2 /= mmul;
1388 mterm2 *= Number(-1, 4);
1389 mstruct.setFunctionId(FUNCTION_ID_COS);
1390 mstruct[0] *= nr_two;
1391 if(!mmul.isOne()) {
1392 mmul ^= nr_two;
1393 mstruct /= mmul;
1394 }
1395 mstruct *= Number(-1, 8);
1396 mstruct += mterm2;
1397 mstruct += mterm3;
1398 mstruct.childrenUpdated(true);
1399 return true;
1400 } else if(mfacexp.number().isTwo()) {
1401 MathStructure mterm2(mstruct);
1402 MathStructure mterm3(x_var);
1403 mterm3 ^= nr_three;
1404 mterm3 *= Number(1, 6);
1405 mterm2[0] *= nr_two;
1406 MathStructure mterm21(1, 8, 0);
1407 if(!mmul.isOne()) {
1408 mterm21 *= mmul;
1409 mterm21.last() ^= Number(-3, 1);
1410 }
1411 MathStructure mterm22(x_var);
1412 mterm22 ^= 2;
1413 if(!mmul.isOne()) mterm22 /= mmul;
1414 mterm22 *= Number(-1, 4);
1415 mterm21 += mterm22;
1416 mterm2 *= mterm21;
1417 mstruct.setFunctionId(FUNCTION_ID_COS);
1418 mstruct[0] *= nr_two;
1419 mstruct *= x_var;
1420 if(!mmul.isOne()) {
1421 mmul ^= nr_two;
1422 mstruct /= mmul;
1423 }
1424 mstruct *= Number(-1, 4);
1425 mstruct += mterm2;
1426 mstruct += mterm3;
1427 mstruct.childrenUpdated(true);
1428 return true;
1429 }
1430 }
1431 } else if(mexp.isOne() && mfac.isFunction()) {
1432 if(mfac.function()->id() == FUNCTION_ID_SIN && mfac.size() == 1 && mpow.isOne()) {
1433 MathStructure mexpf, mmulf, maddf;
1434 if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf, true) && mexpf.isOne() && mmul != mmulf) {
1435 MathStructure mterm2(mstruct);
1436 mterm2[0] += mfac[0];
1437 mstruct[0] -= mfac[0];
1438 MathStructure mden1(mmul);
1439 mden1 -= mmulf;
1440 mden1 *= nr_two;
1441 MathStructure mden2(mmul);
1442 mden2 += mmulf;
1443 mden2 *= nr_two;
1444 mterm2 /= mden2;
1445 mstruct /= mden1;
1446 mstruct -= mterm2;
1447 return true;
1448 }
1449 } else if(mfac.function()->id() == FUNCTION_ID_COS && mfac.size() == 1) {
1450 if(mstruct[0] == mfac[0]) {
1451 UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
1452 MathStructure mtest(var);
1453 if(!mpow.isOne()) mtest ^= mpow;
1454 CALCULATOR->beginTemporaryStopMessages();
1455 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
1456 MathStructure m_interval(mstruct);
1457 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
1458 var->setInterval(m_interval);
1459 } else {
1460 var->setInterval(mstruct);
1461 }
1462 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
1463 CALCULATOR->endTemporaryStopMessages(true);
1464 mtest.replace(var, mstruct);
1465 var->destroy();
1466 mstruct = mtest;
1467 if(!mmul.isOne()) mstruct /= mmul;
1468 return true;
1469 }
1470 CALCULATOR->endTemporaryStopMessages();
1471 var->destroy();
1472 } else if(mpow.isOne()) {
1473 MathStructure mexpf, mmulf, maddf;
1474 if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf, true) && mexpf.isOne()) {
1475 if(mmul != mmulf) {
1476 mstruct.setFunctionId(FUNCTION_ID_COS);
1477 MathStructure mterm2(mstruct);
1478 mterm2[0] += mfac[0];
1479 mstruct[0] -= mfac[0];
1480 MathStructure mden1(mmul);
1481 mden1 -= mmulf;
1482 mden1 *= nr_two;
1483 MathStructure mden2(mmul);
1484 mden2 += mmulf;
1485 mden2 *= nr_two;
1486 mterm2 /= mden2;
1487 mstruct /= mden1;
1488 mstruct.negate();
1489 mstruct -= mterm2;
1490 return true;
1491 } else if(madd == maddf) {
1492 mstruct ^= nr_two;
1493 if(!mmul.isOne()) mstruct /= mmul;
1494 mstruct *= nr_half;
1495 return true;
1496 } else {
1497 MathStructure mterm2(mfac);
1498 mterm2[0].add(mstruct[0]);
1499 mterm2.childUpdated(1);
1500 if(!mmul.isOne()) mterm2 /= mmul;
1501 mterm2 *= Number(-1, 4);
1502 mstruct[0] = maddf;
1503 mstruct[0] -= madd;
1504 mstruct[0] *= CALCULATOR->getRadUnit();
1505 mstruct.childUpdated(1);
1506 mstruct *= x_var;
1507 mstruct *= Number(-1, 2);
1508 mstruct += mterm2;
1509 return true;
1510 }
1511 }
1512 }
1513 }
1514 }
1515 }
1516 } else if(mstruct.function()->id() == FUNCTION_ID_COS && mstruct.size() == 1) {
1517 MathStructure mexp, mmul, madd;
1518 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp, true)) {
1519 if(mfac.isOne()) {
1520 if(mexp.isOne()) {
1521 if(mpow.isOne()) {
1522 mstruct.setFunctionId(FUNCTION_ID_SIN);
1523 if(!mmul.isOne()) mstruct.divide(mmul);
1524 } else if(mpow.number().isTwo()) {
1525 mstruct.setFunctionId(FUNCTION_ID_SIN);
1526 if(!madd.isZero()) {
1527 mstruct[0] = x_var;
1528 mstruct[0] *= CALCULATOR->getRadUnit();
1529 }
1530 mstruct[0] *= nr_two;
1531 mstruct /= 4;
1532 if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
1533 MathStructure xhalf(x_var);
1534 xhalf *= nr_half;
1535 mstruct += xhalf;
1536 if(!madd.isZero()) {
1537 MathStructure marg(x_var);
1538 if(!mmul.isOne()) marg *= mmul;
1539 marg += madd;
1540 mstruct.replace(x_var, marg);
1541 if(!mmul.isOne()) mstruct.divide(mmul);
1542 }
1543 } else if(mpow.number().isMinusOne()) {
1544 MathStructure mtan(mstruct);
1545 mtan.setFunctionId(FUNCTION_ID_TAN);
1546 mstruct.inverse();
1547 mstruct += mtan;
1548 if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1549 if(!mmul.isOne()) mstruct.divide(mmul);
1550 } else if(mpow.number() == -2) {
1551 mstruct.setFunctionId(FUNCTION_ID_TAN);
1552 if(!mmul.isOne()) mstruct.divide(mmul);
1553 } else if(mpow.number().isPositive()) {
1554 MathStructure mbak(mstruct);
1555 MathStructure nm1(mpow);
1556 nm1 += nr_minus_one;
1557 mstruct ^= nm1;
1558 MathStructure msin(mbak);
1559 msin.setFunctionId(FUNCTION_ID_SIN);
1560 mstruct *= msin;
1561 mmul *= mpow;
1562 mstruct /= mmul;
1563 MathStructure minteg(mbak);
1564 MathStructure nm2(mpow);
1565 nm2 += Number(-2, 1);
1566 minteg ^= nm2;
1567 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1568 minteg *= nm1;
1569 minteg /= mpow;
1570 mstruct += minteg;
1571 } else {
1572 MathStructure mbak(mstruct);
1573 MathStructure np1(mpow);
1574 np1 += m_one;
1575 mstruct ^= np1;
1576 MathStructure mcos(mbak);
1577 mcos.setFunctionId(FUNCTION_ID_SIN);
1578 mstruct *= mcos;
1579 mstruct /= np1;
1580 mstruct /= mmul;
1581 mstruct.negate();
1582 MathStructure minteg(mbak);
1583 MathStructure np2(mpow);
1584 np2 += nr_two;
1585 minteg ^= np2;
1586 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1587 minteg *= np2;
1588 minteg /= np1;
1589 mstruct += minteg;
1590 }
1591 return true;
1592 } else if(mexp.isNumber() && mexp.number().isTwo() && madd.isZero() && mpow.isOne()) {
1593 mstruct = nr_two;
1594 mstruct /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1595 mstruct ^= nr_half;
1596 mstruct *= x_var;
1597 mstruct *= mmul;
1598 mstruct.last() ^= nr_half;
1599 mstruct.transformById(FUNCTION_ID_FRESNEL_C);
1600 mstruct *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
1601 mstruct.last() *= nr_half;
1602 mstruct.last() ^= nr_half;
1603 mstruct *= mmul;
1604 mstruct.last() ^= Number(-1, 2);
1605 return true;
1606 }
1607 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
1608 MathStructure mfacexp(1, 1, 0);
1609 if(mfac != x_var) mfacexp = mfac[1];
1610 if(mfacexp.isMinusOne() && !mexp.isZero()) {
1611 if(madd.isZero()) {
1612 if(mpow.isOne()) {
1613 mstruct[0] /= CALCULATOR->getRadUnit();
1614 mstruct.setFunctionId(FUNCTION_ID_COSINT);
1615 if(!mexp.isOne()) mstruct /= mexp;
1616 return true;
1617 } else if(mpow.number().isTwo()) {
1618 mstruct[0] *= nr_two;
1619 mstruct[0] /= CALCULATOR->getRadUnit();
1620 mstruct.setFunctionId(FUNCTION_ID_COSINT);
1621 if(!mexp.isOne()) mstruct /= mexp;
1622 mstruct += x_var;
1623 mstruct.last().transformById(FUNCTION_ID_LOG);
1624 mstruct *= nr_half;
1625 return true;
1626 } else if(mpow.number() == 3) {
1627 mstruct[0] /= CALCULATOR->getRadUnit();
1628 mstruct.setFunctionId(FUNCTION_ID_COSINT);
1629 MathStructure mterm2(mstruct);
1630 mstruct[0] *= nr_three;
1631 mterm2 *= Number(3, 1);
1632 mstruct += mterm2;
1633 if(!mexp.isOne()) mstruct /= mexp;
1634 mstruct *= Number(1, 4);
1635 return true;
1636 }
1637 } else if(mpow.isOne()) {
1638 MathStructure mterm2;
1639 mstruct = x_var;
1640 if(!mexp.isOne()) mstruct ^= mexp;
1641 if(!mmul.isOne()) mstruct *= mmul;
1642 mstruct.transformById(FUNCTION_ID_COSINT);
1643 if(CALCULATOR->getRadUnit()) madd *= CALCULATOR->getRadUnit();
1644 mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COS), &madd, NULL);
1645 mterm2 = x_var;
1646 if(!mexp.isOne()) mterm2 ^= mexp;
1647 if(!mmul.isOne()) mterm2 *= mmul;
1648 mterm2.transformById(FUNCTION_ID_SININT);
1649 mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIN), &madd, NULL);
1650 mstruct -= mterm2;
1651 if(!mexp.isOne()) mstruct /= mexp;
1652 return true;
1653 }
1654 } else if(mexp.isOne() && mpow.isOne()) {
1655 if(mfacexp.isOne()) {
1656 MathStructure mterm2(mstruct);
1657 mterm2.setFunctionId(FUNCTION_ID_SIN);
1658 mterm2 *= x_var;
1659 if(!mmul.isOne()) {
1660 mterm2 /= mmul;
1661 mmul ^= nr_two;
1662 mstruct /= mmul;
1663 }
1664 mstruct += mterm2;
1665 return true;
1666 } else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
1667 mstruct.setFunctionId(FUNCTION_ID_SIN);
1668 MathStructure mterm2(mstruct);
1669 mterm2 *= x_var;
1670 mterm2.last() ^= mfacexp;
1671 if(!mmul.isOne()) mterm2 /= mmul;
1672 mstruct *= x_var;
1673 mstruct.last() ^= mfacexp;
1674 mstruct.last().last() += nr_minus_one;
1675 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1676 mstruct *= mfacexp;
1677 if(!mmul.isOne()) mstruct /= mmul;
1678 mstruct.negate();
1679 mstruct += mterm2;
1680 mstruct.childrenUpdated(true);
1681 return true;
1682 } else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
1683 mfacexp += m_one;
1684 MathStructure mterm2(mstruct);
1685 mterm2 *= x_var;
1686 mterm2.last() ^= mfacexp;
1687 mterm2.childUpdated(mterm2.size());
1688 mterm2 /= mfacexp;
1689 mstruct.setFunctionId(FUNCTION_ID_SIN);
1690 mstruct *= x_var;
1691 mstruct.last() ^= mfacexp;
1692 mstruct.childUpdated(mstruct.size());
1693 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1694 mstruct /= mfacexp;
1695 if(!mmul.isOne()) mstruct *= mmul;
1696 mstruct += mterm2;
1697 return true;
1698 }
1699 } else if(mexp.isOne() && mpow.number().isTwo()) {
1700 if(mfacexp.isOne()) {
1701 MathStructure mterm2(mstruct);
1702 mterm2.setFunctionId(FUNCTION_ID_SIN);
1703 MathStructure mterm3(x_var);
1704 mterm3 ^= nr_two;
1705 mterm3 *= Number(1, 4);
1706 mterm2[0] *= nr_two;
1707 mterm2 *= x_var;
1708 if(!mmul.isOne()) mterm2 /= mmul;
1709 mterm2 *= Number(1, 4);
1710 mstruct[0] *= nr_two;
1711 if(!mmul.isOne()) {
1712 mmul ^= nr_two;
1713 mstruct /= mmul;
1714 }
1715 mstruct *= Number(1, 8);
1716 mstruct += mterm2;
1717 mstruct += mterm3;
1718 return true;
1719 } else if(mfacexp.number().isTwo()) {
1720 MathStructure mterm2(mstruct);
1721 mterm2.setFunctionId(FUNCTION_ID_SIN);
1722 MathStructure mterm3(x_var);
1723 mterm3 ^= nr_three;
1724 mterm3 *= Number(1, 6);
1725 mterm2[0] *= nr_two;
1726 MathStructure mterm21(-1, 8, 0);
1727 if(!mmul.isOne()) {
1728 mterm21 *= mmul;
1729 mterm21.last() ^= Number(-3, 1);
1730 }
1731 MathStructure mterm22(x_var);
1732 mterm22 ^= 2;
1733 if(!mmul.isOne()) mterm22 /= mmul;
1734 mterm22 *= Number(1, 4);
1735 mterm21 += mterm22;
1736 mterm2 *= mterm21;
1737 mstruct[0] *= nr_two;
1738 mstruct *= x_var;
1739 if(!mmul.isOne()) {
1740 mmul ^= nr_two;
1741 mstruct /= mmul;
1742 }
1743 mstruct *= Number(1, 4);
1744 mstruct += mterm2;
1745 mstruct += mterm3;
1746 mstruct.childrenUpdated(true);
1747 return true;
1748 }
1749 }
1750 } else if(mexp.isOne() && mfac.isFunction()) {
1751 if(mfac.function()->id() == FUNCTION_ID_COS && mfac.size() == 1 && mpow.isOne()) {
1752 MathStructure mexpf, mmulf, maddf;
1753 if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf, true) && mexpf.isOne() && mmulf != mmul) {
1754 mstruct.setFunctionId(FUNCTION_ID_SIN);
1755 MathStructure mterm2(mstruct);
1756 mterm2[0] += mfac[0];
1757 mstruct[0] -= mfac[0];
1758 MathStructure mden1(mmul);
1759 mden1 -= mmulf;
1760 mden1 *= nr_two;
1761 MathStructure mden2(mmul);
1762 mden2 += mmulf;
1763 mden2 *= nr_two;
1764 mterm2 /= mden2;
1765 mstruct /= mden1;
1766 mstruct += mterm2;
1767 mstruct.childrenUpdated(true);
1768 return true;
1769 }
1770 } else if(mfac.function()->id() == FUNCTION_ID_SIN && mfac.size() == 1) {
1771 if(mstruct[0] == mfac[0]) {
1772 UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
1773 MathStructure mtest(var);
1774 if(!mpow.isOne()) mtest ^= mpow;
1775 mtest.negate();
1776 CALCULATOR->beginTemporaryStopMessages();
1777 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
1778 MathStructure m_interval(mstruct);
1779 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
1780 var->setInterval(m_interval);
1781 } else {
1782 var->setInterval(mstruct);
1783 }
1784 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
1785 CALCULATOR->endTemporaryStopMessages(true);
1786 mtest.replace(var, mstruct);
1787 var->destroy();
1788 mstruct = mtest;
1789 if(!mmul.isOne()) mstruct /= mmul;
1790 return true;
1791 }
1792 CALCULATOR->endTemporaryStopMessages();
1793 var->destroy();
1794 }
1795 }
1796 }
1797 }
1798 } else if(mstruct.function()->id() == FUNCTION_ID_TAN && mstruct.size() == 1) {
1799 MathStructure mexp, mmul, madd;
1800 if(mfac.isOne() && mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-1) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp, true) && mexp.isOne() && (!definite_integral || mstruct[0].representsNonComplex(true))) {
1801 if(mpow.isOne()) {
1802 mstruct.setFunctionId(FUNCTION_ID_COS);
1803 if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1804 mstruct.negate();
1805 if(!mmul.isOne()) mstruct.divide(mmul);
1806 } else if(mpow.number().isMinusOne()) {
1807 mstruct.setFunctionId(FUNCTION_ID_SIN);
1808 if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
1809 if(!mmul.isOne()) mstruct.divide(mmul);
1810 } else if(mpow.number().isTwo()) {
1811 MathStructure marg(x_var);
1812 if(!mmul.isOne()) marg *= mmul;
1813 marg += madd;
1814 mstruct -= marg;
1815 if(!mmul.isOne()) mstruct.divide(mmul);
1816 } else {
1817 MathStructure minteg(mstruct);
1818 MathStructure nm1(mpow);
1819 nm1 += nr_minus_one;
1820 mstruct ^= nm1;
1821 mmul *= nm1;
1822 mstruct /= mmul;
1823 MathStructure nm2(mpow);
1824 nm2 += Number(-2, 1);
1825 minteg ^= nm2;
1826 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1827 mstruct -= minteg;
1828 }
1829 return true;
1830 }
1831 } else if(mstruct.function()->id() == FUNCTION_ID_ASIN && mstruct.size() == 1) {
1832 MathStructure mexp, mmul, madd;
1833 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
1834 if(definite_integral && !madd.isZero() && (!mmul.representsNonComplex(true) || !mexp.representsInteger()) && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero))) return false;
1835 if(mexp.isOne() && mfac.isOne()) {
1836 if(mpow.isOne()) {
1837 MathStructure marg(mstruct[0]);
1838 if(!madd.isZero()) mstruct[0] = x_var;
1839 mstruct.multiply(x_var);
1840 MathStructure mterm(x_var);
1841 mterm ^= nr_two;
1842 if(madd.isZero() && !mmul.isOne()) {
1843 MathStructure mmul2(mmul);
1844 mmul2 ^= nr_two;
1845 mterm *= mmul2;
1846 }
1847 mterm.negate();
1848 mterm += m_one;
1849 mterm ^= nr_half;
1850 if(madd.isZero() && !mmul.isOne()) mterm /= mmul;
1851 mstruct.add(mterm);
1852 if(!madd.isZero()) {
1853 mstruct.replace(x_var, marg);
1854 if(!mmul.isOne()) mstruct.divide(mmul);
1855 }
1856 return true;
1857 } else if(mpow.isMinusOne()) {
1858 mstruct.transformById(FUNCTION_ID_COSINT);
1859 if(!mmul.isOne()) mstruct /= mmul;
1860 return true;
1861 } else if(mpow.number() == -2) {
1862 MathStructure mterm(mstruct[0]);
1863 mterm ^= nr_two;
1864 mterm.negate();
1865 mterm += m_one;
1866 mterm ^= nr_half;
1867 mterm /= mstruct;
1868 mstruct.transformById(FUNCTION_ID_SININT);
1869 mstruct += mterm;
1870 if(!mmul.isOne()) mstruct /= mmul;
1871 mstruct.negate();
1872 return true;
1873 } else if(mpow.number().isPositive() && madd.isZero()) {
1874 MathStructure mpowm1(mpow);
1875 if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
1876 else mpowm1 += nr_minus_one;
1877 MathStructure mterm(x_var);
1878 mterm ^= nr_two;
1879 if(!mmul.isOne()) {
1880 mterm *= mmul;
1881 mterm.last() ^= nr_two;
1882 }
1883 mterm.negate();
1884 mterm += m_one;
1885 mterm ^= nr_half;
1886 mterm *= mstruct;
1887 if(!mpowm1.isOne()) mterm.last() ^= mpowm1;
1888 mterm *= mpow;
1889 if(!mmul.isOne()) mterm /= mmul;
1890 MathStructure minteg;
1891 if(mpowm1.isOne()) {
1892 minteg = x_var;
1893 } else {
1894 minteg = mstruct;
1895 minteg ^= mpow;
1896 minteg.last() += Number(-2, 1);
1897 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1898 }
1899 minteg *= mpow;
1900 if(!mpowm1.isOne()) minteg *= mpowm1;
1901 mstruct ^= mpow;
1902 mstruct *= x_var;
1903 mstruct += mterm;
1904 mstruct -= minteg;
1905 return true;
1906 } else if(madd.isZero()) {
1907 MathStructure mpowp1(mpow);
1908 mpowp1 += m_one;
1909 MathStructure mpowp2(mpow);
1910 mpowp2 += nr_two;
1911 MathStructure mterm(x_var);
1912 mterm ^= nr_two;
1913 if(!mmul.isOne()) {
1914 mterm *= mmul;
1915 mterm.last() ^= nr_two;
1916 }
1917 mterm.negate();
1918 mterm += m_one;
1919 mterm ^= nr_half;
1920 mterm *= mstruct;
1921 mterm.last() ^= mpowp1;
1922 mterm /= mpowp1;
1923 if(!mmul.isOne()) mterm /= mmul;
1924 MathStructure minteg(mstruct);
1925 minteg ^= mpowp2;
1926 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
1927 minteg /= mpowp1;
1928 minteg /= mpowp2;
1929 mstruct ^= mpowp2;
1930 mstruct *= x_var;
1931 mstruct /= mpowp1;
1932 mstruct /= mpowp2;
1933 mstruct += mterm;
1934 mstruct -= minteg;
1935 return true;
1936 }
1937 } else if(mexp.isOne() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0))) {
1938 MathStructure mfacexp(1, 1, 0);
1939 if(mfac != x_var) mfacexp = mfac[1];
1940 if(mpow.isOne()) {
1941 if(mfacexp.isOne()) {
1942 MathStructure mterm2(mstruct[0]);
1943 mterm2 ^= nr_two;
1944 mterm2.negate();
1945 mterm2 += m_one;
1946 mterm2 ^= nr_half;
1947 MathStructure mfac2(x_var);
1948 if(!mmul.isOne()) mfac2 *= mmul;
1949 if(!madd.isZero()) {
1950 mfac2 += madd;
1951 mfac2.last() *= Number(-3, 1);
1952 }
1953 mterm2 *= mfac2;
1954 MathStructure mfac1(x_var);
1955 mfac1 ^= nr_two;
1956 if(!mmul.isOne()) {
1957 mfac1 *= mmul;
1958 mfac1.last() ^= nr_two;
1959 }
1960 mfac1 *= nr_two;
1961 if(!madd.isZero()) {
1962 mfac1 += madd;
1963 mfac1.last() ^= nr_two;
1964 mfac1.last() *= Number(-2, 1);
1965 }
1966 mfac1 += nr_minus_one;
1967 mstruct *= mfac1;
1968 mstruct += mterm2;
1969 if(!mmul.isOne()) {
1970 mstruct *= mmul;
1971 mstruct.last() ^= Number(-2, 1);
1972 }
1973 mstruct *= Number(1, 4);
1974 return true;
1975 } else if(mfacexp == nr_two && madd.isZero()) {
1976 mstruct *= x_var;
1977 mstruct.last() ^= nr_three;
1978 mstruct *= Number(1, 3);
1979 MathStructure mterm(x_var);
1980 mterm ^= nr_two;
1981 if(!mmul.isOne()) {
1982 mterm *= mmul;
1983 mterm.last() ^= nr_two;
1984 }
1985 MathStructure mfac1(mterm);
1986 mfac1 += nr_two;
1987 mterm.negate();
1988 mterm += m_one;
1989 mterm ^= nr_half;
1990 mterm *= mfac1;
1991 if(!mmul.isOne()) {
1992 mmul ^= Number(-3, 1);
1993 mterm *= mmul;
1994 }
1995 mterm *= Number(1, 9);
1996 mstruct += mterm;
1997 return true;
1998 } else if(!mfacexp.isMinusOne() && madd.isZero()) {
1999 mfacexp += m_one;
2000 MathStructure minteg(x_var);
2001 minteg ^= nr_two;
2002 if(!mmul.isOne()) {
2003 minteg *= mmul;
2004 minteg.last() ^= nr_two;
2005 }
2006 minteg.negate();
2007 minteg += m_one;
2008 minteg ^= Number(-1, 2);
2009 minteg *= x_var;
2010 minteg.last() ^= mfacexp;
2011 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2012 if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2013 if(!mmul.isOne()) minteg *= mmul;
2014 minteg /= mfacexp;
2015 mstruct *= x_var;
2016 mstruct.last() ^= mfacexp;
2017 mstruct /= mfacexp;
2018 mstruct -= minteg;
2019 return true;
2020 }
2021 }
2022 }
2023 }
2024 }
2025 } else if(mstruct.function()->id() == FUNCTION_ID_ACOS && mstruct.size() == 1) {
2026 MathStructure mexp, mmul, madd;
2027 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
2028 if(definite_integral && !madd.isZero() && (!mmul.representsNonComplex(true) || !mexp.representsInteger()) && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero))) return false;
2029 if(mexp.isOne() && mfac.isOne()) {
2030 if(mpow.isOne()) {
2031 MathStructure marg(mstruct[0]);
2032 if(!madd.isZero()) mstruct[0] = x_var;
2033 mstruct.multiply(x_var);
2034 MathStructure mterm(x_var);
2035 mterm ^= nr_two;
2036 if(madd.isZero() && !mmul.isOne()) {
2037 MathStructure mmul2(mmul);
2038 mmul2 ^= nr_two;
2039 mterm *= mmul2;
2040 }
2041 mterm.negate();
2042 mterm += m_one;
2043 mterm ^= nr_half;
2044 if(madd.isZero() && !mmul.isOne()) mterm /= mmul;
2045 mstruct.subtract(mterm);
2046 if(!madd.isZero()) {
2047 mstruct.replace(x_var, marg);
2048 if(!mmul.isOne()) mstruct.divide(mmul);
2049 }
2050 return true;
2051 } else if(mpow.isMinusOne()) {
2052 mstruct.transformById(FUNCTION_ID_SININT);
2053 mstruct.negate();
2054 if(!mmul.isOne()) mstruct /= mmul;
2055 return true;
2056 } else if(mpow.number() == -2) {
2057 MathStructure mterm(mstruct[0]);
2058 mterm ^= nr_two;
2059 mterm.negate();
2060 mterm += m_one;
2061 mterm ^= nr_half;
2062 mterm /= mstruct;
2063 mstruct.transformById(FUNCTION_ID_COSINT);
2064 mstruct.negate();
2065 mstruct += mterm;
2066 if(!mmul.isOne()) mstruct /= mmul;
2067 return true;
2068 } else if(mpow.number().isPositive() && madd.isZero()) {
2069 MathStructure mpowm1(mpow);
2070 if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
2071 else mpowm1 += nr_minus_one;
2072 MathStructure mterm(x_var);
2073 mterm ^= nr_two;
2074 if(!mmul.isOne()) {
2075 mterm *= mmul;
2076 mterm.last() ^= nr_two;
2077 }
2078 mterm.negate();
2079 mterm += m_one;
2080 mterm ^= nr_half;
2081 mterm *= mstruct;
2082 if(!mpowm1.isOne()) mterm.last() ^= mpowm1;
2083 mterm *= mpow;
2084 if(!mmul.isOne()) mterm /= mmul;
2085 MathStructure minteg;
2086 if(mpowm1.isOne()) {
2087 minteg = x_var;
2088 } else {
2089 minteg = mstruct;
2090 minteg ^= mpow;
2091 minteg.last() += Number(-2, 1);
2092 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2093 }
2094 minteg *= mpow;
2095 if(!mpowm1.isOne()) minteg *= mpowm1;
2096 mstruct ^= mpow;
2097 mstruct *= x_var;
2098 mstruct -= mterm;
2099 mstruct -= minteg;
2100 return true;
2101 } else if(madd.isZero()) {
2102 MathStructure mpowp1(mpow);
2103 mpowp1 += m_one;
2104 MathStructure mpowp2(mpow);
2105 mpowp2 += nr_two;
2106 MathStructure mterm(x_var);
2107 mterm ^= nr_two;
2108 if(!mmul.isOne()) {
2109 mterm *= mmul;
2110 mterm.last() ^= nr_two;
2111 }
2112 mterm.negate();
2113 mterm += m_one;
2114 mterm ^= nr_half;
2115 mterm *= mstruct;
2116 mterm.last() ^= mpowp1;
2117 mterm /= mpowp1;
2118 if(!mmul.isOne()) mterm /= mmul;
2119 MathStructure minteg(mstruct);
2120 minteg ^= mpowp2;
2121 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2122 minteg /= mpowp1;
2123 minteg /= mpowp2;
2124 mstruct ^= mpowp2;
2125 mstruct *= x_var;
2126 mstruct /= mpowp1;
2127 mstruct /= mpowp2;
2128 mstruct -= mterm;
2129 mstruct -= minteg;
2130 return true;
2131 }
2132 } else if(mexp.isOne() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0))) {
2133 MathStructure mfacexp(1, 1, 0);
2134 if(mfac != x_var) mfacexp = mfac[1];
2135 if(mpow.isOne()) {
2136 if(mfacexp.isOne()) {
2137 MathStructure mterm2(mstruct[0]);
2138 MathStructure mterm3(mstruct);
2139 mterm2 ^= nr_two;
2140 mterm2.negate();
2141 mterm2 += m_one;
2142 mterm2 ^= nr_half;
2143 MathStructure mfac2(x_var);
2144 if(!mmul.isOne()) {
2145 mfac2 *= mmul;
2146 }
2147 mfac2.negate();
2148 if(!madd.isZero()) {
2149 mfac2 += madd;
2150 mfac2.last() *= nr_three;
2151 }
2152 mterm2 *= mfac2;
2153 mterm3.setFunctionId(FUNCTION_ID_ASIN);
2154 MathStructure mfac3(1, 1, 0);
2155 if(!madd.isZero()) {
2156 mfac3 += madd;
2157 mfac3.last() ^= nr_two;
2158 mfac3.last() *= nr_two;
2159 }
2160 mterm3 *= mfac3;
2161 mstruct *= x_var;
2162 mstruct.last() ^= nr_two;
2163 if(!mmul.isOne()) {
2164 mstruct *= mmul;
2165 mstruct.last() ^= nr_two;
2166 }
2167 mstruct *= nr_two;
2168 mstruct += mterm2;
2169 mstruct += mterm3;
2170 if(!mmul.isOne()) {
2171 mstruct *= mmul;
2172 mstruct.last() ^= Number(-2, 1);
2173 }
2174 mstruct *= Number(1, 4);
2175 return true;
2176 } else if(mfacexp == nr_two && madd.isZero()) {
2177 mstruct *= x_var;
2178 mstruct.last() ^= nr_three;
2179 mstruct *= Number(1, 3);
2180 MathStructure mterm(x_var);
2181 mterm ^= nr_two;
2182 if(!mmul.isOne()) {
2183 mterm *= mmul;
2184 mterm.last() ^= nr_two;
2185 }
2186 MathStructure mfac1(mterm);
2187 mfac1 += nr_two;
2188 mterm.negate();
2189 mterm += m_one;
2190 mterm ^= nr_half;
2191 mterm *= mfac1;
2192 if(!mmul.isOne()) {
2193 mmul ^= Number(-3, 1);
2194 mterm *= mmul;
2195 }
2196 mterm *= Number(-1, 9);
2197 mstruct += mterm;
2198 return true;
2199 } else if(!mfacexp.isMinusOne() && madd.isZero()) {
2200 mfacexp += m_one;
2201 MathStructure minteg(x_var);
2202 minteg ^= nr_two;
2203 if(!mmul.isOne()) {
2204 minteg *= mmul;
2205 minteg.last() ^= nr_two;
2206 }
2207 minteg.negate();
2208 minteg += m_one;
2209 minteg ^= Number(-1, 2);
2210 minteg *= x_var;
2211 minteg.last() ^= mfacexp;
2212 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2213 if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2214 if(!mmul.isOne()) minteg *= mmul;
2215 minteg /= mfacexp;
2216 mstruct *= x_var;
2217 mstruct.last() ^= mfacexp;
2218 mstruct /= mfacexp;
2219 mstruct += minteg;
2220 return true;
2221 }
2222 }
2223 }
2224 }
2225 }
2226 } else if(mstruct.function()->id() == FUNCTION_ID_ATAN && mstruct.size() == 1) {
2227 MathStructure mexp, mmul, madd;
2228 if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && (!definite_integral || x_var.representsNonZero(true) || madd.representsReal(true))) {
2229 if(!mexp.isOne()) {
2230 if(mexp.isMinusOne() && mfac.isOne() && madd.isZero()) {
2231 mstruct *= x_var;
2232 MathStructure mterm(x_var);
2233 mterm ^= nr_two;
2234 mterm += mmul;
2235 if(!mmul.isOne()) mterm.last() ^= nr_two;
2236 mterm.transformById(FUNCTION_ID_LOG);
2237 if(!mmul.isOne()) mterm *= mmul;
2238 mterm *= nr_half;
2239 mstruct += mterm;
2240 return true;
2241 }
2242 } else if(mfac.isOne()) {
2243 MathStructure marg(mstruct[0]);
2244 mstruct.multiply(marg);
2245 MathStructure mterm(marg);
2246 mterm ^= nr_two;
2247 mterm += m_one;
2248 if(!transform_absln(mterm, use_abs, definite_integral, x_var, eo)) return -1;
2249 mterm *= Number(-1, 2);
2250 mstruct += mterm;
2251 if(!mmul.isOne()) mstruct.divide(mmul);
2252 return true;
2253 } else if(madd.isZero() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0))) {
2254 MathStructure mfacexp(1, 1, 0);
2255 if(mfac != x_var) mfacexp = mfac[1];
2256 if(mfacexp.isMinusOne()) {
2257 mstruct.setFunctionId(FUNCTION_ID_POLYLOG);
2258 mstruct.insertChild(nr_two, 1);
2259 MathStructure mterm(mstruct);
2260 mstruct[1] *= nr_minus_i;
2261 mterm[1] *= nr_one_i;
2262 mterm.negate();
2263 mstruct += mterm;
2264 mstruct *= nr_one_i;
2265 mstruct *= nr_half;
2266 return true;
2267 } else if(mfacexp.isOne()) {
2268 MathStructure mterm1(x_var);
2269 mterm1 ^= nr_two;
2270 mterm1 *= mstruct;
2271 mterm1 *= nr_half;
2272 MathStructure mterm2(x_var);
2273 if(!mmul.isOne()) mterm2 /= mmul;
2274 mterm2 *= nr_minus_half;
2275 if(!mmul.isOne()) {mstruct *= mmul; mstruct.last() ^= Number(-2, 1);}
2276 mstruct *= nr_half;
2277 mstruct += mterm1;
2278 mstruct += mterm2;
2279 return true;
2280 } else {
2281 mfacexp += m_one;
2282 MathStructure mxexp(x_var);
2283 mxexp ^= mfacexp;
2284 MathStructure minteg(x_var);
2285 minteg ^= nr_two;
2286 if(!mmul.isOne()) {minteg *= mmul; minteg.last() ^= nr_two;}
2287 minteg += m_one;
2288 if(!definite_integral || COMPARISON_IS_NOT_EQUAL(minteg.compare(m_zero))) {
2289 minteg ^= nr_minus_one;
2290 minteg *= mxexp;
2291 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2292 minteg /= mfacexp;
2293 if(!mmul.isOne()) minteg *= mmul;
2294 mstruct *= mxexp;
2295 mstruct /= mfacexp;
2296 mstruct -= minteg;
2297 return true;
2298 }
2299 }
2300 }
2301 }
2302 } else if(mstruct.function()->id() == FUNCTION_ID_SINH && mstruct.size() == 1) {
2303 if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_LOG && mstruct[0].size() == 1 && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
2304 MathStructure mtest(mstruct[0][0]);
2305 mtest *= Number(-2, 1);
2306 mtest.inverse();
2307 mtest.add(mstruct[0][0]);
2308 mtest.last() *= nr_half;
2309 if(!mpow.isOne()) mtest ^= mpow;
2310 if(!mfac.isOne()) mtest *= mfac;
2311 CALCULATOR->beginTemporaryStopMessages();
2312 if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2313 CALCULATOR->endTemporaryStopMessages(true);
2314 mstruct.set(mtest, true);
2315 return true;
2316 }
2317 CALCULATOR->endTemporaryStopMessages();
2318 }
2319 MathStructure mexp, mmul, madd;
2320 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
2321 if(mfac.isOne() && mexp.isOne()) {
2322 if(mpow.isOne()) {
2323 mstruct.setFunctionId(FUNCTION_ID_COSH);
2324 if(!mmul.isOne()) mstruct.divide(mmul);
2325 } else if(mpow.number().isTwo()) {
2326 MathStructure marg(mstruct[0]);
2327 if(!madd.isZero()) mstruct[0] = x_var;
2328 mstruct[0] *= nr_two;
2329 mstruct /= 4;
2330 if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
2331 MathStructure xhalf(x_var);
2332 xhalf *= nr_half;
2333 mstruct -= xhalf;
2334 if(!madd.isZero()) {
2335 mstruct.replace(x_var, marg);
2336 if(!mmul.isOne()) mstruct.divide(mmul);
2337 }
2338 } else if(mpow.number().isMinusOne()) {
2339 mstruct.setFunctionId(FUNCTION_ID_TANH);
2340 mstruct[0] *= nr_half;
2341 if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
2342 if(!mmul.isOne()) mstruct.divide(mmul);
2343 } else if(mpow.number().isPositive()) {
2344 MathStructure mbak(mstruct);
2345 MathStructure nm1(mpow);
2346 nm1 += nr_minus_one;
2347 mstruct ^= nm1;
2348 MathStructure mcos(mbak);
2349 mcos.setFunctionId(FUNCTION_ID_COSH);
2350 mstruct *= mcos;
2351 mmul *= mpow;
2352 mstruct /= mmul;
2353 MathStructure minteg(mbak);
2354 MathStructure nm2(mpow);
2355 nm2 += Number(-2, 1);
2356 minteg ^= nm2;
2357 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2358 minteg *= nm1;
2359 minteg /= mpow;
2360 mstruct -= minteg;
2361 } else {
2362 MathStructure mbak(mstruct);
2363 MathStructure np1(mpow);
2364 np1 += m_one;
2365 MathStructure np2(mpow);
2366 np2 += nr_two;
2367 mstruct ^= np1;
2368 MathStructure mcos(mbak);
2369 mcos.setFunctionId(FUNCTION_ID_COSH);
2370 mstruct *= mcos;
2371 mstruct /= np1;
2372 if(!mmul.isOne()) mstruct /= mmul;
2373 MathStructure minteg(mbak);
2374 minteg ^= np2;
2375 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2376 minteg *= np2;
2377 minteg /= np1;
2378 mstruct -= minteg;
2379 }
2380 return true;
2381 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
2382 MathStructure mfacexp(1, 1, 0);
2383 if(mfac != x_var) mfacexp = mfac[1];
2384 if(mfacexp.isMinusOne() && !mexp.isZero()) {
2385 if(madd.isZero()) {
2386 if(mpow.isOne()) {
2387 mstruct.setFunctionId(FUNCTION_ID_SINHINT);
2388 if(!mexp.isOne()) mstruct /= mexp;
2389 return true;
2390 } else if(mpow.number().isTwo()) {
2391 mstruct[0] *= nr_two;
2392 mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2393 if(!mexp.isOne()) mstruct /= mexp;
2394 mstruct += x_var;
2395 mstruct.last().transformById(FUNCTION_ID_LOG);
2396 mstruct.last().negate();
2397 mstruct *= nr_half;
2398 return true;
2399 } else if(mpow.number() == 3) {
2400 mstruct.setFunctionId(FUNCTION_ID_SINHINT);
2401 MathStructure mterm2(mstruct);
2402 mstruct[0] *= nr_three;
2403 mterm2 *= Number(-3, 1);
2404 mstruct += mterm2;
2405 if(!mexp.isOne()) mstruct /= mexp;
2406 mstruct *= Number(1, 4);
2407 return true;
2408 }
2409 } else if(mpow.isOne()) {
2410 MathStructure mterm2;
2411 mstruct = x_var;
2412 if(!mexp.isOne()) mstruct ^= mexp;
2413 if(!mmul.isOne()) mstruct *= mmul;
2414 mstruct.transformById(FUNCTION_ID_SINHINT);
2415 mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COSH), &madd, NULL);
2416 mterm2 = x_var;
2417 if(!mexp.isOne()) mterm2 ^= mexp;
2418 if(!mmul.isOne()) mterm2 *= mmul;
2419 mterm2.transformById(FUNCTION_ID_COSHINT);
2420 mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SINH), &madd, NULL);
2421 mstruct += mterm2;
2422 if(!mexp.isOne()) mstruct /= mexp;
2423 return true;
2424 }
2425 } else if(mexp.isOne() && mpow.isOne()) {
2426 if(mfacexp.isOne()) {
2427 MathStructure mterm2(mstruct);
2428 mterm2.setFunctionId(FUNCTION_ID_COSH);
2429 mterm2 *= x_var;
2430 if(!mmul.isOne()) {
2431 mterm2 /= mmul;
2432 mmul ^= nr_two;
2433 mstruct /= mmul;
2434 }
2435 mstruct.negate();
2436 mstruct += mterm2;
2437 return true;
2438 } else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
2439 mstruct.setFunctionId(FUNCTION_ID_COSH);
2440 MathStructure mterm2(mstruct);
2441 mterm2 *= x_var;
2442 mterm2.last() ^= mfacexp;
2443 if(!mmul.isOne()) mterm2 /= mmul;
2444 mstruct *= x_var;
2445 mstruct.last() ^= mfacexp;
2446 mstruct.last().last() += nr_minus_one;
2447 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2448 mstruct *= mfacexp;
2449 if(!mmul.isOne()) mstruct /= mmul;
2450 mstruct.negate();
2451 mstruct += mterm2;
2452 mstruct.childrenUpdated(true);
2453 return true;
2454 } else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
2455 mfacexp += m_one;
2456 MathStructure mterm2(mstruct);
2457 mterm2 *= x_var;
2458 mterm2.last() ^= mfacexp;
2459 mterm2.childUpdated(mterm2.size());
2460 mterm2 /= mfacexp;
2461 mstruct.setFunctionId(FUNCTION_ID_COSH);
2462 mstruct *= x_var;
2463 mstruct.last() ^= mfacexp;
2464 mstruct.childUpdated(mstruct.size());
2465 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2466 mstruct /= mfacexp;
2467 mstruct.negate();
2468 if(!mmul.isOne()) mstruct *= mmul;
2469 mstruct += mterm2;
2470 return true;
2471 }
2472 }
2473 } else if(mfac.isFunction() && mexp.isOne()) {
2474 if(mfac.function()->id() == FUNCTION_ID_SINH && mfac.size() == 1 && mpow.isOne()) {
2475 MathStructure mexpf, mmulf, maddf;
2476 if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf) && mexpf.isOne() && mmul != mmulf) {
2477 MathStructure mterm2(mstruct);
2478 mterm2[0] += mfac[0];
2479 mstruct[0] -= mfac[0];
2480 MathStructure mden1(mmul);
2481 mden1 -= mmulf;
2482 mden1 *= nr_two;
2483 MathStructure mden2(mmul);
2484 mden2 += mmulf;
2485 mden2 *= nr_two;
2486 mterm2 /= mden2;
2487 mstruct /= mden1;
2488 mstruct.negate();
2489 mstruct += mterm2;
2490 return true;
2491 }
2492 } else if(mfac.function()->id() == FUNCTION_ID_COSH && mfac.size() == 1) {
2493 if(mstruct[0] == mfac[0]) {
2494 UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
2495 MathStructure mtest(var);
2496 if(!mpow.isOne()) mtest ^= mpow;
2497 CALCULATOR->beginTemporaryStopMessages();
2498 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
2499 MathStructure m_interval(mstruct);
2500 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
2501 var->setInterval(m_interval);
2502 } else {
2503 var->setInterval(mstruct);
2504 }
2505 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2506 CALCULATOR->endTemporaryStopMessages(true);
2507 mtest.replace(var, mstruct);
2508 var->destroy();
2509 mstruct = mtest;
2510 if(!mmul.isOne()) mstruct /= mmul;
2511 return true;
2512 }
2513 CALCULATOR->endTemporaryStopMessages();
2514 var->destroy();
2515 }
2516 }
2517 }
2518 }
2519 } else if(mstruct.function()->id() == FUNCTION_ID_COSH && mstruct.size() == 1) {
2520 if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_LOG && mstruct[0].size() == 1 && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
2521 MathStructure mtest(mstruct[0][0]);
2522 mtest *= nr_two;
2523 mtest.inverse();
2524 mtest.add(mstruct[0][0]);
2525 mtest.last() *= nr_half;
2526 if(!mpow.isOne()) mtest ^= mpow;
2527 if(!mfac.isOne()) mtest *= mfac;
2528 CALCULATOR->beginTemporaryStopMessages();
2529 if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2530 CALCULATOR->endTemporaryStopMessages(true);
2531 mstruct.set(mtest, true);
2532 return true;
2533 }
2534 CALCULATOR->endTemporaryStopMessages();
2535 }
2536 MathStructure mexp, mmul, madd;
2537 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
2538 if(mfac.isOne() && mexp.isOne()) {
2539 if(mpow.isOne()) {
2540 mstruct.setFunctionId(FUNCTION_ID_SINH);
2541 if(!mmul.isOne()) mstruct.divide(mmul);
2542 return true;
2543 } else if(mpow.number().isTwo()) {
2544 MathStructure marg(mstruct[0]);
2545 if(!madd.isZero()) mstruct[0] = x_var;
2546 mstruct.setFunctionId(FUNCTION_ID_SINH);
2547 mstruct[0] *= nr_two;
2548 mstruct /= 4;
2549 if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
2550 MathStructure xhalf(x_var);
2551 xhalf *= nr_half;
2552 mstruct += xhalf;
2553 if(!madd.isZero()) {
2554 mstruct.replace(x_var, marg);
2555 if(!mmul.isOne()) mstruct.divide(mmul);
2556 }
2557 return true;
2558 } else if(mpow.number().isMinusOne()) {
2559 mstruct.setFunctionId(FUNCTION_ID_SINH);
2560 mstruct.transformById(FUNCTION_ID_ATAN);
2561 if(!mmul.isOne()) mstruct.divide(mmul);
2562 return true;
2563 } else if(mpow.number().isPositive()) {
2564 MathStructure mbak(mstruct);
2565 MathStructure nm1(mpow);
2566 nm1 += nr_minus_one;
2567 mstruct ^= nm1;
2568 MathStructure msin(mbak);
2569 msin.setFunctionId(FUNCTION_ID_SINH);
2570 mstruct *= msin;
2571 mmul *= mpow;
2572 mstruct /= mmul;
2573 MathStructure minteg(mbak);
2574 MathStructure nm2(mpow);
2575 nm2 += Number(-2, 1);
2576 minteg ^= nm2;
2577 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2578 minteg *= nm1;
2579 minteg /= mpow;
2580 mstruct += minteg;
2581 return true;
2582 } else {
2583 MathStructure mbak(mstruct);
2584 MathStructure np1(mpow);
2585 np1 += m_one;
2586 MathStructure np2(mpow);
2587 np2 += nr_two;
2588 mstruct ^= np1;
2589 MathStructure mcos(mbak);
2590 mcos.setFunctionId(FUNCTION_ID_SINH);
2591 mstruct *= mcos;
2592 mstruct /= np1;
2593 if(!mmul.isOne()) mstruct /= mmul;
2594 mstruct.negate();
2595 MathStructure minteg(mbak);
2596 minteg ^= np2;
2597 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2598 minteg *= np2;
2599 minteg /= np1;
2600 mstruct += minteg;
2601 return true;
2602 }
2603 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
2604 MathStructure mfacexp(1, 1, 0);
2605 if(mfac != x_var) mfacexp = mfac[1];
2606 if(mfacexp.isMinusOne() && !mexp.isZero()) {
2607 if(madd.isZero()) {
2608 if(mpow.isOne()) {
2609 mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2610 if(!mexp.isOne()) mstruct /= mexp;
2611 return true;
2612 } else if(mpow.number().isTwo()) {
2613 mstruct[0] *= nr_two;
2614 mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2615 if(!mexp.isOne()) mstruct /= mexp;
2616 mstruct += x_var;
2617 mstruct.last().transformById(FUNCTION_ID_LOG);
2618 mstruct *= nr_half;
2619 return true;
2620 } else if(mpow.number() == 3) {
2621 mstruct.setFunctionId(FUNCTION_ID_COSHINT);
2622 MathStructure mterm2(mstruct);
2623 mstruct[0] *= nr_three;
2624 mterm2 *= nr_three;
2625 mstruct += mterm2;
2626 if(!mexp.isOne()) mstruct /= mexp;
2627 mstruct *= Number(1, 4);
2628 return true;
2629 }
2630 } else if(mpow.isOne()) {
2631 MathStructure mterm2;
2632 mstruct = x_var;
2633 if(!mexp.isOne()) mstruct ^= mexp;
2634 if(!mmul.isOne()) mstruct *= mmul;
2635 mstruct.transformById(FUNCTION_ID_SINHINT);
2636 mstruct *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SINH), &madd, NULL);
2637 mterm2 = x_var;
2638 if(!mexp.isOne()) mterm2 ^= mexp;
2639 if(!mmul.isOne()) mterm2 *= mmul;
2640 mterm2.transformById(FUNCTION_ID_COSHINT);
2641 mterm2 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_COSH), &madd, NULL);
2642 mstruct += mterm2;
2643 if(!mexp.isOne()) mstruct /= mexp;
2644 return true;
2645 }
2646 } else if(mexp.isOne() && mpow.isOne()) {
2647 if(mfacexp.isOne()) {
2648 MathStructure mterm2(mstruct);
2649 mterm2.setFunctionId(FUNCTION_ID_SINH);
2650 mterm2 *= x_var;
2651 if(!mmul.isOne()) {
2652 mterm2 /= mmul;
2653 mmul ^= nr_two;
2654 mstruct /= mmul;
2655 }
2656 mstruct.negate();
2657 mstruct += mterm2;
2658 return true;
2659 } else if(mfacexp.isInteger() && mfacexp.number().isPositive() && mfacexp.number().isLessThan(100)) {
2660 mstruct.setFunctionId(FUNCTION_ID_SINH);
2661 MathStructure mterm2(mstruct);
2662 mterm2 *= x_var;
2663 mterm2.last() ^= mfacexp;
2664 if(!mmul.isOne()) mterm2 /= mmul;
2665 mstruct *= x_var;
2666 mstruct.last() ^= mfacexp;
2667 mstruct.last().last() += nr_minus_one;
2668 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2669 mstruct *= mfacexp;
2670 if(!mmul.isOne()) mstruct /= mmul;
2671 mstruct.negate();
2672 mstruct += mterm2;
2673 mstruct.childrenUpdated(true);
2674 return true;
2675 } else if(madd.isZero() && mfacexp.isInteger() && mfacexp.number().isNegative() && mfacexp.number().isGreaterThan(-100)) {
2676 mfacexp += m_one;
2677 MathStructure mterm2(mstruct);
2678 mterm2 *= x_var;
2679 mterm2.last() ^= mfacexp;
2680 mterm2.childUpdated(mterm2.size());
2681 mterm2 /= mfacexp;
2682 mstruct.setFunctionId(FUNCTION_ID_SINH);
2683 mstruct *= x_var;
2684 mstruct.last() ^= mfacexp;
2685 mstruct.childUpdated(mstruct.size());
2686 if(mstruct.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2687 mstruct /= mfacexp;
2688 mstruct.negate();
2689 if(!mmul.isOne()) mstruct *= mmul;
2690 mstruct += mterm2;
2691 return true;
2692 }
2693 }
2694 } else if(mfac.isFunction() && mexp.isOne()) {
2695 if(mfac.function()->id() == FUNCTION_ID_COSH && mfac.size() == 1 && mpow.isOne()) {
2696 MathStructure mexpf, mmulf, maddf;
2697 if(integrate_info(mfac[0], x_var, maddf, mmulf, mexpf) && mexpf.isOne() && mmulf != mmul) {
2698 mstruct.setFunctionId(FUNCTION_ID_SINH);
2699 MathStructure mterm2(mstruct);
2700 mterm2[0] += mfac[0];
2701 mstruct[0] -= mfac[0];
2702 MathStructure mden1(mmul);
2703 mden1 -= mmulf;
2704 mden1 *= nr_two;
2705 MathStructure mden2(mmul);
2706 mden2 += mmulf;
2707 mden2 *= nr_two;
2708 mterm2 /= mden2;
2709 mstruct /= mden1;
2710 mstruct += mterm2;
2711 mstruct.childrenUpdated(true);
2712 return true;
2713 }
2714 } else if(mfac.function()->id() == FUNCTION_ID_SINH && mfac.size() == 1) {
2715 if(mstruct[0] == mfac[0]) {
2716 UnknownVariable *var = new UnknownVariable("", format_and_print(mstruct));
2717 MathStructure mtest(var);
2718 if(!mpow.isOne()) mtest ^= mpow;
2719 CALCULATOR->beginTemporaryStopMessages();
2720 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
2721 MathStructure m_interval(mstruct);
2722 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
2723 var->setInterval(m_interval);
2724 } else {
2725 var->setInterval(mstruct);
2726 }
2727 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2728 CALCULATOR->endTemporaryStopMessages(true);
2729 mtest.replace(var, mstruct);
2730 var->destroy();
2731 mstruct = mtest;
2732 if(!mmul.isOne()) mstruct /= mmul;
2733 return true;
2734 }
2735 CALCULATOR->endTemporaryStopMessages();
2736 var->destroy();
2737 }
2738 }
2739 }
2740 }
2741 } else if(mstruct.function()->id() == FUNCTION_ID_TANH && mstruct.size() == 1) {
2742 if(mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_LOG && mstruct[0].size() == 1 && (!definite_integral || COMPARISON_IS_NOT_EQUAL(mstruct[0][0].compare(m_zero)))) {
2743 MathStructure mtest(mstruct[0][0]);
2744 mtest ^= nr_two;
2745 mtest += m_one;
2746 mtest.inverse();
2747 mtest *= Number(-2, 1);
2748 mtest += m_one;
2749 if(!mpow.isOne()) mtest ^= mpow;
2750 if(!mfac.isOne()) mtest *= mfac;
2751 CALCULATOR->beginTemporaryStopMessages();
2752 if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2753 CALCULATOR->endTemporaryStopMessages(true);
2754 mstruct.set(mtest, true);
2755 return true;
2756 }
2757 CALCULATOR->endTemporaryStopMessages();
2758 }
2759 MathStructure mexp, mmul, madd;
2760 if(mfac.isOne() && mpow.isInteger() && mpow.number().isLessThanOrEqualTo(10) && mpow.number().isGreaterThanOrEqualTo(-1) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne() && (!definite_integral || madd.representsNonComplex(true) || x_var.representsNonZero())) {
2761 if(mpow.isOne()) {
2762 mstruct.setFunctionId(FUNCTION_ID_COSH);
2763 mstruct.transformById(FUNCTION_ID_LOG);
2764 if(!mmul.isOne()) mstruct.divide(mmul);
2765 } else if(mpow.number().isTwo()) {
2766 MathStructure marg(mstruct[0]);
2767 if(!madd.isZero()) mstruct[0] = x_var;
2768 if(madd.isZero() && !mmul.isOne()) mstruct /= mmul;
2769 mstruct.negate();
2770 mstruct += x_var;
2771 if(!madd.isZero()) {
2772 mstruct.replace(x_var, marg);
2773 if(!mmul.isOne()) mstruct.divide(mmul);
2774 }
2775 } else if(mpow.number().isMinusOne()) {
2776 mstruct.setFunctionId(FUNCTION_ID_SINH);
2777 if(!transform_absln(mstruct, use_abs, definite_integral, x_var, eo)) return -1;
2778 if(!mmul.isOne()) mstruct.divide(mmul);
2779 } else {
2780 MathStructure minteg(mstruct);
2781 MathStructure nm1(mpow);
2782 nm1 += nr_minus_one;
2783 mstruct ^= nm1;
2784 mmul *= nm1;
2785 mstruct /= mmul;
2786 mstruct.negate();
2787 MathStructure nm2(mpow);
2788 nm2 += Number(-2, 1);
2789 minteg ^= nm2;
2790 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2791 mstruct += minteg;
2792 }
2793 return true;
2794 }
2795 } else if(mstruct.function()->id() == FUNCTION_ID_ASINH && mstruct.size() == 1) {
2796 MathStructure mexp, mmul, madd;
2797 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
2798 if(definite_integral && !madd.representsNonComplex(true) && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero))) return false;
2799 if(mfac.isOne()) {
2800 if(mpow.isOne()) {
2801 MathStructure marg(mstruct[0]);
2802 if(!madd.isZero()) mstruct[0] = x_var;
2803 mstruct.multiply(x_var);
2804 MathStructure mterm(x_var);
2805 mterm ^= nr_two;
2806 if(madd.isZero() && !mmul.isOne()) {
2807 MathStructure mmul2(mmul);
2808 mmul2 ^= nr_two;
2809 mterm *= mmul2;
2810 }
2811 mterm += m_one;
2812 mterm ^= nr_half;
2813 if(madd.isZero() && !mmul.isOne()) mterm /= mmul;
2814 mstruct.subtract(mterm);
2815 if(!madd.isZero()) {
2816 mstruct.replace(x_var, marg);
2817 if(!mmul.isOne()) mstruct.divide(mmul);
2818 }
2819 return true;
2820 } else if(mpow.isMinusOne()) {
2821 mstruct.transformById(FUNCTION_ID_COSHINT);
2822 if(!mmul.isOne()) mstruct /= mmul;
2823 return true;
2824 } else if(mpow.number() == -2) {
2825 MathStructure mterm(mstruct[0]);
2826 mterm ^= nr_two;
2827 mterm += m_one;
2828 mterm ^= nr_half;
2829 mterm /= mstruct;
2830 mstruct.transformById(FUNCTION_ID_SINHINT);
2831 mstruct -= mterm;
2832 if(!mmul.isOne()) mstruct /= mmul;
2833 return true;
2834 } else if(madd.isZero()) {
2835 if(mpow.number().isPositive()) {
2836 MathStructure mpowm1(mpow);
2837 if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
2838 else mpowm1 += nr_minus_one;
2839 MathStructure mterm(mstruct);
2840 if(!mpowm1.isOne()) mterm ^= mpowm1;
2841 MathStructure mfac1(x_var);
2842 mfac1 ^= nr_two;
2843 if(!mmul.isOne()) {
2844 mfac1 *= mmul;
2845 mfac1.last() ^= nr_two;
2846 }
2847 mfac1 += m_one;
2848 mfac1 ^= nr_half;
2849 mterm *= mfac1;
2850 mterm *= mpow;
2851 if(!mmul.isOne()) mterm /= mmul;
2852 MathStructure minteg;
2853 if(mpowm1.isOne()) {
2854 minteg = x_var;
2855 } else {
2856 minteg = mstruct;
2857 minteg ^= mpow;
2858 minteg.last() += Number(-2, 1);
2859 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2860 }
2861 minteg *= mpow;
2862 if(!mpowm1.isOne()) minteg *= mpowm1;
2863 mstruct ^= mpow;
2864 mstruct *= x_var;
2865 mstruct -= mterm;
2866 mstruct += minteg;
2867 return true;
2868 } else {
2869 MathStructure mpowp1(mpow);
2870 mpowp1 += m_one;
2871 MathStructure mpowp2(mpow);
2872 mpowp2 += nr_two;
2873 MathStructure mterm(mstruct);
2874 mterm ^= mpowp1;
2875 MathStructure mfac1(x_var);
2876 mfac1 ^= nr_two;
2877 if(!mmul.isOne()) {
2878 mfac1 *= mmul;
2879 mfac1.last() ^= nr_two;
2880 }
2881 mfac1 += m_one;
2882 mfac1 ^= nr_half;
2883 mterm *= mfac1;
2884 if(!mmul.isOne()) mterm /= mmul;
2885 mterm /= mpowp1;
2886 MathStructure minteg(mstruct);
2887 minteg ^= mpowp2;
2888 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2889 minteg /= mpowp1;
2890 minteg /= mpowp2;
2891 mstruct ^= mpowp2;
2892 mstruct *= x_var;
2893 mstruct /= mpowp1;
2894 mstruct /= mpowp2;
2895 mstruct.negate();
2896 mstruct += mterm;
2897 mstruct += minteg;
2898 return true;
2899 }
2900 }
2901 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
2902 MathStructure mfacexp(1, 1, 0);
2903 if(mfac != x_var) mfacexp = mfac[1];
2904 if(mpow.isOne()) {
2905 if(mfacexp.isOne()) {
2906 MathStructure mterm2(mstruct[0]);
2907 mterm2 ^= nr_two;
2908 mterm2 += m_one;
2909 mterm2 ^= nr_half;
2910 MathStructure mfac2(x_var);
2911 if(!mmul.isOne()) mfac2 *= mmul;
2912 mfac2.negate();
2913 if(!madd.isZero()) {
2914 mfac2 += madd;
2915 mfac2.last() *= nr_three;
2916 }
2917 mterm2 *= mfac2;
2918 MathStructure mfac1(x_var);
2919 mfac1 ^= nr_two;
2920 if(!mmul.isOne()) {
2921 mfac1 *= mmul;
2922 mfac1.last() ^= nr_two;
2923 }
2924 mfac1 *= nr_two;
2925 if(!madd.isZero()) {
2926 mfac1 += madd;
2927 mfac1.last() ^= nr_two;
2928 mfac1.last() *= Number(-2, 1);
2929 }
2930 mfac1 += m_one;
2931 mstruct *= mfac1;
2932 mstruct += mterm2;
2933 if(!mmul.isOne()) {
2934 mstruct *= mmul;
2935 mstruct.last() ^= Number(-2, 1);
2936 }
2937 mstruct *= Number(1, 4);
2938 return true;
2939 } else if(mfacexp == nr_two && madd.isZero()) {
2940 mstruct *= x_var;
2941 mstruct.last() ^= nr_three;
2942 mstruct *= Number(1, 3);
2943 MathStructure mterm(x_var);
2944 mterm ^= nr_two;
2945 if(!mmul.isOne()) {
2946 mterm *= mmul;
2947 mterm.last() ^= nr_two;
2948 }
2949 MathStructure mfac1(mterm);
2950 mfac1 += Number(-2, 1);
2951 mterm += m_one;
2952 mterm ^= nr_half;
2953 mterm *= mfac1;
2954 if(!mmul.isOne()) {
2955 mmul ^= Number(-3, 1);
2956 mterm *= mmul;
2957 }
2958 mterm *= Number(-1, 9);
2959 mstruct += mterm;
2960 return true;
2961 } else if(!mfacexp.isMinusOne() && madd.isZero()) {
2962 mfacexp += m_one;
2963 MathStructure minteg(x_var);
2964 minteg ^= nr_two;
2965 if(!mmul.isOne()) {
2966 minteg *= mmul;
2967 minteg.last() ^= nr_two;
2968 }
2969 minteg += m_one;
2970 minteg ^= Number(-1, 2);
2971 minteg *= x_var;
2972 minteg.last() ^= mfacexp;
2973 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
2974 if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
2975 if(!mmul.isOne()) minteg *= mmul;
2976 minteg /= mfacexp;
2977 mstruct *= x_var;
2978 mstruct.last() ^= mfacexp;
2979 mstruct /= mfacexp;
2980 mstruct -= minteg;
2981 return true;
2982 }
2983 }
2984 }
2985 }
2986 }
2987 } else if(mstruct.function()->id() == FUNCTION_ID_ACOSH && mstruct.size() == 1) {
2988 MathStructure mexp, mmul, madd;
2989 if(mpow.isInteger() && mpow.number().isLessThanOrEqualTo(100) && mpow.number().isGreaterThanOrEqualTo(-100) && !mpow.isZero() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
2990 if(definite_integral && (!mmul.representsNonComplex(true) || !x_var.representsNonComplex(true))) return false;
2991 if(mfac.isOne()) {
2992 if(mpow.isOne()) {
2993 MathStructure marg(mstruct[0]);
2994 if(!madd.isZero()) mstruct[0] = x_var;
2995 MathStructure mterm(mstruct[0]);
2996 MathStructure msqrt2(mstruct[0]);
2997 mstruct.multiply(x_var);
2998 mterm += m_one;
2999 mterm ^= nr_half;
3000 msqrt2 += m_minus_one;
3001 msqrt2 ^= nr_half;
3002 mterm *= msqrt2;
3003 if(madd.isZero() && !mmul.isOne()) {
3004 mterm /= mmul;
3005 }
3006 mstruct.subtract(mterm);
3007 if(!madd.isZero()) {
3008 mstruct.replace(x_var, marg);
3009 if(!mmul.isOne()) mstruct.divide(mmul);
3010 }
3011 return true;
3012 } else if(mpow.isMinusOne()) {
3013 mstruct.transformById(FUNCTION_ID_SINHINT);
3014 if(!mmul.isOne()) mstruct /= mmul;
3015 return true;
3016 } else if(mpow.number() == -2) {
3017 MathStructure msqrt(mstruct[0]);
3018 msqrt += m_one;
3019 msqrt.inverse();
3020 msqrt *= mstruct[0];
3021 msqrt.last() += nr_minus_one;
3022 msqrt ^= nr_half;
3023 MathStructure macosh(mstruct);
3024 mstruct.transformById(FUNCTION_ID_COSHINT);
3025 mstruct *= macosh;
3026 mstruct *= msqrt;
3027 mstruct += x_var;
3028 if(!mmul.isOne()) mstruct.last() *= mmul;
3029 mstruct.last().negate();
3030 if(!madd.isZero()) mstruct -= madd;
3031 mstruct += m_one;
3032 mstruct /= macosh;
3033 mstruct /= msqrt;
3034 if(!mmul.isOne()) mstruct /= mmul;
3035 return true;
3036 } else if(madd.isZero()) {
3037 if(mpow.number().isPositive()) {
3038 MathStructure mpowm1(mpow);
3039 if(mpow == nr_two) mpowm1.set(1, 1, 0, true);
3040 else mpowm1 += nr_minus_one;
3041 MathStructure mterm(mstruct);
3042 if(!mpowm1.isOne()) mterm ^= mpowm1;
3043 MathStructure mfac1(x_var);
3044 if(!mmul.isOne()) mfac1 *= mmul;
3045 mfac1 += m_one;
3046 mfac1 ^= nr_half;
3047 MathStructure mfac2(x_var);
3048 if(!mmul.isOne()) mfac2 *= mmul;
3049 mfac2 += nr_minus_one;
3050 mfac2 ^= nr_half;
3051 mterm *= mfac1;
3052 mterm *= mfac2;
3053 mterm *= mpow;
3054 if(!mmul.isOne()) mterm /= mmul;
3055 MathStructure minteg;
3056 if(mpowm1.isOne()) {
3057 minteg = x_var;
3058 } else {
3059 minteg = mstruct;
3060 minteg ^= mpow;
3061 minteg.last() += Number(-2, 1);
3062 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3063 }
3064 minteg *= mpow;
3065 if(!mpowm1.isOne()) minteg *= mpowm1;
3066 mstruct ^= mpow;
3067 mstruct *= x_var;
3068 mstruct -= mterm;
3069 mstruct += minteg;
3070 return true;
3071 } else {
3072 MathStructure mpowp1(mpow);
3073 mpowp1 += m_one;
3074 MathStructure mpowp2(mpow);
3075 mpowp2 += nr_two;
3076 MathStructure mterm(mstruct);
3077 mterm ^= mpowp1;
3078 MathStructure mfac1(x_var);
3079 if(!mmul.isOne()) mfac1 *= mmul;
3080 mfac1 += m_one;
3081 mfac1 ^= nr_half;
3082 MathStructure mfac2(x_var);
3083 if(!mmul.isOne()) mfac2 *= mmul;
3084 mfac2 += nr_minus_one;
3085 mfac2 ^= nr_half;
3086 mterm *= mfac1;
3087 mterm *= mfac2;
3088 if(!mmul.isOne()) mterm /= mmul;
3089 mterm /= mpowp1;
3090 MathStructure minteg(mstruct);
3091 minteg ^= mpowp2;
3092 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3093 minteg /= mpowp1;
3094 minteg /= mpowp2;
3095 mstruct ^= mpowp2;
3096 mstruct *= x_var;
3097 mstruct /= mpowp1;
3098 mstruct /= mpowp2;
3099 mstruct.negate();
3100 mstruct += mterm;
3101 mstruct += minteg;
3102 return true;
3103 }
3104 }
3105 } else if(mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].containsRepresentativeOf(x_var, true, true) == 0)) {
3106 MathStructure mfacexp(1, 1, 0);
3107 if(mfac != x_var) mfacexp = mfac[1];
3108 if(mpow.isOne()) {
3109 if(mfacexp.isOne()) {
3110 MathStructure mterm2(mstruct[0]);
3111 MathStructure mterm2b(mstruct[0]);
3112 mterm2 += nr_minus_one;
3113 mterm2 ^= nr_half;
3114 mterm2b += m_one;
3115 mterm2b ^= nr_half;
3116 mterm2 *= mterm2b;
3117 MathStructure mfac2(x_var);
3118 if(!mmul.isOne()) {
3119 mfac2 *= mmul;
3120 }
3121 mfac2.negate();
3122 if(!madd.isZero()) {
3123 mfac2 += madd;
3124 mfac2.last() *= nr_three;
3125 }
3126 mterm2 *= mfac2;
3127 MathStructure mfac1(x_var);
3128 mfac1 ^= nr_two;
3129 if(!mmul.isOne()) {
3130 mfac1 *= mmul;
3131 mfac1.last() ^= nr_two;
3132 }
3133 mfac1 *= nr_two;
3134 if(!madd.isZero()) {
3135 mfac1 += madd;
3136 mfac1.last() ^= nr_two;
3137 mfac1.last() *= Number(-2, 1);
3138 }
3139 mfac1 += nr_minus_one;
3140 mstruct *= mfac1;
3141 mstruct += mterm2;
3142 if(!mmul.isOne()) {
3143 mstruct *= mmul;
3144 mstruct.last() ^= Number(-2, 1);
3145 }
3146 mstruct *= Number(1, 4);
3147 return true;
3148 } else if(mfacexp == nr_two && madd.isZero()) {
3149 mstruct *= x_var;
3150 mstruct.last() ^= nr_three;
3151 mstruct *= Number(1, 3);
3152 MathStructure mterm(x_var);
3153 if(!mmul.isOne()) mterm *= mmul;
3154 mterm += m_one;
3155 mterm ^= nr_half;
3156 MathStructure mfac1(x_var);
3157 if(!mmul.isOne()) mfac1 *= mmul;
3158 mfac1 += nr_minus_one;
3159 mfac1 ^= nr_half;
3160 mterm *= mfac1;
3161 MathStructure mfac2(x_var);
3162 mfac2 ^= nr_two;
3163 if(!mmul.isOne()) {
3164 mfac2 *= mmul;
3165 mfac2.last() ^= nr_two;
3166 }
3167 mfac2 += nr_two;
3168 mterm *= mfac2;
3169 if(!mmul.isOne()) {
3170 mmul ^= Number(-3, 1);
3171 mterm *= mmul;
3172 }
3173 mterm *= Number(-1, 9);
3174 mstruct += mterm;
3175 return true;
3176 } else if(!mfacexp.isMinusOne() && madd.isZero()) {
3177 mfacexp += m_one;
3178 MathStructure minteg(x_var);
3179 if(!mmul.isOne()) minteg *= mmul;
3180 minteg += m_one;
3181 minteg ^= Number(-1, 2);
3182 MathStructure mfac1(x_var);
3183 if(!mmul.isOne()) mfac1 *= mmul;
3184 mfac1 += nr_minus_one;
3185 mfac1 ^= Number(-1, 2);
3186 minteg *= mfac1;
3187 minteg *= x_var;
3188 minteg.last() ^= mfacexp;
3189 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3190 if(minteg.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3191 if(!mmul.isOne()) minteg *= mmul;
3192 minteg /= mfacexp;
3193 mstruct *= x_var;
3194 mstruct.last() ^= mfacexp;
3195 mstruct /= mfacexp;
3196 mstruct -= minteg;
3197 return true;
3198 }
3199 }
3200 }
3201 }
3202 }
3203 } else if(mstruct.function()->id() == FUNCTION_ID_ATANH && mstruct.size() == 1) {
3204 MathStructure mexp, mmul, madd;
3205 if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp)) {
3206 if(!mexp.isOne()) {
3207 if(mexp.isMinusOne() && mfac.isOne() && madd.isZero()) {
3208 mstruct *= x_var;
3209 if(madd.isZero()) {
3210 MathStructure mterm(mmul);
3211 if(!mmul.isOne()) mterm ^= nr_two;
3212 mterm.negate();
3213 mterm += x_var;
3214 mterm.last() ^= nr_two;
3215 mterm.transformById(FUNCTION_ID_LOG);
3216 if(!mmul.isOne()) mterm *= mmul;
3217 mterm *= nr_half;
3218 mstruct += mterm;
3219 } else {
3220 MathStructure mterm1(x_var);
3221 mterm1 *= madd;
3222 mterm1 += mmul;
3223 MathStructure mterm2(mterm1);
3224 mterm1 += x_var;
3225 mterm2 -= x_var;
3226 mterm1.transformById(FUNCTION_ID_LOG);
3227 mterm2.transformById(FUNCTION_ID_LOG);
3228 mterm1 *= mmul;
3229 mterm2 *= mmul;
3230 madd *= nr_two;
3231 madd += nr_two;
3232 mterm1 /= madd;
3233 madd[0].negate();
3234 mterm2 /= madd;
3235 mstruct += mterm1;
3236 mstruct += mterm2;
3237 }
3238 return true;
3239 }
3240 } else if(mfac.isOne()) {
3241 MathStructure marg(mstruct[0]);
3242 mstruct.multiply(marg);
3243 MathStructure mterm(marg);
3244 mterm ^= nr_two;
3245 mterm.negate();
3246 mterm += m_one;
3247 mterm.transformById(FUNCTION_ID_LOG);
3248 mterm *= nr_half;
3249 mstruct.add(mterm);
3250 if(!mmul.isOne()) mstruct.divide(mmul);
3251 return true;
3252 } else if(madd.isZero() && (mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].isInteger()))) {
3253 MathStructure mfacexp(1, 1, 0);
3254 if(mfac != x_var) mfacexp = mfac[1];
3255 if(mfacexp.isMinusOne()) {
3256 mstruct.setFunctionId(FUNCTION_ID_POLYLOG);
3257 mstruct.insertChild(nr_two, 1);
3258 MathStructure mterm(mstruct);
3259 mterm[1].negate();
3260 mterm.negate();
3261 mstruct += mterm;
3262 mstruct *= nr_half;
3263 return true;
3264 } else if(mfacexp.isOne()) {
3265 MathStructure mterm1(x_var);
3266 mterm1 ^= nr_two;
3267 mterm1 *= mstruct;
3268 mterm1 *= nr_half;
3269 MathStructure mterm2(x_var);
3270 if(!mmul.isOne()) mterm2 /= mmul;
3271 mterm2 *= nr_half;
3272 if(!mmul.isOne()) {mstruct *= mmul; mstruct.last() ^= Number(-2, 1);}
3273 mstruct *= nr_minus_half;
3274 mstruct += mterm1;
3275 mstruct += mterm2;
3276 return true;
3277 } else {
3278 mfacexp += m_one;
3279 MathStructure mxexp(x_var);
3280 mxexp ^= mfacexp;
3281 MathStructure minteg(x_var);
3282 minteg ^= nr_two;
3283 if(!mmul.isOne()) {minteg *= mmul; minteg.last() ^= nr_two;}
3284 minteg.negate();
3285 minteg += m_one;
3286 if(!definite_integral || COMPARISON_IS_NOT_EQUAL(minteg.compare(m_zero))) {
3287 minteg ^= nr_minus_one;
3288 minteg *= mxexp;
3289 if(minteg.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) return -1;
3290 minteg /= mfacexp;
3291 if(!mmul.isOne()) minteg *= mmul;
3292 mstruct *= mxexp;
3293 mstruct /= mfacexp;
3294 mstruct -= minteg;
3295 return true;
3296 }
3297 }
3298 }
3299 }
3300 } else if(mstruct.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct)) {
3301 MathStructure madd, mmul, mexp;
3302 if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3303 if(mfac.isOne()) {
3304 MathStructure np1(mstruct[1]);
3305 mstruct.multiply(mstruct[0]);
3306 np1.inverse();
3307 np1 += m_one;
3308 if(!mmul.isOne()) np1 *= mmul;
3309 mstruct.divide(np1);
3310 return true;
3311 } else if(mfac == x_var) {
3312 MathStructure nm1(mstruct[1]);
3313 nm1.inverse();
3314 nm1 += m_one;
3315 MathStructure mnum(x_var);
3316 mnum *= nm1;
3317 if(!mmul.isOne()) mnum *= mmul;
3318 if(!madd.isZero()) mnum -= madd;
3319 MathStructure mden(mstruct[1]);
3320 mden.inverse();
3321 mden += nr_two;
3322 mden *= nm1;
3323 if(!mmul.isOne()) {
3324 mden *= mmul;
3325 mden.last() ^= nr_two;
3326 }
3327 mstruct.multiply(mstruct[0]);
3328 mstruct *= mnum;
3329 mstruct /= mden;
3330 return true;
3331 }
3332 }
3333 } else if(mstruct.function()->id() == FUNCTION_ID_ERFC && mstruct.size() == 1) {
3334 MathStructure mtest(mstruct);
3335 mtest.setFunctionId(FUNCTION_ID_ERF);
3336 mtest.negate();
3337 mtest += m_one;
3338 if(!mpow.isOne()) mtest ^= mpow;
3339 if(!mfac.isOne()) mtest *= mfac;
3340 CALCULATOR->beginTemporaryStopMessages();
3341 if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0) {
3342 CALCULATOR->endTemporaryStopMessages(true);
3343 mstruct = mtest;
3344 return true;
3345 }
3346 CALCULATOR->endTemporaryStopMessages();
3347 } else if(mstruct.function()->id() == FUNCTION_ID_ERF && mstruct.size() == 1) {
3348 MathStructure madd, mmul, mexp;
3349 if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3350 MathStructure mterm2(CALCULATOR->getVariableById(VARIABLE_ID_E));
3351 mterm2 ^= mstruct[0];
3352 mterm2.last() ^= nr_two;
3353 mterm2.last().negate();
3354 mterm2 *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3355 mterm2.last() ^= Number(-1, 2);
3356 if(!mmul.isOne()) mterm2 /= mmul;
3357 if(madd.isZero()) {
3358 mstruct *= x_var;
3359 } else {
3360 mstruct *= madd;
3361 if(!mmul.isOne()) {
3362 mstruct.last() /= mmul;
3363 mstruct.childrenUpdated();
3364 }
3365 mstruct.last() += x_var;
3366 }
3367 mstruct += mterm2;
3368 return true;
3369 }
3370 } else if(mstruct.function()->id() == FUNCTION_ID_ERFI && mstruct.size() == 1) {
3371 MathStructure madd, mmul, mexp;
3372 if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3373 MathStructure mterm2(CALCULATOR->getVariableById(VARIABLE_ID_E));
3374 mterm2 ^= mstruct[0];
3375 mterm2.last() ^= nr_two;
3376 mterm2 *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3377 mterm2.last() ^= Number(-1, 2);
3378 if(!mmul.isOne()) mterm2 /= mmul;
3379 if(madd.isZero()) {
3380 mstruct *= x_var;
3381 } else {
3382 mstruct *= madd;
3383 if(!mmul.isOne()) {
3384 mstruct.last() /= mmul;
3385 mstruct.childrenUpdated();
3386 }
3387 mstruct.last() += x_var;
3388 }
3389 mstruct -= mterm2;
3390 return true;
3391 }
3392 } else if(mstruct.function()->id() == FUNCTION_ID_FRESNEL_S && mstruct.size() == 1) {
3393 MathStructure madd, mmul, mexp;
3394 if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne() && madd.isOne()) {
3395 MathStructure mterm(x_var);
3396 mterm ^= nr_two;
3397 if(!mmul.isOne()) {
3398 mmul ^= nr_two;
3399 mterm *= mmul;
3400 }
3401 mterm *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3402 mterm *= nr_half;
3403 mterm *= CALCULATOR->getRadUnit();
3404 mterm.transformById(FUNCTION_ID_COS);
3405 if(!mmul.isOne()) mterm /= mmul;
3406 mterm /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3407 mstruct *= x_var;
3408 mstruct += mterm;
3409 return true;
3410 }
3411 } else if(mstruct.function()->id() == FUNCTION_ID_FRESNEL_C && mstruct.size() == 1) {
3412 MathStructure madd, mmul, mexp;
3413 if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne() && madd.isOne()) {
3414 MathStructure mterm(x_var);
3415 mterm ^= nr_two;
3416 if(!mmul.isOne()) {
3417 mmul ^= nr_two;
3418 mterm *= mmul;
3419 }
3420 mterm *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3421 mterm *= nr_half;
3422 mterm *= CALCULATOR->getRadUnit();
3423 mterm.transformById(FUNCTION_ID_SIN);
3424 if(!mmul.isOne()) mterm /= mmul;
3425 mterm /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
3426 mstruct *= x_var;
3427 mstruct -= mterm;
3428 return true;
3429 }
3430 } else if(mstruct.function()->id() == FUNCTION_ID_DIGAMMA && mstruct.size() == 1) {
3431 MathStructure madd, mmul, mexp;
3432 if(mpow.isOne() && mfac.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3433 mstruct.setFunctionId(FUNCTION_ID_GAMMA);
3434 mstruct.transformById(FUNCTION_ID_LOG);
3435 if(!mmul.isOne()) mstruct /= mmul;
3436 return true;
3437 }
3438 } else if(mstruct.function()->id() == FUNCTION_ID_LOGINT && mstruct.size() == 1) {
3439 MathStructure madd, mmul, mexp;
3440 if(mpow.isOne() && integrate_info(mstruct[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3441 if(mfac.isOne()) {
3442 MathStructure mEi(mstruct);
3443 mstruct *= mEi[0];
3444 mEi.setFunctionId(FUNCTION_ID_LOG);
3445 mEi *= nr_two;
3446 mEi.transformById(FUNCTION_ID_EXPINT);
3447 mstruct -= mEi;
3448 if(!mmul.isOne()) mstruct /= mmul;
3449 return true;
3450 } else if(madd.isZero() && mfac.isPower() && mfac[0] == x_var && mfac[1].isMinusOne()) {
3451 MathStructure mln(mstruct);
3452 mln.setFunctionId(FUNCTION_ID_LOG);
3453 mstruct *= mln;
3454 mstruct -= mln[0];
3455 return true;
3456 }
3457 }
3458 } else if(mstruct.function()->id() == FUNCTION_ID_DIFFERENTIATE && (mstruct.size() == 3 || (mstruct.size() == 4 && mstruct[3].isUndefined())) && mstruct[1] == x_var) {
3459 if(!mpow.isOne() || !mfac.isOne()) return false;
3460 if(mstruct[2].isOne()) {
3461 mstruct.setToChild(1, true);
3462 } else {
3463 mstruct[2] += m_minus_one;
3464 }
3465 return true;
3466 } else if(mstruct.function()->id() == FUNCTION_ID_DIFFERENTIATE && mstruct.size() == 2 && mstruct[1] == x_var) {
3467 if(!mpow.isOne() || !mfac.isOne()) return false;
3468 mstruct.setToChild(1, true);
3469 return true;
3470 } else {
3471 return false;
3472 }
3473 if(mstruct.size() == 0) return false;
3474 bool by_parts_tested = false;
3475
3476 if(mfac.isOne() && (mstruct.function()->id() == FUNCTION_ID_LOG || mstruct.function()->id() == FUNCTION_ID_ASIN || mstruct.function()->id() == FUNCTION_ID_ACOS || mstruct.function()->id() == FUNCTION_ID_ATAN || mstruct.function()->id() == FUNCTION_ID_ASINH || mstruct.function()->id() == FUNCTION_ID_ACOSH || mstruct.function()->id() == FUNCTION_ID_ATANH)) {
3477 by_parts_tested = true;
3478 //integrate by parts
3479 if(max_part_depth > 0) {
3480 MathStructure minteg(mstruct);
3481 if(!mpow.isOne()) minteg ^= mpow;
3482 CALCULATOR->beginTemporaryStopMessages();
3483 if(minteg.differentiate(x_var, eo) && minteg.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) <= 0 && (!definite_integral || check_zero_div(minteg, x_var, eo))) {
3484 minteg *= x_var;
3485 EvaluationOptions eo2 = eo;
3486 eo2.expand = true;
3487 eo2.combine_divisions = false;
3488 eo2.sync_units = false;
3489 minteg.evalSort(true);
3490 minteg.calculateFunctions(eo);
3491 minteg.calculatesub(eo2, eo2, true);
3492 combine_ln(minteg, x_var, eo2);
3493 do_simplification(minteg, eo2, true, false, false, true, true);
3494 if(minteg.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0 && minteg.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0) {
3495 CALCULATOR->endTemporaryStopMessages(true);
3496 if(!mpow.isOne()) mstruct ^= mpow;
3497 mstruct.multiply(x_var);
3498 mstruct.subtract(minteg);
3499 return true;
3500 }
3501 }
3502 CALCULATOR->endTemporaryStopMessages();
3503 }
3504 }
3505
3506 MathStructure madd, mmul, mexp;
3507 if(integrate_info(mstruct[0], x_var, madd, mmul, mexp, false, false, true) && !mexp.isZero()) {
3508 if(mexp.isPower() && (mexp[1] == x_var || (mexp[1].isMultiplication() && mexp[1].size() >= 2 && mexp[1].last() == x_var)) && mfac.isPower() && (mfac[1] == x_var || (mfac[1].isMultiplication() && mfac[1].size() >= 2 && mfac[1].last() == x_var)) && (mfac[0] == mexp[0] || (mfac[0].isNumber() && mfac[0].number().isRational() && mexp[0].isNumber() && mexp[0].number().isRational() && mexp[1] == mfac[1])) && mexp[0].containsRepresentativeOf(x_var, true, true) == 0) {
3509 Number pow1(1, 1), pow2;
3510 MathStructure morig(mexp);
3511 bool b = true;
3512 if(mfac[1].isMultiplication()) {
3513 if(!mexp[1].isMultiplication()) {
3514 if(mfac[1].size() != 2 || !mfac[1][0].isNumber()) b = false;
3515 else {pow2 = mfac[1][0].number(); pow2--;}
3516 } else {
3517 for(size_t i = 0; i < mexp[1].size() - 1; i++) {
3518 if(i == 0 && mexp[1][i].isNumber()) {
3519 pow1 = mexp[1][i].number();
3520 } else if(mfac[1][i].containsRepresentativeOf(x_var, true, true) != 0) {
3521 b = false;
3522 break;
3523 }
3524 }
3525 if(b) {
3526 if(mexp[1] == mfac[1]) {
3527 pow1.set(1, 1);
3528 } else if(mfac[1].size() - (mfac[1][0].isNumber() ? 1 : 0) != mexp[1].size() - (mexp[1][0].isNumber() ? 1 : 0)) {
3529 b = false;
3530 } else if(b) {
3531 for(size_t i = 0; i < mfac[1].size() - 1; i++) {
3532 if(i == 0 && mfac[1][i].isNumber()) {
3533 pow2 = mfac[1][i].number();
3534 pow2--;
3535 } else if(mfac[1][i] != mexp[1][i + (mexp[1][0].isNumber() ? 1 : 0) - (mfac[1][0].isNumber() ? 1 : 0)]) {
3536 b = false;
3537 break;
3538 }
3539 }
3540 }
3541 }
3542 }
3543 } else if(mexp[1].isMultiplication()) {
3544 if(mexp[1].size() != 2 || !mexp[1][0].isNumber()) b = false;
3545 else pow1 = mexp[1][0].number();
3546 }
3547 if(b && !pow1.isOne()) morig[1].delChild(1, true);
3548 if(b && mfac[0] != mexp[0]) {
3549 bool b1 = mfac[0].number() < mexp[0].number();
3550 if(mfac[0].number().isFraction() || mexp[0].number().isFraction()) b1 = !b1;
3551 Number nlog(b1 ? mexp[0].number() : mfac[0].number());
3552 nlog.log(b1 ? mfac[0].number() : mexp[0].number());
3553 if(!nlog.isInteger()) {
3554 nlog.round();
3555 b = nlog.isInteger() && (b1 ? ((mfac[0].number() ^ nlog) == mexp[0].number()) : ((mfac[0].number() ^ nlog) == mexp[0].number()));
3556 }
3557 if(b) {
3558 if(b1) {
3559 pow1 = nlog;
3560 morig = mfac;
3561 } else {
3562 pow2 = nlog;
3563 pow2--;
3564 }
3565 }
3566 }
3567 if(b) {
3568 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
3569 MathStructure mtest(var);
3570 if(!pow1.isOne()) mtest ^= pow1;
3571 if(!mmul.isOne()) mtest *= mmul;
3572 if(!madd.isZero()) mtest += madd;
3573 mtest.transform(mstruct.function());
3574 if(!mpow.isOne()) mtest ^= mpow;
3575 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3576 MathStructure m_interval(morig);
3577 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3578 var->setInterval(m_interval);
3579 } else {
3580 var->setInterval(morig);
3581 }
3582 if(!pow2.isZero()) {
3583 mtest *= var;
3584 if(!pow2.isOne()) mtest.last() ^= pow2;
3585 mtest.swapChildren(1, 2);
3586 }
3587 CALCULATOR->beginTemporaryStopMessages();
3588 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3589 CALCULATOR->endTemporaryStopMessages(true);
3590 mstruct.set(mtest, true);
3591 mstruct.replace(var, morig);
3592 if(!morig[0].isVariable() || morig[0].variable()->id() != VARIABLE_ID_E) mstruct.divide_nocopy(new MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &morig[0], NULL));
3593 if(morig[1].isMultiplication()) {
3594 morig[1].delChild(morig[1].size(), true);
3595 mstruct /= morig[1];
3596 }
3597 var->destroy();
3598 return true;
3599 }
3600 CALCULATOR->endTemporaryStopMessages();
3601 var->destroy();
3602 }
3603 } else if(mexp == x_var && !madd.isZero() && (mfac.isOne() || mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].isInteger()))) {
3604 MathStructure morig(x_var);
3605 if(!mmul.isOne()) morig *= mmul;
3606 morig += madd;
3607 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
3608 MathStructure mtest(var);
3609 mtest.transform(mstruct.function());
3610 if(!mpow.isOne()) mtest ^= mpow;
3611 if(!mfac.isOne()) {
3612 MathStructure mrepl(var);
3613 mrepl -= madd;
3614 mrepl /= mmul;
3615 MathStructure mfacnew(mfac);
3616 mfacnew.replace(x_var, mrepl);
3617 mtest *= mfacnew;
3618 }
3619 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3620 MathStructure m_interval(morig);
3621 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3622 var->setInterval(m_interval);
3623 } else {
3624 var->setInterval(morig);
3625 }
3626 CALCULATOR->beginTemporaryStopMessages();
3627 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3628 CALCULATOR->endTemporaryStopMessages(true);
3629 mstruct.set(mtest, true);
3630 mstruct.replace(var, morig);
3631 if(!mmul.isOne()) mstruct /= mmul;
3632 var->destroy();
3633 return true;
3634 }
3635 CALCULATOR->endTemporaryStopMessages();
3636 var->destroy();
3637 } else if(mfac.isOne() && (mexp.isPower() && mexp[0] == x_var && mexp[1].isNumber() && !mexp[1].number().isInteger() && mexp[1].number().isRational())) {
3638 Number num(mexp[1].number().numerator());
3639 Number den(mexp[1].number().denominator());
3640 if(num.isPositive() || num.isMinusOne()) {
3641 MathStructure morig(x_var);
3642 if(num.isNegative()) den.negate();
3643 Number den_inv(den);
3644 den_inv.recip();
3645 morig ^= den_inv;
3646 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
3647 Number den_m1(den);
3648 den_m1--;
3649 MathStructure mtest(var);
3650 if(!num.isOne() && !num.isMinusOne()) mtest ^= num;
3651 if(!mmul.isOne()) mtest *= mmul;
3652 if(!madd.isZero()) mtest += madd;
3653 mtest.transform(mstruct.function());
3654 if(!mpow.isOne()) mtest ^= mpow;
3655 mtest *= var;
3656 if(!den_m1.isOne()) {
3657 mtest.last() ^= den_m1;
3658 mtest.childUpdated(mtest.size());
3659 }
3660 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3661 MathStructure m_interval(morig);
3662 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3663 var->setInterval(m_interval);
3664 } else {
3665 var->setInterval(morig);
3666 }
3667 CALCULATOR->beginTemporaryStopMessages();
3668 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3669 CALCULATOR->endTemporaryStopMessages(true);
3670 mstruct.set(mtest, true);
3671 mstruct.replace(var, morig);
3672 mstruct.multiply(den);
3673 var->destroy();
3674 return true;
3675 }
3676 CALCULATOR->endTemporaryStopMessages();
3677 var->destroy();
3678 }
3679 } else if((mfac.isOne() || mfac == x_var || (mfac.isPower() && mfac[0] == x_var && mfac[1].isInteger())) && (mexp.isPower() && mexp[0] != x_var && mexp[1].isNumber())) {
3680 MathStructure madd2, mmul2, mexp2;
3681 if(integrate_info(mexp[0], x_var, madd2, mmul2, mexp2) && (!madd.isZero() || mexp != x_var) && mexp2.isOne()) {
3682 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mexp[0]) + RIGHT_PARENTHESIS);
3683 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3684 MathStructure m_interval(mexp[0]);
3685 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3686 var->setInterval(m_interval);
3687 } else {
3688 var->setInterval(mexp[0]);
3689 }
3690 MathStructure mtest(var);
3691 mtest ^= mexp[1];
3692 if(!mmul.isOne()) mtest *= mmul;
3693 if(!madd.isZero()) mtest += madd;
3694 mtest.transform(mstruct.function());
3695 if(!mpow.isOne()) mtest ^= mpow;
3696 if(!mfac.isOne()) {
3697 mtest *= var;
3698 if(!madd2.isZero()) {
3699 mtest.last() -= madd2;
3700 mtest.childUpdated(mtest.size());
3701 }
3702 if(mfac.isPower()) {
3703 mtest.last() ^= mfac[1];
3704 mtest.childUpdated(mtest.size());
3705 }
3706 }
3707 CALCULATOR->beginTemporaryStopMessages();
3708 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3709 CALCULATOR->endTemporaryStopMessages(true);
3710 mstruct.set(mtest, true);
3711 mstruct.replace(var, mexp[0]);
3712 if(!mmul2.isOne()) {
3713 mstruct /= mmul2;
3714 if(!mfac.isOne()) {
3715 if(mfac.isPower()) mmul2 ^= mfac[1];
3716 mstruct /= mmul2;
3717 }
3718 }
3719 var->destroy();
3720 return true;
3721 }
3722 CALCULATOR->endTemporaryStopMessages();
3723 var->destroy();
3724 }
3725 }
3726 }
3727 if(mstruct[0].isAddition()) {
3728 bool b = true;
3729 for(size_t i = 0; i < mstruct.size(); i++) {
3730 if(mstruct[i].containsType(STRUCT_ADDITION, true) == 1) {
3731 b = false;
3732 break;
3733 }
3734 }
3735 if(b) {
3736 MathStructure mtest(mstruct);
3737 if(mtest[0].factorize(eo, false, 0, 0, false, false, NULL, x_var, true, true)) {
3738 if(integrate_function(mtest, x_var, eo, mpow, mfac, mpowadd, mpowmul, use_abs, definite_integral, max_part_depth, parent_parts)) {
3739 mstruct = mtest;
3740 return true;
3741 }
3742 }
3743 }
3744 }
3745
3746 if(!mfac.isOne()) return false;
3747 MathStructure *m_func = NULL, *m_pow = NULL;
3748 if(mstruct[0].isFunction() && mstruct[0].contains(x_var, true) > 0) {
3749 m_func = &mstruct[0];
3750 } else if(mstruct[0].isPower() && mstruct[0][0].isFunction() && mstruct[0][0].contains(x_var, true) > 0) {
3751 m_func = &mstruct[0][0];
3752 } else if(mstruct[0].isPower() && mstruct[0][1].contains(x_var, true) > 0) {
3753 m_pow = &mstruct[0];
3754 } else if(mstruct[0].isMultiplication()) {
3755 for(size_t i = 0; i < mstruct[0].size(); i++) {
3756 if(mstruct[0][i].isFunction() && mstruct[0][i].contains(x_var, true) > 0) {
3757 m_func = &mstruct[0][i];
3758 } else if(mstruct[0][i].isPower() && mstruct[0][i][0].isFunction() && mstruct[0][i][0].contains(x_var, true) > 0) {
3759 m_func = &mstruct[0][i][0];
3760 } else if(mstruct[0][i].isPower() && mstruct[0][i][1].contains(x_var, true) > 0) {
3761 m_pow = &mstruct[0][i];
3762 }
3763 }
3764 } else if(mstruct[0].isAddition()) {
3765 for(size_t i2 = 0; i2 < mstruct[0].size(); i2++) {
3766 if(mstruct[0][i2].isFunction() && mstruct[0][i2].contains(x_var, true) > 0) {
3767 m_func = &mstruct[0][i2];
3768 } else if(mstruct[0][i2].isPower() && mstruct[0][i2][0].isFunction() && mstruct[0][i2][0].contains(x_var, true) > 0) {
3769 m_func = &mstruct[0][i2][0];
3770 } else if(mstruct[0][i2].isPower() && mstruct[0][i2][1].contains(x_var, true) > 0) {
3771 m_pow = &mstruct[0][i2];
3772 } else if(mstruct[0][i2].isMultiplication()) {
3773 for(size_t i = 0; i < mstruct[0][i2].size(); i++) {
3774 if(mstruct[0][i2][i].isFunction() && mstruct[0][i2][i].contains(x_var, true) > 0) {
3775 m_func = &mstruct[0][i2][i];
3776 } else if(mstruct[0][i2][i].isPower() && mstruct[0][i2][i][0].isFunction() && mstruct[0][i2][i][0].contains(x_var, true) > 0) {
3777 m_func = &mstruct[0][i2][i][0];
3778 } else if(mstruct[0][i2][i].isPower() && mstruct[0][i2][i][1].contains(x_var, true) > 0) {
3779 m_pow = &mstruct[0][i2][i];
3780 }
3781 }
3782 }
3783 }
3784 }
3785 if(m_func && m_pow) return false;
3786 if(m_func) {
3787 if((m_func->function()->id() == FUNCTION_ID_LOG || m_func->function()->id() == FUNCTION_ID_ASIN || m_func->function()->id() == FUNCTION_ID_ACOS || m_func->function()->id() == FUNCTION_ID_ASINH || m_func->function()->id() == FUNCTION_ID_ACOSH) && m_func->size() == 1 && integrate_info((*m_func)[0], x_var, madd, mmul, mexp) && mexp.isOne()) {
3788 MathStructure m_orig(*m_func);
3789 UnknownVariable *var = new UnknownVariable("", format_and_print(m_orig));
3790 MathStructure mtest(mstruct);
3791 if(!mpow.isOne()) mtest ^= mpow;
3792 mtest[0].replace(m_orig, var, (*m_func)[0].containsInterval());
3793 if(mtest[0].containsRepresentativeOf(x_var, true, true) == 0) {
3794 if(m_func->function()->id() == FUNCTION_ID_LOG) {
3795 MathStructure m_epow(CALCULATOR->getVariableById(VARIABLE_ID_E));
3796 m_epow ^= var;
3797 mtest *= m_epow;
3798 } else if(m_func->function()->id() == FUNCTION_ID_ASIN) {
3799 MathStructure m_cos(var);
3800 if(CALCULATOR->getRadUnit()) m_cos *= CALCULATOR->getRadUnit();
3801 m_cos.transformById(FUNCTION_ID_COS);
3802 mtest *= m_cos;
3803 } else if(m_func->function()->id() == FUNCTION_ID_ACOS) {
3804 MathStructure m_sin(var);
3805 if(CALCULATOR->getRadUnit()) m_sin *= CALCULATOR->getRadUnit();
3806 m_sin.transformById(FUNCTION_ID_SIN);
3807 mtest *= m_sin;
3808 mmul.negate();
3809 } else if(m_func->function()->id() == FUNCTION_ID_ASINH) {
3810 MathStructure m_cos(var);
3811 m_cos.transformById(FUNCTION_ID_COSH);
3812 mtest *= m_cos;
3813 } else if(m_func->function()->id() == FUNCTION_ID_ACOSH) {
3814 MathStructure m_sin(var);
3815 m_sin.transformById(FUNCTION_ID_SINH);
3816 mtest *= m_sin;
3817 }
3818 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3819 MathStructure m_interval(m_orig);
3820 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3821 var->setInterval(m_interval);
3822 } else {
3823 var->setInterval(m_orig);
3824 }
3825 CALCULATOR->beginTemporaryStopMessages();
3826 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3827 CALCULATOR->endTemporaryStopMessages(true);
3828 mstruct.set(mtest, true);
3829 mstruct.replace(var, m_orig);
3830 if(!mmul.isOne()) mstruct /= mmul;
3831 var->destroy();
3832 return true;
3833 }
3834 CALCULATOR->endTemporaryStopMessages();
3835 }
3836 var->destroy();
3837 }
3838 }
3839 if(m_pow) {
3840 if((*m_pow)[0].containsRepresentativeOf(x_var, true, true) == 0 && integrate_info((*m_pow)[1], x_var, madd, mmul, mexp) && mexp.isOne()) {
3841 if(definite_integral && ((*m_pow)[0].compare(m_zero) != COMPARISON_RESULT_LESS)) return false;
3842 MathStructure m_orig(*m_pow);
3843 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_orig) + RIGHT_PARENTHESIS);
3844 MathStructure mtest(mstruct);
3845 mtest[0].replace(m_orig, var, m_pow->containsInterval());
3846 if(mtest[0].containsRepresentativeOf(x_var, true, true) == 0) {
3847 if(!mpow.isOne()) mtest ^= mpow;
3848 mtest /= var;
3849 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
3850 MathStructure m_interval(m_orig);
3851 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
3852 var->setInterval(m_interval);
3853 } else {
3854 var->setInterval(m_orig);
3855 }
3856 CALCULATOR->beginTemporaryStopMessages();
3857 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
3858 CALCULATOR->endTemporaryStopMessages(true);
3859 mstruct.set(mtest, true);
3860 mstruct.replace(var, m_orig);
3861 MathStructure m_ln(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &m_orig[0], NULL);
3862 mstruct /= m_ln;
3863 if(!mmul.isOne()) mstruct /= mmul;
3864 var->destroy();
3865 return true;
3866 }
3867 CALCULATOR->endTemporaryStopMessages();
3868 }
3869 var->destroy();
3870 }
3871 }
3872
3873 if(!by_parts_tested && mstruct.function()->id() != FUNCTION_ID_SIN && mstruct.function()->id() != FUNCTION_ID_COS && mstruct.function()->id() != FUNCTION_ID_TAN && mstruct.function()->id() != FUNCTION_ID_SINH && mstruct.function()->id() != FUNCTION_ID_COSH && mstruct.function()->id() != FUNCTION_ID_TANH) {
3874 //integrate by parts
3875 if(max_part_depth > 0) {
3876 MathStructure minteg(mstruct);
3877 if(!mpow.isOne()) minteg ^= mpow;
3878 CALCULATOR->beginTemporaryStopMessages();
3879 if(minteg.differentiate(x_var, eo) && minteg.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) <= 0 && (!definite_integral || check_zero_div(minteg, x_var, eo))) {
3880 minteg *= x_var;
3881 EvaluationOptions eo2 = eo;
3882 eo2.expand = true;
3883 eo2.combine_divisions = false;
3884 eo2.sync_units = false;
3885 minteg.evalSort(true);
3886 minteg.calculateFunctions(eo);
3887 minteg.calculatesub(eo2, eo2, true);
3888 combine_ln(minteg, x_var, eo2);
3889 do_simplification(minteg, eo2, true, false, false, true, true);
3890 if(minteg.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0 && minteg.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0) {
3891 CALCULATOR->endTemporaryStopMessages(true);
3892 if(!mpow.isOne()) mstruct ^= mpow;
3893 mstruct.multiply(x_var);
3894 mstruct.subtract(minteg);
3895 return true;
3896 }
3897 }
3898 CALCULATOR->endTemporaryStopMessages();
3899 }
3900 }
3901 return false;
3902 }
3903
3904 #define CANNOT_INTEGRATE {MathStructure minteg(CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE), this, &m_undefined, &m_undefined, &x_var, &m_zero, NULL); set(minteg); return false;}
3905 #define CANNOT_INTEGRATE_INTERVAL {MathStructure minteg(CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE), this, &m_undefined, &m_undefined, &x_var, &m_zero, NULL); set(minteg); return -1;}
3906
contains_unsolved_integrate(const MathStructure & mstruct,MathStructure * this_mstruct,vector<MathStructure * > * parent_parts)3907 int contains_unsolved_integrate(const MathStructure &mstruct, MathStructure *this_mstruct, vector<MathStructure*> *parent_parts) {
3908 if(mstruct.isFunction() && mstruct.function()->id() == FUNCTION_ID_INTEGRATE) {
3909 if(this_mstruct->equals(mstruct[0], true)) return 3;
3910 for(size_t i = 0; i < parent_parts->size(); i++) {
3911 if(mstruct[0].equals(*(*parent_parts)[i], true)) return 2;
3912 }
3913 return 1;
3914 }
3915 int ret = 0;
3916 for(size_t i = 0; i < mstruct.size(); i++) {
3917 int ret_i = contains_unsolved_integrate(mstruct[i], this_mstruct, parent_parts);
3918 if(ret_i == 1) {
3919 return 1;
3920 } else if(ret_i > ret) {
3921 ret = ret_i;
3922 }
3923 }
3924 return ret;
3925 }
3926
3927 // remove abs() when possible
fix_abs_x(MathStructure & mstruct,const MathStructure & x_var,const EvaluationOptions & eo,bool definite_integral)3928 bool fix_abs_x(MathStructure &mstruct, const MathStructure &x_var, const EvaluationOptions &eo, bool definite_integral) {
3929 bool b = false;
3930 if(mstruct.isFunction() && mstruct.size() == 1 && mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ABS && mstruct[0].size() == 1) {
3931 if(!definite_integral && (mstruct.function()->id() == FUNCTION_ID_SIN || mstruct.function()->id() == FUNCTION_ID_TAN || mstruct.function()->id() == FUNCTION_ID_SINH || mstruct.function()->id() == FUNCTION_ID_TANH || mstruct.function()->id() == FUNCTION_ID_ASIN || mstruct.function()->id() == FUNCTION_ID_ATAN || mstruct.function()->id() == FUNCTION_ID_ASINH || mstruct.function()->id() == FUNCTION_ID_ATANH) && mstruct[0][0].representsNonComplex(true)) {
3932 // sin(abs(f(x)))=sgn(f(x))*sin(f(x)) if not f(x) is complex
3933 mstruct[0].setToChild(1, true);
3934 mstruct.multiply_nocopy(new MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIGNUM), &mstruct[0], &m_zero, NULL));
3935 mstruct.evalSort(false);
3936 b = true;
3937 } else if((mstruct.function()->id() == FUNCTION_ID_COS || mstruct.function()->id() == FUNCTION_ID_COSH) && mstruct[0][0].representsNonComplex(true)) {
3938 // cos(abs(f(x)))=cos(f(x)) if not f(x) is complex
3939 mstruct[0].setToChild(1, true);
3940 b = true;
3941 } else if(mstruct.function()->id() == FUNCTION_ID_LOG) {
3942 // ln(abs(f(x)))=ln(f(x)^2)/2 if not f(x) is complex
3943 if(mstruct[0][0].representsNonComplex(true)) {
3944 b = true;
3945 } else {
3946 MathStructure mtest(mstruct[0][0]);
3947 transform_absln(mtest, -1, false, x_var, eo);
3948 b = !mtest.isFunction() || mtest.function()->id() != FUNCTION_ID_LOG || (mtest.size() >= 0 && mtest[0].isFunction() && mtest[0].function()->id() == FUNCTION_ID_ABS);
3949 }
3950 if(b) {
3951 mstruct[0].setToChild(1, true);
3952 mstruct[0] ^= nr_two;
3953 mstruct /= nr_two;
3954 }
3955 }
3956 }
3957 for(size_t i = 0; i < mstruct.size(); i++) {
3958 if(fix_abs_x(mstruct[i], x_var, eo, definite_integral)) b = true;
3959 }
3960 return b;
3961 }
3962
find_abs_x2(MathStructure & mstruct,const MathStructure & x_var,const MathStructure * parent=NULL,int level=0)3963 MathStructure *find_abs_x2(MathStructure &mstruct, const MathStructure &x_var, const MathStructure *parent = NULL, int level = 0) {
3964 if(mstruct.isFunction()) {
3965 if(((mstruct.function()->id() == FUNCTION_ID_ABS && mstruct.size() == 1) || (mstruct.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct) && mstruct[1].number().isOdd())) && mstruct[0].contains(x_var, true) > 0 && mstruct[0].representsNonComplex(true)) {
3966 return &mstruct[0];
3967 }
3968 if((!parent || parent->isMultiplication() || parent->isAddition()) && level <= 2 && mstruct.function()->id() == FUNCTION_ID_LOG && mstruct.size() == 1) {
3969 if((mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0].isPower() && mstruct[0][1].isInteger() && mstruct[0][0].isFunction() && mstruct[0][0].function()->id() == FUNCTION_ID_ROOT)) return NULL;
3970 if(mstruct[0].isMultiplication() && mstruct[0].size() == 2 && ((mstruct[0][1].isFunction() && mstruct[0][1].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0][1].isPower() && mstruct[0][1][1].isInteger() && mstruct[0][1][0].isFunction() && mstruct[0][1][0].function()->id() == FUNCTION_ID_ROOT))) return NULL;
3971 }
3972 }
3973 for(size_t i = 0; i < mstruct.size(); i++) {
3974 MathStructure *m = find_abs_x2(mstruct[i], x_var, &mstruct, level + 1);
3975 if(m) return m;
3976 }
3977 return NULL;
3978 }
fix_sgn_x(MathStructure & mstruct,const MathStructure & x_var,const EvaluationOptions & eo)3979 bool fix_sgn_x(MathStructure &mstruct, const MathStructure &x_var, const EvaluationOptions &eo) {
3980 if(mstruct.isFunction() && mstruct.function()->id() == FUNCTION_ID_SIGNUM && mstruct.size() == 2) {
3981 MathStructure mtest(mstruct);
3982 KnownVariable *var = new KnownVariable("", format_and_print(x_var), ((UnknownVariable*) x_var.variable())->interval());
3983 mtest.replace(x_var, var);
3984 CALCULATOR->beginTemporaryStopMessages();
3985 mtest.eval(eo);
3986 var->destroy();
3987 if(!CALCULATOR->endTemporaryStopMessages() && !mtest.isFunction()) {
3988 mstruct.set(mtest);
3989 return true;
3990 }
3991 }
3992 bool b = false;
3993 for(size_t i = 0; i < mstruct.size(); i++) {
3994 if(fix_sgn_x(mstruct[i], x_var, eo)) b = true;
3995 }
3996 return b;
3997 }
replace_abs_x(MathStructure & mstruct,const MathStructure & marg,bool b_minus,const MathStructure * parent=NULL,int level=0)3998 bool replace_abs_x(MathStructure &mstruct, const MathStructure &marg, bool b_minus, const MathStructure *parent = NULL, int level = 0) {
3999 if(mstruct.isFunction()) {
4000 if(mstruct.function()->id() == FUNCTION_ID_ABS && mstruct.size() == 1 && mstruct[0].equals(marg, true)) {
4001 mstruct.setToChild(1);
4002 if(b_minus) mstruct.negate();
4003 return true;
4004 } else if(mstruct.function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct) && mstruct[1].number().isOdd() && mstruct[0].equals(marg, true)) {
4005 if(b_minus) mstruct[0].negate();
4006 mstruct[1].number().recip();
4007 mstruct.setType(STRUCT_POWER);
4008 mstruct.childrenUpdated();
4009 if(b_minus) mstruct.negate();
4010 return true;
4011 }
4012 if((!parent || parent->isMultiplication() || parent->isAddition()) && level <= 2 && mstruct.function()->id() == FUNCTION_ID_LOG && mstruct.size() == 1) {
4013 if((mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0].isPower() && mstruct[0][1].isInteger() && mstruct[0][0].isFunction() && mstruct[0][0].function()->id() == FUNCTION_ID_ROOT)) return false;
4014 if(mstruct[0].isMultiplication() && mstruct[0].size() == 2 && ((mstruct[0][1].isFunction() && mstruct[0][1].function()->id() == FUNCTION_ID_ROOT) || (mstruct[0][1].isPower() && mstruct[0][1][1].isInteger() && mstruct[0][1][0].isFunction() && mstruct[0][1][0].function()->id() == FUNCTION_ID_ROOT))) return false;
4015 }
4016 }
4017 if(mstruct.isPower() && mstruct[1].isInteger() && mstruct[1].number().isOdd() && mstruct[0].isFunction() && mstruct[0].function()->id() == FUNCTION_ID_ROOT && VALID_ROOT(mstruct[0]) && mstruct[0][1].number().isOdd() && mstruct[0][0].equals(marg, true)) {
4018 mstruct[1].number().divide(mstruct[0][1].number());
4019 mstruct[0].setToChild(1, true);
4020 if(mstruct[1].number().isOne()) mstruct.setToChild(1, true);
4021 if(b_minus) mstruct[0].negate();
4022 mstruct.childrenUpdated();
4023 if(b_minus) mstruct.negate();
4024 return true;
4025 }
4026 bool b = false;
4027 for(size_t i = 0; i < mstruct.size(); i++) {
4028 if(replace_abs_x(mstruct[i], marg, b_minus, &mstruct, level + 1)) {
4029 mstruct.childUpdated(i + 1);
4030 b = true;
4031 }
4032 }
4033 return b;
4034 }
4035
test_sign_zero(const MathStructure & m,const MathStructure & x_var,const MathStructure & mzero,const EvaluationOptions & eo)4036 bool test_sign_zero(const MathStructure &m, const MathStructure &x_var, const MathStructure &mzero, const EvaluationOptions &eo) {
4037 if(m.contains(x_var, true) <= 0) return false;
4038 if(m.isMultiplication()) {
4039 for(size_t i = 0; i < m.size(); i++) {
4040 if(m[i].isPower() && m[i][1].representsNegative() && test_sign_zero(m[i][0], x_var, mzero, eo)) return true;
4041 }
4042 }
4043 CALCULATOR->beginTemporaryStopMessages();
4044 MathStructure mtest(m);
4045 mtest.replace(x_var, mzero);
4046 mtest.transform(COMPARISON_EQUALS, m_zero);
4047 mtest.eval(eo);
4048 return !CALCULATOR->endTemporaryStopMessages() && mtest.isOne();
4049 }
4050
do_signum(MathStructure & m1,const MathStructure & marg)4051 void do_signum(MathStructure &m1, const MathStructure &marg) {
4052 /*m1 *= marg;
4053 m1 *= marg;
4054 m1.last().transformById(FUNCTION_ID_ABS);
4055 m1.last().inverse();*/
4056 m1 *= MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_SIGNUM), &marg, &m_zero, NULL);
4057 }
try_sign(MathStructure & m1,MathStructure & m2,const MathStructure & marg,const MathStructure & x_var,const MathStructure & mzero,const EvaluationOptions & eo,bool * test_zero=NULL)4058 bool try_sign(MathStructure &m1, MathStructure &m2, const MathStructure &marg, const MathStructure &x_var, const MathStructure &mzero, const EvaluationOptions &eo, bool *test_zero = NULL) {
4059 if(m1.equals(m2, true)) return true;
4060 if(m1.isNumber() && m1.number().isReal() && m2.isNumber() && m2.number().isReal()) {
4061 m2.number().negate();
4062 if(m1.number().equals(m2.number(), true)) {
4063 m2.number().negate();
4064 if(!test_sign_zero(m1, x_var, mzero, eo)) {
4065 if(!test_zero) return false;
4066 *test_zero = true;
4067 }
4068 if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4069 return true;
4070 }
4071 m2.number().negate();
4072 return false;
4073 }
4074 if(m1.type() != m2.type()) {
4075 if((m1.isMultiplication() && m1.size() == 2 && m1[0].isMinusOne() && try_sign(m1[1], m2, marg, x_var, mzero, eo)) || (m2.isMultiplication() && m2.size() == 2 && m2[0].isMinusOne() && try_sign(m1, m2[1], marg, x_var, mzero, eo))) {
4076 if(!test_sign_zero(m1, x_var, mzero, eo)) {
4077 if(!test_zero) return false;
4078 *test_zero = true;
4079 }
4080 if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4081 return true;
4082 }
4083 return false;
4084 }
4085 if(m1.size() == 0) return false;
4086 if(m1.size() != m2.size()) {
4087 if(m1.isMultiplication() && ((m1.size() == m2.size() + 1 && m1[0].isMinusOne()) || (m2.size() == m1.size() + 1 && m2[0].isMinusOne()))) {
4088 if(m1.size() > m2.size()) {
4089 for(size_t i = 0; i < m2.size(); i++) {
4090 if(!try_sign(m1[i + 1], m2[i], marg, x_var, mzero, eo)) return false;
4091 }
4092 } else {
4093 for(size_t i = 0; i < m1.size(); i++) {
4094 if(!try_sign(m1[i], m2[i + 1], marg, x_var, mzero, eo)) return false;
4095 }
4096 }
4097 if(!test_sign_zero(m1, x_var, mzero, eo)) {
4098 if(!test_zero) return false;
4099 *test_zero = true;
4100 }
4101 if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4102 return true;
4103 }
4104 return false;
4105 }
4106 if(m1.isFunction() && m1.function() != m2.function()) return false;
4107 if(m1.isComparison() && m1.comparisonType() != m2.comparisonType()) return false;
4108 if(m1.isMultiplication() && m1.size() > 1 && m1[0].isNumber() && !m1[0].equals(m2[0], true)) {
4109 if(!m1[0].isNumber()) return false;
4110 m2[0].number().negate();
4111 if(m1[0].number().equals(m2[0].number(), true)) {
4112 m2[0].number().negate();
4113 for(size_t i = 1; i < m1.size(); i++) {
4114 if(!try_sign(m1[i], m2[i], marg, x_var, mzero, eo)) return false;
4115 }
4116 if(!test_sign_zero(m1, x_var, mzero, eo)) {
4117 if(!test_zero) return false;
4118 *test_zero = true;
4119 }
4120 if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4121 return true;
4122 }
4123 m2[0].number().negate();
4124 return false;
4125 }/* else if(m1.isPower()) {
4126 bool b_tz = false;
4127 if(!try_sign(m1[0], m2[0], marg, x_var, mzero, eo, &b_tz) || b_tz) return false;
4128 if(!try_sign(m1[1], m2[1], marg, x_var, mzero, eo, &b_tz)) return false;
4129 if(b_tz && (test_sign_zero(m1[1], x_var, mzero, eo) || !test_sign_zero(m1[0], x_var, mzero, eo))) return false;
4130 return true;
4131 }*/
4132 bool b_tz = false;
4133 bool b_equal = false;
4134 for(size_t i = 0; i < m1.size(); i++) {
4135 if(!b_equal && m1.isAddition() && m1[i].equals(m2[i], true)) b_equal = true;
4136 else if(!try_sign(m1[i], m2[i], marg, x_var, mzero, eo, m1.isAddition() ? &b_tz : NULL)) return false;
4137 if(b_tz && b_equal) break;
4138 }
4139 if(b_tz) {
4140 if(!test_sign_zero(m1, x_var, mzero, eo)) {
4141 if(!test_zero) return false;
4142 *test_zero = true;
4143 }
4144 if(!test_zero || !(*test_zero)) do_signum(m1, marg);
4145 }
4146 return true;
4147 }
contains_imaginary(const MathStructure & m)4148 bool contains_imaginary(const MathStructure &m) {
4149 if(m.isNumber()) return m.number().hasImaginaryPart();
4150 if(m.isVariable() && m.variable()->isKnown()) return contains_imaginary(((KnownVariable*) m.variable())->get());
4151 for(size_t i = 0; i < m.size(); i++) {
4152 if(contains_imaginary(m[i])) return true;
4153 }
4154 return false;
4155 }
4156
integrate(const MathStructure & x_var,const EvaluationOptions & eo_pre,bool simplify_first,int use_abs,bool definite_integral,bool try_abs,int max_part_depth,vector<MathStructure * > * parent_parts)4157 int MathStructure::integrate(const MathStructure &x_var, const EvaluationOptions &eo_pre, bool simplify_first, int use_abs, bool definite_integral, bool try_abs, int max_part_depth, vector<MathStructure*> *parent_parts) {
4158
4159 if(CALCULATOR->aborted()) CANNOT_INTEGRATE
4160
4161 EvaluationOptions eo = eo_pre;
4162 eo.protected_function = CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE);
4163 EvaluationOptions eo2 = eo;
4164 eo2.expand = true;
4165 eo2.combine_divisions = false;
4166 eo2.sync_units = false;
4167 EvaluationOptions eo_t = eo;
4168 eo_t.approximation = APPROXIMATION_TRY_EXACT;
4169 eo_t.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
4170
4171 if(simplify_first) {
4172 unformat(eo_pre);
4173 calculateFunctions(eo2);
4174 calculatesub(eo2, eo2);
4175 combine_ln(*this, x_var, eo2);
4176 if(CALCULATOR->aborted()) CANNOT_INTEGRATE
4177 }
4178 bool recalc = false;
4179
4180 // Try to remove abs() and sgn()
4181
4182 if(fix_abs_x(*this, x_var, eo, definite_integral)) recalc = true;
4183
4184 MathStructure *mfound = NULL;
4185 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4186 if(fix_sgn_x(*this, x_var, eo_t)) recalc = true;
4187 while(true) {
4188 mfound = find_abs_x2(*this, x_var);
4189 if(mfound) {
4190 MathStructure m_interval(*mfound);
4191 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4192 CALCULATOR->beginTemporaryStopMessages();
4193 m_interval.eval(eo_t);
4194 if(!CALCULATOR->endTemporaryStopMessages()) break;
4195 if(m_interval.representsNonNegative(true)) {
4196 replace_abs_x(*this, MathStructure(*mfound), false);
4197 recalc = true;
4198 } else if(m_interval.representsNegative(true)) {
4199 replace_abs_x(*this, MathStructure(*mfound), true);
4200 recalc = true;
4201 } else {
4202 break;
4203 }
4204 } else {
4205 break;
4206 }
4207 }
4208 }
4209 if(recalc) {
4210 calculatesub(eo2, eo2);
4211 combine_ln(*this, x_var, eo2);
4212 }
4213
4214 // x: x^2/2
4215 if(equals(x_var)) {
4216 raise(2);
4217 multiply(MathStructure(1, 2, 0));
4218 return true;
4219 }
4220
4221 // a: a*x
4222 if(containsRepresentativeOf(x_var, true, true) == 0) {
4223 multiply(x_var);
4224 return true;
4225 }
4226
4227 if(m_type == STRUCT_ADDITION) {
4228 // f(x)+g(x): integral of f(x) + integral of g(x)
4229 bool b = false;
4230 MathStructure mbak(*this);
4231 for(size_t i = 0; i < SIZE; i++) {
4232 int bint = CHILD(i).integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts);
4233 if(bint < 0) {
4234 set(mbak);
4235 CANNOT_INTEGRATE_INTERVAL
4236 }
4237 if(bint > 0) b = true;
4238 CHILD_UPDATED(i);
4239 }
4240 if(!b) return false;
4241 return true;
4242 } else if(m_type == STRUCT_MULTIPLICATION) {
4243 // a*f(x): a * integral of f(x)
4244 MathStructure mstruct;
4245 bool b = false;
4246 for(size_t i = 0; i < SIZE;) {
4247 if(CHILD(i).containsRepresentativeOf(x_var, true, true) == 0) {
4248 if(b) {
4249 mstruct *= CHILD(i);
4250 } else {
4251 mstruct = CHILD(i);
4252 b = true;
4253 }
4254 ERASE(i);
4255 } else {
4256 i++;
4257 }
4258 }
4259 if(b) {
4260 if(SIZE == 1) {
4261 setToChild(1, true);
4262 } else if(SIZE == 0) {
4263 set(mstruct, true);
4264 return true;
4265 }
4266 if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) {
4267 multiply(mstruct);
4268 CANNOT_INTEGRATE_INTERVAL
4269 }
4270 multiply(mstruct);
4271 return true;
4272 }
4273
4274 for(size_t i = 0; i < SIZE; i++) {
4275 if((CHILD(i).isFunction() && CHILD(i).function()->id() == FUNCTION_ID_ABS && CHILD(i).size() == 1) || (CHILD(i).isPower() && CHILD(i)[0].isFunction() && CHILD(i)[0].function()->id() == FUNCTION_ID_ABS && CHILD(i)[0].size() == 1 && CHILD(i)[1].representsOdd())) {
4276 if(definite_integral) CANNOT_INTEGRATE
4277 bool b = (m_type == STRUCT_POWER ? CHILD(0)[0].representsNonComplex(true) : CHILD(0).representsNonComplex(true));
4278 if(!b && !(m_type == STRUCT_POWER ? CHILD(0)[0].representsComplex(true) : CHILD(0).representsComplex(true))) {
4279 MathStructure mtest(m_type == STRUCT_POWER ? CHILD(0)[0] : CHILD(0));
4280 CALCULATOR->beginTemporaryStopMessages();
4281 mtest.eval(eo_t);
4282 CALCULATOR->endTemporaryStopMessages();
4283 b = mtest.representsNonComplex(true);
4284 if(!b && !mtest.representsComplex(true)) {
4285 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4286 CALCULATOR->beginTemporaryStopMessages();
4287 mtest.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4288 mtest.eval(eo_t);
4289 CALCULATOR->endTemporaryStopMessages();
4290 b = mtest.representsNonComplex(true);
4291 if(!b && !mtest.representsComplex(true) && !contains_imaginary(mtest) && !contains_imaginary(((UnknownVariable*) x_var.variable())->interval())) {
4292 CALCULATOR->error(false, "Integral assumed real", NULL);
4293 b = true;
4294 }
4295 } else if(!contains_imaginary(mtest)) {
4296 CALCULATOR->error(false, "Integral assumed real", NULL);
4297 b = true;
4298 }
4299 }
4300 }
4301 if(b) {
4302 MathStructure mmul(CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i));
4303 if(CHILD(i).isPower()) CHILD(i)[0].setToChild(1, true);
4304 else CHILD(i).setToChild(1, true);
4305 mmul.inverse();
4306 mmul *= CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i);
4307 if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) {
4308 multiply(mmul);
4309 CANNOT_INTEGRATE_INTERVAL
4310 }
4311 multiply(mmul);
4312 return true;
4313 }
4314 }
4315 }
4316 } else if((m_type == STRUCT_FUNCTION && o_function->id() == FUNCTION_ID_ABS && SIZE == 1) || (m_type == STRUCT_POWER && CHILD(0).isFunction() && CHILD(0).function()->id() == FUNCTION_ID_ABS && CHILD(0).size() == 1 && CHILD(1).representsOdd())) {
4317 bool b = (m_type == STRUCT_POWER ? CHILD(0)[0].representsNonComplex(true) : CHILD(0).representsNonComplex(true));
4318 if(!b && !(m_type == STRUCT_POWER ? CHILD(0)[0].representsComplex(true) : CHILD(0).representsComplex(true))) {
4319 MathStructure mtest(m_type == STRUCT_POWER ? CHILD(0)[0] : CHILD(0));
4320 CALCULATOR->beginTemporaryStopMessages();
4321 mtest.eval(eo_t);
4322 CALCULATOR->endTemporaryStopMessages();
4323 b = mtest.representsNonComplex(true);
4324 if(!b && !mtest.representsComplex(true)) {
4325 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4326 CALCULATOR->beginTemporaryStopMessages();
4327 mtest.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4328 mtest.eval(eo_t);
4329 CALCULATOR->endTemporaryStopMessages();
4330 b = mtest.representsNonComplex(true);
4331 if(!b && !mtest.representsComplex(true) && !contains_imaginary(mtest) && !contains_imaginary(((UnknownVariable*) x_var.variable())->interval())) {
4332 CALCULATOR->error(false, "Integral assumed real", NULL);
4333 b = true;
4334 }
4335 } else if(!contains_imaginary(mtest)) {
4336 CALCULATOR->error(false, "Integral assumed real", NULL);
4337 b = true;
4338 }
4339 }
4340 }
4341 if(b) {
4342 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4343 if(fix_sgn_x(*this, x_var, eo_t)) recalc = true;
4344 while(true) {
4345 mfound = find_abs_x2(*this, x_var);
4346 if(mfound) {
4347 MathStructure m_interval(*mfound);
4348 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4349 CALCULATOR->beginTemporaryStopMessages();
4350 m_interval.eval(eo_t);
4351 if(!CALCULATOR->endTemporaryStopMessages()) break;
4352 if(m_interval.representsNonNegative(true)) {
4353 replace_abs_x(*this, MathStructure(*mfound), false);
4354 recalc = true;
4355 } else if(m_interval.representsNegative(true)) {
4356 replace_abs_x(*this, MathStructure(*mfound), true);
4357 recalc = true;
4358 } else {
4359 break;
4360 }
4361 } else {
4362 break;
4363 }
4364 }
4365 }
4366 if(m_type == STRUCT_FUNCTION && CHILD(0).isFunction() && (CHILD(0).function()->id() == FUNCTION_ID_SIN || CHILD(0).function()->id() == FUNCTION_ID_COS) && CHILD(0).size() == 1) {
4367 MathStructure madd, mmul, mexp;
4368 if(integrate_info(CHILD(0)[0], x_var, madd, mmul, mexp, true) && mexp.isOne() && madd.isZero()) {
4369 // abs(sin(ax)): 2/a*floor(ax/pi)-1/a*cos(ax-floor(ax/pi)*pi)
4370 // abs(cos(ax)): 2/a*floor(ax/pi+1/2)+1/a*sin(ax-floor(ax/pi+1/2)*pi)
4371 setToChild(1, true);
4372 MathStructure mdivpi(x_var);
4373 if(!mmul.isOne()) mdivpi *= mmul;
4374 mdivpi /= CALCULATOR->getVariableById(VARIABLE_ID_PI);
4375 if(o_function->id() == FUNCTION_ID_COS) mdivpi += nr_half;
4376 mdivpi.transformById(FUNCTION_ID_FLOOR);
4377 if(o_function->id() == FUNCTION_ID_SIN) setFunctionId(FUNCTION_ID_COS);
4378 else setFunctionId(FUNCTION_ID_SIN);
4379 CHILD(0) += mdivpi;
4380 CHILD(0).last() *= CALCULATOR->getVariableById(VARIABLE_ID_PI);
4381 CHILD(0).last() *= CALCULATOR->getRadUnit();
4382 CHILD(0).last().negate();
4383 CHILD(0).childUpdated(CHILD(0).size());
4384 CHILD_UPDATED(0)
4385 if(o_function->id() == FUNCTION_ID_COS) negate();
4386 if(!mmul.isOne()) divide(mmul);
4387 add(mdivpi);
4388 LAST *= nr_two;
4389 if(!mmul.isOne()) LAST /= mmul;
4390 CHILD_UPDATED(SIZE - 1)
4391 return true;
4392 }
4393 }
4394 MathStructure mstruct(m_type == STRUCT_POWER ? CHILD(0) : *this);
4395 if(m_type != STRUCT_POWER || (CHILD(1).isInteger() && !CHILD(1).number().isMinusOne() && CHILD(1).number().isOdd())) {
4396 MathStructure mexp, mmul, madd;
4397 if(integrate_info(m_type == STRUCT_POWER ? CHILD(0)[0] : CHILD(0), x_var, madd, mmul, mexp) && mexp.isOne()) {
4398 MathStructure mpowp1(m_type == STRUCT_POWER ? CHILD(1) : nr_two);
4399 if(m_type == STRUCT_POWER) {
4400 mpowp1 += m_one;
4401 setToChild(1, true);
4402 }
4403 MathStructure msgn(*this);
4404 msgn.setFunctionId(FUNCTION_ID_SIGNUM);
4405 setToChild(1, true);
4406 raise(mpowp1);
4407 divide(mmul);
4408 divide(mpowp1);
4409 multiply(msgn);
4410 return true;
4411 }
4412 }
4413 if(definite_integral) CANNOT_INTEGRATE
4414 MathStructure mmul;
4415 MathStructure mbak(*this);
4416 if(isPower()) {
4417 mmul = CHILD(0);
4418 CHILD(0).setToChild(1, true);
4419 mmul.inverse();
4420 mmul *= CHILD(0);
4421 } else {
4422 mmul = *this;
4423 setToChild(1, true);
4424 mmul.inverse();
4425 mmul *= *this;
4426 }
4427 int b_int = integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts);
4428 if(b_int <= 0) {
4429 set(mbak);
4430 if(b_int < 0) CANNOT_INTEGRATE_INTERVAL
4431 CANNOT_INTEGRATE
4432 }
4433 multiply(mmul);
4434 return true;
4435 }
4436 }
4437 mfound = try_abs ? find_abs_x2(*this, x_var) : NULL;
4438 if(mfound) {
4439 MathStructure mtest(*this);
4440 MathStructure mtest_m(mtest);
4441 if(!replace_abs_x(mtest, *mfound, false) || !replace_abs_x(mtest_m, *mfound, true)) CANNOT_INTEGRATE
4442 eo_t.isolate_x = true;
4443 eo_t.isolate_var = &x_var;
4444 CALCULATOR->beginTemporaryStopMessages();
4445 MathStructure mpos(*mfound);
4446 mpos.transform(COMPARISON_EQUALS_GREATER, m_zero);
4447 mpos.eval(eo_t);
4448 UnknownVariable *var_p = NULL, *var_m = NULL;
4449 if(!CALCULATOR->endTemporaryStopMessages() && mpos.isComparison() && (mpos.comparisonType() == COMPARISON_EQUALS_GREATER || mpos.comparisonType() == COMPARISON_EQUALS_LESS) && mpos[0] == x_var && mpos[1].isNumber()) {
4450 var_p = new UnknownVariable("", format_and_print(x_var));
4451 var_m = new UnknownVariable("", format_and_print(x_var));
4452 Number nr_interval_p, nr_interval_m;
4453 if(x_var.isVariable() && !x_var.variable()->isKnown() && ((UnknownVariable*) x_var.variable())->interval().isNumber() && ((UnknownVariable*) x_var.variable())->interval().number().isInterval() && ((UnknownVariable*) x_var.variable())->interval().number().isReal() && ((UnknownVariable*) x_var.variable())->interval().number().upperEndPoint().isGreaterThanOrEqualTo(mpos[1].number()) && ((UnknownVariable*) x_var.variable())->interval().number().lowerEndPoint().isLessThanOrEqualTo(mpos[1].number())) {
4454 if(mpos.comparisonType() == COMPARISON_EQUALS_GREATER) {
4455 nr_interval_p.setInterval(mpos[1].number(), ((UnknownVariable*) x_var.variable())->interval().number().upperEndPoint());
4456 nr_interval_m.setInterval(((UnknownVariable*) x_var.variable())->interval().number().lowerEndPoint(), mpos[1].number());
4457 } else {
4458 nr_interval_m.setInterval(mpos[1].number(), ((UnknownVariable*) x_var.variable())->interval().number().upperEndPoint());
4459 nr_interval_p.setInterval(((UnknownVariable*) x_var.variable())->interval().number().lowerEndPoint(), mpos[1].number());
4460 }
4461 } else {
4462
4463 if(mpos.comparisonType() == COMPARISON_EQUALS_GREATER) {
4464 nr_interval_p.setInterval(mpos[1].number(), nr_plus_inf);
4465 nr_interval_m.setInterval(nr_minus_inf, mpos[1].number());
4466 } else {
4467 nr_interval_m.setInterval(mpos[1].number(), nr_plus_inf);
4468 nr_interval_p.setInterval(nr_minus_inf, mpos[1].number());
4469 }
4470 }
4471 var_p->setInterval(nr_interval_p);
4472 var_m->setInterval(nr_interval_m);
4473 mtest.replace(x_var, var_p);
4474 mtest_m.replace(x_var, var_m);
4475 }
4476 int bint1 = mtest.integrate(var_p ? var_p : x_var, eo, true, use_abs, true, definite_integral, max_part_depth, parent_parts);
4477 if(var_p) {
4478 mtest.replace(var_p, x_var);
4479 var_p->destroy();
4480 }
4481 if(bint1 <= 0 || mtest.containsFunctionId(FUNCTION_ID_INTEGRATE, true) > 0) {
4482 if(var_m) var_m->destroy();
4483 if(bint1 < 0) CANNOT_INTEGRATE_INTERVAL
4484 CANNOT_INTEGRATE;
4485 }
4486 int bint2 = mtest_m.integrate(var_m ? var_m : x_var, eo, true, use_abs, false, definite_integral, max_part_depth, parent_parts);
4487 if(var_m) {
4488 mtest_m.replace(var_m, x_var);
4489 var_m->destroy();
4490 }
4491 if(bint2 < 0) CANNOT_INTEGRATE_INTERVAL
4492 if(bint2 == 0 || mtest_m.containsFunctionId(FUNCTION_ID_INTEGRATE, true) > 0) CANNOT_INTEGRATE;
4493 MathStructure m1(mtest), m2(mtest_m);
4494 CALCULATOR->beginTemporaryStopMessages();
4495 MathStructure mzero(*mfound);
4496 mzero.transform(COMPARISON_EQUALS, m_zero);
4497 mzero.eval(eo_t);
4498 if(!CALCULATOR->endTemporaryStopMessages() && mzero.isComparison() && mzero.comparisonType() == COMPARISON_EQUALS && mzero[0] == x_var) {
4499 mzero.setToChild(2);
4500 CALCULATOR->beginTemporaryStopMessages();
4501 m1.calculatesub(eo2, eo2, true);
4502 m2.calculatesub(eo2, eo2, true);
4503 m1.evalSort(true, true);
4504 m2.evalSort(true, true);
4505 eo_t.test_comparisons = true;
4506 eo_t.isolate_x = false;
4507 eo_t.isolate_var = NULL;
4508 if((definite_integral && m1.equals(m2, true)) || (!definite_integral && try_sign(m1, m2, *mfound, x_var, mzero, eo_t))) {
4509 set(m1, true);
4510 CALCULATOR->endTemporaryStopMessages(true);
4511 return true;
4512 }
4513 CALCULATOR->endTemporaryStopMessages();
4514 }
4515 /*MathStructure mcmp(*mfound);
4516 mcmp.transform(COMPARISON_EQUALS_GREATER, m_zero);
4517 set(mtest);
4518 multiply(mcmp);
4519 mcmp.setComparisonType(COMPARISON_LESS);
4520 mtest_m *= mcmp;
4521 add(mtest_m);*/
4522 /*eo2.test_comparisons = true;
4523 calculatesub(eo2, eo2, true);*/
4524
4525 ///return true;
4526 }
4527
4528 switch(m_type) {
4529 case STRUCT_UNIT: {}
4530 case STRUCT_NUMBER: {
4531 // a: a*x
4532 multiply(x_var);
4533 break;
4534 }
4535 case STRUCT_POWER: {
4536 if(CHILD(1).isNumber() || CHILD(1).containsRepresentativeOf(x_var, true, true) == 0) {
4537 bool b_minusone = (CHILD(1).isNumber() && CHILD(1).number().isMinusOne());
4538 MathStructure madd, mmul, mmul2, mexp;
4539 if(CHILD(0).isFunction()) {
4540 MathStructure mbase(CHILD(0));
4541 int bint = integrate_function(mbase, x_var, eo, CHILD(1), m_one, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
4542 if(bint < 0) CANNOT_INTEGRATE_INTERVAL
4543 if(bint) {
4544 set(mbase, true);
4545 return true;
4546 }
4547 } else if(integrate_info(CHILD(0), x_var, madd, mmul, mmul2, false, true)) {
4548 if(mmul2.isZero()) {
4549 if(madd.isZero() && mmul.isOne()) {
4550 if(b_minusone) {
4551 // x^-1: ln(x)
4552 if(!transform_absln(CHILD(0), use_abs, definite_integral, x_var, eo)) CANNOT_INTEGRATE_INTERVAL
4553 SET_CHILD_MAP(0);
4554 } else {
4555 // x^a: x^(a+1)/(a+1)
4556 CHILD(1) += m_one;
4557 MathStructure mstruct(CHILD(1));
4558 divide(mstruct);
4559 }
4560 return true;
4561 } else if(b_minusone) {
4562 // (ax+b)^-1: ln(ax+b)/a
4563 if(!transform_absln(CHILD(0), use_abs, definite_integral, x_var, eo)) CANNOT_INTEGRATE_INTERVAL
4564 SET_CHILD_MAP(0);
4565 if(!mmul.isOne()) divide(mmul);
4566 return true;
4567 } else {
4568 if(definite_integral && !madd.isZero() && (!x_var.representsNonComplex(true) || !mmul.representsNonComplex(true)) && !CHILD(1).representsInteger() && COMPARISON_MIGHT_BE_EQUAL(x_var.compare(m_zero)) && !COMPARISON_IS_EQUAL_OR_LESS(madd.compare(m_zero))) CANNOT_INTEGRATE
4569 // (ax+b)^c: (ax+b)^(c+1)/(a(c+1))
4570 mexp = CHILD(1);
4571 mexp += m_one;
4572 SET_CHILD_MAP(0);
4573 raise(mexp);
4574 if(!mmul.isOne()) mexp *= mmul;
4575 divide(mexp);
4576 return true;
4577 }
4578 } else if(mmul.isZero() && !madd.isZero() && CHILD(1).number().denominatorIsTwo()) {
4579 MathStructure mmulsqrt2(mmul2);
4580 if(!mmul2.isOne()) mmulsqrt2 ^= nr_half;
4581 Number num(CHILD(1).number().numerator());
4582 if(num.isOne()) {
4583 // sqrt(ax^2+b): (ln(sqrt(ax^2+b)+x*sqrt(a))*b+sqrt(a)*b*sqrt(ax^2+b))/(2*sqrt(a))
4584 MathStructure mthis(*this);
4585 add(x_var);
4586 if(!mmul2.isOne()) LAST *= mmulsqrt2;
4587 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mthis); CANNOT_INTEGRATE_INTERVAL}
4588 multiply(madd);
4589 mthis *= x_var;
4590 if(!mmul2.isOne()) mthis *= mmulsqrt2;
4591 add(mthis);
4592 multiply(nr_half);
4593 if(!mmul2.isOne()) divide(mmulsqrt2);
4594 childrenUpdated(true);
4595 return true;
4596 } else if(num == 3) {
4597 // (ax^2+b)^(3/2):
4598 // (ln(sqrt(ax^2+b)+x*sqrt(a))*b^2*3/8+(ax^2+b)^(3/2)*x*sqrt(a)/4+sqrt(ax^2+b)*x*sqrt(a)*b*3/8)/sqrt(a)
4599 MathStructure mterm3(*this);
4600 CHILD(1).number().set(1, 2, 0, true);
4601 MathStructure mterm2(*this);
4602 add(x_var);
4603 if(!mmul2.isOne()) LAST *= mmulsqrt2;
4604 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mterm3); CANNOT_INTEGRATE_INTERVAL}
4605 multiply(madd);
4606 LAST ^= nr_two;
4607 multiply(Number(3, 8, 0), true);
4608 mterm2 *= x_var;
4609 if(!mmul2.isOne()) mterm2 *= mmulsqrt2;
4610 mterm2 *= madd;
4611 mterm2 *= Number(3, 8, 0);
4612 mterm3 *= x_var;
4613 if(!mmul2.isOne()) mterm3 *= mmulsqrt2;
4614 mterm3 *= Number(1, 4, 0);
4615 add(mterm2);
4616 add(mterm3);
4617 if(!mmul2.isOne()) divide(mmulsqrt2);
4618 return true;
4619 } else if(num == 5) {
4620 // (ax^2+b)^(5/2):
4621 // sqrt(ax^2+b)*x^5*a^2/6+ln(sqrt(ax^2+b)*sqrt(a)+ax)*b^3/sqrt(a)*5/16+sqrt(ax^2+b)*x*b^2*11/16+sqrt(ax^2+b)*x^3*b*a*13/24
4622 CHILD(1).number().set(1, 2, 0, true);
4623 MathStructure mterm2(*this);
4624 MathStructure mterm3(*this);
4625 MathStructure mterm4(*this);
4626 multiply(x_var);
4627 LAST ^= Number(5, 1);
4628 if(!mmul2.isOne()) {
4629 multiply(mmul2, true);
4630 LAST ^= nr_two;
4631 }
4632 multiply(Number(1, 6), true);
4633 if(!mmul2.isOne()) mterm2 *= mmulsqrt2;
4634 mterm2 += x_var;
4635 if(!mmul2.isOne()) mterm2.last() *= mmul2;
4636 if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mterm3); CANNOT_INTEGRATE_INTERVAL}
4637 mterm2 *= madd;
4638 mterm2.last() ^= nr_three;
4639 if(!mmul2.isOne()) mterm2 /= mmulsqrt2;
4640 mterm2 *= Number(5, 16);
4641 mterm3 *= x_var;
4642 mterm3 *= madd;
4643 mterm3.last() ^= nr_two;
4644 mterm3 *= Number(11, 16);
4645 mterm4 *= x_var;
4646 mterm4.last() ^= nr_three;
4647 mterm4 *= madd;
4648 if(!mmul2.isOne()) mterm4 *= mmul2;
4649 mterm4 *= Number(13, 24);
4650 add(mterm2);
4651 add(mterm3);
4652 add(mterm4);
4653 childrenUpdated(true);
4654 return true;
4655 } else if(num.isMinusOne()) {
4656 // 1/sqrt(ax^2+b): ln(sqrt(ax^2+b)*sqrt(a)+ax)/sqrt(a)
4657 MathStructure mbak(*this);
4658 CHILD(1).number().set(1, 2, 0, true);
4659 if(!mmul2.isOne()) multiply(mmulsqrt2);
4660 add(x_var);
4661 if(!mmul2.isOne()) LAST.multiply(mmul2);
4662 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
4663 if(!mmul2.isOne()) divide(mmulsqrt2);
4664 return true;
4665 } else if(num == -3) {
4666 // (ax^2+b)^(-3/2): x/(b*sqrt(ax^2+b))
4667 CHILD(1).number().set(-1, 2, 0, true);
4668 madd.inverse();
4669 multiply(madd);
4670 multiply(x_var);
4671 return true;
4672 } else if(num == -5) {
4673 // (ax^2+b)^(-5/2): (x(2ax^2+3b)/(3b^2*(ax^2+b)^(3/2))
4674 CHILD(1).number().set(-3, 2, 0, true);
4675 mmul = x_var;
4676 mmul ^= nr_two;
4677 if(!mmul2.isOne()) mmul *= mmul2;
4678 mmul *= nr_two;
4679 mmul += madd;
4680 mmul.last() *= nr_three;
4681 multiply(mmul);
4682 multiply(x_var);
4683 multiply(madd);
4684 LAST ^= Number(-2, 1);
4685 multiply(Number(1, 3));
4686 return true;
4687 }
4688 } else if(b_minusone) {
4689 // 1/(ax^2+bx+c)
4690 // y=4ac-b^2
4691 MathStructure m4acmb2(madd);
4692 m4acmb2 *= mmul2;
4693 m4acmb2 *= Number(4, 1);
4694 m4acmb2 += mmul;
4695 m4acmb2.last() ^= nr_two;
4696 m4acmb2.last().negate();
4697 m4acmb2.calculatesub(eo, eo, true);
4698 if(!m4acmb2.representsNonZero(true)) {
4699 if(m4acmb2.isZero()) {
4700 // y=0: -2/(2ax+b)
4701 set(x_var, true);
4702 multiply(mmul2);
4703 multiply(nr_two, true);
4704 add(mmul);
4705 inverse();
4706 multiply(Number(-2, 1));
4707 return true;
4708 } else if(!warn_about_denominators_assumed_nonzero(m4acmb2, eo)) {
4709 CANNOT_INTEGRATE
4710 }
4711 }
4712 if(m4acmb2.representsNegative(true)) {
4713 // y<0: ln((2ax+b-sqrt(-4ac+b^2))/(2ax+b+sqrt(-4ac+b^2)))/sqrt(-4ac+b^2)
4714 MathStructure mbak(*this);
4715 MathStructure m2axpb(x_var);
4716 m2axpb *= mmul2;
4717 m2axpb *= nr_two;
4718 m2axpb += mmul;
4719 MathStructure mb2m4ac(madd);
4720 mb2m4ac *= mmul2;
4721 mb2m4ac *= Number(-4, 1);
4722 mb2m4ac += mmul;
4723 mb2m4ac.last() ^= nr_two;
4724 mb2m4ac ^= nr_half;
4725 set(m2axpb);
4726 subtract(mb2m4ac);
4727 multiply(m2axpb);
4728 LAST += mb2m4ac;
4729 LAST ^= nr_minus_one;
4730 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
4731 divide(mb2m4ac);
4732 return true;
4733 }
4734 // y!=0: 2y*atan((2ax+b)/y^2)
4735 m4acmb2 ^= Number(-1, 2);
4736 set(x_var, true);
4737 multiply(mmul2);
4738 multiply(nr_two, true);
4739 add(mmul);
4740 multiply(m4acmb2);
4741 transformById(FUNCTION_ID_ATAN);
4742 multiply(nr_two);
4743 multiply(m4acmb2, true);
4744 return true;
4745 } else if(CHILD(1).isInteger() && CHILD(1).number().isNegative()) {
4746 // (ax^2+bx+c)^(-n): integral of (ax^2+bx+c)^(-n+1)*(-2a*(-2n+3)*c*a*4+1/(b^(2)*(n-1)))+(2ax+b)*c*a*4+1/b^(2)(ax^2+bx+c)^(-n+1)/(n-1)
4747 MathStructure m2nm3(CHILD(1));
4748 m2nm3 *= nr_two;
4749 m2nm3 += Number(3, 1);
4750 CHILD(1).number()++;
4751 MathStructure mnp1(CHILD(1));
4752 mnp1.number().negate();
4753 mnp1.number().recip();
4754 MathStructure mthis(*this);
4755 if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
4756 MathStructure m4acmb2(madd);
4757 m4acmb2 *= mmul2;
4758 m4acmb2 *= Number(4, 1);
4759 m4acmb2 += mmul;
4760 m4acmb2.last() ^= nr_two;
4761 m4acmb2.last().negate();
4762 m4acmb2.inverse();
4763 MathStructure mfac1(mmul2);
4764 mfac1 *= Number(-2, 1);
4765 mfac1 *= m2nm3;
4766 mfac1 *= mnp1;
4767 mfac1 *= m4acmb2;
4768 multiply(mfac1);
4769 MathStructure mterm2(x_var);
4770 mterm2 *= mmul2;
4771 mterm2 *= nr_two;
4772 mterm2 += mmul;
4773 mterm2 *= m4acmb2;
4774 mterm2 *= mthis;
4775 mterm2 *= mnp1;
4776 add(mterm2);
4777 return true;
4778 }
4779 } else if(integrate_info(CHILD(0), x_var, madd, mmul, mexp, false, false)) {
4780 if(madd.isZero() && !b_minusone) {
4781 // (ax^b)^n (n != -1): (ax^b)^n*x/(b*n+1)
4782 MathStructure mden(mexp);
4783 mden *= CHILD(1);
4784 mden += m_one;
4785 multiply(x_var);
4786 divide(mden);
4787 return true;
4788 } else if(b_minusone && mexp.isNumber() && mexp.number().isNegative() && mexp.number().isInteger()) {
4789 if(!madd.isZero()) {
4790 // 1/(ax^(-n)+b): integral of 1/(x^n*b+a)*x^n
4791 Number nexp(mexp.number());
4792 nexp.negate();
4793 MathStructure mtest(x_var);
4794 mtest ^= nexp;
4795 mtest *= madd;
4796 mtest += mmul;
4797 mtest.inverse();
4798 mtest *= x_var;
4799 mtest.last() ^= nexp;
4800 CALCULATOR->beginTemporaryStopMessages();
4801 if(mtest.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
4802 CALCULATOR->endTemporaryStopMessages(true);
4803 set(mtest, true);
4804 return true;
4805 }
4806 CALCULATOR->endTemporaryStopMessages();
4807 }
4808 } else if(mexp.isNumber() && mexp.number().isRational() && !mexp.number().isInteger()) {
4809 // (ax^(n/d)+b)^c:
4810 // integral of (ay^(n=-1?1:n)+b)^c*(y^(sgn(n)/d))^(sgn(n)*d-1) where y=x^(sgn(n)/d) and divide with sgn(n)*d
4811 Number num(mexp.number().numerator());
4812 Number den(mexp.number().denominator());
4813 MathStructure morig(x_var);
4814 if(num.isNegative()) den.negate();
4815 Number den_inv(den);
4816 den_inv.recip();
4817 morig ^= den_inv;
4818 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
4819 Number den_m1(den);
4820 den_m1--;
4821 MathStructure mtest(var);
4822 if(!num.isOne() && !num.isMinusOne()) mtest ^= num;
4823 if(!mmul.isOne()) mtest *= mmul;
4824 if(!madd.isZero()) mtest += madd;
4825 mtest ^= CHILD(1);
4826 mtest *= var;
4827 if(!den_m1.isOne()) {
4828 mtest.last() ^= den_m1;
4829 mtest.childUpdated(mtest.size());
4830 }
4831 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4832 MathStructure m_interval(morig);
4833 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4834 var->setInterval(m_interval);
4835 } else {
4836 var->setInterval(morig);
4837 }
4838 CALCULATOR->beginTemporaryStopMessages();
4839 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
4840 CALCULATOR->endTemporaryStopMessages(true);
4841 set(mtest, true);
4842 replace(var, morig);
4843 multiply(den);
4844 var->destroy();
4845 return true;
4846 }
4847 CALCULATOR->endTemporaryStopMessages();
4848 var->destroy();
4849 }
4850 } else if(integrate_info(CHILD(0), x_var, madd, mmul, mexp, false, false, true) && !madd.isZero()) {
4851 if(mexp.isFunction()) {
4852 // (a*f(x)+b)^c
4853 MathStructure mfunc(mexp);
4854 int bint = integrate_function(mfunc, x_var, eo, CHILD(1), m_one, madd, mmul, use_abs, definite_integral, max_part_depth, parent_parts);
4855 if(bint < 0) CANNOT_INTEGRATE_INTERVAL
4856 if(bint) {
4857 set(mfunc, true);
4858 return true;
4859 }
4860 } else if(mexp.isPower() && mexp[1].containsRepresentativeOf(x_var, true, true) == 0) {
4861 MathStructure mbase(mexp[0]);
4862 if(integrate_info(mbase, x_var, madd, mmul, mexp, false, false) && mexp.isOne() && (!madd.isZero() || !mmul.isOne())) {
4863 // ((ax^c1+b)^c2+b2)^c3: integral of (y^c2+b^2)^c3 where y=ax^c1+b and divide with a
4864 MathStructure mtest(*this);
4865
4866 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mbase) + RIGHT_PARENTHESIS);
4867 mtest.replace(mbase, var, mbase.containsInterval());
4868 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
4869 MathStructure m_interval(mbase);
4870 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
4871 var->setInterval(m_interval);
4872 } else {
4873 var->setInterval(mbase);
4874 }
4875 CALCULATOR->beginTemporaryStopMessages();
4876 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
4877 CALCULATOR->endTemporaryStopMessages(true);
4878 set(mtest, true);
4879 replace(var, mbase);
4880 if(!mmul.isOne()) divide(mmul);
4881 var->destroy();
4882 return true;
4883 }
4884 CALCULATOR->endTemporaryStopMessages();
4885 var->destroy();
4886 }
4887 }
4888 }
4889 if(CHILD(0).isAddition()) {
4890 MathStructure mtest(*this);
4891 // factor base
4892 if(mtest[0].factorize(eo, false, 0, 0, false, false, NULL, x_var)) {
4893 mmul = m_one;
4894 while(mtest[0].isMultiplication() && mtest[0].size() >= 2 && mtest[0][0].containsRepresentativeOf(x_var, true, true) == 0) {
4895 MathStructure *mchild = &mtest[0][0];
4896 mchild->ref();
4897 mtest[0].delChild(1, true);
4898 if(mtest[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[0].compare(m_zero))) {
4899 if(mmul.isOne()) mmul = *mchild;
4900 else mmul *= *mchild;
4901 mchild->unref();
4902 } else {
4903 mtest[0].multiply_nocopy(mchild, true);
4904 }
4905 }
4906 if(!mmul.isOne()) {
4907 mmul ^= mtest[1];
4908 }
4909 MathStructure mtest2(mtest);
4910 if(mtest2.decomposeFractions(x_var, eo) && mtest2.isAddition()) {
4911 bool b = true;
4912 CALCULATOR->beginTemporaryStopMessages();
4913 for(size_t i = 0; i < mtest2.size(); i++) {
4914 if(mtest2[i].integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) <= 0) {
4915 b = false;
4916 break;
4917 }
4918 }
4919 CALCULATOR->endTemporaryStopMessages(b);
4920 if(b) {
4921 set(mtest2, true);
4922 if(!mmul.isOne()) multiply(mmul);
4923 return true;
4924 }
4925 }
4926 MathStructure mmul2(1, 1, 0);
4927 if(mtest[0].isMultiplication() && mtest[0].size() >= 2 && !mtest[0][0].isAddition()) {
4928 MathStructure *mchild = &mtest[0][0];
4929 mchild->ref();
4930 mtest[0].delChild(1, true);
4931 if(mtest[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[0].compare(m_zero))) {
4932 mmul2 = *mchild;
4933 mmul2.calculateRaise(mtest[1], eo2);
4934 mchild->unref();
4935 } else {
4936 mtest[0].multiply_nocopy(mchild, true);
4937 }
4938 }
4939 if(mtest[0].isPower()) {
4940 if(mtest[1].representsInteger() || mtest[0][1].representsFraction() || COMPARISON_IS_EQUAL_OR_LESS(mtest[0][0].compare(m_zero))) {
4941 mtest[1].calculateMultiply(mtest[0][1], eo2);
4942 mtest[0].setToChild(1);
4943 } else if(mtest[0][1].representsEven()) {
4944 if(COMPARISON_IS_EQUAL_OR_GREATER(mtest[0][0].compare(m_zero))) {
4945 mtest[1].calculateMultiply(mtest[0][1], eo2);
4946 mtest[0].setToChild(1);
4947 mtest[0].calculateNegate(eo2);
4948 } else if(!definite_integral && mtest[0][0].representsReal(true)) {
4949 mtest[1].calculateMultiply(mtest[0][1], eo2);
4950 mtest[0].setToChild(1);
4951 mtest[0].transformById(FUNCTION_ID_ABS);
4952 }
4953 }
4954 }
4955 mtest[0].evalSort(false);
4956 if(!mmul2.isOne()) {
4957 mtest *= mmul2;
4958 mtest.evalSort(false);
4959 }
4960 CALCULATOR->beginTemporaryStopMessages();
4961 if(mtest.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
4962 CALCULATOR->endTemporaryStopMessages(true);
4963 set(mtest, true);
4964 if(!mmul.isOne()) multiply(mmul);
4965 return true;
4966 }
4967 CALCULATOR->endTemporaryStopMessages();
4968 }
4969 }
4970 } else if((CHILD(0).isNumber() && !CHILD(0).number().isOne()) || (!CHILD(0).isNumber() && CHILD(0).containsRepresentativeOf(x_var, true, true) == 0)) {
4971 MathStructure madd, mmul, mmul2, mexp;
4972 if(integrate_info(CHILD(1), x_var, madd, mmul, mexp)) {
4973 if(mexp.isOne()) {
4974 if(CHILD(0).isVariable() && CHILD(0).variable()->id() == VARIABLE_ID_E) {
4975 // e^(ax+b): e^(ax+b)/a
4976 if(!mmul.isOne()) divide(mmul);
4977 return true;
4978 } else if(CHILD(0).isNumber() || warn_about_assumed_not_value(CHILD(0), m_one, eo)) {
4979 // c^(ax+b): c^(ax+b)/(a*ln(c))
4980 MathStructure mmulfac(CHILD(0));
4981 mmulfac.transformById(FUNCTION_ID_LOG);
4982 if(!mmul.isOne()) mmulfac *= mmul;
4983 divide(mmulfac);
4984 return true;
4985 }
4986 } else if(madd.isZero() || COMPARISON_IS_NOT_EQUAL(madd.compare(m_zero))) {
4987 if(mmul.representsPositive(true) && COMPARISON_IS_EQUAL_OR_GREATER(CHILD(0).compare(m_one)) && CHILD(0).compare(m_zero) == COMPARISON_RESULT_LESS) {
4988 madd.negate();
4989 mmul.negate();
4990 CHILD(0).inverse();
4991 }
4992 if(mexp == nr_two) {
4993 if(!madd.isZero()) {madd ^= CHILD(0); madd.swapChildren(1, 2);}
4994 bool mmul_neg = mmul.representsNegative(true);
4995 if(mmul_neg) mmul.negate();
4996 if(CHILD(0).isVariable() && CHILD(0).variable()->id() == VARIABLE_ID_E) {
4997 set(mmul);
4998 if(!mmul.isOne()) raise(nr_half);
4999 multiply(x_var);
5000 if(!mmul_neg) multiply(nr_one_i);
5001 transformById(FUNCTION_ID_ERF);
5002 if(!mmul.isOne()) {
5003 mmul ^= Number(-1, 2);
5004 multiply(mmul);
5005 }
5006 multiply(CALCULATOR->getVariableById(VARIABLE_ID_PI));
5007 LAST ^= nr_half;
5008 multiply(nr_half);
5009 if(!mmul_neg) multiply(nr_minus_i);
5010 } else {
5011 MathStructure mlog(CHILD(0));
5012 mlog.transformById(FUNCTION_ID_LOG);
5013 mlog ^= nr_half;
5014 set(mmul);
5015 if(!mmul.isOne()) raise(nr_half);
5016 multiply(x_var);
5017 multiply(mlog);
5018 if(!mmul_neg) multiply(nr_one_i);
5019 transformById(FUNCTION_ID_ERF);
5020 if(!mmul.isOne()) {
5021 mmul ^= Number(-1, 2);
5022 multiply(mmul);
5023 }
5024 multiply(CALCULATOR->getVariableById(VARIABLE_ID_PI));
5025 LAST ^= nr_half;
5026 multiply(nr_half);
5027 if(!mmul_neg) multiply(nr_minus_i);
5028 divide(mlog);
5029 }
5030 if(!madd.isZero()) multiply(madd);
5031 return true;
5032 } else if(mexp.isNumber() && mexp.number().isRational() && !mexp.isInteger()) {
5033 Number num(mexp.number().numerator());
5034 Number den(mexp.number().denominator());
5035 MathStructure morig(x_var);
5036 Number den_inv(den);
5037 den_inv.recip();
5038 morig ^= den_inv;
5039
5040 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
5041 MathStructure mvar(var);
5042 if(!num.isOne()) mvar ^= num;
5043 MathStructure mtest(CHILD(0));
5044 mtest ^= mvar;
5045 if(!mmul.isOne()) mtest.last() *= mmul;
5046 if(!madd.isZero()) mtest.last() += madd;
5047 mtest.childUpdated(mtest.size());
5048 Number npow(den);
5049 npow--;
5050 mtest *= var;
5051 if(!npow.isOne()) mtest.last() ^= npow;
5052 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5053 MathStructure m_interval(morig);
5054 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5055 var->setInterval(m_interval);
5056 } else {
5057 var->setInterval(morig);
5058 }
5059 CALCULATOR->beginTemporaryStopMessages();
5060 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5061 CALCULATOR->endTemporaryStopMessages(true);
5062 set(mtest, true);
5063 replace(var, morig);
5064 multiply(den);
5065 var->destroy();
5066 return true;
5067 }
5068 CALCULATOR->endTemporaryStopMessages();
5069 var->destroy();
5070 }
5071 // a^(b+cx^d): -x*a^b*(-c*x^d*ln(a))^(-1/d)*igamma(1/d, -c*x^d*ln(a))/d
5072 if(definite_integral) CANNOT_INTEGRATE
5073 if(!madd.isZero()) {madd ^= CHILD(0); madd.swapChildren(1, 2);}
5074 MathStructure mexpinv(mexp);
5075 mexpinv.inverse();
5076 MathStructure marg2(CHILD(0));
5077 marg2.transformById(FUNCTION_ID_LOG);
5078 marg2 *= x_var;
5079 marg2.last() ^= mexp;
5080 marg2 *= mmul;
5081 marg2.negate();
5082 set(CALCULATOR->getFunctionById(FUNCTION_ID_I_GAMMA), &mexpinv, &marg2, NULL);
5083 if(!madd.isZero()) multiply(madd);
5084 multiply(x_var);
5085 multiply(mexpinv);
5086 mexpinv.negate();
5087 multiply(marg2);
5088 LAST ^= mexpinv;
5089 negate();
5090 return true;
5091 }
5092 } else if(integrate_info(CHILD(1), x_var, madd, mmul, mmul2, false, true)) {
5093 // a^(bx-cx^2+d): sqrt(pi)*a^(b^2/(4c)+d)*erf(sqrt(ln(a))*(2cx-b)/(2*sqrt(c)))/(2*sqrt(c)*sqrt(ln(a))
5094 MathStructure sqrt2(1, 1, 0);
5095 if(mmul2.isMinusOne()) {
5096 mmul2 = m_one;
5097 } else {
5098 mmul2.negate();
5099 sqrt2 = mmul2;
5100 sqrt2 ^= Number(-1, 2);
5101 }
5102 MathStructure loga(1, 1, 0);
5103 if(CHILD(0) != CALCULATOR->getVariableById(VARIABLE_ID_E)) {loga = CHILD(0); loga.transformById(FUNCTION_ID_LOG);}
5104 loga ^= nr_half;
5105 MathStructure merf(x_var);
5106 if(!mmul2.isOne()) merf *= mmul2;
5107 merf *= nr_two;
5108 merf -= mmul;
5109 if(!loga.isOne()) merf *= loga;
5110 merf *= nr_half;
5111 if(!sqrt2.isOne()) merf *= sqrt2;
5112 merf.transformById(FUNCTION_ID_ERF);
5113 MathStructure mapow(mmul);
5114 if(!mapow.isOne()) mapow ^= nr_two;
5115 mapow *= Number(1, 4);
5116 if(!mmul2.isOne()) mapow /= mmul2;
5117 if(!madd.isZero()) mapow += madd;
5118 SET_CHILD_MAP(0)
5119 raise(mapow);
5120 multiply(merf);
5121 multiply(CALCULATOR->getVariableById(VARIABLE_ID_PI));
5122 LAST ^= nr_half;
5123 if(!sqrt2.isOne()) multiply(sqrt2);
5124 if(!loga.isOne()) divide(loga);
5125 multiply(nr_half);
5126 return true;
5127 }
5128 }
5129 CANNOT_INTEGRATE
5130 }
5131 case STRUCT_FUNCTION: {
5132 MathStructure mfunc(*this);
5133 int bint = integrate_function(mfunc, x_var, eo, m_one, m_one, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
5134 if(bint < 0) CANNOT_INTEGRATE_INTERVAL
5135 if(!bint) CANNOT_INTEGRATE
5136 set(mfunc, true);
5137 break;
5138 }
5139 case STRUCT_MULTIPLICATION: {
5140 if(combine_powers(*this, x_var, eo2) && m_type != STRUCT_MULTIPLICATION) return integrate(x_var, eo, false, use_abs, definite_integral, try_abs, max_part_depth, parent_parts);
5141 if(SIZE == 2) {
5142 if(CHILD(0) != x_var && (CHILD(1) == x_var || (CHILD(1).isPower() && CHILD(1)[0] == x_var))) SWAP_CHILDREN(0, 1);
5143 if(CHILD(1).isPower() && CHILD(1)[1].containsRepresentativeOf(x_var, true, true) == 0) {
5144 MathStructure madd, mmul, mmul2;
5145 MathStructure mexp(CHILD(1)[1]);
5146 if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mmul2, false, true)) {
5147 if(mmul2.isZero() && mexp.isNumber()) {
5148 if(CHILD(0) == x_var) {
5149 MathStructure mbak(*this);
5150 SET_CHILD_MAP(1)
5151 SET_CHILD_MAP(0)
5152 if(mexp.number().isMinusOne()) {
5153 MathStructure mterm(x_var);
5154 if(!mmul.isOne()) mterm /= mmul;
5155 if(!madd.isZero()) {
5156 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5157 multiply(madd);
5158 if(!mmul.isOne()) {
5159 MathStructure a2(mmul);
5160 a2 ^= nr_two;
5161 divide(a2);
5162 }
5163 negate();
5164 add(mterm);
5165 } else {
5166 set(mterm, true);
5167 }
5168 } else if(mexp.number() == -2) {
5169 MathStructure mterm(*this);
5170 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5171 MathStructure a2(mmul);
5172 if(!mmul.isOne()) {
5173 a2 ^= nr_two;
5174 divide(a2);
5175 }
5176 if(!madd.isZero()) {
5177 if(!mmul.isOne()) mterm *= a2;
5178 mterm.inverse();
5179 mterm *= madd;
5180 }
5181 add(mterm);
5182 } else if(mexp.number().isNegative()) {
5183 MathStructure onemn(1, 1, 0);
5184 onemn += mexp;
5185 MathStructure nm1(mexp);
5186 nm1.negate();
5187 MathStructure nm2(nm1);
5188 nm1 += nr_minus_one;
5189 nm2 += Number(-2, 1);
5190 raise(nm1);
5191 multiply(nm2);
5192 multiply(nm1);
5193 if(!mmul.isOne()) {
5194 MathStructure a2(mmul);
5195 a2 ^= nr_two;
5196 multiply(a2);
5197 }
5198 inverse();
5199 MathStructure mnum(x_var);
5200 mnum *= onemn;
5201 if(!mmul.isOne()) mnum *= mmul;
5202 if(!madd.isZero()) mnum -= madd;
5203 multiply(mnum);
5204 } else {
5205 MathStructure nm1(mexp);
5206 nm1 += m_one;
5207 raise(nm1);
5208 MathStructure mnum(x_var);
5209 mnum *= nm1;
5210 if(!mmul.isOne()) mnum *= mmul;
5211 mnum -= madd;
5212 MathStructure mden(mexp);
5213 mden += nr_two;
5214 mden *= nm1;
5215 if(!mmul.isOne()) {
5216 mden *= mmul;
5217 mden.last() ^= nr_two;
5218 }
5219 multiply(mnum);
5220 divide(mden);
5221 return true;
5222 }
5223 return true;
5224 } else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1] == nr_two) {
5225 MathStructure mbak(*this);
5226 SET_CHILD_MAP(1)
5227 SET_CHILD_MAP(0)
5228 if(mexp.number().isMinusOne()) {
5229 MathStructure mterm(x_var);
5230 mterm ^= nr_two;
5231 if(!mmul.isOne()) mterm *= mmul;
5232 if(!madd.isZero()) {
5233 MathStructure mtwobx(-2 ,1, 0);
5234 mtwobx *= madd;
5235 mtwobx *= x_var;
5236 mterm += mtwobx;
5237 }
5238 if(!mmul.isOne()) {
5239 MathStructure a2(mmul);
5240 a2 ^= nr_two;
5241 a2 *= nr_two;
5242 mterm /= a2;
5243 } else {
5244 mterm /= nr_two;
5245 }
5246 if(!madd.isZero()) {
5247 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5248 MathStructure b2(madd);
5249 b2 ^= nr_two;
5250 multiply(b2);
5251 if(!mmul.isOne()) {
5252 MathStructure a3(mmul);
5253 a3 ^= nr_three;
5254 divide(a3);
5255 }
5256 add(mterm);
5257 } else {
5258 set(mterm, true);
5259 }
5260 } else if(mexp.number() == -2) {
5261 MathStructure mterm1(x_var);
5262 if(!mmul.isOne()) mterm1 *= mmul;
5263 if(!madd.isZero()) {
5264 MathStructure mterm2(*this);
5265 if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5266 mterm2 *= madd;
5267 mterm2 *= -2;
5268 MathStructure mterm3(*this);
5269 mterm3.inverse();
5270 madd ^= nr_two;
5271 mterm3 *= madd;
5272 mterm3.negate();
5273 set(mterm1);
5274 add(mterm2);
5275 add(mterm3);
5276 } else {
5277 set(mterm1);
5278 }
5279 if(!mmul.isOne()) {
5280 MathStructure a3(mmul);
5281 a3 ^= nr_three;
5282 divide(a3);
5283 }
5284 } else if(mexp.number() == -3) {
5285 if(!madd.isZero()) {
5286 MathStructure mterm2(*this);
5287 mterm2.inverse();
5288 mterm2 *= madd;
5289 mterm2 *= nr_two;
5290 MathStructure mterm3(*this);
5291 mterm3 ^= nr_two;
5292 mterm3 *= nr_two;
5293 mterm3.inverse();
5294 madd ^= nr_two;
5295 mterm3 *= madd;
5296 mterm3.negate();
5297 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5298 add(mterm2);
5299 add(mterm3);
5300 } else {
5301 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5302 }
5303 if(!mmul.isOne()) {
5304 MathStructure a3(mmul);
5305 a3 ^= nr_three;
5306 divide(a3);
5307 }
5308 } else {
5309 MathStructure mterm2(*this);
5310 MathStructure mterm3(*this);
5311 raise(nr_three);
5312 CHILD(1) += mexp;
5313 MathStructure mden(mexp);
5314 mden += nr_three;
5315 divide(mden);
5316 if(!madd.isZero()) {
5317 mterm2 ^= nr_two;
5318 mterm2[1] += mexp;
5319 mterm2 *= madd;
5320 mterm2 *= -2;
5321 mden = mexp;
5322 mden += nr_two;
5323 mterm2 /= mden;
5324 mterm3 ^= m_one;
5325 mterm3[1] += mexp;
5326 madd ^= nr_two;
5327 mterm3 *= madd;
5328 mden = mexp;
5329 mden += m_one;
5330 mterm3 /= mden;
5331 add(mterm2);
5332 add(mterm3);
5333 }
5334 if(!mmul.isOne()) {
5335 MathStructure a3(mmul);
5336 a3 ^= nr_three;
5337 divide(a3);
5338 }
5339 }
5340 return true;
5341 } else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1] == nr_minus_one && !madd.isZero()) {
5342 if(mexp.number().isMinusOne()) {
5343 MathStructure mbak(*this);
5344 SET_CHILD_MAP(1)
5345 SET_CHILD_MAP(0)
5346 divide(x_var);
5347 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5348 divide(madd);
5349 negate();
5350 return true;
5351 }
5352 } else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1] == -2 && !madd.isZero()) {
5353 if(mexp.number().isMinusOne()) {
5354 MathStructure mbak(*this);
5355 SET_CHILD_MAP(1)
5356 SET_CHILD_MAP(0)
5357 divide(x_var);
5358 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5359 MathStructure madd2(madd);
5360 madd2 ^= nr_two;
5361 divide(madd2);
5362 if(!mmul.isOne()) multiply(mmul);
5363 madd *= x_var;
5364 madd.inverse();
5365 subtract(madd);
5366 return true;
5367 } else if(mexp.number() == -2) {
5368 MathStructure mbak(*this);
5369 SET_CHILD_MAP(1)
5370 SET_CHILD_MAP(0)
5371 MathStructure mterm2(madd);
5372 mterm2 ^= nr_two;
5373 MathStructure mterm3(mterm2);
5374 mterm2 *= *this;
5375 mterm2.inverse();
5376 divide(x_var);
5377 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5378 MathStructure madd3(madd);
5379 madd3 ^= nr_three;
5380 divide(madd3);
5381 multiply(Number(-2, 1, 0));
5382 mterm3 *= x_var;
5383 if(!mmul.isOne()) mterm3 *= mmul;
5384 mterm3.inverse();
5385 add(mterm2);
5386 add(mterm3);
5387 mmul.negate();
5388 multiply(mmul);
5389 return true;
5390 }
5391 }
5392 } else if(mmul.isZero() && !madd.isZero() && mexp.isNumber() && mexp.number().denominatorIsTwo()) {
5393 Number num(mexp.number());
5394 if(CHILD(0) == x_var) {
5395 num.add(1);
5396 SET_CHILD_MAP(1)
5397 SET_CHILD_MAP(0)
5398 raise(num);
5399 num.multiply(2);
5400 num.recip();
5401 multiply(num);
5402 if(!mmul2.isOne()) divide(mmul2);
5403 return true;
5404 } else if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isInteger()) {
5405 if(CHILD(0)[1].number() == 2) {
5406 if(num == nr_half) {
5407 MathStructure mbak(*this);
5408 SET_CHILD_MAP(1)
5409 MathStructure mterm2(*this);
5410 if(!mmul2.isOne()) {
5411 mterm2 *= mmul2;
5412 mterm2.last() ^= nr_half;
5413 }
5414 mterm2 += x_var;
5415 if(!mmul2.isOne()) mterm2.last() *= mmul2;
5416 if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5417 mterm2.multiply(madd);
5418 mterm2.last() ^= nr_two;
5419 multiply(x_var);
5420 if(!mmul2.isOne()) {
5421 multiply(mmul2);
5422 LAST ^= nr_half;
5423 }
5424 multiply(x_var);
5425 LAST ^= nr_two;
5426 if(!mmul2.isOne()) LAST *= mmul2;
5427 LAST *= nr_two;
5428 LAST += madd;
5429 subtract(mterm2);
5430 multiply(Number(1, 8));
5431 if(!mmul2.isOne()) {
5432 multiply(mmul2);
5433 LAST ^= Number(-3, 2);
5434 }
5435 return true;
5436 }
5437 } else if(CHILD(0)[1].number() == -1) {
5438 if(num == nr_minus_half) {
5439 MathStructure mbak(*this);
5440 SET_CHILD_MAP(1)
5441 SET_CHILD_MAP(0)
5442 raise(nr_half);
5443 multiply(madd);
5444 LAST ^= nr_half;
5445 add(madd);
5446 transformById(FUNCTION_ID_LOG);
5447 negate();
5448 add(x_var);
5449 if(!transform_absln(LAST, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5450 multiply(madd);
5451 LAST ^= nr_minus_half;
5452 return true;
5453 } else if(num == nr_half) {
5454 MathStructure mbak(*this);
5455 SET_CHILD_MAP(1)
5456 MathStructure mterm2(*this);
5457 mterm2 *= madd;
5458 mterm2.last() ^= nr_half;
5459 mterm2 += madd;
5460 mterm2.transformById(FUNCTION_ID_LOG);
5461 mterm2 *= madd;
5462 mterm2.last() ^= nr_half;
5463 MathStructure mterm3(x_var);
5464 if(!transform_absln(mterm3, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5465 mterm3 *= madd;
5466 mterm3.last() ^= nr_half;
5467 subtract(mterm2);
5468 add(mterm3);
5469 return true;
5470 }
5471 }
5472 }
5473 } else if(mmul2.isZero()) {
5474 if(CHILD(0) == x_var) {
5475 SET_CHILD_MAP(1)
5476 CHILD(1) += m_one;
5477 MathStructure mnum(x_var);
5478 mnum *= CHILD(1);
5479 if(!mmul.isOne()) mnum *= mmul;
5480 mnum -= madd;
5481 MathStructure mden(CHILD(1)[0]);
5482 mden += nr_two;
5483 mden *= CHILD(1);
5484 if(!mmul.isOne()) {
5485 mden *= mmul;
5486 mden[mden.size() - 1] ^= nr_two;
5487 }
5488 multiply(mnum);
5489 divide(mden);
5490 return true;
5491 }
5492 } else if(mexp.isMinusOne() && CHILD(0) == x_var) {
5493 MathStructure mbak(*this);
5494 SET_CHILD_MAP(1)
5495 MathStructure mterm2(CHILD(0));
5496 if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
5497 multiply(mmul);
5498 divide(mmul2);
5499 multiply(Number(-1, 2));
5500 if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5501 mterm2 /= mmul2;
5502 mterm2 *= nr_half;
5503 add(mterm2);
5504 return true;
5505 } else if(mexp.isMinusOne() && CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isMinusOne()) {
5506 MathStructure mbak(*this);
5507 SET_CHILD_MAP(1)
5508 MathStructure mterm2(CHILD(0));
5509 if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
5510 multiply(mmul);
5511 divide(madd);
5512 multiply(Number(-1, 2));
5513 mterm2.inverse();
5514 mterm2 *= x_var;
5515 mterm2.last() ^= nr_two;
5516 if(!transform_absln(mterm2, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5517 mterm2 /= madd;
5518 mterm2 *= nr_half;
5519 add(mterm2);
5520 return true;
5521 } else if(mexp.isInteger() && mexp.number().isNegative() && CHILD(0) == x_var) {
5522 MathStructure mbak(*this);
5523 SET_CHILD_MAP(1)
5524 MathStructure m2nm3(CHILD(1));
5525 m2nm3 *= nr_two;
5526 m2nm3 += Number(3, 1);
5527 CHILD(1).number()++;
5528 MathStructure mnp1(CHILD(1));
5529 mnp1.number().negate();
5530 mnp1.number().recip();
5531 MathStructure mthis(*this);
5532 if(integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5533 MathStructure m4acmb2(madd);
5534 m4acmb2 *= mmul2;
5535 m4acmb2 *= Number(4, 1);
5536 m4acmb2 += mmul;
5537 m4acmb2.last() ^= nr_two;
5538 m4acmb2.last().negate();
5539 m4acmb2.inverse();
5540 MathStructure mfac1(mmul);
5541 mfac1 *= m2nm3;
5542 mfac1 *= mnp1;
5543 mfac1 *= m4acmb2;
5544 multiply(mfac1);
5545 MathStructure mterm2(x_var);
5546 mterm2 *= mmul;
5547 mterm2 += madd;
5548 mterm2.last() *= nr_two;
5549 mterm2 *= m4acmb2;
5550 mterm2 *= mthis;
5551 mterm2 *= mnp1;
5552 subtract(mterm2);
5553 return true;
5554 }
5555 }
5556
5557 if(CHILD(0) == x_var || (CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isRational())) {
5558 Number nexp(1, 1, 0);
5559 if(CHILD(0).isPower()) nexp = CHILD(0)[1].number();
5560 MathStructure madd, mmul, mpow;
5561 if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mpow, false, false, true)) {
5562 if(mpow.isPower() && mpow[0] == x_var) {
5563 mpow.setToChild(2);
5564 if(mpow.isNumber() && mpow.number().isRational() & !mpow.number().isOne()) {
5565 if(!nexp.isOne() && mpow.isInteger()) {
5566 if(mexp.isMinusOne() && nexp.isMinusOne()) {
5567 MathStructure mbak(*this);
5568 if(mpow.number().isNegative()) {
5569 set(x_var, true);
5570 mpow.number().negate();
5571 raise(mpow);
5572 if(!madd.isOne()) multiply(madd);
5573 add(mmul);
5574 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5575 divide(mpow);
5576 if(!madd.isOne()) divide(madd);
5577 } else {
5578 SET_CHILD_MAP(1)
5579 SET_CHILD_MAP(0)
5580 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5581 add(x_var);
5582 if(!transform_absln(LAST, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5583 LAST *= mpow;
5584 LAST.negate();
5585 negate();
5586 divide(mpow);
5587 if(!madd.isOne()) divide(madd);
5588 }
5589 return true;
5590 }
5591 Number mpowmexp(mpow.number());
5592 mpowmexp -= nexp;
5593 if(mpowmexp.isOne()) {
5594 if(mexp.isMinusOne()) {
5595 MathStructure mbak(*this);
5596 if(mpow.number().isNegative()) {
5597 set(x_var, true);
5598 mpow.number().negate();
5599 raise(mpow);
5600 if(!madd.isOne()) multiply(madd);
5601 add(mmul);
5602 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5603 divide(mpow);
5604 divide(madd);
5605 add(x_var);
5606 if(!transform_absln(LAST, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5607 LAST.negate();
5608 divide(mpow);
5609 divide(madd);
5610 negate();
5611 } else {
5612 SET_CHILD_MAP(1)
5613 SET_CHILD_MAP(0)
5614 if(!transform_absln(*this, use_abs, definite_integral, x_var, eo)) {set(mbak); CANNOT_INTEGRATE_INTERVAL}
5615 divide(mpow);
5616 if(!mmul.isOne()) divide(mmul);
5617 }
5618 } else {
5619 SET_CHILD_MAP(1)
5620 MathStructure mden(CHILD(1));
5621 CHILD(1) += m_one;
5622 mden *= mpow;
5623 if(!mmul.isOne()) mden *= mmul;
5624 mden += mpow;
5625 if(!mmul.isOne()) mden.last() *= mmul;
5626 divide(mden);
5627 }
5628 return true;
5629 }
5630 }
5631 if(x_var.representsNonNegative(true) || mpow.number().isEven() || mpow.number().isFraction()) {
5632 for(int i = 1; i <= 3; i++) {
5633 if(i > 1 && (!mpow.isInteger() || !mpow.number().isIntegerDivisible(i) || mpow.number() == i)) break;
5634 UnknownVariable *var = NULL;
5635 MathStructure m_replace(x_var);
5636 MathStructure mtest(CHILD(1));
5637 Number new_pow(nexp);
5638 bool b = false;
5639 if(i == 1) {
5640 m_replace ^= mpow;
5641 var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
5642 mtest.replace(m_replace, var);
5643 new_pow++;
5644 new_pow -= mpow.number();
5645 new_pow /= mpow.number();
5646 b = true;
5647 } else if(i == 2) {
5648 new_pow = nexp;
5649 new_pow++;
5650 new_pow -= 2;
5651 new_pow /= 2;
5652 if(new_pow.isInteger()) {
5653 b = true;
5654 m_replace ^= nr_two;
5655 var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
5656 MathStructure m_prev(x_var), m_new(var);
5657 m_prev ^= mpow;
5658 m_new ^= mpow;
5659 m_new[1].number() /= 2;
5660 mtest.replace(m_prev, m_new);
5661 }
5662 } else if(i == 3) {
5663 new_pow++;
5664 new_pow -= 3;
5665 new_pow /= 3;
5666 if(new_pow.isInteger()) {
5667 b = true;
5668 m_replace ^= nr_three;
5669 var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
5670 MathStructure m_prev(x_var), m_new(var);
5671 m_prev ^= mpow;
5672 m_new ^= mpow;
5673 m_new[1].number() /= 3;
5674 mtest.replace(m_prev, m_new);
5675 }
5676 }
5677 if(b) {
5678 if(!new_pow.isZero()) {
5679 mtest *= var;
5680 mtest.swapChildren(1, mtest.size());
5681 if(!new_pow.isOne()) mtest[0] ^= new_pow;
5682 }
5683 CALCULATOR->beginTemporaryStopMessages();
5684 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5685 MathStructure m_interval(m_replace);
5686 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5687 var->setInterval(m_interval);
5688 } else {
5689 var->setInterval(m_replace);
5690 }
5691 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
5692 CALCULATOR->endTemporaryStopMessages(true);
5693 mtest.replace(var, m_replace);
5694 set(mtest, true);
5695 divide(m_replace[1]);
5696 var->destroy();
5697 return true;
5698 }
5699 CALCULATOR->endTemporaryStopMessages();
5700 var->destroy();
5701 }
5702 }
5703 }
5704 }
5705 } else if(mpow.isPower() && nexp.isInteger() && !madd.isZero() && mpow[1].containsRepresentativeOf(x_var, true, true) == 0) {
5706 MathStructure mbase(mpow[0]);
5707 if(integrate_info(mbase, x_var, madd, mmul, mpow, false, false) && mpow.isOne() && (!madd.isZero() || !mmul.isOne())) {
5708 MathStructure mtest(CHILD(1));
5709
5710 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mbase) + RIGHT_PARENTHESIS);
5711 mtest.replace(mbase, var, mbase.containsInterval());
5712 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5713 MathStructure m_interval(mbase);
5714 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5715 var->setInterval(m_interval);
5716 } else {
5717 var->setInterval(mbase);
5718 }
5719 mtest *= var;
5720 if(!madd.isZero()) {
5721 mtest.last() -= madd;
5722 mtest.childUpdated(mtest.size());
5723 }
5724 if(!nexp.isOne()) {
5725 mtest.last() ^= nexp;
5726 mtest.childUpdated(mtest.size());
5727 }
5728 CALCULATOR->beginTemporaryStopMessages();
5729 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5730 CALCULATOR->endTemporaryStopMessages(true);
5731 set(mtest, true);
5732 replace(var, mbase);
5733 if(!mmul.isOne()) {
5734 nexp++;
5735 if(!nexp.isOne()) mmul ^= nexp;
5736 divide(mmul);
5737 }
5738 var->destroy();
5739 return true;
5740 }
5741 CALCULATOR->endTemporaryStopMessages();
5742 var->destroy();
5743 }
5744 } /*else if(mpow.isFunction() && mpow.function()->id() == FUNCTION_ID_LOG && mpow.size() == 1 && mpow[0] == x_var) {
5745 MathStructure mtest(CHILD(1));
5746 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(mpow) + RIGHT_PARENTHESIS);
5747 mtest.replace(mpow, var, mpow.containsInterval());
5748 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5749 MathStructure m_interval(mpow);
5750 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5751 var->setInterval(m_interval);
5752 } else {
5753 var->setInterval(mpow);
5754 }
5755 nexp++;
5756 mtest *= CALCULATOR->getVariableById(VARIABLE_ID_E);
5757 mtest.last() ^= nexp;
5758 mtest.last().last() *= var;
5759 mmul = CALCULATOR->getVariableById(VARIABLE_ID_E);
5760 mmul ^= nexp;
5761 mmul.last() *= Number(-2, 1);
5762 CALCULATOR->beginTemporaryStopMessages();
5763 if(mtest.integrate(var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5764 CALCULATOR->endTemporaryStopMessages(true);
5765 set(mtest, true);
5766 replace(var, mpow);
5767 multiply(mmul);
5768 var->destroy();
5769 return true;
5770 }
5771 CALCULATOR->endTemporaryStopMessages();
5772 var->destroy();
5773 }*/
5774 }
5775 }
5776 if(CHILD(0).isPower() && (CHILD(0)[1] == x_var || (CHILD(0)[1].isMultiplication() && CHILD(0)[1].size() >= 2 && CHILD(0)[1].last() == x_var)) && CHILD(0)[0].containsRepresentativeOf(x_var, true, true) == 0) {
5777 MathStructure mpow, madd, mmul;
5778 if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mpow, false, false, true) && mpow.isPower() && (mpow[1] == x_var || (mpow[1].isMultiplication() && mpow[1].size() >= 2 && mpow[1].last() == x_var)) && (CHILD(0)[0] == mpow[0] || (CHILD(0)[0].isNumber() && CHILD(0)[0].number().isRational() && mpow[0].isNumber() && mpow[0].number().isRational() && mpow[1] == CHILD(0)[1]))) {
5779 Number pow1(1, 1), pow2;
5780 MathStructure morig(mpow);
5781 bool b = true;
5782 if(CHILD(0)[1].isMultiplication()) {
5783 if(!mpow[1].isMultiplication()) {
5784 if(CHILD(0)[1].size() != 2 || !CHILD(0)[1][0].isNumber()) b = false;
5785 else {pow2 = CHILD(0)[1][0].number(); pow2--;}
5786 } else {
5787 for(size_t i = 0; i < mpow[1].size() - 1; i++) {
5788 if(i == 0 && mpow[1][i].isNumber()) {
5789 pow1 = mpow[1][i].number();
5790 } else if(CHILD(0)[1][i].containsRepresentativeOf(x_var, true, true) != 0) {
5791 b = false;
5792 break;
5793 }
5794 }
5795 if(b) {
5796 if(mpow[1] == CHILD(0)[1]) {
5797 pow1.set(1, 1);
5798 } else if(CHILD(0)[1].size() - (CHILD(0)[1][0].isNumber() ? 1 : 0) != mpow[1].size() - (mpow[1][0].isNumber() ? 1 : 0)) {
5799 b = false;
5800 } else if(b) {
5801 for(size_t i = 0; i < CHILD(0)[1].size() - 1; i++) {
5802 if(i == 0 && CHILD(0)[1][i].isNumber()) {
5803 pow2 = CHILD(0)[1][i].number();
5804 pow2--;
5805 } else if(CHILD(0)[1][i] != mpow[1][i + (mpow[1][0].isNumber() ? 1 : 0) - (CHILD(0)[1][0].isNumber() ? 1 : 0)]) {
5806 b = false;
5807 break;
5808 }
5809 }
5810 }
5811 }
5812 }
5813 } else if(mpow[1].isMultiplication()) {
5814 if(mpow[1].size() != 2 || !mpow[1][0].isNumber()) b = false;
5815 else pow1 = mpow[1][0].number();
5816 }
5817 if(b && !pow1.isOne()) morig[1].delChild(1, true);
5818 if(b && CHILD(0)[0] != mpow[0]) {
5819 bool b1 = CHILD(0)[0].number() < mpow[0].number();
5820 if(mpow[0].number().isFraction() || CHILD(0)[0].number().isFraction()) b1 = !b1;
5821 Number nlog(b1 ? mpow[0].number() : CHILD(0)[0].number());
5822 nlog.log(b1 ? CHILD(0)[0].number() : mpow[0].number());
5823 if(!nlog.isInteger()) {
5824 nlog.round();
5825 b = nlog.isInteger() && (b1 ? ((CHILD(0)[0].number() ^ nlog) == mpow[0].number()) : ((mpow[0].number() ^ nlog) == CHILD(0)[0].number()));
5826 }
5827 if(b) {
5828 if(b1) {
5829 pow1 = nlog;
5830 morig = CHILD(0);
5831 } else {
5832 pow2 = nlog;
5833 pow2--;
5834 }
5835 }
5836 }
5837 if(b) {
5838 UnknownVariable *var = new UnknownVariable("", string(LEFT_PARENTHESIS) + format_and_print(morig) + RIGHT_PARENTHESIS);
5839 MathStructure mtest(var);
5840 if(!pow1.isOne()) mtest ^= pow1;
5841 if(!mmul.isOne()) mtest *= mmul;
5842 if(!madd.isZero()) mtest += madd;
5843 if(!mexp.isOne()) mtest ^= mexp;
5844 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
5845 MathStructure m_interval(morig);
5846 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
5847 var->setInterval(m_interval);
5848 } else {
5849 var->setInterval(morig);
5850 }
5851 if(!pow2.isZero()) {
5852 mtest *= var;
5853 if(!pow2.isOne()) mtest.last() ^= pow2;
5854 mtest.swapChildren(1, 2);
5855 }
5856 CALCULATOR->beginTemporaryStopMessages();
5857 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
5858 CALCULATOR->endTemporaryStopMessages(true);
5859 set(mtest, true);
5860 replace(var, morig);
5861 if(!morig[0].isVariable() || morig[0].variable()->id() != VARIABLE_ID_E) divide_nocopy(new MathStructure(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &morig[0], NULL));
5862 if(morig[1].isMultiplication()) {
5863 morig[1].delChild(morig[1].size(), true);
5864 divide(morig[1]);
5865 }
5866 var->destroy();
5867 return true;
5868 }
5869 CALCULATOR->endTemporaryStopMessages();
5870 var->destroy();
5871 }
5872 }
5873 }
5874 if(CHILD(1)[1].number().isMinusOne() && CHILD(1)[0].isMultiplication() && CHILD(1)[0].size() == 2 && CHILD(1)[0][0].isAddition() && CHILD(1)[0][1].isAddition() && (CHILD(0) == x_var || (CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isTwo()))) {
5875 MathStructure madd1, mmul1, mexp1;
5876 if(integrate_info(CHILD(1)[0][0], x_var, madd1, mmul1, mexp1) && mexp1.isOne()) {
5877 MathStructure madd2, mexp2;
5878 if(integrate_info(CHILD(1)[0][1], x_var, madd2, mmul2, mexp2) && mexp2.isOne()) {
5879 MathStructure mnum1, mnum2, mx1(madd2), mx2(madd1);
5880 mx1.negate();
5881 if(!mmul2.isOne()) mx1 /= mmul2;
5882 mnum1 = mx1;
5883 if(!mmul1.isOne()) mx1 *= mmul1;
5884 mx1 += madd1;
5885 mnum1 /= mx1;
5886 mx2.negate();
5887 if(!mmul1.isOne()) mx2 /= mmul1;
5888 mnum2 = mx2;
5889 if(!mmul2.isOne()) mx2 *= mmul2;
5890 mx2 += madd2;
5891 mnum2 /= mx2;
5892 mnum2 /= CHILD(1)[0][0];
5893 mnum1 /= CHILD(1)[0][1];
5894 if(CHILD(0) != x_var) {
5895 mnum1 *= x_var;
5896 mnum2 *= x_var;
5897 }
5898 mnum2 += mnum1;
5899 CALCULATOR->beginTemporaryStopMessages();
5900 if(mnum2.integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
5901 CALCULATOR->endTemporaryStopMessages(true);
5902 set(mnum2, true);
5903 return true;
5904 }
5905 CALCULATOR->endTemporaryStopMessages();
5906 }
5907 }
5908 }
5909 if(CHILD(1)[0].isAddition()) {
5910 bool b_poly = false;
5911 if(CHILD(1)[1].isMinusOne()) {
5912 MathStructure mquo, mrem;
5913 b_poly = polynomial_long_division(CHILD(0), CHILD(1)[0], x_var, mquo, mrem, eo, true);
5914 if(b_poly && !mquo.isZero()) {
5915 MathStructure mtest(mquo);
5916 if(!mrem.isZero()) {
5917 mtest += mrem;
5918 mtest.last() *= CHILD(1);
5919 mtest.childrenUpdated();
5920 }
5921 CALCULATOR->beginTemporaryStopMessages();
5922 if(mtest.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
5923 CALCULATOR->endTemporaryStopMessages(true);
5924 set(mtest, true);
5925 return true;
5926 }
5927 CALCULATOR->endTemporaryStopMessages();
5928 }
5929 }
5930 MathStructure mtest(*this);
5931 if(mtest[1][0].factorize(eo, false, 0, 0, false, false, NULL, x_var)) {
5932 mmul = m_one;
5933 while(mtest[1][0].isMultiplication() && mtest[1][0].size() >= 2 && mtest[1][0][0].containsRepresentativeOf(x_var, true, true) == 0) {
5934 MathStructure *mchild = &mtest[1][0][0];
5935 mchild->ref();
5936 mtest[1][0].delChild(1, true);
5937 if(CHILD(1)[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[1][0].compare(m_zero))) {
5938 if(mmul.isOne()) mmul = *mchild;
5939 else mmul *= *mchild;
5940 mchild->unref();
5941 } else {
5942 mtest[1][0].multiply_nocopy(mchild, true);
5943 }
5944 }
5945 if(!mmul.isOne()) {
5946 mmul ^= CHILD(1)[1];
5947 }
5948 if(b_poly) {
5949 MathStructure mtest2(mtest);
5950 if(mtest2.decomposeFractions(x_var, eo)) {
5951 if(mtest2.isAddition()) {
5952 bool b = true;
5953 CALCULATOR->beginTemporaryStopMessages();
5954 for(size_t i = 0; i < mtest2.size(); i++) {
5955 if(mtest2[i].integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) <= 0) {
5956 b = false;
5957 break;
5958 }
5959 }
5960 CALCULATOR->endTemporaryStopMessages(b);
5961 if(b) {
5962 set(mtest2, true);
5963 if(!mmul.isOne()) multiply(mmul);
5964 return true;
5965 }
5966 }
5967 } else {
5968 mtest2 = mtest[1];
5969 if(mtest2.decomposeFractions(x_var, eo) && mtest2.isAddition()) {
5970 if(mtest2.isAddition()) {
5971 bool b = true;
5972 CALCULATOR->beginTemporaryStopMessages();
5973 for(size_t i = 0; i < mtest2.size(); i++) {
5974 mtest2[i] *= mtest[0];
5975 if(mtest2[i].integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) <= 0) {
5976 b = false;
5977 break;
5978 }
5979 }
5980 CALCULATOR->endTemporaryStopMessages(b);
5981 if(b) {
5982 set(mtest2, true);
5983 if(!mmul.isOne()) multiply(mmul);
5984 return true;
5985 }
5986 }
5987 }
5988 }
5989 }
5990 mmul2 = m_one;
5991 if(mtest[1][0].isMultiplication() && mtest[1][0].size() >= 2 && !mtest[1][0][0].isAddition()) {
5992 MathStructure *mchild = &mtest[1][0][0];
5993 mchild->ref();
5994 mtest[1][0].delChild(1, true);
5995 if(CHILD(1)[1].representsInteger(true) || COMPARISON_IS_EQUAL_OR_LESS(mchild->compare(m_zero)) || COMPARISON_IS_EQUAL_OR_LESS(mtest[1][0].compare(m_zero))) {
5996 mmul2 = *mchild;
5997 mmul2.calculateRaise(CHILD(1)[1], eo2);
5998 mchild->unref();
5999 } else {
6000 mtest[1][0].multiply_nocopy(mchild, true);
6001 }
6002 }
6003 if(mtest[1][0].isPower()) {
6004 if(mtest[1][1].representsInteger() || mtest[1][0][1].representsFraction() || COMPARISON_IS_EQUAL_OR_LESS(mtest[1][0][0].compare(m_zero))) {
6005 mtest[1][1].calculateMultiply(mtest[1][0][1], eo2);
6006 mtest[1][0].setToChild(1);
6007 } else if(mtest[1][0][1].representsEven()) {
6008 if(COMPARISON_IS_EQUAL_OR_GREATER(mtest[1][0][0].compare(m_zero))) {
6009 mtest[1][1].calculateMultiply(mtest[1][0][1], eo2);
6010 mtest[1][0].setToChild(1);
6011 mtest[1][0].calculateNegate(eo2);
6012 } else if(!definite_integral && mtest[1][0][0].representsReal(true)) {
6013 mtest[1][1].calculateMultiply(mtest[1][0][1], eo2);
6014 mtest[1][0].setToChild(1);
6015 mtest[1][0].transformById(FUNCTION_ID_ABS);
6016 }
6017 }
6018 }
6019 mtest[1][0].evalSort(false);
6020 if(!mmul2.isOne()) {
6021 mtest *= mmul2;
6022 mtest.evalSort(false);
6023 }
6024 CALCULATOR->beginTemporaryStopMessages();
6025 if(mtest.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0) {
6026 CALCULATOR->endTemporaryStopMessages(true);
6027 set(mtest);
6028 if(!mmul.isOne()) multiply(mmul);
6029 return true;
6030 }
6031 CALCULATOR->endTemporaryStopMessages();
6032 }
6033 if(CHILD(1)[1].number().isMinusOne() && CHILD(0) == x_var) {
6034 if(integrate_info(CHILD(1)[0], x_var, madd, mmul, mmul2, false, true) && !mmul2.isZero() && mmul.isZero() && !madd.isZero()) {
6035 SET_CHILD_MAP(1)
6036 SET_CHILD_MAP(0)
6037 transformById(FUNCTION_ID_LOG);
6038 mmul2 *= Number(-2, 1);
6039 multiply(mmul2);
6040 return true;
6041 }
6042 }
6043 }
6044 } else if(CHILD(1).isPower() && ((CHILD(1)[0].isNumber() && !CHILD(1)[0].number().isOne()) || (!CHILD(1)[0].isNumber() && CHILD(1)[0].containsRepresentativeOf(x_var, true, true) == 0))) {
6045 MathStructure mexp(1, 1, 0);
6046 if(CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isInteger()) mexp = CHILD(0)[1];
6047 else if(CHILD(0) != x_var) CANNOT_INTEGRATE;
6048 MathStructure madd, mmul, mpow;
6049 if(mexp.number() < 100 && mexp.number() > -100 && integrate_info(CHILD(1)[1], x_var, madd, mmul, mpow, false, false) && mpow.isInteger()) {
6050 bool b_e = CHILD(1)[0].isVariable() && CHILD(1)[0].variable()->id() == VARIABLE_ID_E;
6051 if(b_e || CHILD(1)[0].isNumber() || warn_about_assumed_not_value(CHILD(1)[0], m_one, eo)) {
6052 if(mpow.isOne()) {
6053 SET_CHILD_MAP(1)
6054 if(!b_e) {
6055 if(mmul.isOne()) {
6056 mmul = CHILD(0);
6057 mmul.transformById(FUNCTION_ID_LOG);
6058 } else {
6059 MathStructure lnbase(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &CHILD(0), NULL);
6060 mmul *= lnbase;
6061 }
6062 }
6063 if(mexp.isOne()) {
6064 MathStructure mmulfac(x_var);
6065 if(!mmul.isOne()) mmulfac *= mmul;
6066 mmulfac += nr_minus_one;
6067 multiply(mmulfac);
6068 if(!mmul.isOne()) {
6069 mmul ^= Number(-2, 1);;
6070 multiply(mmul);
6071 }
6072 } else if(mexp.number().isTwo()) {
6073 MathStructure mmulfac(x_var);
6074 mmulfac ^= nr_two;
6075 if(!mmul.isOne()) mmulfac /= mmul;
6076 mmulfac += x_var;
6077 mmulfac.last() *= Number(-2, 1);
6078 if(!mmul.isOne()) {
6079 mmulfac.last() *= mmul;
6080 mmulfac.last().last() ^= Number(-2, 1);
6081 }
6082 mmulfac += nr_two;
6083 if(!mmul.isOne()) {
6084 mmulfac.last() *= mmul;
6085 mmulfac.last().last() ^= Number(-3, 1);
6086 }
6087 mmulfac.childrenUpdated(true);
6088 multiply(mmulfac);
6089 } else if(mexp.isMinusOne()) {
6090 if(!madd.isZero()) {
6091 madd.raise(CHILD(0));
6092 madd.swapChildren(1, 2);
6093 }
6094 set(x_var, true);
6095 if(!mmul.isOne()) multiply(mmul);
6096 transformById(FUNCTION_ID_EXPINT);
6097 if(!madd.isZero()) multiply(madd);
6098 } else if(mexp.number().isNegative()) {
6099 MathStructure mterm2(*this);
6100 mexp += m_one;
6101 multiply(x_var);
6102 LAST ^= mexp;
6103 CHILDREN_UPDATED
6104 if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
6105 if(!mmul.isOne()) multiply(mmul);
6106 mterm2 *= x_var;
6107 mterm2.last() ^= mexp;
6108 mterm2.childrenUpdated();
6109 subtract(mterm2);
6110 mexp.negate();
6111 divide(mexp);
6112 } else {
6113 MathStructure mterm2(*this);
6114 multiply(x_var);
6115 LAST ^= mexp;
6116 LAST[1] += nr_minus_one;
6117 LAST.childUpdated(2);
6118 CHILDREN_UPDATED
6119 if(integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts) < 0) CANNOT_INTEGRATE_INTERVAL
6120 multiply(mexp);
6121 if(!mmul.isOne()) divide(mmul);
6122 negate();
6123 mterm2 *= x_var;
6124 mterm2.last() ^= mexp;
6125 mterm2.childrenUpdated();
6126 if(!mmul.isOne()) mterm2.divide(mmul);
6127 add(mterm2);
6128 }
6129 return true;
6130 } else {
6131 Number mpowmexp(mpow.number());
6132 mpowmexp -= mexp.number();
6133 if(mpowmexp.isOne()) {
6134 SET_CHILD_MAP(1)
6135 MathStructure malog(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &CHILD(0), NULL);
6136 divide(mpow);
6137 if(!mmul.isOne()) divide(mmul);
6138 if(!b_e) divide(malog);
6139 return true;
6140 } else if(mexp.isMinusOne() && mpow.number().isPositive()) {
6141 MathStructure malog;
6142 if(b_e) {
6143 malog = x_var;
6144 malog ^= mpow;
6145 } else {
6146 malog.set(CALCULATOR->getFunctionById(FUNCTION_ID_LOG), &CHILD(1)[0], NULL);
6147 malog *= x_var;
6148 malog.last() ^= mpow;
6149 }
6150 if(!mmul.isOne()) malog *= mmul;
6151 malog.transformById(FUNCTION_ID_EXPINT);
6152 if(madd.isZero()) {
6153 set(malog, true);
6154 } else {
6155 SET_CHILD_MAP(1)
6156 SET_CHILD_MAP(0)
6157 raise(madd);
6158 multiply(malog);
6159 }
6160 divide(mpow);
6161 return true;
6162 }
6163 }
6164 }
6165 }
6166 }
6167 }
6168 if(SIZE >= 2) {
6169 for(size_t i = 0; i < SIZE; i++) {
6170 if((CHILD(i).isFunction() && CHILD(i).function()->id() == FUNCTION_ID_SIGNUM) || (CHILD(i).isPower() && CHILD(i)[0].isFunction() && CHILD(i)[0].function()->id() == FUNCTION_ID_SIGNUM)) {
6171 MathStructure mfunc(CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i));
6172 MathStructure mmul(*this);
6173 mmul.delChild(i + 1, true);
6174 CALCULATOR->beginTemporaryStopMessages();
6175 int bint = integrate_function(mfunc, x_var, eo, CHILD(i).isPower() ? CHILD(i)[1] : m_one, mmul, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
6176 CALCULATOR->endTemporaryStopMessages(bint > 0);
6177 if(bint < 0) CANNOT_INTEGRATE_INTERVAL
6178 if(bint) {
6179 set(mfunc, true);
6180 return true;
6181 }
6182 }
6183 }
6184 for(size_t i = 0; i < SIZE; i++) {
6185 if((CHILD(i).isFunction() && CHILD(i).function()->id() != FUNCTION_ID_SIGNUM) || (CHILD(i).isPower() && CHILD(i)[0].isFunction() && CHILD(i)[0].function()->id() != FUNCTION_ID_SIGNUM)) {
6186 MathStructure mfunc(CHILD(i).isPower() ? CHILD(i)[0] : CHILD(i));
6187 MathStructure mmul(*this);
6188 mmul.delChild(i + 1, true);
6189 CALCULATOR->beginTemporaryStopMessages();
6190 int bint = integrate_function(mfunc, x_var, eo, CHILD(i).isPower() ? CHILD(i)[1] : m_one, mmul, m_zero, m_one, use_abs, definite_integral, max_part_depth, parent_parts);
6191 CALCULATOR->endTemporaryStopMessages(bint > 0);
6192 if(bint < 0) CANNOT_INTEGRATE_INTERVAL
6193 if(bint) {
6194 set(mfunc, true);
6195 return true;
6196 }
6197 }
6198 }
6199 MathStructure mbak(*this);
6200 if(CHILD(0) == x_var || (CHILD(0).isPower() && CHILD(0)[0] == x_var && CHILD(0)[1].isNumber() && CHILD(0)[1].number().isRational())) {
6201 Number nexp(1, 1, 0);
6202 if(CHILD(0).isPower()) nexp = CHILD(0)[1].number();
6203 MathStructure mpow(1, 1, 0);
6204 bool b = true;
6205 MathStructure madd, mmul, mpown;
6206 for(size_t i = 1; i < SIZE; i++) {
6207 if(CHILD(i).isFunction() && CHILD(i).size() >= 1) {
6208 if(!integrate_info(CHILD(i)[0], x_var, madd, mmul, mpown, false, false) || !mpown.isNumber() || !mpown.number().isRational() || mpown.number().isOne() || (!mpow.isOne() && mpow != mpown)) {
6209 b = false;
6210 break;
6211 }
6212 mpow = mpown;
6213 } else if(CHILD(i).isPower() && CHILD(i)[1].containsRepresentativeOf(x_var, true, true) == 0) {
6214 if((CHILD(i)[0].isFunction() && CHILD(i)[0].size() == 1)) {
6215 if(!integrate_info(CHILD(i)[0][0], x_var, madd, mmul, mpown, false, false)) {b = false; break;}
6216 } else if(integrate_info(CHILD(i)[0], x_var, madd, mmul, mpown, false, false, true)) {
6217 if(mpown.isPower() && mpown[0] == x_var) {
6218 mpown.setToChild(2);
6219 if(SIZE == 2 && mpown.isInteger()) {b = false; break;}
6220 } else if(mpown.isFunction() && mpown.size() >= 1) {
6221 MathStructure marg(mpown[0]);
6222 if(!integrate_info(marg, x_var, madd, mmul, mpown, false, false)) {b = false; break; }
6223 } else {
6224 b = false; break;
6225 }
6226 } else {
6227 b = false; break;
6228 }
6229 if(!mpown.isNumber() || !mpown.number().isRational() || mpown.number().isOne() || (!mpow.isOne() && mpow != mpown)) {
6230 b = false;
6231 break;
6232 }
6233 mpow = mpown;
6234 } else if(CHILD(i).isPower() && CHILD(i)[0].containsRepresentativeOf(x_var, true, true) == 0) {
6235 if(!integrate_info(CHILD(i)[1], x_var, madd, mmul, mpown, false, false) || !mpown.isNumber() || !mpown.number().isRational() || mpown.number().isOne() || (!mpow.isOne() && mpow != mpown)) {
6236 b = false;
6237 break;
6238 }
6239 mpow = mpown;
6240 } else {
6241 b = false;
6242 break;
6243 }
6244 }
6245 if(b && (x_var.representsNonNegative(true) || mpow.number().isEven() || mpow.number().isFraction())) {
6246 for(int i = 1; i <= 3; i++) {
6247 if(!mpow.isInteger()) {
6248 if(i > 2) break;
6249 } else if(i > 1 && (!mpow.number().isIntegerDivisible(i) || mpow.number() == i)) {
6250 break;
6251 }
6252 if(CALCULATOR->aborted()) CANNOT_INTEGRATE
6253 UnknownVariable *var = NULL;
6254 MathStructure m_replace(x_var);
6255 MathStructure mtest(*this);
6256 mtest.delChild(1, true);
6257 Number new_pow(nexp);
6258 b = false;
6259 if(i == 1) {
6260 m_replace ^= mpow;
6261 var = new UnknownVariable("", "");
6262 mtest.replace(m_replace, var);
6263 new_pow++;
6264 new_pow -= mpow.number();
6265 new_pow /= mpow.number();
6266 b = true;
6267 } else if(i == 2) {
6268 if(!mpow.number().isInteger()) {
6269 Number nden = mpow.number().denominator();
6270 nden.recip();
6271 nden--;
6272 nden.negate();
6273 new_pow = nexp;
6274 new_pow += nden;
6275 new_pow *= mpow.number().denominator();
6276 if(new_pow.isInteger()) {
6277 b = true;
6278 m_replace ^= mpow.number().denominator();
6279 m_replace[1].number().recip();
6280 var = new UnknownVariable("", "");
6281 MathStructure m_prev(x_var), m_new(var);
6282 m_prev ^= mpow;
6283 if(!mpow.number().numeratorIsOne()) m_new ^= mpow.number().numerator();
6284 mtest.replace(m_prev, m_new);
6285 }
6286 } else if((mpow.number() / 2).isEven()) {
6287 new_pow = nexp;
6288 new_pow++;
6289 new_pow -= 2;
6290 new_pow /= 2;
6291 if(new_pow.isInteger()) {
6292 b = true;
6293 m_replace ^= nr_two;
6294 var = new UnknownVariable("", "");
6295 MathStructure m_prev(x_var), m_new(var);
6296 m_prev ^= mpow;
6297 m_new ^= mpow;
6298 m_new[1].number() /= 2;
6299 mtest.replace(m_prev, m_new);
6300 }
6301 }
6302 } else if(i == 3) {
6303 new_pow++;
6304 new_pow -= 3;
6305 new_pow /= 3;
6306 if(new_pow.isInteger()) {
6307 b = true;
6308 m_replace ^= nr_three;
6309 var = new UnknownVariable("", "");
6310 MathStructure m_prev(x_var), m_new(var);
6311 m_prev ^= mpow;
6312 m_new ^= mpow;
6313 m_new[1].number() /= 3;
6314 mtest.replace(m_prev, m_new);
6315 }
6316 }
6317 if(b) {
6318 if(!new_pow.isZero()) {
6319 mtest *= var;
6320 mtest.swapChildren(1, mtest.size());
6321 if(!new_pow.isOne()) mtest[0] ^= new_pow;
6322 }
6323 CALCULATOR->beginTemporaryStopMessages();
6324 var->setName(string(LEFT_PARENTHESIS) + format_and_print(m_replace) + RIGHT_PARENTHESIS);
6325 if(x_var.isVariable() && !x_var.variable()->isKnown() && !((UnknownVariable*) x_var.variable())->interval().isUndefined()) {
6326 MathStructure m_interval(m_replace);
6327 m_interval.replace(x_var, ((UnknownVariable*) x_var.variable())->interval());
6328 var->setInterval(m_interval);
6329 } else {
6330 var->setInterval(m_replace);
6331 }
6332 if(mtest.integrate(var, eo, false, use_abs, definite_integral, true, max_part_depth, parent_parts) > 0 && mtest.containsFunctionId(FUNCTION_ID_INTEGRATE) <= 0) {
6333 CALCULATOR->endTemporaryStopMessages(true);
6334 mtest.replace(var, m_replace);
6335 set(mtest, true);
6336 if(m_replace.isPower()) divide(m_replace[1]);
6337 var->destroy();
6338 return true;
6339 }
6340 CALCULATOR->endTemporaryStopMessages();
6341 var->destroy();
6342 }
6343 }
6344 }
6345 }
6346
6347 vector<MathStructure*> parent_parts_pre;
6348 if(parent_parts) {
6349 for(size_t i = 0; i < parent_parts->size(); i++) {
6350 if(equals(*(*parent_parts)[i], true)) CANNOT_INTEGRATE
6351 }
6352 } else {
6353 parent_parts = &parent_parts_pre;
6354 }
6355 size_t pp_size = parent_parts->size();
6356 bool b = false;
6357
6358 // integration by parts: u(x)*v(x): u*integral of(v) - integral of (u'(x) * integral of v(x))
6359 for(size_t i = 0; !b && max_part_depth > 0 && (i < SIZE || (SIZE == 3 && i < SIZE * 2)) && SIZE < 10; i++) {
6360 if(CALCULATOR->aborted()) CANNOT_INTEGRATE
6361 CALCULATOR->beginTemporaryStopMessages();
6362 MathStructure mstruct_u;
6363 MathStructure mstruct_v;
6364 MathStructure minteg_v;
6365
6366 // select two parts
6367 if(SIZE == 3 && i >= 3) {
6368 mstruct_v = CHILD(i - 3);
6369 mstruct_u = *this;
6370 mstruct_u.delChild(i - 2);
6371 } else {
6372 mstruct_u = CHILD(i);
6373 if(SIZE == 2 && i == 0) mstruct_v = CHILD(1);
6374 else if(SIZE == 2 && i == 1) mstruct_v = CHILD(0);
6375 else {mstruct_v = *this; mstruct_v.delChild(i + 1);}
6376 }
6377
6378 MathStructure mdiff_u(mstruct_u);
6379 if(mdiff_u.differentiate(x_var, eo2) && mdiff_u.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) <= 0 && (!definite_integral || check_zero_div(mdiff_u, x_var, eo))) {
6380 minteg_v = mstruct_v;
6381 if(minteg_v.integrate(x_var, eo, false, use_abs, definite_integral, true, 0, parent_parts) > 0) {
6382 parent_parts->push_back(this);
6383 MathStructure minteg_2(minteg_v);
6384 if(!mdiff_u.isOne()) minteg_2 *= mdiff_u;
6385 if(minteg_2.countTotalChildren() < 1000) {
6386 minteg_2.evalSort(true);
6387 minteg_2.calculateFunctions(eo2);
6388 minteg_2.calculatesub(eo2, eo2, true);
6389 combine_ln(minteg_2, x_var, eo2);
6390 do_simplification(minteg_2, eo2, true, false, false, true, true);
6391 }
6392 if(minteg_2.countTotalChildren() < 100 && minteg_2.integrate(x_var, eo, false, use_abs, definite_integral, true, max_part_depth - 1, parent_parts) > 0) {
6393 int cui = contains_unsolved_integrate(minteg_2, this, parent_parts);
6394 if(cui == 3) {
6395 MathStructure mfunc(CALCULATOR->getFunctionById(FUNCTION_ID_INTEGRATE), this, &m_undefined, &m_undefined, &x_var, &m_zero, NULL);
6396 UnknownVariable *var = new UnknownVariable("", format_and_print(mfunc));
6397 var->setAssumptions(mfunc);
6398 MathStructure mvar(var);
6399 minteg_2.replace(mfunc, mvar);
6400 MathStructure msolve(mstruct_u);
6401 msolve.multiply(minteg_v);
6402 msolve.evalSort(false);
6403 msolve.calculatesub(eo2, eo2, true);
6404 msolve.subtract(minteg_2);
6405 msolve.evalSort(false);
6406 msolve.calculatesub(eo2, eo2, true);
6407 MathStructure msolve_d(msolve);
6408 if(msolve_d.differentiate(mvar, eo2) && COMPARISON_IS_NOT_EQUAL(msolve_d.compare(m_one))) {
6409 msolve.transform(COMPARISON_EQUALS, mvar);
6410 msolve.isolate_x(eo2, mvar);
6411 if(msolve.isComparison() && msolve.comparisonType() == COMPARISON_EQUALS && msolve[0] == mvar && msolve[1].contains(mvar, true) <= 0) {
6412 b = true;
6413 set(msolve[1], true);
6414 }
6415 }
6416 var->destroy();
6417 } else if(cui != 1) {
6418 set(mstruct_u);
6419 multiply(minteg_v);
6420 subtract(minteg_2);
6421 b = true;
6422 }
6423 }
6424 parent_parts->pop_back();
6425 }
6426 }
6427 CALCULATOR->endTemporaryStopMessages(b);
6428 }
6429 while(parent_parts->size() > pp_size) parent_parts->pop_back();
6430 if(b) return true;
6431 }
6432 CANNOT_INTEGRATE
6433 break;
6434 }
6435 case STRUCT_SYMBOLIC: {
6436 if(representsNumber(true)) {
6437 // y: x*y
6438 multiply(x_var);
6439 } else {
6440 CANNOT_INTEGRATE
6441 }
6442 break;
6443 }
6444 case STRUCT_VARIABLE: {
6445 if(eo.calculate_variables && o_variable->isKnown()) {
6446 if(eo.approximation != APPROXIMATION_EXACT || !o_variable->isApproximate()) {
6447 set(((KnownVariable*) o_variable)->get(), true);
6448 unformat(eo);
6449 return integrate(x_var, eo, true, use_abs, definite_integral, true, max_part_depth, parent_parts);
6450 } else if(containsRepresentativeOf(x_var, true, true) != 0) {
6451 CANNOT_INTEGRATE
6452 }
6453 }
6454 // y: x*y
6455 if(representsNumber(true)) {
6456 multiply(x_var);
6457 break;
6458 }
6459 }
6460 default: {
6461 CANNOT_INTEGRATE
6462 }
6463 }
6464 return true;
6465 }
6466
6467 // Type 0: Simpson's rule, 1: trapezoid, 2: Simpson's 3/8, 3: Boole's
6468
numerical_integration(const MathStructure & mstruct,Number & nvalue,const MathStructure & x_var,const EvaluationOptions & eo2,const Number & nr_begin,const Number & nr_end,int i_samples,int type=0)6469 bool numerical_integration(const MathStructure &mstruct, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo2, const Number &nr_begin, const Number &nr_end, int i_samples, int type = 0) {
6470 if((type == 0 && i_samples % 2 == 1) || (type == 2 && i_samples % 3 == 2) || (type == 3 && i_samples % 4 == 3)) {
6471 i_samples++;
6472 } else if((type == 2 && i_samples % 3 == 1) || (type == 3 && i_samples % 4 == 2)) {
6473 i_samples += 2;
6474 } else if(type == 3 && i_samples % 4 == 1) {
6475 i_samples += 3;
6476 }
6477 Number nr_step(nr_end);
6478 nr_step -= nr_begin;
6479 nr_step /= i_samples;
6480 MathStructure m_a = mstruct;
6481 m_a.replace(x_var, nr_begin);
6482 m_a.eval(eo2);
6483 if(!m_a.isNumber()) return false;
6484 nvalue = m_a.number();
6485 m_a = mstruct;
6486 m_a.replace(x_var, nr_end);
6487 m_a.eval(eo2);
6488 if(!m_a.isNumber()) return false;
6489 if(!nvalue.add(m_a.number())) return false;
6490 if(type == 1 && !nvalue.multiply(nr_half)) return false;
6491 if(type == 3 && !nvalue.multiply(7)) return false;
6492 for(int i = 1; i < i_samples; i++) {
6493 if(CALCULATOR->aborted()) {
6494 return false;
6495 }
6496 Number nr(nr_step);
6497 nr *= i;
6498 nr += nr_begin;
6499 MathStructure m_a(mstruct);
6500 m_a.replace(x_var, nr);
6501 m_a.eval(eo2);
6502 if(!m_a.isNumber()) return false;
6503 if((type == 0 && i % 2 == 0) || (type == 2 && i % 3 == 0)) {
6504 if(!m_a.number().multiply(nr_two)) return false;
6505 } else if(type == 0) {
6506 if(!m_a.number().multiply(4)) return false;
6507 } else if(type == 2) {
6508 if(!m_a.number().multiply(nr_three)) return false;
6509 } else if(type == 3 && i % 4 == 0) {
6510 if(!m_a.number().multiply(14)) return false;
6511 } else if(type == 3 && i % 2 == 0) {
6512 if(!m_a.number().multiply(12)) return false;
6513 } else if(type == 3) {
6514 if(!m_a.number().multiply(32)) return false;
6515 }
6516 if(!nvalue.add(m_a.number())) return false;
6517 }
6518 if(!nvalue.multiply(nr_step)) return false;
6519 if(type == 0 && !nvalue.multiply(Number(1, 3))) return false;
6520 if(type == 2 && !nvalue.multiply(Number(3, 8))) return false;
6521 if(type == 3 && !nvalue.multiply(Number(2, 45))) return false;
6522 return true;
6523 }
montecarlo(const MathStructure & minteg,Number & nvalue,const MathStructure & x_var,const EvaluationOptions & eo,Number a,Number b,Number n)6524 bool montecarlo(const MathStructure &minteg, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b, Number n) {
6525 Number range(b); range -= a;
6526 MathStructure m;
6527 Number u;
6528 nvalue.clear();
6529 vector<Number> v;
6530 Number i(1, 1);
6531 while(i <= n) {
6532 if(CALCULATOR->aborted()) {
6533 n = i;
6534 break;
6535 }
6536 u.rand();
6537 u *= range;
6538 u += a;
6539 m = minteg;
6540 m.replace(x_var, u);
6541 m.eval(eo);
6542 if(!m.isNumber() || m.number().includesInfinity()) return false;
6543 if(!m.number().multiply(range)) return false;
6544 if(!nvalue.add(m.number())) return false;
6545 v.push_back(m.number());
6546 i++;
6547 }
6548 if(!nvalue.divide(n)) return false;
6549 Number var;
6550 for(size_t i = 0; i < v.size(); i++) {
6551 if(!v[i].subtract(nvalue) || !v[i].square() || !var.add(v[i])) return false;
6552 }
6553 if(!var.divide(n) || !var.sqrt()) return false;
6554 Number nsqrt(n); if(!nsqrt.sqrt() || !var.divide(nsqrt)) return false;
6555 nvalue.setUncertainty(var);
6556 return true;
6557 }
has_wide_trig_interval(const MathStructure & m,const MathStructure & x_var,const EvaluationOptions & eo,Number a,Number b)6558 bool has_wide_trig_interval(const MathStructure &m, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b) {
6559 for(size_t i = 0; i < m.size(); i++) {
6560 if(has_wide_trig_interval(m[i], x_var, eo, a, b)) return true;
6561 }
6562 if(m.isFunction() && m.size() == 1 && (m.function()->id() == FUNCTION_ID_SINC || m.function()->id() == FUNCTION_ID_SIN || m.function()->id() == FUNCTION_ID_COS)) {
6563 Number nr_interval;
6564 nr_interval.setInterval(a, b);
6565 MathStructure mtest(m[0]);
6566 mtest.replace(x_var, nr_interval);
6567 CALCULATOR->beginTemporaryStopMessages();
6568 mtest.eval(eo);
6569 CALCULATOR->endTemporaryStopMessages();
6570 return mtest.isMultiplication() && mtest.size() >= 1 && mtest[0].isNumber() && (mtest[0].number().uncertainty().realPart() > 100 || mtest[0].number().uncertainty().imaginaryPart() > 100);
6571 }
6572 return false;
6573 }
romberg(const MathStructure & minteg,Number & nvalue,const MathStructure & x_var,const EvaluationOptions & eo,Number a,Number b,long int max_steps,long int min_steps,bool safety_measures)6574 bool romberg(const MathStructure &minteg, Number &nvalue, const MathStructure &x_var, const EvaluationOptions &eo, Number a, Number b, long int max_steps, long int min_steps, bool safety_measures) {
6575
6576 bool auto_max = max_steps <= 0;
6577 if(auto_max) max_steps = 22;
6578 if(min_steps > max_steps) max_steps = min_steps;
6579
6580 Number R1[max_steps], R2[max_steps];
6581 Number *Rp = &R1[0], *Rc = &R2[0];
6582 Number h(b); h -= a;
6583 Number acc, acc_i, c, ntmp, prevunc, prevunc_i, nunc, nunc_i;
6584
6585 nvalue.clear();
6586
6587 MathStructure mf(minteg);
6588 mf.replace(x_var, a);
6589 mf.eval(eo);
6590 if(!mf.isNumber() || mf.number().includesInfinity()) {
6591 if(!a.setToFloatingPoint()) return false;
6592 mpfr_nextabove(a.internalLowerFloat());
6593 mpfr_nextabove(a.internalUpperFloat());
6594 mf = minteg;
6595 mf.replace(x_var, a);
6596 mf.eval(eo);
6597 }
6598 if(!mf.isNumber()) return false;
6599 Rp[0] = mf.number();
6600
6601 mf = minteg;
6602 mf.replace(x_var, b);
6603 mf.eval(eo);
6604 if(!mf.isNumber() || mf.number().includesInfinity()) {
6605 if(!b.setToFloatingPoint()) return false;
6606 mpfr_nextbelow(b.internalLowerFloat());
6607 mpfr_nextbelow(b.internalUpperFloat());
6608 mf = minteg;
6609 mf.replace(x_var, a);
6610 mf.eval(eo);
6611 }
6612 if(!mf.isNumber()) return false;
6613
6614 if(!Rp[0].add(mf.number()) || !Rp[0].multiply(nr_half) || !Rp[0].multiply(h)) return false;
6615
6616 if(safety_measures && min_steps < 15 && has_wide_trig_interval(minteg, x_var, eo, a, b)) min_steps = (max_steps < 15 ? max_steps : 15);
6617
6618 for(long int i = 1; i < max_steps; i++) {
6619
6620 if(CALCULATOR->aborted()) break;
6621
6622 if(!h.multiply(nr_half)) return false;
6623
6624 c.clear();
6625
6626 long int ep = 1 << (i - 1);
6627 ntmp = a; ntmp += h;
6628 for(long int j = 1; j <= ep; j++){
6629 if(CALCULATOR->aborted()) break;
6630 mf = minteg;
6631 mf.replace(x_var, ntmp);
6632 mf.eval(eo);
6633 if(CALCULATOR->aborted()) break;
6634 if(!mf.isNumber() || mf.number().includesInfinity()) {
6635 Number ntmp2(ntmp);
6636 if(ntmp2.setToFloatingPoint()) return false;
6637 if(j % 2 == 0) {mpfr_nextabove(ntmp2.internalLowerFloat()); mpfr_nextabove(ntmp2.internalUpperFloat());}
6638 else {mpfr_nextbelow(ntmp2.internalLowerFloat()); mpfr_nextbelow(ntmp2.internalUpperFloat());}
6639 mf = minteg;
6640 mf.replace(x_var, ntmp2);
6641 mf.eval(eo);
6642 if(CALCULATOR->aborted()) break;
6643 }
6644 if(!mf.isNumber() || !c.add(mf.number())) return false;
6645 ntmp += h; ntmp += h;
6646 }
6647 if(CALCULATOR->aborted()) break;
6648
6649 Rc[0] = h;
6650 ntmp = Rp[0];
6651 if(!ntmp.multiply(nr_half) || !Rc[0].multiply(c) || !Rc[0].add(ntmp)) return false;
6652
6653 for(long int j = 1; j <= i; ++j){
6654 if(CALCULATOR->aborted()) break;
6655 ntmp = 4;
6656 ntmp ^= j;
6657 Rc[j] = ntmp;
6658 ntmp--; ntmp.recip();
6659 if(!Rc[j].multiply(Rc[j - 1]) || !Rc[j].subtract(Rp[j - 1]) || !Rc[j].multiply(ntmp)) return false;
6660 }
6661 if(CALCULATOR->aborted()) break;
6662
6663 if(i >= min_steps - 1 && !Rp[i - 1].includesInfinity() && !Rc[i].includesInfinity()) {
6664 if(Rp[i - 1].hasImaginaryPart()) nunc = Rp[i - 1].realPart();
6665 else nunc = Rp[i - 1];
6666 if(Rc[i].hasImaginaryPart()) nunc -= Rc[i].realPart();
6667 else nunc -= Rc[i];
6668 nunc.abs();
6669 if(safety_measures) nunc *= 10;
6670 nunc.intervalToMidValue();
6671 if(Rp[i - 1].hasImaginaryPart() || Rc[i].hasImaginaryPart()) {
6672 nunc_i = Rp[i - 1].imaginaryPart();
6673 nunc_i -= Rc[i].imaginaryPart();
6674 nunc_i.abs();
6675 } else {
6676 nunc_i.clear();
6677 }
6678 if(safety_measures) nunc_i *= 10;
6679 nunc_i.intervalToMidValue();
6680 long int prec = PRECISION + (auto_max ? 3 : 1);
6681 if(auto_max) {
6682 if(i > 10) prec += 10 - ((!prevunc.isZero() || !prevunc_i.isZero()) ? i - 1 : i);
6683 if(prec < 4) prec = 4;
6684 }
6685 acc.set(1, 1, -prec);
6686 ntmp = Rc[i - 1];
6687 ntmp.intervalToMidValue();
6688 if(ntmp.hasImaginaryPart()) {
6689 if(ntmp.hasRealPart()) acc *= ntmp.realPart();
6690 } else {
6691 if(!ntmp.isZero()) acc *= ntmp;
6692 }
6693 acc.abs();
6694 acc.intervalToMidValue();
6695 nvalue = Rc[i - 1];
6696 if(nunc <= acc) {
6697 if(!nunc_i.isZero()) {
6698 acc_i.set(1, 1, -prec);
6699 if(ntmp.hasImaginaryPart()) acc_i *= ntmp.imaginaryPart();
6700 acc_i.abs();
6701 acc_i.intervalToMidValue();
6702 if(nunc_i <= acc_i) {
6703 if(!safety_measures) {
6704 nunc.setImaginaryPart(nunc_i);
6705 nvalue.setUncertainty(nunc);
6706 return true;
6707 }
6708 if(!prevunc.isZero() || !prevunc_i.isZero() || (nunc.isZero() && nunc_i.isZero())) {
6709 if(nunc <= prevunc && nunc_i <= prevunc_i) {
6710 if(!ntmp.hasRealPart()) prevunc = acc;
6711 if(!ntmp.hasImaginaryPart()) prevunc.setImaginaryPart(acc_i);
6712 else prevunc.setImaginaryPart(prevunc_i);
6713 nvalue.setUncertainty(prevunc);
6714 } else {
6715 acc.setImaginaryPart(acc_i);
6716 nvalue.setUncertainty(acc);
6717 }
6718 return true;
6719 }
6720 prevunc = nunc;
6721 prevunc_i = nunc_i;
6722 } else {
6723 prevunc.clear();
6724 prevunc_i.clear();
6725 }
6726 } else {
6727 if(!safety_measures) {
6728 nvalue.setUncertainty(nunc);
6729 return true;
6730 }
6731 if(!prevunc.isZero() || nunc.isZero()) {
6732 if(!prevunc_i.isZero()) nunc.setImaginaryPart(prevunc_i);
6733 if(!ntmp.isZero() && nunc <= prevunc) nvalue.setUncertainty(prevunc);
6734 else nvalue.setUncertainty(acc);
6735 return true;
6736 }
6737 prevunc = nunc;
6738 prevunc_i = nunc_i;
6739 }
6740 } else {
6741 prevunc.clear();
6742 prevunc_i.clear();
6743 }
6744 }
6745
6746 Number *rt = Rp;
6747 Rp = Rc;
6748 Rc = rt;
6749 }
6750 if(!nunc.isZero() || !nunc_i.isZero()) {
6751 acc.set(1, 1, auto_max ? -3 : -2);
6752 ntmp = nvalue;
6753 ntmp.intervalToMidValue();
6754 if(ntmp.hasImaginaryPart()) {
6755 if(ntmp.hasRealPart()) acc *= ntmp.realPart();
6756 } else {
6757 if(!ntmp.isZero()) acc *= ntmp;
6758 }
6759 acc.abs();
6760 acc.intervalToMidValue();
6761 if(nunc > acc) return false;
6762 if(!ntmp.hasRealPart()) nunc = acc;
6763 if(!nunc_i.isZero()) {
6764 acc.set(1, 1, -3);
6765 if(ntmp.hasImaginaryPart()) acc *= ntmp.imaginaryPart();
6766 acc.abs();
6767 acc.intervalToMidValue();
6768 if(nunc_i > acc) return false;
6769 if(ntmp.hasImaginaryPart()) nunc.setImaginaryPart(nunc_i);
6770 else nunc.setImaginaryPart(acc);
6771 }
6772 if(safety_measures) nunc *= 10;
6773 nvalue.setUncertainty(nunc);
6774 return true;
6775 }
6776 return false;
6777 }
numerical_integration_part(const MathStructure & minteg,const MathStructure & x_var,const MathStructure & merr_pre,const MathStructure & merr_diff,KnownVariable * v,Number & nvalue,EvaluationOptions & eo,const Number & nr,int type=0,int depth=0,bool nzerodiff=false)6778 int numerical_integration_part(const MathStructure &minteg, const MathStructure &x_var, const MathStructure &merr_pre, const MathStructure &merr_diff, KnownVariable *v, Number &nvalue, EvaluationOptions &eo, const Number &nr, int type = 0, int depth = 0, bool nzerodiff = false) {
6779 if(CALCULATOR->aborted()) return 0;
6780 eo.interval_calculation = INTERVAL_CALCULATION_NONE;
6781 MathStructure merr(merr_pre);
6782 int i_ret = 1;
6783 v->set(nr);
6784 bool do_parts = true;
6785 /*if(nzerodiff) {
6786 v->set(nr.lowerEndPoint());
6787 MathStructure mlow(merr);
6788 mlow.eval(eo);
6789 v->set(nr.upperEndPoint());
6790 merr.eval(eo);
6791 if(!merr.isNumber() || !mlow.isNumber() || merr.number().includesInfinity() || mlow.number().includesInfinity()) return 0;
6792 merr.number().setInterval(mlow.number(), merr.number());
6793 do_parts = false;
6794 } else if(depth > 1 && !merr_diff.isUndefined()) {
6795 CALCULATOR->beginTemporaryStopMessages();
6796 MathStructure mzero(merr_diff);
6797 mzero.eval(eo);
6798 if(CALCULATOR->endTemporaryStopMessages() == 0 && mzero.isNumber() && mzero.number().isNonZero() && (!mzero.number().hasImaginaryPart() || mzero.number().internalImaginary()->isNonZero())) {
6799 v->set(nr.lowerEndPoint());
6800 MathStructure mlow(merr);
6801 mlow.eval(eo);
6802 v->set(nr.upperEndPoint());
6803 merr.eval(eo);
6804 if(!merr.isNumber() || !mlow.isNumber() || merr.number().includesInfinity() || mlow.number().includesInfinity()) return 0;
6805 merr.number().setInterval(mlow.number(), merr.number());
6806 do_parts = false;
6807 nzerodiff = true;
6808 }
6809 }*/
6810 if(depth > 0 && do_parts) {
6811 CALCULATOR->beginTemporaryStopMessages();
6812 merr.eval(eo);
6813 do_parts = (CALCULATOR->endTemporaryStopMessages() > 0 || !merr.isNumber() || merr.number().includesInfinity());
6814 }
6815 if(do_parts) {
6816 integrate_parts:
6817 if(depth > 4) {
6818 if(numerical_integration(minteg, nvalue, x_var, eo, nr.lowerEndPoint(), nr.upperEndPoint(), 1002, type)) {nvalue.setApproximate(); return -1;}
6819 return 0;
6820 }
6821 vector<Number> parts;
6822 nr.splitInterval(depth == 0 ? 5 : 5, parts);
6823 nvalue.clear();
6824 Number n_i;
6825 for(size_t i = 0; i < parts.size(); i++) {
6826 int i_reti = numerical_integration_part(minteg, x_var, merr_pre, merr_diff, v, n_i, eo, parts[i], type, depth + 1, nzerodiff);
6827 if(i_reti != 0) {
6828 if(i_reti < i_ret) i_ret = i_reti;
6829 if(!nvalue.add(n_i)) return false;
6830 } else {
6831 return 0;
6832 }
6833 }
6834 return i_ret;
6835 } else {
6836 CALCULATOR->beginTemporaryStopIntervalArithmetic();
6837 eo.interval_calculation = INTERVAL_CALCULATION_NONE;
6838 Number nr_interval(merr.number());
6839 Number nr_interval_abs;
6840 Number nr1(nr_interval.upperEndPoint(true));
6841 Number nr2(nr_interval.lowerEndPoint(true));
6842 nr1.abs();
6843 nr2.abs();
6844 if(nr1.isGreaterThan(nr2)) nr_interval_abs = nr1;
6845 else nr_interval_abs = nr2;
6846 if(merr.number().hasImaginaryPart()) {
6847 if(merr.number().hasRealPart()) {
6848 nr1 = merr.number().realPart().upperEndPoint();
6849 nr2 = merr.number().realPart().lowerEndPoint();
6850 nr1.abs();
6851 nr2.abs();
6852 if(nr1.isGreaterThan(nr2)) nr_interval = nr1;
6853 else nr_interval = nr2;
6854 nr1 = merr.number().imaginaryPart().upperEndPoint();
6855 nr2 = merr.number().imaginaryPart().lowerEndPoint();
6856 nr1.abs();
6857 nr2.abs();
6858 if(nr1.isGreaterThan(nr2)) nr_interval.setImaginaryPart(nr1);
6859 else nr_interval.setImaginaryPart(nr2);
6860 } else {
6861 nr_interval.setImaginaryPart(nr_interval_abs);
6862 }
6863 } else {
6864 nr_interval = nr_interval_abs;
6865 }
6866 Number nr_samples(6, 1);
6867 Number nr_range(nr.upperEndPoint());
6868 nr_range -= nr.lowerEndPoint();
6869 int i_run = 0;
6870 while(true) {
6871 if(CALCULATOR->aborted()) {CALCULATOR->endTemporaryStopIntervalArithmetic(); return 0;}
6872 if(numerical_integration(minteg, nvalue, x_var, eo, nr.lowerEndPoint(), nr.upperEndPoint(), nr_samples.intValue(), type)) {
6873 if(nr.includesInfinity()) {
6874 CALCULATOR->endTemporaryStopIntervalArithmetic();
6875 return 0;
6876 }
6877 Number nr_prec(nr_range);
6878 if(type == 0 || type == 2) {
6879 nr_prec /= nr_samples;
6880 nr_prec ^= 4;
6881 nr_prec *= nr_range;
6882 nr_prec /= (type == 2 ? 80 : 180);
6883 } else if(type == 1) {
6884 nr_prec /= nr_samples;
6885 nr_prec ^= 2;
6886 nr_prec *= nr_range;
6887 nr_prec /= 12;
6888 } else if(type == 3) {
6889 nr_prec ^= 7;
6890 //nr_prec *= Number(8, 945); ?
6891 nr_prec /= (nr_samples ^ 6);
6892 }
6893 nr_prec *= nr_interval;
6894 Number nr_prec_abs(nr_prec);
6895 nr_prec_abs.abs();
6896 Number mabs(nvalue);
6897 mabs.abs();
6898 Number max_error(1, 1, -(PRECISION + 1 - (i_run * 2)));
6899 max_error *= mabs;
6900 if(nr_prec_abs >= max_error) {
6901 for(int i = 0; ; i++) {
6902 if(type == 0 || type == 2) {
6903 nr_samples = nr_range;
6904 nr_samples ^= 5;
6905 nr_samples /= (type == 2 ? 80 : 180);
6906 nr_samples *= nr_interval_abs;
6907 nr_samples /= max_error;
6908 nr_samples.root(4);
6909 } else if(type == 3) {
6910 nr_samples = nr_range;
6911 nr_samples ^= 7;
6912 //nr_samples *= Number(8, 945); ?
6913 nr_samples *= nr_interval_abs;
6914 nr_samples /= max_error;
6915 nr_samples.root(6);
6916 } else {
6917 nr_samples = nr_range;
6918 nr_samples ^= 3;
6919 nr_samples /= 12;
6920 nr_samples *= nr_interval_abs;
6921 nr_samples /= max_error;
6922 nr_samples.sqrt();
6923 }
6924 nr_samples.intervalToMidValue();
6925 nr_samples.ceil();
6926 if(type == 0 && nr_samples.isOdd()) {
6927 nr_samples++;
6928 } else if(type == 2 && !nr_samples.isIntegerDivisible(3)) {
6929 Number nmod(nr_samples);
6930 nmod.mod(3);
6931 if(nmod == 1) nr_samples += 2;
6932 else nr_samples += 1;
6933 } else if(type == 3 && !nr_samples.isIntegerDivisible(4)) {
6934 Number nmod(nr_samples);
6935 nmod.mod(4);
6936 if(nmod == 1) nr_samples += 3;
6937 if(nmod == 2) nr_samples += 2;
6938 else nr_samples += 1;
6939 }
6940 if(nr_samples < 10000) break;
6941 i_run++;
6942 if(depth <= 3 && PRECISION + 1 - (i_run * 2) < (PRECISION > 10 ? 10 : PRECISION) - depth) goto integrate_parts;
6943 if(PRECISION + 1 - (i_run * 2) < 5) {
6944 if(nr_samples < 50000) break;
6945 if(PRECISION + 1 - (i_run * 2) < 2 - depth) {
6946 if(numerical_integration(minteg, nvalue, x_var, eo, nr.lowerEndPoint(), nr.upperEndPoint(), 1002, type)) {nvalue.setApproximate(); return -1;}
6947 return 0;
6948 }
6949 }
6950 max_error *= Number(1, 1, (PRECISION + 1 - ((i_run - 1) * 2)));
6951 max_error *= Number(1, 1, -(PRECISION + 1 - (i_run * 2)));
6952 }
6953 } else {
6954 CALCULATOR->endTemporaryStopIntervalArithmetic();
6955 nvalue.setUncertainty(nr_prec);
6956 return 1;
6957 }
6958 } else {
6959 CALCULATOR->endTemporaryStopIntervalArithmetic();
6960 return 0;
6961 }
6962 i_run++;
6963 }
6964 }
6965 return 0;
6966 }
contains_complex(const MathStructure & mstruct)6967 bool contains_complex(const MathStructure &mstruct) {
6968 if(mstruct.isNumber()) return mstruct.number().isComplex();
6969 if(mstruct.isVariable() && mstruct.variable()->isKnown()) return contains_complex(((KnownVariable*) mstruct.variable())->get());
6970 for(size_t i = 0; i < mstruct.size(); i++) {
6971 if(contains_complex(mstruct[i])) return true;
6972 }
6973 return false;
6974 }
6975
check_denominators(const MathStructure & m,const MathStructure & mi,const MathStructure & mx,const EvaluationOptions & eo)6976 bool check_denominators(const MathStructure &m, const MathStructure &mi, const MathStructure &mx, const EvaluationOptions &eo) {
6977 if(m.contains(mx, false, true, true) == 0) return true;
6978 for(size_t i = 0; i < m.size(); i++) {
6979 if(!check_denominators(m[i], mi, mx, eo)) return false;
6980 }
6981 if(m.isPower()) {
6982 bool b_neg = m[1].representsNegative();
6983 if(!m[1].representsNonNegative()) {
6984 if(!m[0].representsNonZero()) {
6985 EvaluationOptions eo2 = eo;
6986 eo2.approximation = APPROXIMATION_APPROXIMATE;
6987 eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
6988 CALCULATOR->beginTemporaryStopMessages();
6989 KnownVariable *v = new KnownVariable("", "v", mi);
6990 MathStructure mpow(m[1]);
6991 mpow.replace(mx, v, true);
6992 mpow.eval(eo2);
6993 b_neg = mpow.representsNegative();
6994 CALCULATOR->endTemporaryStopMessages();
6995 v->destroy();
6996 }
6997 }
6998 if(b_neg && !m[0].representsNonZero()) {
6999 if(m[0].isZero()) return false;
7000 EvaluationOptions eo2 = eo;
7001 eo2.approximation = APPROXIMATION_APPROXIMATE;
7002 eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
7003 CALCULATOR->beginTemporaryStopMessages();
7004 MathStructure mbase(m[0]);
7005 KnownVariable *v = new KnownVariable("", "v", mi);
7006 mbase.replace(mx, v, true);
7007 bool b_multiple = mbase.contains(mx, true) > 0;
7008 if(b_multiple) mbase.replace(mx, v);
7009 mbase.eval(eo2);
7010 CALCULATOR->endTemporaryStopMessages();
7011 /*if(mbase.isZero()) {
7012 v->destroy(); return false;
7013 } else if(!b_multiple && mbase.isNumber()) {
7014 if(!mbase.number().isNonZero()) {v->destroy(); return false;}
7015 } else if(!mbase.isNumber() || !mbase.number().isNonZero()) {
7016 CALCULATOR->beginTemporaryStopMessages();
7017 eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
7018 mbase = m[0];
7019 mbase.replace(mx, v);
7020 mbase.eval(eo2);
7021 CALCULATOR->endTemporaryStopMessages();
7022 }*/
7023 if(mbase.isZero()) {
7024 v->destroy(); return false;
7025 } else if(!b_multiple && mbase.isNumber()) {
7026 if(!mbase.number().isNonZero()) {v->destroy(); return false;}
7027 } else if(!mbase.isNumber() || !mbase.number().isNonZero()) {
7028 CALCULATOR->beginTemporaryStopMessages();
7029 mbase = m[0];
7030 eo2.isolate_x = true;
7031 eo2.isolate_var = &mx;
7032 eo2.test_comparisons = true;
7033 eo2.approximation = APPROXIMATION_EXACT;
7034 mbase.transform(COMPARISON_NOT_EQUALS, m_zero);
7035 mbase.eval(eo2);
7036 eo2.approximation = APPROXIMATION_APPROXIMATE;
7037 eo2.isolate_x = false;
7038 eo2.isolate_var = NULL;
7039 if(!mbase.isNumber()) {
7040 MathStructure mtest(mbase);
7041 mtest.replace(mx, v);
7042 mtest.eval(eo2);
7043 if(mtest.isNumber()) mbase = mtest;
7044 }
7045 CALCULATOR->endTemporaryStopMessages();
7046 if(!mbase.isOne()) {
7047 if(mbase.isZero()) {v->destroy(); return false;}
7048 bool b = false;
7049 if(mbase.isComparison()) {
7050 CALCULATOR->beginTemporaryStopMessages();
7051 mbase[0].eval(eo2); mbase[1].eval(eo2);
7052 CALCULATOR->endTemporaryStopMessages();
7053 }
7054 if(mbase.isComparison() && mbase.comparisonType() == COMPARISON_NOT_EQUALS && (mbase[0] == mx || mbase[0].isFunction()) && mbase[1].isNumber() && mi.isNumber()) {
7055 ComparisonResult cr = COMPARISON_RESULT_UNKNOWN;
7056 if(mbase[0].isFunction()) {
7057 MathStructure mfunc(mbase[0]);
7058 mfunc.replace(mx, v);
7059 mfunc.eval(eo2);
7060 if(mfunc.isNumber()) cr = mbase[1].number().compare(mfunc.number());
7061 } else {
7062 cr = mbase[1].number().compare(mi.number());
7063 }
7064 b = COMPARISON_IS_NOT_EQUAL(cr);
7065 if(!b && cr != COMPARISON_RESULT_UNKNOWN) {v->destroy(); return false;}
7066 } else if(mbase.isLogicalAnd()) {
7067 for(size_t i = 0; i < mbase.size(); i++) {
7068 if(mbase[i].isComparison()) {mbase[i][0].eval(eo2); mbase[i][1].eval(eo2);}
7069 if(mbase[i].isComparison() && mbase[i].comparisonType() == COMPARISON_NOT_EQUALS && (mbase[i][0] == mx || mbase[i][0].isFunction()) && mbase[i][1].isNumber() && mi.isNumber()) {
7070 ComparisonResult cr = COMPARISON_RESULT_UNKNOWN;
7071 if(mbase[i][0].isFunction()) {
7072 MathStructure mfunc(mbase[i][0]);
7073 mfunc.replace(mx, v);
7074 mfunc.eval(eo2);
7075 if(mfunc.isNumber()) cr = mbase[i][1].number().compare(mfunc.number());
7076 } else {
7077 cr = mbase[i][1].number().compare(mi.number());
7078 }
7079 b = COMPARISON_IS_NOT_EQUAL(cr);
7080 if(!b && cr != COMPARISON_RESULT_UNKNOWN) {v->destroy(); return false;}
7081 }
7082 }
7083 }
7084 if(!b) {
7085 CALCULATOR->endTemporaryStopMessages();
7086 CALCULATOR->endTemporaryStopMessages();
7087 CALCULATOR->error(false, _("To avoid division by zero, the following must be true: %s."), format_and_print(mbase).c_str(), NULL);
7088 CALCULATOR->beginTemporaryStopMessages();
7089 CALCULATOR->beginTemporaryStopMessages();
7090 }
7091 }
7092 }
7093 v->destroy();
7094 }
7095 } else if(m.isVariable()) {
7096 if(m.variable()->isKnown() && !check_denominators(((KnownVariable*) m.variable())->get(), mi, mx, eo)) return false;
7097 } else if(m.isFunction() && (m.function()->id() == FUNCTION_ID_TAN || m.function()->id() == FUNCTION_ID_TANH || !m.representsNumber(true))) {
7098 EvaluationOptions eo2 = eo;
7099 eo2.approximation = APPROXIMATION_APPROXIMATE;
7100 eo2.assume_denominators_nonzero = false;
7101 MathStructure mfunc(m);
7102 bool b = mfunc.calculateFunctions(eo2);
7103 if(b && !check_denominators(mfunc, mi, mx, eo)) return false;
7104 if(mfunc.isFunction() && (mfunc.function()->id() == FUNCTION_ID_TAN || mfunc.function()->id() == FUNCTION_ID_TANH)) {
7105 mfunc.replace(mx, mi);
7106 eo2.interval_calculation = INTERVAL_CALCULATION_INTERVAL_ARITHMETIC;
7107 CALCULATOR->beginTemporaryStopMessages();
7108 b = mfunc.calculateFunctions(eo2);
7109 CALCULATOR->endTemporaryStopMessages();
7110 if(!b) return false;
7111 }
7112 }
7113 return true;
7114 }
replace_atanh(MathStructure & m,const MathStructure & x_var,const MathStructure & m1,const MathStructure & m2,const EvaluationOptions & eo)7115 bool replace_atanh(MathStructure &m, const MathStructure &x_var, const MathStructure &m1, const MathStructure &m2, const EvaluationOptions &eo) {
7116 bool b = false;
7117 if(m.isFunction() && m.function()->id() == FUNCTION_ID_ATANH && m.size() == 1 && m[0].contains(x_var, true)) {
7118 /*MathStructure mtest(m[0]);
7119 mtest.replace(x_var, m1);
7120 b = (mtest.compare(m_one) == COMPARISON_RESULT_EQUAL) || (mtest.compare(m_minus_one) == COMPARISON_RESULT_EQUAL);
7121 if(!b) {
7122 mtest = m[0];
7123 mtest.replace(x_var, m2);
7124 b = (mtest.compare(m_one) == COMPARISON_RESULT_EQUAL) || (mtest.compare(m_minus_one) == COMPARISON_RESULT_EQUAL);
7125 }*/
7126 b = true;
7127 if(b) {
7128 MathStructure marg(m[0]);
7129 m = marg;
7130 m += m_one;
7131 m.transformById(FUNCTION_ID_LOG);
7132 m *= nr_half;
7133 m += marg;
7134 m.last().negate();
7135 m.last() += m_one;
7136 m.last().transformById(FUNCTION_ID_LOG);
7137 m.last() *= Number(-1, 2);
7138 return true;
7139 }
7140 }
7141 if(m.isPower() && m[1].isInteger() && (m[1].number() > 10 || m[1].number() < -10)) return false;
7142 for(size_t i = 0; i < m.size(); i++) {
7143 if(replace_atanh(m[i], x_var, m1, m2, eo)) b = true;
7144 }
7145 if(b) {
7146 m.childrenUpdated();
7147 m.calculatesub(eo, eo, false);
7148 }
7149 return b;
7150 }
find_abs_x(MathStructure & mstruct,const MathStructure & x_var)7151 MathStructure *find_abs_x(MathStructure &mstruct, const MathStructure &x_var) {
7152 for(size_t i = 0; i < mstruct.size(); i++) {
7153 MathStructure *m = find_abs_x(mstruct[i], x_var);
7154 if(m) return m;
7155 }
7156 if(mstruct.isFunction() && ((mstruct.function()->id() == FUNCTION_ID_ABS && mstruct.size() == 1) || (mstruct.function()->id() == FUNCTION_ID_ROOT && mstruct.size() == 2 && mstruct[1].isInteger() && mstruct[1].number().isOdd()))) {
7157 return &mstruct;
7158 }
7159 return NULL;
7160 }
replace_abs(MathStructure & mstruct,const MathStructure & mabs,bool neg)7161 bool replace_abs(MathStructure &mstruct, const MathStructure &mabs, bool neg) {
7162 if(mstruct.equals(mabs, true, true)) {
7163 if(mabs.function()->id() == FUNCTION_ID_ROOT) {
7164 mstruct[1].inverse();
7165 mstruct.setType(STRUCT_POWER);
7166 if(neg) {
7167 mstruct[0].negate();
7168 mstruct.negate();
7169 }
7170 } else {
7171 mstruct.setToChild(1, true);
7172 if(neg) mstruct.negate();
7173 }
7174 return true;
7175 }
7176 bool b_ret = false;
7177 for(size_t i = 0; i < mstruct.size(); i++) {
7178 if(replace_abs(mstruct[i], mabs, neg)) b_ret = true;
7179 }
7180 return b_ret;
7181 }
7182
7183 // Check definite integral for functions that cannot be calculated
contains_incalc_function(const MathStructure & mstruct,const EvaluationOptions & eo)7184 bool contains_incalc_function(const MathStructure &mstruct, const EvaluationOptions &eo) {
7185 for(size_t i = 0; i < mstruct.size(); i++) {
7186 if(contains_incalc_function(mstruct[i], eo)) return true;
7187 }
7188 if(mstruct.isFunction()) {
7189 if((mstruct.function()->id() == FUNCTION_ID_FRESNEL_S || mstruct.function()->id() == FUNCTION_ID_FRESNEL_C) && mstruct.size() == 1) {
7190 if(mstruct[0].representsComplex()) return true;
7191 MathStructure mtest(mstruct[0]);
7192 mtest.eval(eo);
7193 return !mtest.isNumber() || !(mtest.number() >= -6) || !(mtest.number() <= 6);
7194 } else if(mstruct.function()->id() == FUNCTION_ID_POLYLOG || ((mstruct.function()->id() == FUNCTION_ID_EXPINT || mstruct.function()->id() == FUNCTION_ID_ERF || mstruct.function()->id() == FUNCTION_ID_ERFI) && mstruct.size() == 1 && !mstruct[0].representsReal())) {
7195 MathStructure mtest(mstruct);
7196 mtest.eval(eo);
7197 return !mtest.isNumber();
7198 } else if(mstruct.function()->id() == FUNCTION_ID_I_GAMMA && mstruct.size() == 2) {
7199 #if MPFR_VERSION_MAJOR < 4
7200 return true;
7201 #else
7202 return !COMPARISON_IS_EQUAL_OR_LESS(mstruct[1].compare(m_zero));
7203 #endif
7204 }
7205 }
7206 return false;
7207 }
7208
test_definite_ln(const MathStructure & m,const MathStructure & mi,const MathStructure & mx,const EvaluationOptions & eo)7209 bool test_definite_ln(const MathStructure &m, const MathStructure &mi, const MathStructure &mx, const EvaluationOptions &eo) {
7210 for(size_t i = 0; i < m.size(); i++) {
7211 if(!test_definite_ln(m[i], mi, mx, eo)) return false;
7212 }
7213 if(m.isFunction() && m.function()->id() == FUNCTION_ID_LOG && m.size() == 1 && m[0].contains(mx, true) > 0 && !m[0].representsNonComplex(true)) {
7214 MathStructure mtest(m[0]);
7215 mtest.replace(mx, mi);
7216 EvaluationOptions eo2 = eo;
7217 eo2.approximation = APPROXIMATION_APPROXIMATE;
7218 eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
7219 CALCULATOR->beginTemporaryStopMessages();
7220 mtest.eval(eo2);
7221 CALCULATOR->endTemporaryStopMessages();
7222 if(mtest.isNumber() && mtest.number().hasImaginaryPart() && !mtest.number().imaginaryPartIsNonZero() && !mtest.number().realPart().isNonNegative()) return false;
7223 }
7224 return true;
7225 }
7226
replace_intervals(MathStructure & m,vector<KnownVariable * > vars)7227 void replace_intervals(MathStructure &m, vector<KnownVariable*> vars) {
7228 if(m.isNumber() && m.number().isInterval()) {
7229 KnownVariable *v = new KnownVariable("", format_and_print(m), m);
7230 m.set(v, true);
7231 vars.push_back(v);
7232 return;
7233 }
7234 for(size_t i = 0; i < m.size(); i++) {
7235 replace_intervals(m[i], vars);
7236 }
7237 }
restore_intervals(MathStructure & m,MathStructure & m2,vector<KnownVariable * > vars,const EvaluationOptions & eo)7238 void restore_intervals(MathStructure &m, MathStructure &m2, vector<KnownVariable*> vars, const EvaluationOptions &eo) {
7239 for(size_t i = 0; i < vars.size(); i++) {
7240 if(eo.approximation == APPROXIMATION_EXACT) {
7241 m.replace(vars[i], vars[i]->get());
7242 m2.replace(vars[i], vars[i]->get());
7243 }
7244 vars[i]->destroy();
7245 }
7246 }
7247
integrate(const MathStructure & lower_limit,const MathStructure & upper_limit,const MathStructure & x_var_pre,const EvaluationOptions & eo,bool force_numerical,bool simplify_first)7248 bool MathStructure::integrate(const MathStructure &lower_limit, const MathStructure &upper_limit, const MathStructure &x_var_pre, const EvaluationOptions &eo, bool force_numerical, bool simplify_first) {
7249
7250 if(!lower_limit.isUndefined() && lower_limit == upper_limit) {
7251 clear();
7252 return true;
7253 }
7254
7255 MathStructure m1(lower_limit), m2(upper_limit);
7256 MathStructure x_var = x_var_pre;
7257 if(m1.isUndefined() != m2.isUndefined()) {
7258 if(m1.isUndefined()) m1.set(nr_minus_inf);
7259 else m2.set(nr_plus_inf);
7260 }
7261 m1.eval(eo);
7262 m2.eval(eo);
7263 int definite_integral = 0;
7264 if(!m1.isUndefined() && !m2.isUndefined()) definite_integral = -1;
7265 if(definite_integral < 0 && (!m1.isNumber() || !m1.number().isMinusInfinity()) && (!m2.isNumber() || !m2.number().isPlusInfinity())) definite_integral = 1;
7266 if(definite_integral > 0 && m1 == m2) {
7267 clear();
7268 return true;
7269 }
7270
7271 CALCULATOR->beginTemporaryStopMessages();
7272 EvaluationOptions eo2 = eo;
7273 if(simplify_first) eo2.approximation = APPROXIMATION_EXACT;
7274 CALCULATOR->beginTemporaryStopMessages();
7275 MathStructure mstruct_pre(*this);
7276 MathStructure m_interval;
7277 if(!m1.isUndefined()) {
7278 m_interval.set(CALCULATOR->getFunctionById(FUNCTION_ID_INTERVAL), &m1, &m2, NULL);
7279 CALCULATOR->beginTemporaryStopMessages();
7280 EvaluationOptions eo3 = eo;
7281 eo3.approximation = APPROXIMATION_APPROXIMATE;
7282 m_interval.calculateFunctions(eo3);
7283 CALCULATOR->endTemporaryStopMessages();
7284 UnknownVariable *var = new UnknownVariable("", format_and_print(x_var_pre));
7285 var->setInterval(m_interval);
7286 x_var.set(var);
7287 mstruct_pre.replace(x_var_pre, x_var);
7288 var->destroy();
7289 if(definite_integral && !check_denominators(mstruct_pre, m_interval, x_var, eo)) {
7290 if(definite_integral < 0) {
7291 definite_integral = 0;
7292 } else {
7293 CALCULATOR->endTemporaryStopMessages();
7294 CALCULATOR->endTemporaryStopMessages(true);
7295 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7296 return false;
7297 }
7298 }
7299 }
7300 MathStructure mstruct(mstruct_pre);
7301 vector<KnownVariable*> vars;
7302 replace_intervals(mstruct, vars);
7303 eo2.do_polynomial_division = false;
7304
7305 if(simplify_first) mstruct.eval(eo2);
7306
7307 if(definite_integral > 0 && mstruct.isAddition() && m1.isNumber() && m1.number().isReal() && m2.isNumber() && m2.number().isReal()) {
7308 mstruct.replace(x_var, x_var_pre);
7309 MathStructure mbak(mstruct);
7310 Number nr;
7311 for(size_t i = 0; i < mstruct.size();) {
7312 if(!mstruct[i].integrate(lower_limit, upper_limit, x_var_pre, eo, force_numerical, simplify_first)) {
7313 CALCULATOR->endTemporaryStopMessages();
7314 CALCULATOR->endTemporaryStopMessages();
7315 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7316 if(simplify_first) set(mbak);
7317 return false;
7318 }
7319 if(mstruct[i].isNumber()) {
7320 if(nr.add(mstruct[i].number())) mstruct.delChild(i + 1);
7321 else i++;
7322 } else i++;
7323 }
7324 mstruct.childrenUpdated();
7325 if(mstruct.size() == 0) mstruct.set(nr, true);
7326 else if(!nr.isZero() || nr.isApproximate()) mstruct.addChild(nr);
7327 CALCULATOR->endTemporaryStopMessages(true);
7328 CALCULATOR->endTemporaryStopMessages(true);
7329 set(mstruct);
7330 return true;
7331 }
7332 if(simplify_first) do_simplification(mstruct, eo2, true, false, false, true, true);
7333 eo2.do_polynomial_division = eo.do_polynomial_division;
7334 MathStructure mbak(mstruct);
7335
7336 if(!force_numerical || definite_integral == 0) {
7337 int use_abs = -1;
7338 /*if(m1.isUndefined() && x_var.representsReal() && !contains_complex(mstruct)) {
7339 use_abs = 1;
7340 }*/
7341 if(definite_integral) replace_atanh(mstruct, x_var, lower_limit, upper_limit, eo2);
7342 if(definite_integral && !simplify_first) combine_ln(mstruct, x_var, eo2);
7343
7344 int b = mstruct.integrate(x_var, eo2, simplify_first, use_abs, definite_integral, true, (definite_integral && eo.approximation != APPROXIMATION_EXACT && PRECISION < 20) ? 2 : 4);
7345
7346 if(b < 0) {
7347 restore_intervals(mstruct, mbak, vars, eo);
7348 CALCULATOR->endTemporaryStopMessages(true);
7349 CALCULATOR->endTemporaryStopMessages(true);
7350 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7351 if(simplify_first) {
7352 set(mbak);
7353 if(definite_integral != 0) replace(x_var, x_var_pre);
7354 }
7355 return false;
7356 }
7357 if(simplify_first && eo.approximation != APPROXIMATION_EXACT && (!b || mstruct.containsFunctionId(FUNCTION_ID_INTEGRATE, true) > 0)) {
7358 vector<CalculatorMessage> blocked_messages;
7359 CALCULATOR->endTemporaryStopMessages(false, &blocked_messages);
7360 CALCULATOR->beginTemporaryStopMessages();
7361 MathStructure mbak_integ(mstruct);
7362 eo2.approximation = eo.approximation;
7363 eo2.do_polynomial_division = false;
7364 mstruct = mstruct_pre;
7365 if(definite_integral) replace_atanh(mstruct, x_var, lower_limit, upper_limit, eo2);
7366 mstruct.eval(eo2);
7367 do_simplification(mstruct, eo2, true, false, false, true, true);
7368 eo2.do_polynomial_division = eo.do_polynomial_division;
7369 int b2 = mstruct.integrate(x_var, eo2, true, use_abs, definite_integral, true, (definite_integral && eo.approximation != APPROXIMATION_EXACT && PRECISION < 20) ? 2 : 4);
7370 if(b2 < 0) {
7371 restore_intervals(mstruct, mbak, vars, eo);
7372 CALCULATOR->endTemporaryStopMessages(true);
7373 CALCULATOR->endTemporaryStopMessages(true);
7374 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7375 if(simplify_first) {
7376 set(mbak);
7377 if(definite_integral != 0) replace(x_var, x_var_pre);
7378 }
7379 return false;
7380 }
7381 if(b2 && (!b || mstruct.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0)) {
7382 CALCULATOR->endTemporaryStopMessages(true);
7383 b = true;
7384 } else {
7385 CALCULATOR->endTemporaryStopMessages(false);
7386 if(b) {
7387 CALCULATOR->addMessages(&blocked_messages);
7388 mstruct = mbak_integ;
7389 }
7390 }
7391 } else {
7392 restore_intervals(mstruct, mbak, vars, eo);
7393 CALCULATOR->endTemporaryStopMessages(true);
7394 }
7395 eo2.approximation = eo.approximation;
7396 if(b) {
7397 if(definite_integral && mstruct.containsFunctionId(FUNCTION_ID_INTEGRATE, true) <= 0 && test_definite_ln(mstruct, m_interval, x_var, eo)) {
7398 CALCULATOR->endTemporaryStopMessages(true);
7399 MathStructure mstruct_lower(mstruct);
7400 if(m1.isInfinite() || m2.isInfinite()) {
7401 CALCULATOR->beginTemporaryStopMessages();
7402 EvaluationOptions eo3 = eo;
7403 eo3.approximation = APPROXIMATION_EXACT;
7404 if(m1.isInfinite()) {
7405 b = mstruct_lower.calculateLimit(x_var, m1, eo3) && !mstruct_lower.isInfinite();
7406 } else {
7407 mstruct_lower.replace(x_var, lower_limit);
7408 b = eo.approximation == APPROXIMATION_EXACT || !contains_incalc_function(mstruct_lower, eo);
7409 }
7410 MathStructure mstruct_upper(mstruct);
7411 if(m2.isInfinite()) {
7412 b = mstruct_upper.calculateLimit(x_var, m2, eo3) && !mstruct_upper.isInfinite();
7413 } else {
7414 mstruct_upper.replace(x_var, upper_limit);
7415 b = eo.approximation == APPROXIMATION_EXACT || !contains_incalc_function(mstruct_upper, eo);
7416 }
7417 if(b) {
7418 set(mstruct_upper);
7419 subtract(mstruct_lower);
7420 return true;
7421 } else {
7422 if(definite_integral > 0) {
7423 CALCULATOR->endTemporaryStopMessages(true);
7424 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7425 if(simplify_first) {
7426 set(mbak);
7427 replace(x_var, x_var_pre);
7428 }
7429 return false;
7430 } else {
7431 definite_integral = 0;
7432 }
7433 }
7434 } else {
7435 mstruct_lower.replace(x_var, lower_limit);
7436 if(eo.approximation == APPROXIMATION_EXACT || !m1.isNumber() || !m1.number().isReal() || !contains_incalc_function(mstruct_lower, eo)) {
7437 mstruct.replace(x_var, upper_limit);
7438 if(eo.approximation != APPROXIMATION_EXACT && m2.isNumber() && m2.number().isReal() && contains_incalc_function(mstruct, eo)) {
7439 mstruct = mbak;
7440 } else {
7441 set(mstruct);
7442 subtract(mstruct_lower);
7443 return true;
7444 }
7445 }
7446 }
7447 } else if(definite_integral < 0) {
7448 definite_integral = 0;
7449 } else if(definite_integral > 0) {
7450 mstruct = mbak;
7451 }
7452 if(!definite_integral) {
7453 set(mstruct);
7454 if(!m1.isUndefined()) replace(x_var, x_var_pre);
7455 CALCULATOR->endTemporaryStopMessages(true);
7456 add(CALCULATOR->getVariableById(VARIABLE_ID_C));
7457 return true;
7458 }
7459 }
7460 if(!b) {
7461 if(definite_integral <= 0) {
7462 CALCULATOR->endTemporaryStopMessages(true);
7463 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7464 if(simplify_first) {
7465 set(mbak);
7466 replace(x_var, x_var_pre);
7467 }
7468 return false;
7469 } else {
7470 mstruct = mbak;
7471 }
7472 }
7473
7474 // Calculate definite integral with abs() or root() with appropriate intervals
7475 MathStructure *mabs = find_abs_x(mbak, x_var);
7476 if(mabs && !is_differentiable((*mabs)[0])) mabs = NULL;
7477 if(mabs && !(*mabs)[0].representsNonComplex(true)) {
7478 MathStructure mtest((*mabs)[0]);
7479 mtest.transformById(FUNCTION_ID_IM);
7480 if(mtest.compare(m_zero) != COMPARISON_RESULT_EQUAL) mabs = NULL;
7481 }
7482 if(mabs) {
7483 bool b_reversed = COMPARISON_IS_EQUAL_OR_GREATER(m2.compare(m1));
7484 MathStructure m0((*mabs)[0]);
7485 m0.transform(COMPARISON_EQUALS, m_zero);
7486 EvaluationOptions eo3 = eo;
7487 eo3.approximation = APPROXIMATION_EXACT;
7488 eo3.isolate_x = true;
7489 eo3.isolate_var = &x_var;
7490 m0.eval(eo3);
7491 bool b_exit = false;
7492 if(m0.isZero()) {
7493 m0 = (*mabs)[0];
7494 m0.replace(x_var, lower_limit);
7495 ComparisonResult cr1 = m0.compare(m_zero);
7496 if(COMPARISON_IS_EQUAL_OR_LESS(cr1)) {
7497 if(replace_abs(mbak, *mabs, false)) {
7498 mbak.replace(x_var, x_var_pre);
7499 CALCULATOR->endTemporaryStopMessages(true);
7500 if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7501 set(mbak);
7502 return true;
7503 }
7504 if(simplify_first) set(mbak);
7505 return false;
7506 }
7507 } else if(COMPARISON_IS_EQUAL_OR_GREATER(cr1)) {
7508 if(replace_abs(mbak, *mabs, true)) {
7509 mbak.replace(x_var, x_var_pre);
7510 CALCULATOR->endTemporaryStopMessages(true);
7511 if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7512 set(mbak);
7513 return true;
7514 }
7515 if(simplify_first) set(mbak);
7516 return false;
7517 }
7518 }
7519 } else if(m0.isComparison() && m0.comparisonType() == COMPARISON_EQUALS && m0[0] == x_var && m0[1].contains(x_var, true) == 0) {
7520 CALCULATOR->endTemporaryStopMessages();
7521 CALCULATOR->beginTemporaryStopMessages();
7522 m0.setToChild(2, true);
7523 ComparisonResult cr1 = m0.compare(b_reversed ? m2 : m1);
7524 ComparisonResult cr2 = m0.compare(b_reversed ? m1 : m2);
7525 if(COMPARISON_IS_EQUAL_OR_GREATER(cr1) || COMPARISON_IS_EQUAL_OR_LESS(cr2)) {
7526 MathStructure mtest((*mabs)[0]);
7527 if(b_reversed) mtest.replace(x_var, COMPARISON_IS_EQUAL_OR_GREATER(cr1) ? lower_limit : upper_limit);
7528 else mtest.replace(x_var, COMPARISON_IS_EQUAL_OR_GREATER(cr1) ? upper_limit : lower_limit);
7529 ComparisonResult cr = mtest.compare(m_zero);
7530 if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7531 if(replace_abs(mbak, *mabs, false)) {
7532 mbak.replace(x_var, x_var_pre);
7533 CALCULATOR->endTemporaryStopMessages(true);
7534 if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7535 set(mbak);
7536 return true;
7537 }
7538 if(simplify_first) set(mbak);
7539 return false;
7540 }
7541 } else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7542 if(replace_abs(mbak, *mabs, true)) {
7543 mbak.replace(x_var, x_var_pre);
7544 CALCULATOR->endTemporaryStopMessages(true);
7545 if(mbak.integrate(lower_limit, upper_limit, x_var_pre, eo, false, true)) {
7546 set(mbak);
7547 return true;
7548 }
7549 if(simplify_first) set(mbak);
7550 return false;
7551 }
7552 }
7553 } else if(cr1 == COMPARISON_RESULT_LESS && cr2 == COMPARISON_RESULT_GREATER) {
7554 MathStructure mtest((*mabs)[0]);
7555 mtest.replace(x_var, lower_limit);
7556 ComparisonResult cr = mtest.compare(m_zero);
7557 MathStructure minteg1(mbak), minteg2;
7558 b = false;
7559 if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7560 if(replace_abs(minteg1, *mabs, false)) b = true;
7561 } else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7562 if(replace_abs(minteg1, *mabs, true)) b = true;
7563 }
7564 if(b) {
7565 minteg1.replace(x_var, x_var_pre);
7566 CALCULATOR->beginTemporaryStopMessages();
7567 b = minteg1.integrate(lower_limit, m0, x_var_pre, eo, false, true);
7568 b_exit = CALCULATOR->endTemporaryStopMessages(NULL, NULL, MESSAGE_ERROR) == 0;
7569 if(!b_exit) b = false;
7570 }
7571 if(b) {
7572 mtest = (*mabs)[0];
7573 mtest.replace(x_var, upper_limit);
7574 cr = mtest.compare(m_zero);
7575 minteg2 = mbak;
7576 b = false;
7577 if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7578 if(replace_abs(minteg2, *mabs, false)) b = true;
7579 } else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7580 if(replace_abs(minteg2, *mabs, true)) b = true;
7581 }
7582 }
7583 if(b) {
7584 minteg2.replace(x_var, x_var_pre);
7585 CALCULATOR->beginTemporaryStopMessages();
7586 b = minteg2.integrate(m0, upper_limit, x_var_pre, eo, false, true);
7587 b_exit = CALCULATOR->endTemporaryStopMessages(NULL, NULL, MESSAGE_ERROR) == 0;
7588 if(!b_exit) b = false;
7589 }
7590 if(b) {
7591 CALCULATOR->endTemporaryStopMessages(true);
7592 set(minteg1);
7593 add(minteg2);
7594 return true;
7595 }
7596 }
7597 } else if(m0.isLogicalOr() && m0.size() <= 10) {
7598 vector<MathStructure> zeroes;
7599 bool b = true;
7600 for(size_t i = 0; i < m0.size(); i++) {
7601 if(!m0[i].isComparison() || m0[i].comparisonType() != COMPARISON_EQUALS || m0[i][0] != x_var) {
7602 b = false;
7603 break;
7604 } else {
7605 for(size_t i2 = 0; i2 < zeroes.size(); i2++) {
7606 ComparisonResult cr = m0[i][1].compare(zeroes[i2]);
7607 if(cr == COMPARISON_RESULT_GREATER) {zeroes.insert(zeroes.begin() + i2, m0[i][1]); break;}
7608 else if(cr != COMPARISON_RESULT_LESS) {b = false; break;}
7609 }
7610 if(!b) break;
7611 if(zeroes.size() == i) zeroes.push_back(m0[i][1]);
7612 }
7613 }
7614 if(b) {
7615 vector<MathStructure> integs;
7616 for(size_t i = 0; i <= zeroes.size(); i++) {
7617 MathStructure mtest((*mabs)[0]);
7618 if(i == 0) {
7619 mtest.replace(x_var, b_reversed ? upper_limit : lower_limit);
7620 } else if(i == zeroes.size()) {
7621 mtest.replace(x_var, b_reversed ? lower_limit : upper_limit);
7622 } else {
7623 MathStructure mrepl(zeroes[i - 1]);
7624 mrepl += zeroes[i];
7625 mrepl *= nr_half;
7626 mtest.replace(x_var, mrepl);
7627 }
7628 ComparisonResult cr = mtest.compare(m_zero);
7629 MathStructure minteg(mbak);
7630 b = false;
7631 if(COMPARISON_IS_EQUAL_OR_LESS(cr)) {
7632 if(replace_abs(minteg, *mabs, false)) b = true;
7633 } else if(COMPARISON_IS_EQUAL_OR_GREATER(cr)) {
7634 if(replace_abs(minteg, *mabs, true)) b = true;
7635 }
7636 if(b) {
7637 minteg.replace(x_var, x_var_pre);
7638 CALCULATOR->beginTemporaryStopMessages();
7639 b = minteg.integrate(i == 0 ? (b_reversed ? upper_limit : lower_limit) : zeroes[i - 1], i == zeroes.size() ? (b_reversed ? lower_limit : upper_limit) : zeroes[i], x_var_pre, eo, false, true);
7640 b_exit = CALCULATOR->endTemporaryStopMessages(NULL, NULL, MESSAGE_ERROR) == 0;
7641 if(!b_exit) b = false;
7642 if(b_reversed) minteg.negate();
7643 }
7644 if(!b) break;
7645 integs.push_back(minteg);
7646 }
7647 if(b) {
7648 for(size_t i = 0; i < integs.size(); i++) {
7649 if(i == 0) set(integs[i]);
7650 else add(integs[i], true);
7651 }
7652 CALCULATOR->endTemporaryStopMessages(true);
7653 return true;
7654 }
7655 }
7656 }
7657 if(b_exit) {
7658 CALCULATOR->endTemporaryStopMessages();
7659 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7660 if(simplify_first) {
7661 set(mbak);
7662 replace(x_var, x_var_pre);
7663 }
7664 return false;
7665 }
7666 }
7667 CALCULATOR->endTemporaryStopMessages();
7668 if(mstruct.containsInterval() && eo.approximation == APPROXIMATION_EXACT) {
7669 CALCULATOR->error(false, _("Unable to integrate the expression exact."), NULL);
7670 if(simplify_first) {
7671 set(mstruct);
7672 replace(x_var, x_var_pre);
7673 }
7674 return false;
7675 }
7676 } else {
7677 CALCULATOR->endTemporaryStopMessages();
7678 CALCULATOR->endTemporaryStopMessages();
7679 restore_intervals(mstruct, mbak, vars, eo);
7680 }
7681
7682 if(m1.isNumber() && m1.number().isReal() && m2.isNumber() && m2.number().isReal()) {
7683
7684 if(eo.approximation != APPROXIMATION_EXACT) eo2.approximation = APPROXIMATION_APPROXIMATE;
7685
7686 mstruct = mstruct_pre;
7687 mstruct.eval(eo2);
7688
7689 eo2.interval_calculation = INTERVAL_CALCULATION_SIMPLE_INTERVAL_ARITHMETIC;
7690 eo2.warn_about_denominators_assumed_nonzero = false;
7691
7692 Number nr_begin, nr_end;
7693 bool b_reversed = false;
7694 if(m1.number().isGreaterThan(m2.number())) {
7695 nr_begin = m2.number();
7696 nr_end = m1.number();
7697 b_reversed = true;
7698 } else {
7699 nr_begin = m1.number();
7700 nr_end = m2.number();
7701 }
7702 if(eo.approximation != APPROXIMATION_EXACT) {
7703 Number nr;
7704 CALCULATOR->beginTemporaryStopMessages();
7705 if(romberg(mstruct, nr, x_var, eo2, nr_begin, nr_end)) {
7706 CALCULATOR->endTemporaryStopMessages();
7707 if(b_reversed) nr.negate();
7708 if(!force_numerical) CALCULATOR->error(false, _("Definite integral was approximated."), NULL);
7709 set(nr);
7710 return true;
7711 }
7712 CALCULATOR->endTemporaryStopMessages();
7713 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7714 if(simplify_first) {
7715 set(mbak);
7716 replace(x_var, x_var_pre);
7717 }
7718 return false;
7719 }
7720 Number nr_range(nr_end);
7721 nr_range -= nr_begin;
7722 MathStructure merr(mstruct);
7723 CALCULATOR->beginTemporaryStopMessages();
7724 eo2.expand = false;
7725 for(size_t i = 0; i < 4; i++) {
7726 if(merr.containsFunctionId(FUNCTION_ID_DIFFERENTIATE, true) > 0 || !merr.differentiate(x_var, eo2)) {
7727 break;
7728 }
7729 merr.calculatesub(eo2, eo2, true);
7730 if(CALCULATOR->aborted() || merr.countTotalChildren() > 200) {
7731 break;
7732 }
7733 }
7734 eo2.expand = eo.expand;
7735 CALCULATOR->endTemporaryStopMessages();
7736 if(merr.isZero()) {
7737 Number nr;
7738 if(numerical_integration(mstruct, nr, x_var, eo2, nr_begin, nr_end, 12, 0)) {
7739 if(b_reversed) nr.negate();
7740 set(nr);
7741 return true;
7742 }
7743 }
7744 CALCULATOR->error(false, _("Unable to integrate the expression exact."), NULL);
7745 if(simplify_first) {
7746 set(mbak);
7747 replace(x_var, x_var_pre);
7748 }
7749 return false;
7750 }
7751 if(simplify_first) {
7752 set(mbak);
7753 replace(x_var, x_var_pre);
7754 }
7755 CALCULATOR->error(false, _("Unable to integrate the expression."), NULL);
7756 return false;
7757 }
7758
7759
7760
7761