nerdamer 1.1.9 → 1.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Calculus.js CHANGED
@@ -1,79 +1,79 @@
1
1
  /* global module */
2
2
 
3
3
  /*
4
- * Author : Martin Donk
5
- * Website : http://www.nerdamer.com
6
- * Email : martin.r.donk@gmail.com
7
- * Source : https://github.com/jiggzson/nerdamer
8
- */
4
+ * Author : Martin Donk
5
+ * Website : http://www.nerdamer.com
6
+ * Email : martin.r.donk@gmail.com
7
+ * Source : https://github.com/jiggzson/nerdamer
8
+ */
9
9
 
10
10
  if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
11
11
  var nerdamer = require('./nerdamer.core.js');
12
12
  require('./Algebra.js');
13
13
  }
14
14
 
15
- (function() {
15
+ (function () {
16
16
  "use strict";
17
-
17
+
18
18
  var core = nerdamer.getCore(),
19
- _ = core.PARSER,
20
- Frac = core.Frac,
21
- Settings = core.Settings,
22
- isSymbol = core.Utils.isSymbol,
23
- FN = core.groups.FN,
24
- Symbol = core.Symbol,
25
- text = core.Utils.text,
26
- inBrackets = core.Utils.inBrackets,
27
- isInt = core.Utils.isInt,
28
- format = core.Utils.format,
29
- even = core.Utils.even,
30
- evaluate = core.Utils.evaluate,
31
- N = core.groups. N,
32
- S = core.groups.S,
33
- FN = core.groups.FN,
34
- PL = core.groups.PL,
35
- CP = core.groups.CP,
36
- CB = core.groups.CB,
37
- EX = core.groups.EX,
38
- P = core.groups.P,
39
- LOG = Settings.LOG,
40
- EXP = 'exp',
41
- ABS = 'abs',
42
- SQRT = 'sqrt',
43
- SIN = 'sin',
44
- COS = 'cos',
45
- TAN = 'tan',
46
- SEC = 'sec',
47
- CSC = 'csc',
48
- COT = 'cot',
49
- ASIN = 'asin',
50
- ACOS = 'acos',
51
- ATAN = 'atan',
52
- ASEC = 'asec',
53
- ACSC = 'acsc',
54
- ACOT = 'acot',
55
- SINH = 'sinh',
56
- COSH = 'cosh',
57
- TANH = 'tanh',
58
- CSCH = 'csch',
59
- SECH = 'sech',
60
- COTH = 'coth',
61
- ASECH = 'asech',
62
- ACSCH = 'acsch',
63
- ACOTH = 'acoth';
64
-
19
+ _ = core.PARSER,
20
+ Frac = core.Frac,
21
+ Settings = core.Settings,
22
+ isSymbol = core.Utils.isSymbol,
23
+ FN = core.groups.FN,
24
+ Symbol = core.Symbol,
25
+ text = core.Utils.text,
26
+ inBrackets = core.Utils.inBrackets,
27
+ isInt = core.Utils.isInt,
28
+ format = core.Utils.format,
29
+ even = core.Utils.even,
30
+ evaluate = core.Utils.evaluate,
31
+ N = core.groups.N,
32
+ S = core.groups.S,
33
+ FN = core.groups.FN,
34
+ PL = core.groups.PL,
35
+ CP = core.groups.CP,
36
+ CB = core.groups.CB,
37
+ EX = core.groups.EX,
38
+ P = core.groups.P,
39
+ LOG = Settings.LOG,
40
+ EXP = 'exp',
41
+ ABS = 'abs',
42
+ SQRT = 'sqrt',
43
+ SIN = 'sin',
44
+ COS = 'cos',
45
+ TAN = 'tan',
46
+ SEC = 'sec',
47
+ CSC = 'csc',
48
+ COT = 'cot',
49
+ ASIN = 'asin',
50
+ ACOS = 'acos',
51
+ ATAN = 'atan',
52
+ ASEC = 'asec',
53
+ ACSC = 'acsc',
54
+ ACOT = 'acot',
55
+ SINH = 'sinh',
56
+ COSH = 'cosh',
57
+ TANH = 'tanh',
58
+ CSCH = 'csch',
59
+ SECH = 'sech',
60
+ COTH = 'coth',
61
+ ASECH = 'asech',
62
+ ACSCH = 'acsch',
63
+ ACOTH = 'acoth';
64
+
65
65
  //custom errors
66
- function NoIntegralFound(msg){
66
+ function NoIntegralFound(msg) {
67
67
  this.message = msg || "";
68
68
  }
69
69
  NoIntegralFound.prototype = new Error();
70
-
70
+
71
71
  //Preparations
72
- Symbol.prototype.hasIntegral = function() {
72
+ Symbol.prototype.hasIntegral = function () {
73
73
  return this.containsFunction('integrate');
74
74
  };
75
75
  //transforms a function
76
- Symbol.prototype.fnTransform = function() {
76
+ Symbol.prototype.fnTransform = function () {
77
77
  if(this.group !== FN)
78
78
  return this;
79
79
  var retval, a = this.args[0];
@@ -159,26 +159,26 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
159
159
  }
160
160
  //cos(a*x)^(2*n) or sin(a*x)^(2*n)
161
161
  else if((this.fname === COS || this.fname === SIN) && even(this.power)) {
162
- var n = this.power/2;
162
+ var n = this.power / 2;
163
163
  //convert to a double angle
164
164
  var double_angle = _.pow(this.clone().toLinear(), _.parse(2)).fnTransform();
165
165
  //raise to the n and expand
166
166
  var transformed = _.expand(_.pow(double_angle, _.parse(n)));
167
-
167
+
168
168
  retval = new Symbol(0);
169
-
170
- transformed.each(function(s) {
169
+
170
+ transformed.each(function (s) {
171
171
  var t = s.fnTransform();
172
172
  retval = _.add(retval, t);
173
173
  }, true);
174
174
  }
175
175
  else
176
176
  retval = sym;
177
-
177
+
178
178
  return _.multiply(retval, m);
179
179
  };
180
-
181
- Symbol.prototype.hasTrig = function() {
180
+
181
+ Symbol.prototype.hasTrig = function () {
182
182
  if(this.isConstant(true) || this.group === S)
183
183
  return false;
184
184
  if(this.fname && (core.Utils.in_trig(this.fname) || core.Utils.in_inverse_trig(this.fname)))
@@ -191,25 +191,25 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
191
191
  return false;
192
192
  };
193
193
 
194
- core.Expression.prototype.hasIntegral = function() {
194
+ core.Expression.prototype.hasIntegral = function () {
195
195
  return this.symbol.hasIntegral();
196
196
  };
197
197
  /**
198
198
  * Attempts to rewrite a symbol under one common denominator
199
199
  * @param {Symbol} symbol
200
200
  */
201
- core.Utils.toCommonDenominator = function(symbol) {
201
+ core.Utils.toCommonDenominator = function (symbol) {
202
202
  //transform x/a+x -> (ax+x)/a
203
203
  if(symbol.isComposite() && symbol.isLinear()) {
204
204
  var m = new Symbol(symbol.multiplier);
205
205
  var denominator = new Symbol(1);
206
206
  var numerator = new Symbol(0);
207
- symbol.each(function(x) {
207
+ symbol.each(function (x) {
208
208
  denominator = _.multiply(denominator, x.getDenom());
209
209
  }, true);
210
210
 
211
211
  //remove the denomitor in each term
212
- symbol.each(function(x) {
212
+ symbol.each(function (x) {
213
213
  var num = x.getNum();
214
214
  var den = x.getDenom();
215
215
  var factor = _.multiply(num, _.divide(denominator.clone(), den));
@@ -221,132 +221,170 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
221
221
  return symbol;
222
222
  };
223
223
  //A function to check if a function name is an inverse trig function
224
- core.Utils.in_inverse_trig = function(x) {
225
- var inv_trig_fns = [ASIN, ACOS, ATAN, ACSC, ASEC, ACOT];
224
+ core.Utils.in_inverse_trig = function (x) {
225
+ var inv_trig_fns = [ASIN, ACOS, ATAN, ACSC, ASEC, ACOT];
226
226
  return inv_trig_fns.indexOf(x) !== -1;
227
227
  };
228
228
  //A function to check if a function name is a trig function
229
- core.Utils.in_trig = function(x) {
229
+ core.Utils.in_trig = function (x) {
230
230
  var trig_fns = [COS, SIN, TAN, SEC, CSC, COT];
231
231
  return trig_fns.indexOf(x) !== -1;
232
232
  };
233
-
234
- core.Utils.in_htrig = function(x) {
233
+
234
+ core.Utils.in_htrig = function (x) {
235
235
  var trig_fns = [SINH, COSH, TANH, ACSCH, ASECH, ACOTH];
236
236
  return trig_fns.indexOf(x) !== -1;
237
237
  };
238
-
239
- var all_functions = core.Utils.all_functions = function(arr) {
240
- for(var i=0, l=arr.length; i<l; i++)
238
+
239
+ // Matrix functions
240
+ core.Matrix.jacobian = function (eqns, vars) {
241
+ var jacobian = new core.Matrix();
242
+ //get the variables if not supplied
243
+ if(!vars) {
244
+ vars = core.Utils.arrayGetVariables(eqns);
245
+ }
246
+
247
+ vars.forEach(function (v, i) {
248
+ eqns.forEach(function (eq, j) {
249
+ var e = core.Calculus.diff(eq.clone(), v);
250
+ jacobian.set(j, i, e);
251
+ });
252
+ });
253
+
254
+ return jacobian;
255
+ };
256
+
257
+ core.Matrix.prototype.max = function () {
258
+ var max = new Symbol(0);
259
+ this.each(function (x) {
260
+ var e = x.abs();
261
+ if(e.gt(max))
262
+ max = e;
263
+ });
264
+ return max;
265
+ };
266
+
267
+ core.Matrix.cMatrix = function (value, vars) {
268
+ var m = new core.Matrix();
269
+ //make an initial guess
270
+ vars.forEach(function (v, i) {
271
+ m.set(i, 0, _.parse(value));
272
+ });
273
+ return m;
274
+ };
275
+
276
+ var all_functions = core.Utils.all_functions = function (arr) {
277
+ for(var i = 0, l = arr.length; i < l; i++)
241
278
  if(arr[i].group !== FN)
242
279
  return false;
243
280
  return true;
244
281
  },
245
- cosAsinBtransform = core.Utils.cosAsinBtranform = function(symbol1, symbol2) {
246
- var a, b;
247
- a = symbol1.args[0];
248
- b = symbol2.args[0];
249
- return _.parse(format('(sin(({0})+({1}))-sin(({0})-({1})))/2', a, b));
250
- },
251
- cosAsinAtransform = core.Utils.cosAsinAtranform = function(symbol1, symbol2) {
252
- //TODO: temporary fix for integrate(e^x*sin(x)*cos(x)^2).
253
- //we technically know how to do this transform but more is needed for correct output
254
- if(Number(symbol2.power) !== 1)
255
- return _.multiply(symbol1, symbol2);
256
- var a;
257
- a = symbol1.args[0];
258
- return _.parse(format('(sin(2*({0})))/2', a));
259
- },
260
- sinAsinBtransform = core.Utils.cosAsinBtranform = function(symbol1, symbol2) {
261
- var a, b;
262
- a = symbol1.args[0];
263
- b = symbol2.args[0];
264
- return _.parse(format('(cos(({0})+({1}))-cos(({0})-({1})))/2', a, b));
265
- },
266
- trigTransform = core.Utils.trigTransform = function(arr) {
267
- var map = {}, symbol, t,
268
- retval = new Symbol(1);
269
- for(var i=0, l=arr.length; i<l; i++) {
270
- symbol = arr[i];
271
-
272
- if(symbol.group === FN) {
273
- var fname = symbol.fname;
274
-
275
- if(fname === COS && map[SIN]) {
276
-
277
- if(map[SIN].args[0].toString() !== symbol.args[0].toString()) {
278
- t = cosAsinBtransform(symbol, map[SIN]);
279
- }
280
- else{
281
- t = cosAsinAtransform(symbol, map[SIN]);
282
- }
283
- delete map[SIN];
284
-
285
- retval = _.multiply(retval, t);
286
- }
287
- else if(fname === SIN && map[COS]) {
288
- if(map[COS].args[0].toString() !== symbol.args[0].toString()) {
289
- t = cosAsinBtransform(symbol, map[COS]);
290
- }
291
- else {
292
- t = cosAsinAtransform(symbol, map[COS]);
293
- }
294
- delete map[COS];
295
-
296
- retval = _.multiply(retval, t);
297
- }
298
- else if(fname === SIN && map[SIN]) {
299
- if(map[SIN].args[0].toString() !== symbol.args[0].toString()) {
300
- t = sinAsinBtransform(symbol, map[SIN]);
301
- delete map[SIN];
302
- }
303
- else {
304
- //This should actually be redundant code but let's put just in case
305
- t = _.multiply(symbol, map[SIN]);
306
- delete map[SIN];
282
+ cosAsinBtransform = core.Utils.cosAsinBtranform = function (symbol1, symbol2) {
283
+ var a, b;
284
+ a = symbol1.args[0];
285
+ b = symbol2.args[0];
286
+ return _.parse(format('(sin(({0})+({1}))-sin(({0})-({1})))/2', a, b));
287
+ },
288
+ cosAsinAtransform = core.Utils.cosAsinAtranform = function (symbol1, symbol2) {
289
+ //TODO: temporary fix for integrate(e^x*sin(x)*cos(x)^2).
290
+ //we technically know how to do this transform but more is needed for correct output
291
+ if(Number(symbol2.power) !== 1)
292
+ return _.multiply(symbol1, symbol2);
293
+ var a;
294
+ a = symbol1.args[0];
295
+ return _.parse(format('(sin(2*({0})))/2', a));
296
+ },
297
+ sinAsinBtransform = core.Utils.cosAsinBtranform = function (symbol1, symbol2) {
298
+ var a, b;
299
+ a = symbol1.args[0];
300
+ b = symbol2.args[0];
301
+ return _.parse(format('(cos(({0})+({1}))-cos(({0})-({1})))/2', a, b));
302
+ },
303
+ trigTransform = core.Utils.trigTransform = function (arr) {
304
+ var map = {}, symbol, t,
305
+ retval = new Symbol(1);
306
+ for(var i = 0, l = arr.length; i < l; i++) {
307
+ symbol = arr[i];
308
+
309
+ if(symbol.group === FN) {
310
+ var fname = symbol.fname;
311
+
312
+ if(fname === COS && map[SIN]) {
313
+
314
+ if(map[SIN].args[0].toString() !== symbol.args[0].toString()) {
315
+ t = cosAsinBtransform(symbol, map[SIN]);
316
+ }
317
+ else {
318
+ t = cosAsinAtransform(symbol, map[SIN]);
319
+ }
320
+ delete map[SIN];
321
+
322
+ retval = _.multiply(retval, t);
323
+ }
324
+ else if(fname === SIN && map[COS]) {
325
+ if(map[COS].args[0].toString() !== symbol.args[0].toString()) {
326
+ t = cosAsinBtransform(symbol, map[COS]);
327
+ }
328
+ else {
329
+ t = cosAsinAtransform(symbol, map[COS]);
330
+ }
331
+ delete map[COS];
332
+
333
+ retval = _.multiply(retval, t);
334
+ }
335
+ else if(fname === SIN && map[SIN]) {
336
+ if(map[SIN].args[0].toString() !== symbol.args[0].toString()) {
337
+ t = sinAsinBtransform(symbol, map[SIN]);
338
+ delete map[SIN];
339
+ }
340
+ else {
341
+ //This should actually be redundant code but let's put just in case
342
+ t = _.multiply(symbol, map[SIN]);
343
+ delete map[SIN];
344
+ }
345
+
346
+ retval = t;
347
+ }
348
+ else {
349
+ map[fname] = symbol;
350
+ }
307
351
  }
308
-
309
- retval = t;
310
- }
311
- else {
312
- map[fname] = symbol;
352
+ else
353
+ retval = _.multiply(retval, symbol);
313
354
  }
314
- }
315
- else
316
- retval = _.multiply(retval, symbol);
317
- }
318
-
319
- //put back the remaining functions
320
- for(var x in map)
321
- retval = _.multiply(retval, map[x]);
322
-
323
- return retval;
324
355
 
325
- };
326
-
356
+ //put back the remaining functions
357
+ for(var x in map)
358
+ retval = _.multiply(retval, map[x]);
359
+
360
+ return retval;
361
+
362
+ };
363
+
327
364
  core.Settings.integration_depth = 10;
328
-
365
+
329
366
  core.Settings.max_lim_depth = 10;
330
-
367
+
331
368
  var __ = core.Calculus = {
332
369
 
333
370
  version: '1.4.6',
334
371
 
335
- sum: function(fn, index, start, end) {
336
- if(!(index.group === core.groups.S)) throw new core.exceptions.NerdamerTypeError('Index must be symbol. '+text(index)+' provided');
372
+ sum: function (fn, index, start, end) {
373
+ if(!(index.group === core.groups.S))
374
+ throw new core.exceptions.NerdamerTypeError('Index must be symbol. ' + text(index) + ' provided');
337
375
  index = index.value;
338
376
  var retval;
339
377
  if(core.Utils.isNumericSymbol(start) && core.Utils.isNumericSymbol(end)) {
340
378
  var modifier = end - start < 200 ? '' : 'PARSE2NUMBER';
341
379
  start = Number(start);
342
380
  end = Number(end);
343
- retval = core.Utils.block(modifier, function() {
381
+ retval = core.Utils.block(modifier, function () {
344
382
  var f = fn.text(),
345
- subs = {'~': true}, //lock subs. Is this even being used?
346
- retval = new core.Symbol(0);
383
+ subs = {'~': true}, //lock subs. Is this even being used?
384
+ retval = new core.Symbol(0);
347
385
 
348
- for(var i=start; i<=end; i++) {
349
- subs[index] = new Symbol(i);
386
+ for(var i = start; i <= end; i++) {
387
+ subs[index] = new Symbol(i);
350
388
  var ans = _.parse(f, subs);
351
389
  retval = _.add(retval, ans);
352
390
  }
@@ -354,27 +392,28 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
354
392
  });
355
393
  }
356
394
  else {
357
- retval = _.symfunction('sum',arguments);
395
+ retval = _.symfunction('sum', arguments);
358
396
  }
359
397
 
360
398
  return retval;
361
399
  },
362
- product: function(fn, index, start, end) {
363
- if(!(index.group === core.groups.S)) throw new core.exceptions.NerdamerTypeError('Index must be symbol. '+text(index)+' provided');
400
+ product: function (fn, index, start, end) {
401
+ if(!(index.group === core.groups.S))
402
+ throw new core.exceptions.NerdamerTypeError('Index must be symbol. ' + text(index) + ' provided');
364
403
  index = index.value;
365
404
  var retval;
366
405
  if(core.Utils.isNumericSymbol(start) && core.Utils.isNumericSymbol(end)) {
367
406
  var modifier = end - start < 200 ? '' : 'PARSE2NUMBER';
368
- retval = core.Utils.block(modifier, function() {
407
+ retval = core.Utils.block(modifier, function () {
369
408
  start = Number(start);
370
409
  end = Number(end.multiplier);
371
410
 
372
411
  var f = fn.text(),
373
- subs = {},
374
- retval = new core.Symbol(1);
412
+ subs = {},
413
+ retval = new core.Symbol(1);
375
414
 
376
- for(var i=start; i<=end; i++) {
377
- subs[index] = new Symbol(i);
415
+ for(var i = start; i <= end; i++) {
416
+ subs[index] = new Symbol(i);
378
417
  retval = _.multiply(retval, _.parse(f, subs));
379
418
  }
380
419
  return retval;
@@ -386,100 +425,102 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
386
425
 
387
426
  return retval;
388
427
  },
389
- diff: function(symbol, wrt, nth) {
428
+ diff: function (symbol, wrt, nth) {
390
429
  if(core.Utils.isVector(symbol)) {
391
430
  var vector = new core.Vector([]);
392
- symbol.each(function(x) {
431
+ symbol.each(function (x) {
393
432
  vector.elements.push(__.diff(x, wrt, nth));
394
433
  });
395
434
  return vector;
396
435
  }
397
436
  else if(core.Utils.isMatrix(symbol)) {
398
437
  var matrix = new core.Matrix();
399
- symbol.each(function(x, i, j) {
438
+ symbol.each(function (x, i, j) {
400
439
  matrix.set(i, j, __.diff(x, wrt, nth));
401
440
  });
402
441
  return matrix;
403
442
  }
404
443
 
405
- var d = isSymbol(wrt) ? wrt.text() : wrt;
444
+ var d = isSymbol(wrt) ? wrt.text() : wrt;
406
445
  //the nth derivative
407
446
  nth = isSymbol(nth) ? nth.multiplier : nth || 1;
408
-
409
- if(d === undefined) d = core.Utils.variables(symbol)[0];
410
-
447
+
448
+ if(d === undefined)
449
+ d = core.Utils.variables(symbol)[0];
450
+
411
451
  //unwrap sqrt
412
452
  if(symbol.group === FN && symbol.fname === SQRT) {
413
453
  var s = symbol.args[0],
414
- sp = symbol.power.clone();
454
+ sp = symbol.power.clone();
415
455
  //these groups go to zero anyway so why waste time?
416
456
  if(s.group !== N || s.group !== P) {
417
- s.power = isSymbol(s.power) ? _.multiply(s.power, _.multiply(new Symbol(1/2)), sp) : s.power.multiply(new Frac(0.5)).multiply(sp);
457
+ s.power = isSymbol(s.power) ? _.multiply(s.power, _.multiply(new Symbol(1 / 2)), sp) : s.power.multiply(new Frac(0.5)).multiply(sp);
418
458
  s.multiplier = s.multiplier.multiply(symbol.multiplier);
419
459
  }
420
-
460
+
421
461
  symbol = s;
422
462
  }
423
463
 
424
464
  if(symbol.group === FN && !isSymbol(symbol.power)) {
425
- var a = derive(_.parse(symbol));
426
- var b = __.diff(symbol.args[0].clone(), d);
465
+ var a = derive(_.parse(symbol));
466
+ var b = __.diff(symbol.args[0].clone(), d);
427
467
  symbol = _.multiply(a, b);//chain rule
428
468
  }
429
469
  else {
430
470
  symbol = derive(symbol);
431
471
  }
432
-
433
- if(nth > 1) {
472
+
473
+ if(nth > 1) {
434
474
  nth--;
435
475
  symbol = __.diff(symbol, wrt, nth);
436
476
  }
437
477
 
438
478
  return symbol;
439
-
440
- // Equivalent to "derivative of the outside".
479
+
480
+ // Equivalent to "derivative of the outside".
441
481
  function polydiff(symbol) {
442
- if(symbol.value === d || symbol.contains(d, true)) {
482
+ if(symbol.value === d || symbol.contains(d, true)) {
443
483
  symbol.multiplier = symbol.multiplier.multiply(symbol.power);
444
- symbol.power = symbol.power.subtract(new Frac(1));
484
+ symbol.power = symbol.power.subtract(new Frac(1));
445
485
  if(symbol.power.equals(0)) {
446
486
  symbol = Symbol(symbol.multiplier);
447
487
  }
448
- }
449
-
488
+ }
489
+
450
490
  return symbol;
451
- };
452
- function derive(symbol) {
453
- var g = symbol.group, a, b, cp;
491
+ }
492
+
493
+ function derive(symbol) {
494
+ var g = symbol.group, a, b, cp;
454
495
 
455
- if(g === N || g === S && symbol.value !== d || g === P) {
496
+ if(g === N || g === S && symbol.value !== d || g === P) {
456
497
  symbol = Symbol(0);
457
498
  }
458
- else if(g === S) {
499
+ else if(g === S) {
459
500
  symbol = polydiff(symbol);
460
501
  }
461
- else if(g === CB) {
502
+ else if(g === CB) {
462
503
  var m = symbol.multiplier.clone();
463
504
  symbol.toUnitMultiplier();
464
- var retval = _.multiply(product_rule(symbol),polydiff(symbol));
505
+ var retval = _.multiply(product_rule(symbol), polydiff(symbol));
465
506
  retval.multiplier = retval.multiplier.multiply(m);
466
507
  return retval;
467
508
  }
468
- else if(g === FN && symbol.power.equals(1)) {
509
+ else if(g === FN && symbol.power.equals(1)) {
469
510
  // Table of known derivatives
470
511
  switch(symbol.fname) {
471
512
  case LOG:
472
- cp = symbol.clone();
513
+ cp = symbol.clone();
473
514
  symbol = symbol.args[0].clone();//get the arguments
474
515
  symbol.power = symbol.power.negate();
475
- symbol.multiplier = cp.multiplier.divide(symbol.multiplier);
516
+ symbol.multiplier = cp.multiplier.divide(symbol.multiplier);
476
517
  break;
477
518
  case COS:
478
519
  //cos -> -sin
479
520
  symbol.fname = SIN;
480
521
  symbol.multiplier.negate();
481
522
  break;
482
- case SIN:
523
+ case SIN:
483
524
  //sin -> cos
484
525
  symbol.fname = COS;
485
526
  break;
@@ -488,7 +529,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
488
529
  symbol.fname = SEC;
489
530
  symbol.power = new Frac(2);
490
531
  break;
491
- case SEC:
532
+ case SEC:
492
533
  // Use a clone if this gives errors
493
534
  symbol = qdiff(symbol, TAN);
494
535
  break;
@@ -501,22 +542,22 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
501
542
  symbol.power = new Frac(2);
502
543
  break;
503
544
  case ASIN:
504
- symbol = _.parse('(sqrt(1-('+text(symbol.args[0])+')^2))^(-1)');
545
+ symbol = _.parse('(sqrt(1-(' + text(symbol.args[0]) + ')^2))^(-1)');
505
546
  break;
506
547
  case ACOS:
507
- symbol = _.parse('-(sqrt(1-('+text(symbol.args[0])+')^2))^(-1)');
548
+ symbol = _.parse('-(sqrt(1-(' + text(symbol.args[0]) + ')^2))^(-1)');
508
549
  break;
509
550
  case ATAN:
510
- symbol = _.parse('(1+('+text(symbol.args[0])+')^2)^(-1)');
551
+ symbol = _.parse('(1+(' + text(symbol.args[0]) + ')^2)^(-1)');
511
552
  break;
512
- case ABS:
513
- m = symbol.multiplier.clone();
553
+ case ABS:
554
+ m = symbol.multiplier.clone();
514
555
  symbol.toUnitMultiplier();
515
556
  //depending on the complexity of the symbol it's easier to just parse it into a new symbol
516
557
  //this should really be readdressed soon
517
558
  b = symbol.args[0].clone();
518
559
  b.toUnitMultiplier();
519
- symbol = _.parse(inBrackets(text(symbol.args[0]))+'/abs'+inBrackets(text(b)));
560
+ symbol = _.parse(inBrackets(text(symbol.args[0])) + '/abs' + inBrackets(text(b)));
520
561
  symbol.multiplier = m;
521
562
  break;
522
563
  case 'parens':
@@ -528,7 +569,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
528
569
  //cosh -> -sinh
529
570
  symbol.fname = 'sinh';
530
571
  break;
531
- case 'sinh':
572
+ case 'sinh':
532
573
  //sinh -> cosh
533
574
  symbol.fname = 'cosh';
534
575
  break;
@@ -537,88 +578,88 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
537
578
  symbol.fname = SECH;
538
579
  symbol.power = new Frac(2);
539
580
  break;
540
- case SECH:
581
+ case SECH:
541
582
  // Use a clone if this gives errors
542
583
  symbol = qdiff(symbol, '-tanh');
543
584
  break;
544
- case CSCH:
585
+ case CSCH:
545
586
  var arg = String(symbol.args[0]);
546
- return _.parse('-coth('+arg+')*csch('+arg+')');
587
+ return _.parse('-coth(' + arg + ')*csch(' + arg + ')');
547
588
  break;
548
- case COTH:
589
+ case COTH:
549
590
  var arg = String(symbol.args[0]);
550
- return _.parse('-csch('+arg+')^2');
591
+ return _.parse('-csch(' + arg + ')^2');
551
592
  break;
552
593
  case 'asinh':
553
- symbol = _.parse('(sqrt(1+('+text(symbol.args[0])+')^2))^(-1)');
594
+ symbol = _.parse('(sqrt(1+(' + text(symbol.args[0]) + ')^2))^(-1)');
554
595
  break;
555
596
  case 'acosh':
556
- symbol = _.parse('(sqrt(-1+('+text(symbol.args[0])+')^2))^(-1)');
597
+ symbol = _.parse('(sqrt(-1+(' + text(symbol.args[0]) + ')^2))^(-1)');
557
598
  break;
558
599
  case 'atanh':
559
- symbol = _.parse('(1-('+text(symbol.args[0])+')^2)^(-1)');
600
+ symbol = _.parse('(1-(' + text(symbol.args[0]) + ')^2)^(-1)');
560
601
  break;
561
602
  case ASECH:
562
603
  var arg = String(symbol.args[0]);
563
- symbol = _.parse('-1/(sqrt(1/('+arg+')^2-1)*('+arg+')^2)');
604
+ symbol = _.parse('-1/(sqrt(1/(' + arg + ')^2-1)*(' + arg + ')^2)');
564
605
  break;
565
606
  case ACOTH:
566
- symbol = _.parse('-1/(('+symbol.args[0]+')^2-1)');
607
+ symbol = _.parse('-1/((' + symbol.args[0] + ')^2-1)');
567
608
  break;
568
609
  case ACSCH:
569
610
  var arg = String(symbol.args[0]);
570
- symbol = _.parse('-1/(sqrt(1/('+arg+')^2+1)*('+arg+')^2)');
611
+ symbol = _.parse('-1/(sqrt(1/(' + arg + ')^2+1)*(' + arg + ')^2)');
571
612
  break;
572
613
  case ASEC:
573
614
  var arg = String(symbol.args[0]);
574
- symbol = _.parse('1/(sqrt(1-1/('+arg+')^2)*('+arg+')^2)');
615
+ symbol = _.parse('1/(sqrt(1-1/(' + arg + ')^2)*(' + arg + ')^2)');
575
616
  break;
576
617
  case ACSC:
577
618
  var arg = String(symbol.args[0]);
578
- symbol = _.parse('-1/(sqrt(1-1/('+arg+')^2)*('+arg+')^2)');
619
+ symbol = _.parse('-1/(sqrt(1-1/(' + arg + ')^2)*(' + arg + ')^2)');
579
620
  break;
580
621
  case ACOT:
581
- symbol = _.parse('-1/(('+symbol.args[0]+')^2+1)');
622
+ symbol = _.parse('-1/((' + symbol.args[0] + ')^2+1)');
582
623
  break;
583
624
  case 'S':
584
625
  var arg = String(symbol.args[0]);
585
- symbol = _.parse('sin((pi*('+arg+')^2)/2)');
626
+ symbol = _.parse('sin((pi*(' + arg + ')^2)/2)');
586
627
  break;
587
628
  case 'C':
588
629
  var arg = String(symbol.args[0]);
589
- symbol = _.parse('cos((pi*('+arg+')^2)/2)');
630
+ symbol = _.parse('cos((pi*(' + arg + ')^2)/2)');
590
631
  break;
591
632
  case 'Si':
592
633
  var arg = symbol.args[0];
593
- symbol = _.parse('sin('+arg+')/('+arg+')');
634
+ symbol = _.parse('sin(' + arg + ')/(' + arg + ')');
594
635
  break;
595
636
  case 'Shi':
596
637
  var arg = symbol.args[0];
597
- symbol = _.parse('sinh('+arg+')/('+arg+')');
638
+ symbol = _.parse('sinh(' + arg + ')/(' + arg + ')');
598
639
  break;
599
640
  case 'Ci':
600
641
  var arg = symbol.args[0];
601
- symbol = _.parse('cos('+arg+')/('+arg+')');
642
+ symbol = _.parse('cos(' + arg + ')/(' + arg + ')');
602
643
  break;
603
644
  case 'Chi':
604
645
  var arg = symbol.args[0];
605
- symbol = _.parse('cosh('+arg+')/('+arg+')');
646
+ symbol = _.parse('cosh(' + arg + ')/(' + arg + ')');
606
647
  break;
607
648
  case 'Ei':
608
649
  var arg = symbol.args[0];
609
- symbol = _.parse('e^('+arg+')/('+arg+')');
650
+ symbol = _.parse('e^(' + arg + ')/(' + arg + ')');
610
651
  break;
611
652
  case 'Li':
612
653
  var arg = symbol.args[0];
613
- symbol = _.parse('1/'+Settings.LOG+'('+arg+')');
654
+ symbol = _.parse('1/' + Settings.LOG + '(' + arg + ')');
614
655
  break;
615
656
  case 'erf':
616
- symbol = _.parse('(2*e^(-('+symbol.args[0]+')^2))/sqrt(pi)');
657
+ symbol = _.parse('(2*e^(-(' + symbol.args[0] + ')^2))/sqrt(pi)');
617
658
  break;
618
659
  case 'atan2':
619
660
  var x_ = String(symbol.args[0]),
620
- y_ = String(symbol.args[1]);
621
- symbol = _.parse('('+y_+')/(('+y_+')^2+('+x_+')^2)');
661
+ y_ = String(symbol.args[1]);
662
+ symbol = _.parse('(' + y_ + ')/((' + y_ + ')^2+(' + x_ + ')^2)');
622
663
  break;
623
664
  case 'sign':
624
665
  symbol = new Symbol(0);
@@ -627,35 +668,36 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
627
668
  symbol = _.parse(format('(({0})*cos({0})-sin({0}))*({0})^(-2)', symbol.args[0]));
628
669
  break;
629
670
  case Settings.LOG10:
630
- symbol = _.parse('1/(('+symbol.args[0]+')*'+Settings.LOG+'(10))');
671
+ symbol = _.parse('1/((' + symbol.args[0] + ')*' + Settings.LOG + '(10))');
631
672
  break;
632
673
  default:
633
674
  symbol = _.symfunction('diff', [symbol, wrt]);
634
675
  }
635
676
  }
636
- else if(g === EX || g === FN && isSymbol(symbol.power)) {
677
+ else if(g === EX || g === FN && isSymbol(symbol.power)) {
637
678
  var value;
638
679
  if(g === EX) {
639
680
  value = symbol.value;
640
681
  }
641
- else if(g === FN && symbol.contains(d)) {
682
+ else if(g === FN && symbol.contains(d)) {
642
683
  value = symbol.fname + inBrackets(text(symbol.args[0]));
643
684
  }
644
685
  else {
645
686
  value = symbol.value + inBrackets(text(symbol.args[0]));
646
687
  }
647
- a = _.multiply(_.parse(LOG+inBrackets(value)), symbol.power.clone());
648
- b = __.diff(_.multiply(_.parse(LOG+inBrackets(value)), symbol.power.clone()), d);
688
+ a = _.multiply(_.parse(LOG + inBrackets(value)), symbol.power.clone());
689
+ b = __.diff(_.multiply(_.parse(LOG + inBrackets(value)), symbol.power.clone()), d);
649
690
  symbol = _.multiply(symbol, b);
650
691
  }
651
- else if(g === FN && !symbol.power.equals(1)) {
692
+ else if(g === FN && !symbol.power.equals(1)) {
652
693
  b = symbol.clone();
653
694
  b.toLinear();
654
695
  b.toUnitMultiplier();
655
- symbol = _.multiply(polydiff(symbol.clone()), derive(b));
696
+ symbol = _.multiply(polydiff(symbol.clone()), derive(b));
656
697
  }
657
- else if( g === CP || g === PL ) {
658
- var c = _.parse(symbol);
698
+ else if(g === CP || g === PL) {
699
+ // Note: Do not use `parse` since this puts back the sqrt and causes a bug as in #610. Use clone.
700
+ var c = symbol.clone();
659
701
  var result = new Symbol(0);
660
702
  for(var x in symbol.symbols) {
661
703
  result = _.add(result, __.diff(symbol.symbols[x].clone(), d));
@@ -664,23 +706,25 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
664
706
  }
665
707
 
666
708
  symbol.updateHash();
667
-
709
+
668
710
  return symbol;
669
- };
711
+ }
712
+ ;
670
713
 
671
714
  function qdiff(symbol, val, altVal) {
672
- return _.multiply(symbol, _.parse(val+inBrackets(altVal || text(symbol.args[0]))));
673
- };
715
+ return _.multiply(symbol, _.parse(val + inBrackets(altVal || text(symbol.args[0]))));
716
+ }
717
+ ;
674
718
 
675
- function product_rule(symbol) {
719
+ function product_rule(symbol) {
676
720
  //grab all the symbols within the CB symbol
677
- var symbols = symbol.collectSymbols(),
678
- result = new Symbol(0),
679
- l = symbols.length;
721
+ var symbols = symbol.collectSymbols(),
722
+ result = new Symbol(0),
723
+ l = symbols.length;
680
724
  //loop over all the symbols
681
- for(var i=0; i<l; i++) {
725
+ for(var i = 0; i < l; i++) {
682
726
  var df = __.diff(symbols[i].clone(), d);
683
- for(var j=0; j<l; j++) {
727
+ for(var j = 0; j < l; j++) {
684
728
  //skip the symbol of which we just pulled the derivative
685
729
  if(i !== j) {
686
730
  //multiply out the remaining symbols
@@ -691,18 +735,19 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
691
735
  result = _.add(result, df);
692
736
  }
693
737
  return result; //done
694
- };
738
+ }
739
+ ;
695
740
  },
696
741
  integration: {
697
- u_substitution: function(symbols, dx) {
742
+ u_substitution: function (symbols, dx) {
698
743
  function try_combo(a, b, f) {
699
744
  var d = __.diff(b, dx);
700
745
  var q = f ? f(a, b) : _.divide(a.clone(), d);
701
- if(!q.contains(dx, true))
746
+ if(!q.contains(dx, true))
702
747
  return q;
703
748
  return null;
704
749
  }
705
- function do_fn_sub(fname, arg) {
750
+ function do_fn_sub(fname, arg) {
706
751
  var subbed = __.integrate(_.symfunction(fname, [new Symbol(u)]), u, 0);
707
752
  subbed = subbed.sub(new Symbol(u), arg);
708
753
  subbed.updateHash();
@@ -710,18 +755,18 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
710
755
  }
711
756
 
712
757
  var a = symbols[0].clone(),
713
- b = symbols[1].clone(),
714
- g1 = a.group,
715
- g2 = b.group,
716
- //may cause problems if person is using this already. Will need
717
- //to find algorithm for detecting conflict
718
- u = '__u__',
719
- Q;
758
+ b = symbols[1].clone(),
759
+ g1 = a.group,
760
+ g2 = b.group,
761
+ //may cause problems if person is using this already. Will need
762
+ //to find algorithm for detecting conflict
763
+ u = '__u__',
764
+ Q;
720
765
  if(g1 === FN && g2 !== FN) {
721
766
  //e.g. 2*x*cos(x^2)
722
767
  var arg = a.args[0];
723
768
  Q = try_combo(b, arg.clone());
724
- if(Q)
769
+ if(Q)
725
770
  return _.multiply(Q, do_fn_sub(a.fname, arg));
726
771
  Q = try_combo(b, a);
727
772
  if(Q) {
@@ -732,7 +777,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
732
777
  //e.g. 2*(x+1)*cos((x+1)^2
733
778
  var arg = b.args[0];
734
779
  Q = try_combo(a, arg.clone());
735
- if(Q)
780
+ if(Q)
736
781
  return _.multiply(Q, do_fn_sub(b.fname, arg));
737
782
  }
738
783
  else if(g1 === FN && g2 === FN) {
@@ -743,8 +788,8 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
743
788
  if(Q)
744
789
  return _.multiply(__.integration.poly_integrate(b), Q);
745
790
  }
746
- else if(g1 === EX && g2 !== EX) {
747
- var p = a.power;
791
+ else if(g1 === EX && g2 !== EX) {
792
+ var p = a.power;
748
793
  Q = try_combo(b, p.clone());
749
794
  if(!Q) {
750
795
  //one more try
@@ -764,8 +809,8 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
764
809
  }
765
810
  var integrated = __.integrate(a.sub(p.clone(), new Symbol(u)), u, 0),
766
811
  retval = _.multiply(integrated.sub(new Symbol(u), p), Q);
767
-
768
-
812
+
813
+
769
814
  return retval;
770
815
  }
771
816
  else if(g2 === EX && g1 !== EX) {
@@ -774,18 +819,18 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
774
819
  var integrated = __.integrate(b.sub(p, new Symbol(u)), u, 0);
775
820
  return _.multiply(integrated.sub(new Symbol(u), p), Q);
776
821
  }
777
- else if(a.isComposite() || b.isComposite()) {
778
- var f = function(a, b) {
822
+ else if(a.isComposite() || b.isComposite()) {
823
+ var f = function (a, b) {
779
824
  var d = __.diff(b, dx);
780
825
  var A = core.Algebra.Factor.factor(a),
781
- B = core.Algebra.Factor.factor(d);
826
+ B = core.Algebra.Factor.factor(d);
782
827
  var q = _.divide(A, B);
783
828
  return q;
784
829
  };
785
830
  var f1 = a.isComposite() ? a.clone().toLinear() : a.clone(),
786
- f2 = b.isComposite() ? b.clone().toLinear() : b.clone();
787
- Q = try_combo(f1.clone(), f2.clone(), f);
788
- if(Q)
831
+ f2 = b.isComposite() ? b.clone().toLinear() : b.clone();
832
+ Q = try_combo(f1.clone(), f2.clone(), f);
833
+ if(Q)
789
834
  return _.multiply(__.integration.poly_integrate(b), Q);
790
835
  Q = try_combo(f2.clone(), f1.clone(), f);
791
836
  if(Q)
@@ -793,10 +838,10 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
793
838
  }
794
839
  },
795
840
  //simple integration of a single polynomial x^(n+1)/(n+1)
796
- poly_integrate: function(x) {
841
+ poly_integrate: function (x) {
797
842
  var p = x.power.toString(),
798
- m = x.multiplier.toDecimal(),
799
- s = x.toUnitMultiplier().toLinear();
843
+ m = x.multiplier.toDecimal(),
844
+ s = x.toUnitMultiplier().toLinear();
800
845
  if(Number(p) === -1) {
801
846
  return _.multiply(new Symbol(m), _.symfunction(LOG, [s]));
802
847
  }
@@ -804,27 +849,27 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
804
849
  },
805
850
  //If we're just spinning wheels we want to stop. This is why we
806
851
  //wrap integration in a try catch block and call this to stop.
807
- stop: function(msg) {
852
+ stop: function (msg) {
808
853
  msg = msg || 'Unable to compute integral!';
809
854
  core.Utils.warn(msg);
810
855
  throw new NoIntegralFound(msg);
811
856
  },
812
- partial_fraction: function(input, dx, depth, opt) {
857
+ partial_fraction: function (input, dx, depth, opt) {
813
858
  //TODO: This whole thing needs to be rolled into one but for now I'll leave it as two separate parts
814
859
  if(!isSymbol(dx))
815
860
  dx = _.parse(dx);
816
-
861
+
817
862
  var result, partial_fractions;
818
863
  result = new Symbol(0);
819
864
  partial_fractions = core.Algebra.PartFrac.partfrac(input, dx);
820
865
 
821
866
  if(partial_fractions.group === CB && partial_fractions.isLinear()) {
822
867
  //perform a quick check to make sure that all partial fractions are linear
823
- partial_fractions.each(function(x) {
868
+ partial_fractions.each(function (x) {
824
869
  if(!x.isLinear())
825
870
  __.integration.stop();
826
871
  });
827
- partial_fractions.each(function(x) {
872
+ partial_fractions.each(function (x) {
828
873
  result = _.add(result, __.integrate(x, dx, depth, opt));
829
874
  });
830
875
  }
@@ -833,11 +878,11 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
833
878
  }
834
879
  return result;
835
880
  },
836
- get_udv: function(symbol) {
881
+ get_udv: function (symbol) {
837
882
  var parts = [[/*L*/], [/*I*/], [/*A*/], [/*T*/], [/*E*/]];
838
883
  //first we sort them
839
- var setSymbol = function(x) {
840
- var g = x.group;
884
+ var setSymbol = function (x) {
885
+ var g = x.group;
841
886
  if(g === FN) {
842
887
  var fname = x.fname;
843
888
  if(core.Utils.in_trig(fname) || core.Utils.in_htrig(fname))
@@ -846,7 +891,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
846
891
  parts[1].push(x);
847
892
  else if(fname === LOG)
848
893
  parts[0].push(x);
849
- else {
894
+ else {
850
895
  __.integration.stop();
851
896
  }
852
897
  }
@@ -858,72 +903,73 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
858
903
  else
859
904
  __.integration.stop();
860
905
  };
861
-
862
- if(symbol.group === CB)
863
- symbol.each(function(x) {
906
+
907
+ if(symbol.group === CB)
908
+ symbol.each(function (x) {
864
909
  setSymbol(Symbol.unwrapSQRT(x, true));
865
910
  });
866
- else
911
+ else
867
912
  setSymbol(symbol);
868
913
  var u, dv = new Symbol(1);
869
914
  //compile u and dv
870
- for(var i=0; i<5; i++) {
915
+ for(var i = 0; i < 5; i++) {
871
916
  var part = parts[i], t,
872
- l = part.length;
917
+ l = part.length;
873
918
  if(l > 0) {
874
919
  if(l > 1) {
875
920
  t = new Symbol(1);
876
- for(var j=0; j<l; j++)
921
+ for(var j = 0; j < l; j++)
877
922
  t = _.multiply(t, part[j].clone());
878
923
  }
879
924
  else
880
925
  t = part[0].clone();
881
926
 
882
- if(!u) {
927
+ if(!u) {
883
928
  u = t;//the first u encountered gets chosen
884
929
  u.multiplier = u.multiplier.multiply(symbol.multiplier); //the first one gets the mutliplier
885
- }
886
- else dv = _.multiply(dv, t); //everything else belongs to dv
887
- }
930
+ }
931
+ else
932
+ dv = _.multiply(dv, t); //everything else belongs to dv
933
+ }
888
934
  }
889
935
 
890
936
  return [u, dv];
891
937
  },
892
-
893
- trig_sub: function(symbol, dx, depth, opt, parts, symbols) {
938
+
939
+ trig_sub: function (symbol, dx, depth, opt, parts, symbols) {
894
940
  parts = parts || __.integration.decompose_arg(symbol.clone().toLinear(), dx);
895
941
  var b = parts[3],
896
- ax = parts[2],
897
- a = parts[0],
898
- x = parts[1];
942
+ ax = parts[2],
943
+ a = parts[0],
944
+ x = parts[1];
899
945
  if(x.power.equals(2) && a.greaterThan(0)) {
900
946
  //use tan(x)
901
947
  var t = core.Utils.getU(symbol), //get an appropriate u
902
- u = _.parse(TAN+inBrackets(t)), //u
903
- du = _.parse(SEC+inBrackets(t)+'^2'), //du
904
- f = _.multiply(symbol.sub(x, u), du);
948
+ u = _.parse(TAN + inBrackets(t)), //u
949
+ du = _.parse(SEC + inBrackets(t) + '^2'), //du
950
+ f = _.multiply(symbol.sub(x, u), du);
905
951
  var integral = __.integrate(f, t, depth, opt).sub(u, x);
906
952
  core.Utils.clearU(u);
907
953
  return integral;
908
954
  }
909
955
  },
910
-
911
- by_parts: function(symbol, dx, depth, o) {
956
+
957
+ by_parts: function (symbol, dx, depth, o) {
912
958
  o.previous = o.previous || [];
913
959
  var udv, u, dv, du, v, vdu, uv, retval, integral_vdu, m, c, vdu_s;
914
960
  //first LIATE
915
961
  udv = __.integration.get_udv(symbol);
916
- u = udv[0];
917
- dv = udv[1];
918
- du = Symbol.unwrapSQRT(_.expand(__.diff(u.clone(), dx)), true);
962
+ u = udv[0];
963
+ dv = udv[1];
964
+ du = Symbol.unwrapSQRT(_.expand(__.diff(u.clone(), dx)), true);
919
965
  c = du.clone().stripVar(dx);
920
966
  //strip any coefficients
921
967
  du = _.divide(du, c.clone());
922
- v = __.integrate(dv.clone(), dx, depth || 0);
923
- vdu = _.multiply(v.clone(), du);
968
+ v = __.integrate(dv.clone(), dx, depth || 0);
969
+ vdu = _.multiply(v.clone(), du);
924
970
  vdu_s = vdu.toString();
925
971
  //currently only supports e^x*(some trig)
926
- if(o.previous.indexOf(vdu_s) !== -1 && (core.Utils.in_trig(u.fname)) && dv.isE()) {
972
+ if(o.previous.indexOf(vdu_s) !== -1 && (core.Utils.in_trig(u.fname)) && dv.isE()) {
927
973
  //We're going to exploit the fact that vdu can never be constant
928
974
  //to work out way out of this cycle. We'll return the length of
929
975
  //the this.previous array until we're back at level one
@@ -934,21 +980,21 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
934
980
  else
935
981
  o.previous.push(vdu_s);
936
982
 
937
- uv = _.multiply(u, v);
983
+ uv = _.multiply(u, v);
938
984
  //clear the multiplier so we're dealing with a bare integral
939
985
  m = vdu.multiplier.clone();
940
986
  vdu.toUnitMultiplier();
941
- integral_vdu = _.multiply(__.integrate(vdu.clone(), dx, depth, o), c);
987
+ integral_vdu = _.multiply(__.integrate(vdu.clone(), dx, depth, o), c);
942
988
  integral_vdu.multiplier = integral_vdu.multiplier.multiply(m);
943
989
  retval = _.subtract(uv, integral_vdu);
944
990
  //we know that there cannot be constants so they're a holdover from a cyclic integral
945
- if(o.is_cyclic) {
991
+ if(o.is_cyclic) {
946
992
  //start popping the previous stack so we know how deep in we are
947
993
  o.previous.pop();
948
994
  if(o.previous.length === 0) {
949
995
  retval = _.expand(retval);
950
996
  var rem = new Symbol(0);
951
- retval.each(function(x) {
997
+ retval.each(function (x) {
952
998
  if(!x.contains(dx))
953
999
  rem = _.add(rem, x.clone());
954
1000
  });
@@ -956,7 +1002,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
956
1002
  retval = _.divide(_.subtract(retval, rem.clone()), _.subtract(new Symbol(1), rem));
957
1003
  }
958
1004
  }
959
-
1005
+
960
1006
  return retval;
961
1007
  },
962
1008
  /*
@@ -965,56 +1011,56 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
965
1011
  decompose_arg: core.Utils.decompose_fn
966
1012
  },
967
1013
  //TODO: nerdamer.integrate('-e^(-a*t)*sin(t)', 't') -> gives incorrect output
968
- integrate: function(original_symbol, dt, depth, opt) {
1014
+ integrate: function (original_symbol, dt, depth, opt) {
969
1015
  //assume integration wrt independent variable if expression only has one variable
970
1016
  if(!dt) {
971
1017
  var vars = core.Utils.variables(original_symbol);
972
1018
  if(vars.length === 1)
973
- dt = vars[0];
1019
+ dt = vars[0];
974
1020
  //defaults to x
975
1021
  dt = dt || 'x';
976
1022
  }
977
1023
  //add support for integrating vectors
978
1024
  if(core.Utils.isVector(original_symbol)) {
979
1025
  var vector = new core.Vector([]);
980
- original_symbol.each(function(x) {
1026
+ original_symbol.each(function (x) {
981
1027
  vector.elements.push(__.integrate(x, dt));
982
1028
  });
983
1029
  return vector;
984
1030
  }
985
1031
  if(!isNaN(dt))
986
- _.error('variable expected but received '+dt);
1032
+ _.error('variable expected but received ' + dt);
987
1033
  //get rid of constants right away
988
1034
  if(original_symbol.isConstant(true))
989
1035
  return _.multiply(original_symbol.clone(), _.parse(dt));
990
-
1036
+
991
1037
  //configurations options for integral. This is needed for tracking extra options
992
1038
  //e.g. cyclic integrals or additional settings
993
1039
  opt = opt || {};
994
- return core.Utils.block('PARSE2NUMBER', function() {
1040
+ return core.Utils.block('PARSE2NUMBER', function () {
995
1041
  //make a note of the original symbol. Set only if undefined
996
1042
  depth = depth || 0;
997
1043
  var dx = isSymbol(dt) ? dt.toString() : dt,
998
- //we don't want the symbol in sqrt form. x^(1/2) is prefererred
999
- symbol = Symbol.unwrapSQRT(original_symbol.clone(), true),
1000
- g = symbol.group,
1001
- retval;
1044
+ //we don't want the symbol in sqrt form. x^(1/2) is prefererred
1045
+ symbol = Symbol.unwrapSQRT(original_symbol.clone(), true),
1046
+ g = symbol.group,
1047
+ retval;
1002
1048
 
1003
- try {
1049
+ try {
1004
1050
  //We stop integration after x amount of recursive calls
1005
- if(++depth > core.Settings.integration_depth)
1051
+ if(++depth > core.Settings.integration_depth)
1006
1052
  __.integration.stop('Maximum depth reached. Exiting!');
1007
1053
 
1008
1054
  //constants. We first eliminate anything that doesn't have dx. Everything after this has
1009
1055
  //to have dx or else it would have been taken care of below
1010
- if(!symbol.contains(dx, true)) {
1056
+ if(!symbol.contains(dx, true)) {
1011
1057
  retval = _.multiply(symbol.clone(), _.parse(dx));
1012
1058
  }
1013
1059
  //e.g. 2*x
1014
1060
  else if(g === S) {
1015
1061
  retval = __.integration.poly_integrate(symbol, dx, depth);
1016
1062
  }
1017
- else if(g === EX) {
1063
+ else if(g === EX) {
1018
1064
  if(symbol.previousGroup === FN && !(symbol.fname === 'sqrt' || symbol.fname === Settings.PARENTHESIS))
1019
1065
  __.integration.stop();
1020
1066
  //check the base
@@ -1023,7 +1069,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1023
1069
  //don't know what to do with it e.g. x^x
1024
1070
  if(symbol.power.contains(dx))
1025
1071
  __.integration.stop();
1026
- else {
1072
+ else {
1027
1073
  var t = __.diff(symbol.clone().toLinear(), dx);
1028
1074
  if(t.contains(dx))
1029
1075
  __.integration.stop();
@@ -1037,7 +1083,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1037
1083
  var a = __.diff(symbol.power.clone(), dx);
1038
1084
  if(a.contains(dx)) {
1039
1085
  var aa = a.stripVar(dx),
1040
- x = _.divide(a.clone(), aa.clone());
1086
+ x = _.divide(a.clone(), aa.clone());
1041
1087
  if(x.group === S && x.isLinear()) {
1042
1088
  aa.multiplier = aa.multiplier.divide(new Frac(2));
1043
1089
  return _.parse(format('({2})*(sqrt(pi)*erf(sqrt(-{0})*{1}))/(2*sqrt(-{0}))', aa, dx, symbol.multiplier));
@@ -1045,7 +1091,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1045
1091
  else
1046
1092
  __.integration.stop();
1047
1093
  }
1048
- if(symbol.isE()) {
1094
+ if(symbol.isE()) {
1049
1095
  if(a.isLinear())
1050
1096
  retval = symbol;
1051
1097
  else {
@@ -1062,63 +1108,63 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1062
1108
  retval = _.divide(retval, a);
1063
1109
  }
1064
1110
  }
1065
- else if(symbol.isComposite() && symbol.isLinear()) {
1111
+ else if(symbol.isComposite() && symbol.isLinear()) {
1066
1112
  var m = _.parse(symbol.multiplier);
1067
1113
  symbol.toUnitMultiplier();
1068
1114
  retval = new Symbol(0);
1069
- symbol.each(function(x) {
1115
+ symbol.each(function (x) {
1070
1116
  retval = _.add(retval, __.integrate(x, dx, depth));
1071
1117
  });
1072
1118
  retval = _.multiply(m, retval);
1073
1119
  }
1074
- else if(g === CP) {
1120
+ else if(g === CP) {
1075
1121
  if(symbol.power.greaterThan(1))
1076
1122
  symbol = _.expand(symbol);
1077
1123
  if(symbol.power.equals(1)) {
1078
1124
  retval = new Symbol(0);
1079
- symbol.each(function(x) {
1125
+ symbol.each(function (x) {
1080
1126
  retval = _.add(retval, __.integrate(x, dx, depth));
1081
1127
  }, true);
1082
1128
  }
1083
1129
  else {
1084
1130
  var p = Number(symbol.power),
1085
- m = symbol.multiplier.clone();//temporarily remove the multiplier
1131
+ m = symbol.multiplier.clone();//temporarily remove the multiplier
1086
1132
  symbol.toUnitMultiplier();
1087
1133
  var //below we consider the form ax+b
1088
- fn = symbol.clone().toLinear(), //get just the pure function without the power
1089
- decomp = __.integration.decompose_arg(fn, dx),
1090
- //I have no idea why I used bx+a and not ax+b. TODO change this to something that makes sense
1091
- b = decomp[3],
1092
- ax = decomp[2],
1093
- a = decomp[0],
1094
- x = decomp[1];
1095
- if(p === -1 && x.group !== PL && x.power.equals(2)) {
1134
+ fn = symbol.clone().toLinear(), //get just the pure function without the power
1135
+ decomp = __.integration.decompose_arg(fn, dx),
1136
+ //I have no idea why I used bx+a and not ax+b. TODO change this to something that makes sense
1137
+ b = decomp[3],
1138
+ ax = decomp[2],
1139
+ a = decomp[0],
1140
+ x = decomp[1];
1141
+ if(p === -1 && x.group !== PL && x.power.equals(2)) {
1096
1142
  var b_is_positive = isInt(b) ? b > 0 : true;
1097
1143
  //we can now check for atan
1098
- if(x.group === S && x.power.equals(2) && b_is_positive) {
1144
+ if(x.group === S && x.power.equals(2) && b_is_positive) {
1099
1145
  ////then we have atan
1100
1146
  //abs is redundants since the sign appears in both denom and num.
1101
- var unwrapAbs = function(s) {
1147
+ var unwrapAbs = function (s) {
1102
1148
  var result = new Symbol(1);
1103
- s.each(function(x) {
1149
+ s.each(function (x) {
1104
1150
  result = _.multiply(result, x.fname === 'abs' ? x.args[0] : x);
1105
1151
  });
1106
1152
  return result;
1107
1153
  };
1108
1154
  var A = a.clone(),
1109
- B = b.clone();
1110
- A = _.pow(A, new Symbol(1/2));
1111
- B = _.pow(B, new Symbol(1/2));
1155
+ B = b.clone();
1156
+ A = _.pow(A, new Symbol(1 / 2));
1157
+ B = _.pow(B, new Symbol(1 / 2));
1112
1158
  //unwrap abs
1113
1159
 
1114
1160
  var d = _.multiply(unwrapAbs(B), unwrapAbs(A)),
1115
- f = _.symfunction(ATAN, [_.divide(_.multiply(a, x.toLinear()), d.clone())]);
1161
+ f = _.symfunction(ATAN, [_.divide(_.multiply(a, x.toLinear()), d.clone())]);
1116
1162
  retval = _.divide(f, d);
1117
1163
  }
1118
1164
  else if(x.group === S && x.isLinear()) {
1119
1165
  retval = _.divide(__.integration.poly_integrate(symbol), a);
1120
1166
  }
1121
- else {
1167
+ else {
1122
1168
  //1/(x^4+1)
1123
1169
  if(x.power.equals(4)) {
1124
1170
  //https://www.freemathhelp.com/forum/threads/55678-difficult-integration-int-1-(1-x-4)-dx
@@ -1126,22 +1172,22 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1126
1172
  var br = inBrackets;
1127
1173
  //apply rule: ax^4+b = (√ax^2+√2∜a∜bx+√b)(√ax^2-√2∜a∜bx+√b)
1128
1174
  //get quadratic factors
1129
- A = _.parse(SQRT+br(a)+'*'+dx+'^2');
1130
- B = _.parse(SQRT+br(2)+'*'+br(a)+'^'+br('1/4')+'*'+br(b)+'^'+br('1/4')+'*'+dx);
1131
- C = _.parse(SQRT+br(b));
1175
+ A = _.parse(SQRT + br(a) + '*' + dx + '^2');
1176
+ B = _.parse(SQRT + br(2) + '*' + br(a) + '^' + br('1/4') + '*' + br(b) + '^' + br('1/4') + '*' + dx);
1177
+ C = _.parse(SQRT + br(b));
1132
1178
  f1 = _.add(_.add(A.clone(), B.clone()), C.clone());
1133
1179
  f2 = _.add(_.subtract(A, B), C);
1134
1180
  //calculate numerators: [D+E, D-E] -> [√2*b^(3/4)+√b∜ax, √2*b^(3/4)-√b∜ax]
1135
- D = _.parse(SQRT+br(2)+'*'+br(b)+'^'+br('3/4'));
1136
- E = _.parse(SQRT+br(b)+'*'+br(b)+'^'+br('1/4')+'*'+dx);
1181
+ D = _.parse(SQRT + br(2) + '*' + br(b) + '^' + br('3/4'));
1182
+ E = _.parse(SQRT + br(b) + '*' + br(b) + '^' + br('1/4') + '*' + dx);
1137
1183
  //let F = 2b√2∜b
1138
- F = _.parse(2+'*'+br(b)+'*'+SQRT+br(2)+'*'+br(b)+'^'+br('1/4'));
1184
+ F = _.parse(2 + '*' + br(b) + '*' + SQRT + br(2) + '*' + br(b) + '^' + br('1/4'));
1139
1185
  //calculate the factors
1140
1186
  L1 = _.divide(_.subtract(D.clone(), E.clone()), _.multiply(F.clone(), f2));
1141
1187
  L2 = _.divide(_.add(D, E), _.multiply(F, f1.clone()));
1142
1188
  retval = _.add(
1143
- __.integrate(L1, dx, depth, opt),
1144
- __.integrate(L2, dx, depth, opt)
1189
+ __.integrate(L1, dx, depth, opt),
1190
+ __.integrate(L2, dx, depth, opt)
1145
1191
  );
1146
1192
  }
1147
1193
  else
@@ -1149,7 +1195,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1149
1195
  retval = __.integration.partial_fraction(symbol, dx, depth);
1150
1196
  }
1151
1197
  }
1152
- else if(p === -1/2) {
1198
+ else if(p === -1 / 2) {
1153
1199
  //detect asin and atan
1154
1200
  if(x.group === S && x.power.equals(2)) {
1155
1201
  if(ax.multiplier.lessThan(0) && !b.multiplier.lessThan(0)) {
@@ -1157,13 +1203,13 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1157
1203
  //it's asin
1158
1204
  if(b.isConstant() && a.isConstant()) {
1159
1205
  var d = _.symfunction(SQRT, [a.clone()]),
1160
- d2 = _.symfunction(SQRT, [_.multiply(a.clone(), b)]);
1206
+ d2 = _.symfunction(SQRT, [_.multiply(a.clone(), b)]);
1161
1207
  retval = _.divide(_.symfunction(ASIN, [_.divide(ax.toLinear(), d2)]), d);
1162
1208
  }
1163
1209
  //I'm not sure about this one. I'm trusting Wolfram Alpha here
1164
1210
  else {
1165
1211
  var sqrt_a = _.symfunction(SQRT, [a]),
1166
- sqrt_ax = _.multiply(sqrt_a.clone(), x.clone().toLinear());
1212
+ sqrt_ax = _.multiply(sqrt_a.clone(), x.clone().toLinear());
1167
1213
  retval = _.divide(_.symfunction(ATAN, [_.divide(sqrt_ax, _.symfunction(SQRT, [fn.clone()]))]), sqrt_a);
1168
1214
  }
1169
1215
  }
@@ -1177,38 +1223,42 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1177
1223
  __.integration.stop();
1178
1224
  }
1179
1225
  }
1180
- else {
1181
- if(x.isLinear() && x.group !== PL)
1226
+ else if(p === 1/2 && x.power.equals(2) && a.greaterThan(0)) {
1227
+ // TODO: Revisit
1228
+ __.integration.stop();
1229
+ }
1230
+ else {
1231
+ if(x.isLinear() && x.group !== PL)
1182
1232
  retval = _.divide(__.integration.poly_integrate(symbol), a);
1183
- else if(x.power.equals(2) && a.greaterThan(0)) {
1233
+ else if(x.power.equals(2) && a.greaterThan(0)) {
1184
1234
  var sqa, sqb, aob, bsqi, n, integral, u, v, uv;
1185
1235
  //1/(a*x^2+b^2)^n
1186
1236
  //strip the value of b so b = 1
1187
- sqa = _.parse(SQRT+inBrackets(a)); //strip a so b = 1
1188
- sqb = _.parse(SQRT+inBrackets(b));
1237
+ sqa = _.parse(SQRT + inBrackets(a)); //strip a so b = 1
1238
+ sqb = _.parse(SQRT + inBrackets(b));
1189
1239
  aob = _.multiply(sqa.clone(), sqb.clone()).invert();
1190
1240
  bsqi = _.pow(b, new Symbol(symbol.power));
1191
1241
  uv = core.Utils.getU(symbol);
1192
1242
  u = _.multiply(aob, x.clone().toLinear());
1193
- v = _.parse(ATAN+inBrackets(u));
1243
+ v = _.parse(ATAN + inBrackets(u));
1194
1244
  //the conversion will be 1+tan(x)^2 -> sec(x)^2
1195
1245
  //since the denominator is now (sec(x)^2)^n and the numerator is sec(x)^2
1196
1246
  //then the remaining sec will be (n-1)*2;
1197
- var n = (Math.abs(symbol.power)-1)*2;
1247
+ var n = (Math.abs(symbol.power) - 1) * 2;
1198
1248
  //1/sec(x)^n can now be converted to cos(x)^n and we can pull the integral of that
1199
- var integral = __.integrate(_.parse(COS+inBrackets(uv)+'^'+n));
1249
+ var integral = __.integrate(_.parse(COS + inBrackets(uv) + '^' + n));
1200
1250
  core.Utils.clearU(uv);
1201
1251
  return _.multiply(integral.sub(uv, v), bsqi);
1202
1252
  }
1203
- else {
1253
+ else {
1204
1254
  if(symbol.group !== CB && !symbol.power.lessThan(0)) {
1205
1255
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1206
1256
  }
1207
- else {
1257
+ else {
1208
1258
  var f = symbol.clone().toLinear();
1209
1259
  var factored = core.Algebra.Factor.factor(f);
1210
1260
  var was_factored = factored.toString() !== f.toString();
1211
- if(core.Algebra.degree(f, _.parse(dx)).equals(2) && !was_factored) {
1261
+ if(core.Algebra.degree(f, _.parse(dx)).equals(2) && !was_factored) {
1212
1262
  try {
1213
1263
  var f1, fx, u, sq;
1214
1264
  sq = core.Algebra.sqComplete(f, dx);
@@ -1229,43 +1279,43 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1229
1279
  retval.multiplier = retval.multiplier.multiply(m);
1230
1280
  }
1231
1281
  }
1232
- else if(g === FN) {
1282
+ else if(g === FN) {
1233
1283
  var arg = symbol.args[0],
1234
- m = symbol.multiplier.clone();
1284
+ m = symbol.multiplier.clone();
1235
1285
  symbol.toUnitMultiplier();
1236
1286
  var decomp = __.integration.decompose_arg(arg, dx);
1237
1287
  //easies way I can think of to get the coefficient and to make sure
1238
1288
  //that the symbol is linear wrt dx. I'm not actually trying to get the
1239
1289
  //derivative
1240
1290
  var a = decomp[0],
1241
- x = decomp[1],
1242
- fname = symbol.fname;
1291
+ x = decomp[1],
1292
+ fname = symbol.fname;
1243
1293
  //log is a special case that can be handled with integration by parts
1244
- if(fname === LOG || (fname === ASIN || fname === ACOS || fname === ATAN && x.isLinear())) {
1294
+ if(fname === LOG || (fname === ASIN || fname === ACOS || fname === ATAN && x.isLinear())) {
1245
1295
  /*integration by parts */
1246
- var p = symbol.power.toString();
1296
+ var p = symbol.power.toString();
1247
1297
  if(isInt(p))
1248
1298
  depth = depth - p; //it needs more room to find the integral
1249
-
1299
+
1250
1300
  if(!arg.isComposite())
1251
- retval = _.multiply(_.parse(m),__.integration.by_parts(symbol, dx, depth, opt));
1301
+ retval = _.multiply(_.parse(m), __.integration.by_parts(symbol, dx, depth, opt));
1252
1302
  else {
1253
1303
  //integral u du
1254
1304
  var u = core.Utils.getU(symbol);
1255
- var f = _.pow(_.parse(LOG+inBrackets(u)),new Symbol(p));
1305
+ var f = _.pow(_.parse(LOG + inBrackets(u)), new Symbol(p));
1256
1306
  var du = __.diff(arg, dx);
1257
1307
  var u_du = _.multiply(f, du);
1258
1308
  var integral = __.integrate(u_du, u, depth, opt);
1259
- retval = _.multiply(_.parse(m),integral.sub(u, arg));
1309
+ retval = _.multiply(_.parse(m), integral.sub(u, arg));
1260
1310
  }
1261
1311
 
1262
1312
  }
1263
1313
  else if(fname === TAN && symbol.power.lessThan(0)) {
1264
1314
  //convert to cotangent
1265
- var sym = symbol.clone();
1315
+ var sym = symbol.clone();
1266
1316
  sym.power.negate();
1267
1317
  sym.fname = COT;
1268
- return _.multiply(_.parse(m),__.integrate(sym, dx, depth));
1318
+ return _.multiply(_.parse(m), __.integrate(sym, dx, depth));
1269
1319
  }
1270
1320
  else {
1271
1321
  if(!a.contains(dx, true) && symbol.isLinear()) { //perform a deep search for safety
@@ -1283,13 +1333,13 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1283
1333
  retval = _.multiply(_.multiply(_.symfunction(ABS, [x.toLinear()]), integrated), a);
1284
1334
  }
1285
1335
  }
1286
- else
1336
+ else
1287
1337
  __.integration.stop();
1288
1338
  }
1289
- else {
1339
+ else {
1290
1340
  var ag = symbol.args[0].group,
1291
- decomposed = __.integration.decompose_arg(arg, dx);
1292
-
1341
+ decomposed = __.integration.decompose_arg(arg, dx);
1342
+
1293
1343
  if(!(ag === CP || ag === S || ag === CB) || !decomposed[1].power.equals(1) || arg.hasFunc())
1294
1344
  __.integration.stop();
1295
1345
  /**TODO**/ //ASIN, ACOS, ATAN
@@ -1302,16 +1352,16 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1302
1352
  retval.negate();
1303
1353
  break;
1304
1354
  case TAN:
1305
- retval = _.parse(format(Settings.LOG+'(sec({0}))', arg));
1355
+ retval = _.parse(format(Settings.LOG + '(sec({0}))', arg));
1306
1356
  break;
1307
1357
  case SEC:
1308
- retval = _.parse(format(Settings.LOG+'(tan({0})+sec({0}))', arg));
1358
+ retval = _.parse(format(Settings.LOG + '(tan({0})+sec({0}))', arg));
1309
1359
  break;
1310
1360
  case CSC:
1311
- retval = _.parse(format('-'+Settings.LOG+'(csc({0})+cot({0}))', arg));
1361
+ retval = _.parse(format('-' + Settings.LOG + '(csc({0})+cot({0}))', arg));
1312
1362
  break;
1313
1363
  case COT:
1314
- retval = _.parse(format(Settings.LOG+'(sin({0}))', arg));
1364
+ retval = _.parse(format(Settings.LOG + '(sin({0}))', arg));
1315
1365
  break;
1316
1366
  case SINH:
1317
1367
  retval = _.symfunction(COSH, [arg]);
@@ -1320,7 +1370,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1320
1370
  retval = _.symfunction(SINH, [arg]);
1321
1371
  break;
1322
1372
  case TANH:
1323
- retval = _.parse(format(Settings.LOG+'(cosh({0}))', arg));
1373
+ retval = _.parse(format(Settings.LOG + '(cosh({0}))', arg));
1324
1374
  break;
1325
1375
  case ASEC:
1326
1376
  retval = __.integration.by_parts(symbol, dx, depth, opt);
@@ -1331,7 +1381,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1331
1381
  case ACOT:
1332
1382
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1333
1383
  break;
1334
- //inverse htrig
1384
+ //inverse htrig
1335
1385
  case ASECH:
1336
1386
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1337
1387
  break;
@@ -1341,42 +1391,42 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1341
1391
  case ACOTH:
1342
1392
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1343
1393
  break;
1344
- //end inverse htrig
1345
- //htrigh
1394
+ //end inverse htrig
1395
+ //htrigh
1346
1396
  case SECH:
1347
1397
  retval = _.parse(format('atan(sinh({0}))', arg));
1348
1398
  break;
1349
1399
  case CSCH:
1350
- retval = _.parse(format(Settings.LOG+'(tanh(({0})/2))', arg));
1400
+ retval = _.parse(format(Settings.LOG + '(tanh(({0})/2))', arg));
1351
1401
  break;
1352
1402
  case COTH:
1353
- retval = _.parse(format(Settings.LOG+'(sinh({0}))', arg));
1403
+ retval = _.parse(format(Settings.LOG + '(sinh({0}))', arg));
1354
1404
  break;
1355
- //end htrig
1405
+ //end htrig
1356
1406
  case EXP:
1357
1407
  retval = __.integrate(_.parse(format('e^({0})', arg)), dx, depth);
1358
1408
  break;
1359
1409
  case 'S':
1360
1410
  var arg = symbol.args[0].clone(),
1361
- dc = __.integration.decompose_arg(arg, dx),
1362
- x_ = dc[1],
1363
- a_ = dc[0];
1411
+ dc = __.integration.decompose_arg(arg, dx),
1412
+ x_ = dc[1],
1413
+ a_ = dc[0];
1364
1414
  var b_ = dc[3];
1365
1415
  retval = _.parse(format('(cos((1/2)*pi*(({1})+({0})*({2}))^2)+pi*(({1})+({0})*({2}))*S(({1})+({0})*({2})))/(({0})*pi)', a_, b_, x));
1366
1416
  break;
1367
1417
  case 'C':
1368
1418
  var arg = symbol.args[0].clone(),
1369
- dc = __.integration.decompose_arg(arg, dx),
1370
- x_ = dc[1],
1371
- a_ = dc[0];
1419
+ dc = __.integration.decompose_arg(arg, dx),
1420
+ x_ = dc[1],
1421
+ a_ = dc[0];
1372
1422
  var b_ = dc[3];
1373
1423
  retval = _.parse(format('(pi*(({1})+({0})*({2}))*C(({1})+({0})*({2}))-sin((1/2)*pi*(({1})+({0})*({2}))^2))/(({0})*pi)', a_, b_, x_));
1374
1424
  break;
1375
1425
  case 'erf':
1376
1426
  var arg = symbol.args[0].clone(),
1377
- dc = __.integration.decompose_arg(arg, dx),
1378
- x_ = dc[1],
1379
- a_ = dc[0];
1427
+ dc = __.integration.decompose_arg(arg, dx),
1428
+ x_ = dc[1],
1429
+ a_ = dc[0];
1380
1430
  retval = _.parse(format('e^(-(({2}))^2)/(({0})*sqrt(pi))+(1/({0})+({1}))*erf(({2}))', a_, x_, arg));
1381
1431
  break;
1382
1432
  case 'sign':
@@ -1386,10 +1436,10 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1386
1436
  __.integration.stop();
1387
1437
  }
1388
1438
 
1389
- retval = _.divide(retval, a);
1439
+ retval = _.divide(retval, a);
1390
1440
  }
1391
1441
  }
1392
- else if(x.isLinear()) {
1442
+ else if(x.isLinear()) {
1393
1443
  if(fname === COS || fname === SIN) {
1394
1444
  var p = Number(symbol.power);
1395
1445
  //check to see if it's negative and then just transform it to sec or csc
@@ -1400,44 +1450,45 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1400
1450
  }
1401
1451
  else {
1402
1452
  var arg = symbol.args[0],
1403
- rd = symbol.clone(), //cos^(n-1)
1404
- rd2 = symbol.clone(), //cos^(n-2)
1405
- q = new Symbol((p-1)/p), //
1406
- na = _.multiply(a.clone(), new Symbol(p)).invert(); //1/(n*a)
1453
+ rd = symbol.clone(), //cos^(n-1)
1454
+ rd2 = symbol.clone(), //cos^(n-2)
1455
+ q = new Symbol((p - 1) / p), //
1456
+ na = _.multiply(a.clone(), new Symbol(p)).invert(); //1/(n*a)
1407
1457
  rd.power = rd.power.subtract(new Frac(1));
1408
1458
  rd2.power = rd2.power.subtract(new Frac(2));
1409
1459
 
1410
1460
  var t = _.symfunction(fname === COS ? SIN : COS, [arg.clone()]);
1411
- if(fname === SIN) t.negate();
1461
+ if(fname === SIN)
1462
+ t.negate();
1412
1463
  retval = _.add(_.multiply(_.multiply(na, rd), t), _.multiply(q, __.integrate(_.parse(rd2), dx, depth)));
1413
1464
  }
1414
1465
  }
1415
1466
  //tan(x)^n or cot(x)^n
1416
- else if(fname === TAN || fname === COT) {
1467
+ else if(fname === TAN || fname === COT) {
1417
1468
  //http://www.sosmath.com/calculus/integration/moretrigpower/moretrigpower.html
1418
1469
  if(symbol.args[0].isLinear(dx)) {
1419
1470
  var n = symbol.power.subtract(new Frac(1)).toString(),
1420
- r = symbol.clone().toUnitMultiplier(),
1421
- w = _.parse(format((fname === COT ? '-' : '')+'1/({2}*{0})*{3}({1})^({0})', n, arg, a, fname));
1471
+ r = symbol.clone().toUnitMultiplier(),
1472
+ w = _.parse(format((fname === COT ? '-' : '') + '1/({2}*{0})*{3}({1})^({0})', n, arg, a, fname));
1422
1473
  r.power = r.power.subtract(new Frac(2));
1423
1474
  if(r.power.equals(0))
1424
1475
  r = _.parse(r);
1425
1476
  retval = _.subtract(w, __.integrate(r, dx, depth));
1426
- }
1477
+ }
1427
1478
  }
1428
1479
  //sec(x)^n or csc(x)^n
1429
- else if(fname === SEC || fname === CSC) {
1480
+ else if(fname === SEC || fname === CSC) {
1430
1481
  //http://www.sosmath.com/calculus/integration/moretrigpower/moretrigpower.html
1431
1482
  var n1 = symbol.power.subtract(new Frac(1)).toString(),
1432
- n2 = symbol.power.subtract(new Frac(2)).toString(),
1433
- f2 = fname === SEC ? TAN : COT,
1434
- r = symbol.clone().toUnitMultiplier(),
1435
- parse_str = format((fname === CSC ? '-' : '')+'1/({0}*{1})*{4}({3})^({2})*{5}({3})', a, n1, n2, arg, fname, f2),
1436
- w = _.parse(parse_str);
1483
+ n2 = symbol.power.subtract(new Frac(2)).toString(),
1484
+ f2 = fname === SEC ? TAN : COT,
1485
+ r = symbol.clone().toUnitMultiplier(),
1486
+ parse_str = format((fname === CSC ? '-' : '') + '1/({0}*{1})*{4}({3})^({2})*{5}({3})', a, n1, n2, arg, fname, f2),
1487
+ w = _.parse(parse_str);
1437
1488
  r.power = r.power.subtract(new Frac(2));
1438
1489
  if(r.power.equals(0))
1439
1490
  r = _.parse(r);
1440
- retval = _.add(w, _.multiply(new Symbol(n2/n1), __.integrate(r, dx, depth)));
1491
+ retval = _.add(w, _.multiply(new Symbol(n2 / n1), __.integrate(r, dx, depth)));
1441
1492
  }
1442
1493
  else if((fname === COSH || fname === SINH) && symbol.power.equals(2)) {
1443
1494
  retval = __.integrate(symbol.fnTransform(), dx, depth);
@@ -1445,7 +1496,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1445
1496
  else
1446
1497
  __.integration.stop();
1447
1498
  }
1448
- else
1499
+ else
1449
1500
  __.integration.stop();
1450
1501
 
1451
1502
  retval.multiplier = retval.multiplier.multiply(m);
@@ -1458,9 +1509,9 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1458
1509
  var den = symbol.getDenom();
1459
1510
  if(den.group === S)
1460
1511
  symbol = _.expand(symbol);
1461
-
1512
+
1462
1513
  //separate the coefficient since all we care about are symbols containing dx
1463
- var coeff = symbol.stripVar(dx);
1514
+ var coeff = symbol.stripVar(dx);
1464
1515
  //now get only those that apply
1465
1516
  var cfsymbol = _.divide(symbol.clone(), coeff.clone()); //a coeff free symbol
1466
1517
  //peform a correction for stripVar. This is a serious TODO!
@@ -1468,32 +1519,34 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1468
1519
  cfsymbol = _.multiply(cfsymbol, coeff);
1469
1520
  coeff = new Symbol(1);
1470
1521
  }
1471
-
1522
+
1472
1523
  //if we only have one symbol left then let's not waste time. Just pull the integral
1473
1524
  //and let the chips fall where they may
1474
1525
  if(cfsymbol.group !== CB) {
1475
- if(cfsymbol.equals(1)) {
1526
+ if(cfsymbol.equals(1)) {
1476
1527
  return __.integrate(_.expand(symbol), dx, depth);
1477
1528
  }
1478
-
1529
+
1479
1530
  //only factor for multivariate which are polynomials
1480
1531
  if(cfsymbol.clone().toLinear().isPoly(true) && core.Utils.variables(cfsymbol).length > 1) {
1481
1532
  cfsymbol = core.Algebra.Factor.factor(cfsymbol);
1482
1533
  }
1483
-
1534
+
1484
1535
  retval = __.integrate(cfsymbol, dx, depth);
1485
1536
  }
1486
- else {
1537
+ else {
1487
1538
  //we collect the symbols and sort them descending group, descending power, descending alpabethically
1488
- var symbols = cfsymbol.collectSymbols().sort(function(a, b) {
1489
- if(a.group === b.group) {
1539
+ var symbols = cfsymbol.collectSymbols().sort(function (a, b) {
1540
+ if(a.group === b.group) {
1490
1541
  if(Number(a.power) === Number(b.power))
1491
- if(a < b) return 1; //I want sin first
1492
- else return -1;
1542
+ if(a < b)
1543
+ return 1; //I want sin first
1544
+ else
1545
+ return -1;
1493
1546
  return b.power - a.power; //descending power
1494
1547
  }
1495
1548
  return b.group - a.group; //descending groups
1496
- }).map(function(x) {
1549
+ }).map(function (x) {
1497
1550
  var unwrapped = Symbol.unwrapSQRT(x, true);
1498
1551
  if(unwrapped.fname === EXP) {
1499
1552
  return _.parse(format('({1})*e^({0})', unwrapped.args[0], unwrapped.multiplier));
@@ -1501,7 +1554,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1501
1554
  return unwrapped;
1502
1555
  });
1503
1556
  var l = symbols.length;
1504
- if(symbol.power < 0) {
1557
+ if(symbol.power < 0) {
1505
1558
  if(l === 2) {
1506
1559
  return __.integrate(_.expand(symbol), dx, depth, opt);
1507
1560
  }
@@ -1514,25 +1567,27 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1514
1567
  try {
1515
1568
  retval = __.integration.u_substitution(symbols, dx);
1516
1569
  }
1517
- catch(e){/* failed :`(*/; }
1570
+ catch(e) {/* failed :`(*/
1571
+ ;
1572
+ }
1518
1573
 
1519
- if(!retval) {
1574
+ if(!retval) {
1520
1575
  //no success with u substitution so let's try known combinations
1521
1576
  //are they two functions
1522
1577
  var g1 = symbols[0].group,
1523
- g2 = symbols[1].group,
1524
- sym1 = symbols[0],
1525
- sym2 = symbols[1],
1526
- fn1 = sym1.fname,
1527
- fn2 = sym2.fname;
1578
+ g2 = symbols[1].group,
1579
+ sym1 = symbols[0],
1580
+ sym2 = symbols[1],
1581
+ fn1 = sym1.fname,
1582
+ fn2 = sym2.fname;
1528
1583
  //reset the symbol minus the coeff
1529
1584
  symbol = _.multiply(sym1.clone(), sym2.clone());
1530
- if(g1 === FN && g2 === FN) {
1531
- if(fn1 === LOG || fn2 === LOG) {
1585
+ if(g1 === FN && g2 === FN) {
1586
+ if(fn1 === LOG || fn2 === LOG) {
1532
1587
  retval = __.integration.by_parts(symbol.clone(), dx, depth, opt);
1533
1588
  }
1534
- else {
1535
- symbols.sort(function(a, b) {
1589
+ else {
1590
+ symbols.sort(function (a, b) {
1536
1591
  return b.fname > a.fname;
1537
1592
  });
1538
1593
  var arg1 = sym1.args[0];
@@ -1542,7 +1597,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1542
1597
 
1543
1598
  var decomp = __.integration.decompose_arg(arg1, dx);
1544
1599
  x = decomp[1],
1545
- a = decomp[0];
1600
+ a = decomp[0];
1546
1601
  if(!x.isLinear()) //again... linear arguments only wrt x
1547
1602
  __.integration.stop();
1548
1603
 
@@ -1550,12 +1605,12 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1550
1605
  //make sure we can integrate FN & FN
1551
1606
  var arg2 = sym2.args[0];
1552
1607
  //make sure that their argument matches
1553
- if(arg1.equals(arg2)) {
1554
- if(fn1 === SIN && fn2 === COS || fn1 === COS && fn2 === SIN) {
1608
+ if(arg1.equals(arg2)) {
1609
+ if(fn1 === SIN && fn2 === COS || fn1 === COS && fn2 === SIN) {
1555
1610
  if(sym1.power.lessThan(0))
1556
1611
  __.integration.stop();//we don't know how to handle, sin(x)^n/cos(x)^m where m > n, yet
1557
1612
  //if it's in the form sin(x)^n*cos(x)^n then we can just return tan(x)^n which we know how to integrate
1558
- if(fn1 === SIN && sym1.power.add(sym2.power).equals(0)) {
1613
+ if(fn1 === SIN && sym1.power.add(sym2.power).equals(0)) {
1559
1614
  sym1.fname = TAN;
1560
1615
  sym1.updateHash();
1561
1616
  retval = __.integrate(sym1, dx, depth);
@@ -1563,64 +1618,66 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1563
1618
  else {
1564
1619
  if(even(sym1.power) && fn2 === COS && sym2.power.lessThan(0)) {
1565
1620
  //transform sin^(2*n) to (1-cos^2)^n
1566
- var n = Number(sym1.power)/2,
1567
- new_sym = _.parse(format('(1-cos({0})^2)^({1})', sym1.args[0], n));
1621
+ var n = Number(sym1.power) / 2,
1622
+ new_sym = _.parse(format('(1-cos({0})^2)^({1})', sym1.args[0], n));
1568
1623
  retval = __.integrate(_.expand(_.multiply(new_sym, sym2.clone())), dx, depth, opt);
1569
1624
  }
1570
1625
  else if(even(sym1.power) && fn2 === SIN && sym2.power.lessThan(0)) {
1571
1626
  //transform cos^(2*n) to (1-sin^2)^n
1572
- var n = Number(sym1.power)/2,
1573
- new_sym = _.parse(format('(1-sin({0})^2)^({1})', sym1.args[0], n));
1627
+ var n = Number(sym1.power) / 2,
1628
+ new_sym = _.parse(format('(1-sin({0})^2)^({1})', sym1.args[0], n));
1574
1629
  retval = __.integrate(_.expand(_.multiply(new_sym, sym2.clone())), dx, depth, opt);
1575
1630
  }
1576
1631
  else {
1577
1632
  var p1_even = core.Utils.even(sym1.power),
1578
- p2_even = core.Utils.even(sym2.power);
1633
+ p2_even = core.Utils.even(sym2.power);
1579
1634
  retval = new Symbol(0);
1580
- if(!p1_even || !p2_even) {
1635
+ if(!p1_even || !p2_even) {
1581
1636
  var u, r, trans;
1582
1637
  //since cos(x) is odd it carries du. If sin was odd then it would be the other way around
1583
1638
  //know that p1 satifies the odd portion in this case. If p2 did than it would contain r
1584
1639
  if(!p1_even) {
1585
1640
  //u = sin(x)
1586
- u = sym2; r = sym1;
1641
+ u = sym2;
1642
+ r = sym1;
1587
1643
  }
1588
1644
  else {
1589
- u = sym1; r = sym2;
1645
+ u = sym1;
1646
+ r = sym2;
1590
1647
  }
1591
1648
  //get the sign of du. In this case r carries du as stated before and D(cos(x),x) = -sin(x)
1592
1649
  var sign = u.fname === COS ? -1 : 1,
1593
- n = r.power,
1594
- //remove the du e.g. cos(x)^2*sin(x)^3 dx -> cos(x)^2*sin(x)^2*sin(x). We're left with two
1595
- //even powers afterwards which can be transformed
1596
- k = (n - 1)/2,
1597
- //make the transformation cos(x)^2 = 1 - sin(x)^2
1598
- trans = _.parse('(1-'+u.fname+core.Utils.inBrackets(arg1)+'^2)^'+k),
1599
- sym = _.expand(_.multiply(new Symbol(sign), _.multiply(u.clone(), trans)));
1650
+ n = r.power,
1651
+ //remove the du e.g. cos(x)^2*sin(x)^3 dx -> cos(x)^2*sin(x)^2*sin(x). We're left with two
1652
+ //even powers afterwards which can be transformed
1653
+ k = (n - 1) / 2,
1654
+ //make the transformation cos(x)^2 = 1 - sin(x)^2
1655
+ trans = _.parse('(1-' + u.fname + core.Utils.inBrackets(arg1) + '^2)^' + k),
1656
+ sym = _.expand(_.multiply(new Symbol(sign), _.multiply(u.clone(), trans)));
1600
1657
  //we can now just loop through and integrate each since it's now just a polynomial with functions
1601
- sym.each(function(x) {
1658
+ sym.each(function (x) {
1602
1659
  retval = _.add(retval, __.integration.poly_integrate(x.clone()));
1603
1660
  });
1604
1661
  }
1605
- else {
1662
+ else {
1606
1663
  //performs double angle transformation
1607
- var double_angle = function(symbol) {
1664
+ var double_angle = function (symbol) {
1608
1665
  var p = symbol.power,
1609
- k = p/2, e;
1666
+ k = p / 2, e;
1610
1667
  if(symbol.fname === COS)
1611
- e = '((1/2)+(cos(2*('+symbol.args[0]+'))/2))^'+k;
1668
+ e = '((1/2)+(cos(2*(' + symbol.args[0] + '))/2))^' + k;
1612
1669
  else
1613
- e = '((1/2)-(cos(2*('+symbol.args[0]+'))/2))^'+k;
1670
+ e = '((1/2)-(cos(2*(' + symbol.args[0] + '))/2))^' + k;
1614
1671
 
1615
1672
  return _.parse(e);
1616
1673
  };
1617
1674
  //they're both even so transform both using double angle identities and we'll just
1618
1675
  //be able to integrate by the sum of integrals
1619
1676
  var a = double_angle(sym1),
1620
- b = double_angle(sym2),
1621
- t = _.multiply(a, b);
1677
+ b = double_angle(sym2),
1678
+ t = _.multiply(a, b);
1622
1679
  var sym = _.expand(t);
1623
- sym.each(function(x) {
1680
+ sym.each(function (x) {
1624
1681
  retval = _.add(retval, __.integrate(x, dx, depth));
1625
1682
  });
1626
1683
  return _.multiply(retval, coeff);
@@ -1629,16 +1686,16 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1629
1686
  }
1630
1687
  }
1631
1688
  //tan(x)*sec(x)^n
1632
- else if(fn1 === SEC && fn2 === TAN && x.isLinear() && sym2.isLinear()) {
1689
+ else if(fn1 === SEC && fn2 === TAN && x.isLinear() && sym2.isLinear()) {
1633
1690
  retval = _.parse(format('sec({0})^({1})/({1})', sym1.args[0], sym1.power));
1634
1691
  }
1635
- else if(fn1 === TAN && fn2 === SEC && x.isLinear()) {
1692
+ else if(fn1 === TAN && fn2 === SEC && x.isLinear()) {
1636
1693
  //remaining: tan(x)^3*sec(x)^6
1637
1694
  if(sym1.isLinear() && sym2.isLinear()) {
1638
1695
  retval = _.divide(_.symfunction(SEC, [arg1.clone()]), a);
1639
1696
  }
1640
1697
  else if(even(sym1.power)) {
1641
- var p = Number(sym1.power)/2;
1698
+ var p = Number(sym1.power) / 2;
1642
1699
  //transform tangent
1643
1700
  var t = _.parse(format('(sec({0})^2-1)^({1})', sym1.args[0], p));
1644
1701
  retval = __.integrate(_.expand(_.multiply(t, sym2)), dx, depth);
@@ -1661,14 +1718,14 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1661
1718
  var t = _.multiply(sym1.fnTransform(), sym2);
1662
1719
  retval = __.integrate(_.expand(t), dx, depth);
1663
1720
  }
1664
- else {
1721
+ else {
1665
1722
  var t = _.multiply(sym1.fnTransform(), sym2.fnTransform());
1666
1723
  retval = __.integrate(_.expand(t), dx, depth);
1667
1724
  }
1668
1725
  }
1669
1726
  //TODO: In progress
1670
1727
  else if((fn1 === SIN || fn1 === COS) && (fn2 === SIN || fn2 === COS)) {
1671
-
1728
+
1672
1729
  if(sym1.isLinear() && sym2.isLinear()) {
1673
1730
  //if in the form cos(a*x)*sin(b*x)
1674
1731
  if(sym1.args[0].isLinear() && sym2.args[0].isLinear()) {
@@ -1682,7 +1739,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1682
1739
  bx = sym1.args[0];
1683
1740
  ax = sym2.args[0];
1684
1741
  }
1685
-
1742
+
1686
1743
  //make the transformation
1687
1744
  f = _.parse(format('(sin(({1})+({0}))+sin(({1})-({0})))/2', ax.toString(), bx.toString()));
1688
1745
 
@@ -1696,7 +1753,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1696
1753
  }
1697
1754
  else {
1698
1755
  var transformed = new Symbol(1);
1699
- symbols.map(function(sym) {
1756
+ symbols.map(function (sym) {
1700
1757
  var s = sym.fnTransform();
1701
1758
  transformed = _.multiply(transformed, s);
1702
1759
  });
@@ -1715,9 +1772,9 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1715
1772
 
1716
1773
  }
1717
1774
  }
1718
- else if(g1 === FN && g2 === S) {
1775
+ else if(g1 === FN && g2 === S) {
1719
1776
  var sym1_is_linear = sym1.isLinear();
1720
- if(sym1.fname === COS && sym1_is_linear && sym2.power.equals(-1))
1777
+ if(sym1.fname === COS && sym1_is_linear && sym2.power.equals(-1))
1721
1778
  retval = _.symfunction('Ci', [sym1.args[0]]);
1722
1779
  else if(sym1.fname === COS && sym2.power.equals(-1)) {
1723
1780
  retval = __.integrate(_.multiply(sym1.fnTransform(), sym2.clone()), dx, depth);
@@ -1744,18 +1801,18 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1744
1801
  else if(sym1.fname === 'erf') {
1745
1802
  if(sym2.power.equals(1)) {
1746
1803
  var dc = __.integration.decompose_arg(sym1.args[0], dx),
1747
- a_ = dc[0],
1748
- x_ = dc[1],
1749
- arg = sym1.args[0].toString();
1804
+ a_ = dc[0],
1805
+ x_ = dc[1],
1806
+ arg = sym1.args[0].toString();
1750
1807
  retval = _.parse(format('(e^(-(({2}))^2)*(sqrt(pi)*e^((({2}))^2)*(2*({0})^2*({1})^2-3)*erf(({2}))+2*({0})*({1})-2))/(4*sqrt(pi)*({0})^2)', a_, x_, arg))
1751
1808
  }
1752
1809
  }
1753
- else {
1810
+ else {
1754
1811
  //since group S is guaranteed convergence we need not worry about tracking depth of integration
1755
1812
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1756
1813
  }
1757
1814
  }
1758
- else if(g1 === EX && g2 === S) {
1815
+ else if(g1 === EX && g2 === S) {
1759
1816
  var x = fn1 === LOG ? __.integration.decompose_arg(sym1.args[0], dx)[1] : null;
1760
1817
  if(sym1.isE() && (sym1.power.group === S || sym1.power.group === CB) && sym2.power.equals(-1)) {
1761
1818
  retval = _.symfunction('Ei', [sym1.power.clone()]);
@@ -1778,7 +1835,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1778
1835
  factor.power = new Frac(pc);
1779
1836
  sym2 = _.divide(sym2, factor.clone()); //reduce the denominator
1780
1837
  var t = new Symbol(0);
1781
- sym1.each(function(x) {
1838
+ sym1.each(function (x) {
1782
1839
  t = _.add(t, _.divide(x.clone(), factor.clone()));
1783
1840
  });
1784
1841
  t.multiplier = sym1.multiplier;
@@ -1789,31 +1846,31 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1789
1846
  }
1790
1847
  retval = __.integration.partial_fraction(symbol, dx, depth);
1791
1848
  }
1792
- else if(g1 === CP && g2 === S) {
1849
+ else if(g1 === CP && g2 === S) {
1793
1850
  var f = sym1.clone().toLinear(),
1794
- f_is_linear = core.Algebra.degree(f, _.parse(dx)).equals(1);
1851
+ f_is_linear = core.Algebra.degree(f, _.parse(dx)).equals(1);
1795
1852
  //handle cases x^(2*n)/sqrt(1-x^2)
1796
- if(sym1.power.equals(-1/2)) {
1853
+ if(sym1.power.equals(-1 / 2)) {
1797
1854
  var decomp = __.integration.decompose_arg(sym1.clone().toLinear(), dx);
1798
1855
  var a = decomp[0].negate(),
1799
- x = decomp[1],
1800
- b = decomp[3],
1801
- p1 = Number(sym1.power),
1802
- p2 = Number(sym2.power);
1856
+ x = decomp[1],
1857
+ b = decomp[3],
1858
+ p1 = Number(sym1.power),
1859
+ p2 = Number(sym2.power);
1803
1860
  if(isInt(p2) && core.Utils.even(p2) && x.power.equals(2)) {
1804
1861
  //if the substitution
1805
- var c = _.divide(_.multiply(_.pow(b.clone(), new Symbol(2)),
1806
- _.symfunction(SQRT, [_.divide(b.clone(), a.clone())])),
1807
- _.pow(a.clone(), new Symbol(2)));
1862
+ var c = _.divide(_.multiply(_.pow(b.clone(), new Symbol(2)),
1863
+ _.symfunction(SQRT, [_.divide(b.clone(), a.clone())])),
1864
+ _.pow(a.clone(), new Symbol(2)));
1808
1865
  c = _.multiply(c, _.symfunction(SQRT, [b]).invert());
1809
1866
  var dummy = _.parse('sin(u)');
1810
1867
  dummy.power = dummy.power.multiply(sym2.power);
1811
1868
  var integral = __.integrate(dummy, 'u', depth);
1812
- var bksub = _.parse(ASIN+'('+SQRT+'('+a+'/'+b+')*'+dx+')');
1869
+ var bksub = _.parse(ASIN + '(' + SQRT + '(' + a + '/' + b + ')*' + dx + ')');
1813
1870
  retval = _.multiply(c, integral.sub(new Symbol('u'), bksub));
1814
- }
1815
- else if(p1 === -1/2) {
1816
- var u_transform = function(f, u) {
1871
+ }
1872
+ else if(p1 === -1 / 2) {
1873
+ var u_transform = function (f, u) {
1817
1874
  var integral = _.parse(__.integrate(f, dx, depth, opt).sub(dx, format(u, dx)));
1818
1875
  if(!integral.hasIntegral())
1819
1876
  return integral;
@@ -1822,58 +1879,58 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1822
1879
  retval = u_transform(
1823
1880
  _.expand(_.expand(_.pow(_.multiply(sym1.invert(), sym2.invert()), new Symbol(2)))).invert(),
1824
1881
  'sqrt(1-1/({0})^2)'
1825
- );
1882
+ );
1826
1883
  }
1827
1884
  else if(p2 === -2) {
1828
1885
  //apply transformation to see if it matches asin(x)
1829
1886
  retval = u_transform(
1830
1887
  _.sqrt(_.expand(_.divide(_.pow(symbol, new Symbol(2)).invert(), _.pow(new Symbol(dx), new Symbol(2))).negate())).invert(),
1831
1888
  'sqrt(1-1/({0})^2)'
1832
- );
1889
+ );
1833
1890
  }
1834
1891
  }
1835
1892
  }
1836
- else if(sym1.power.equals(-1) && sym2.isLinear() && f_is_linear) {
1893
+ else if(sym1.power.equals(-1) && sym2.isLinear() && f_is_linear) {
1837
1894
  retval = __.integration.partial_fraction(symbol, dx, depth);
1838
1895
  }
1839
- else if(!sym1.power.lessThan(0) && isInt(sym1.power)) {
1896
+ else if(!sym1.power.lessThan(0) && isInt(sym1.power)) {
1840
1897
  //sum of integrals
1841
1898
  var expanded = _.expand(sym1);
1842
1899
  retval = new Symbol(0);
1843
- expanded.each(function(x) {
1900
+ expanded.each(function (x) {
1844
1901
  if(x.group === PL) {
1845
- x.each(function(y) {
1902
+ x.each(function (y) {
1846
1903
  retval = _.add(retval, __.integrate(_.multiply(sym2.clone(), y), dx, depth));
1847
1904
  });
1848
1905
  }
1849
- else
1906
+ else
1850
1907
  retval = _.add(retval, __.integrate(_.multiply(sym2.clone(), x), dx, depth));
1851
1908
  });
1852
1909
  }
1853
- else if(sym1.power.lessThan(-2)) {
1910
+ else if(sym1.power.lessThan(-2)) {
1854
1911
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1855
1912
  }
1856
- else if(sym1.power.lessThan(0) && sym2.power.greaterThan(1)) {
1913
+ else if(sym1.power.lessThan(0) && sym2.power.greaterThan(1)) {
1857
1914
  var decomp = __.integration.decompose_arg(sym1.clone().toLinear(), dx),
1858
- a = decomp[0].negate(),
1859
- x = decomp[1],
1860
- b = decomp[3],
1861
- fn = sym1.clone().toLinear();
1915
+ a = decomp[0].negate(),
1916
+ x = decomp[1],
1917
+ b = decomp[3],
1918
+ fn = sym1.clone().toLinear();
1862
1919
 
1863
- if(x.group !== PL && x.isLinear()) {
1920
+ if(x.group !== PL && x.isLinear()) {
1864
1921
  var p = Number(sym2.power),
1865
- du = '_u_',
1866
- u = new Symbol(du),
1867
- //pull the integral with the subsitution
1868
- U = _.expand(_.divide(_.pow(_.subtract(u.clone(), b.clone()), new Symbol(p)), u.clone())),
1869
- scope = {};
1922
+ du = '_u_',
1923
+ u = new Symbol(du),
1924
+ //pull the integral with the subsitution
1925
+ U = _.expand(_.divide(_.pow(_.subtract(u.clone(), b.clone()), new Symbol(p)), u.clone())),
1926
+ scope = {};
1870
1927
 
1871
1928
  //generate a scope for resubbing the symbol
1872
1929
  scope[du] = fn;
1873
1930
  var U2 = _.parse(U, scope);
1874
1931
  retval = __.integrate(U2, dx, 0);
1875
1932
  }
1876
- else if(sym2.power.greaterThan(x.power) || sym2.power.equals(x.power)) {
1933
+ else if(sym2.power.greaterThan(x.power) || sym2.power.equals(x.power)) {
1877
1934
 
1878
1935
  //factor out coefficients
1879
1936
  var factors = new core.Algebra.Classes.Factors();
@@ -1882,11 +1939,11 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1882
1939
  //it assumed that the result will be of group CB
1883
1940
  if(div.group !== CB) {
1884
1941
  retval = new Symbol(0);
1885
- div.each(function(t) {
1942
+ div.each(function (t) {
1886
1943
  retval = _.add(retval, __.integrate(t, dx, depth));
1887
1944
  });
1888
1945
  //put back the factors
1889
- factors.each(function(factor) {
1946
+ factors.each(function (factor) {
1890
1947
  retval = _.divide(retval, factor);
1891
1948
  });
1892
1949
 
@@ -1897,16 +1954,16 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1897
1954
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1898
1955
  }
1899
1956
  }
1900
- else
1957
+ else
1901
1958
  retval = __.integration.partial_fraction(symbol, dx, depth);
1902
1959
  }
1903
- else {
1960
+ else {
1904
1961
  //handle cases such as (1-x^2)^(n/2)*x^(m) where n is odd ___ cracking knuckles... This can get a little hairy
1905
- if(sym1.power.den.equals(2)) {
1962
+ if(sym1.power.den.equals(2)) {
1906
1963
  //assume the function is in the form (a^2-b*x^n)^(m/2)
1907
1964
  var dc = __.integration.decompose_arg(sym1.clone().toLinear(), dx),
1908
- //using the above definition
1909
- a = dc[3], x = dc[1], b = dc[0], bx = dc[2];
1965
+ //using the above definition
1966
+ a = dc[3], x = dc[1], b = dc[0], bx = dc[2];
1910
1967
  if(x.power.equals(2) && b.lessThan(0)) { //if n is even && b is negative
1911
1968
  //make a equal 1 so we can do a trig sub
1912
1969
  if(!a.equals(1)) { //divide a out of everything
@@ -1914,14 +1971,14 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1914
1971
  coeff = _.multiply(coeff, _.pow(a, new Symbol(2)));
1915
1972
  }
1916
1973
  var u = dx;
1917
- var c = _.divide(_.pow(b.clone().negate(), new Symbol(1/2)), _.pow(a, new Symbol(1/2))),
1918
- du = _.symfunction(COS, [new Symbol(u)]),
1919
- cosn = _.pow(_.symfunction(COS, [new Symbol(u)]), new Symbol(sym1.power.num)),
1920
- X = _.pow(_.symfunction(SIN, [new Symbol(u)]), new Symbol(sym2.power)),
1921
- val = _.multiply(_.multiply(cosn, du), X),
1922
- integral = __.integrate(val, u, depth);
1923
- //but remember that u = asin(sqrt(b)*a*x)
1924
- retval = integral.sub(u, _.symfunction(ASIN, [_.multiply(new Symbol(dx), c)]));
1974
+ var c = _.divide(_.pow(b.clone().negate(), new Symbol(1 / 2)), _.pow(a, new Symbol(1 / 2))),
1975
+ du = _.symfunction(COS, [new Symbol(u)]),
1976
+ cosn = _.pow(_.symfunction(COS, [new Symbol(u)]), new Symbol(sym1.power.num)),
1977
+ X = _.pow(_.symfunction(SIN, [new Symbol(u)]), new Symbol(sym2.power)),
1978
+ val = _.multiply(_.multiply(cosn, du), X),
1979
+ integral = __.integrate(val, u, depth);
1980
+ //but remember that u = asin(sqrt(b)*a*x)
1981
+ retval = integral.sub(u, _.symfunction(ASIN, [_.multiply(new Symbol(dx), c)]));
1925
1982
  }
1926
1983
  else {
1927
1984
  retval = __.integration.partial_fraction(symbol, dx, depth, opt);
@@ -1933,28 +1990,30 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1933
1990
  }
1934
1991
 
1935
1992
  }
1936
- else if(sym1.isComposite() && sym2.isComposite()) {
1993
+ else if(sym1.isComposite() && sym2.isComposite()) {
1937
1994
  //sum of integrals
1938
1995
  retval = new Symbol(0);
1939
1996
  if(sym1.power.greaterThan(0) && sym2.power.greaterThan(0)) {
1940
1997
  //combine and pull the integral of each
1941
1998
  var sym = _.expand(symbol);
1942
- sym.each(function(x) {
1999
+ sym.each(function (x) {
1943
2000
  retval = _.add(retval, __.integrate(x, dx, depth));
1944
2001
  }, true);
1945
2002
  }
1946
2003
  else {
1947
2004
  var p1 = Number(sym1.power),
1948
- p2 = Number(sym2.power);
2005
+ p2 = Number(sym2.power);
1949
2006
  if(p1 < 0 && p2 > 0) {
1950
2007
  //swap
1951
- var t = sym1; sym1 = sym2; sym2 = t;
2008
+ var t = sym1;
2009
+ sym1 = sym2;
2010
+ sym2 = t;
1952
2011
  }
1953
2012
  if(p1 === -1 && p2 === -1) {
1954
2013
  retval = __.integration.partial_fraction(symbol, dx);
1955
2014
  }
1956
2015
  else {
1957
- sym1.each(function(x) {
2016
+ sym1.each(function (x) {
1958
2017
  var k = _.multiply(x, sym2.clone());
1959
2018
  var integral = __.integrate(k, dx, depth);
1960
2019
  retval = _.add(retval, integral);
@@ -1965,7 +2024,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1965
2024
  else if(g1 === CP && symbols[0].power.greaterThan(0)) {
1966
2025
  sym1 = _.expand(sym1);
1967
2026
  retval = new Symbol(0);
1968
- sym1.each(function(x) {
2027
+ sym1.each(function (x) {
1969
2028
  retval = _.add(retval, __.integrate(_.multiply(x, sym2.clone()), dx, depth));
1970
2029
  }, true);
1971
2030
  }
@@ -1975,12 +2034,14 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1975
2034
  }
1976
2035
  else if(g1 === FN && g2 === CP || g2 === FN && g1 === CP) {
1977
2036
  if(g2 === FN && g1 === CP) {
1978
- var t = sym1; sym1 = sym2; sym2 = t; //swap
2037
+ var t = sym1;
2038
+ sym1 = sym2;
2039
+ sym2 = t; //swap
1979
2040
  }
1980
2041
  var du, sym2_clone, p, q, sa, sb;
1981
2042
  du = Symbol.unwrapSQRT(__.diff(sym1.clone(), dx), true);
1982
2043
  sym2_clone = Symbol.unwrapSQRT(sym2, true);
1983
- if(du.power.equals(sym2_clone.power)) {
2044
+ if(du.power.equals(sym2_clone.power)) {
1984
2045
  p = new Symbol(sym2.power);
1985
2046
  sa = du.clone().toLinear();
1986
2047
  sb = sym2.clone().toLinear();
@@ -1994,58 +2055,58 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
1994
2055
  retval = __.integration.by_parts(symbol, dx, depth, opt);
1995
2056
  }
1996
2057
  }
1997
- else {
2058
+ else {
1998
2059
  var syma = sym1.clone().toLinear();
1999
2060
  var symb = sym2.clone().toLinear();
2000
- if(g1 === EX && g2 === EX && sym1.power.contains(dx) && sym2.power.contains(dx)
2061
+ if(g1 === EX && g2 === EX && sym1.power.contains(dx) && sym2.power.contains(dx)
2001
2062
  && !syma.contains(dx) && !symb.contains(dx)) {
2002
2063
  retval = _.parse(format('(({0})^(({2})*({4}))*({1})^(({3})*({4})))/(log(({0})^({2}))+log(({1})^({3})))',
2003
- syma.toString(),
2004
- symb.toString(),
2005
- sym1.power.multiplier.toString(),
2006
- sym2.power.multiplier.toString(),
2007
- dx
2008
- ));
2064
+ syma.toString(),
2065
+ symb.toString(),
2066
+ sym1.power.multiplier.toString(),
2067
+ sym2.power.multiplier.toString(),
2068
+ dx
2069
+ ));
2009
2070
  }
2010
- else
2071
+ else
2011
2072
  retval = __.integration.by_parts(symbol, dx, depth, opt);
2012
2073
  }
2013
2074
  }
2014
2075
  }
2015
- else if(l === 3 && (symbols[2].group === S && symbols[2].power.lessThan(2) || symbols[0].group === CP)) {
2076
+ else if(l === 3 && (symbols[2].group === S && symbols[2].power.lessThan(2) || symbols[0].group === CP)) {
2016
2077
  var first = symbols[0];
2017
2078
  if(first.group === CP) { //TODO {support higher powers of x in the future}
2018
2079
  if(first.power.greaterThan(1))
2019
2080
  first = _.expand(first);
2020
2081
  var r = _.multiply(symbols[1], symbols[2]);
2021
2082
  retval = new Symbol(0);
2022
- first.each(function(x) {
2083
+ first.each(function (x) {
2023
2084
  var t = _.multiply(x, r.clone());
2024
2085
  var intg = __.integrate(t, dx, depth);
2025
2086
  retval = _.add(retval, intg);
2026
2087
  }, true);
2027
2088
  }
2028
- else {
2089
+ else {
2029
2090
  //try integration by parts although technically it will never work
2030
2091
  retval = __.integration.by_parts(symbol, dx, depth, opt);
2031
2092
  }
2032
2093
 
2033
2094
  }
2034
- else if(all_functions(symbols)) {
2095
+ else if(all_functions(symbols)) {
2035
2096
  var t = new Symbol(1);
2036
- for(var i=0,l=symbols.length; i<l; i++) {
2097
+ for(var i = 0, l = symbols.length; i < l; i++) {
2037
2098
  t = _.multiply(t, symbols[i].fnTransform());
2038
2099
  }
2039
2100
  t = _.expand(t);
2040
2101
  retval = __.integrate(t, dx, depth);
2041
2102
  }
2042
- else {
2103
+ else {
2043
2104
  //one more go
2044
2105
  var transformed = trigTransform(symbols);
2045
2106
  retval = __.integrate(_.expand(transformed), dx, depth);
2046
2107
  }
2047
2108
  }
2048
-
2109
+
2049
2110
  }
2050
2111
 
2051
2112
  retval = _.multiply(retval, coeff);
@@ -2055,19 +2116,19 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2055
2116
  return retval;
2056
2117
  }
2057
2118
 
2058
- catch(error){
2119
+ catch(error) {
2059
2120
  //do nothing if it's a NoIntegralFound error otherwise let it bubble
2060
- if(!(error instanceof NoIntegralFound || error instanceof core.exceptions.DivisionByZero))
2121
+ if(!(error instanceof NoIntegralFound || error instanceof core.exceptions.DivisionByZero))
2061
2122
  throw error;
2062
- }
2123
+ }
2063
2124
 
2064
2125
  //no symbol found so we return the integral again
2065
2126
  return _.symfunction('integrate', [original_symbol, dt]);
2066
2127
  }, false);
2067
2128
  },
2068
- defint: function(symbol, from, to, dx) {
2129
+ defint: function (symbol, from, to, dx) {
2069
2130
  dx = dx || 'x'; //make x the default variable of integration
2070
- var get_value = function(integral, vars, point) {
2131
+ var get_value = function (integral, vars, point) {
2071
2132
  try {
2072
2133
  return _.parse(integral, vars);
2073
2134
  }
@@ -2077,54 +2138,54 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2077
2138
  return lim;
2078
2139
  }
2079
2140
  };
2080
-
2141
+
2081
2142
  var vars = core.Utils.variables(symbol),
2082
- hasTrig = symbol.hasTrig();
2143
+ hasTrig = symbol.hasTrig();
2083
2144
  var retval, integral;
2084
-
2145
+
2085
2146
  // Fix #593 - Only assume the first variable if dx is not defined.
2086
2147
  if(vars.length === 1 && !dx)
2087
2148
  dx = vars[0];
2088
-
2149
+
2089
2150
  if(!hasTrig) {
2090
2151
  integral = __.integrate(symbol, dx);
2091
2152
  }
2092
-
2093
- if(!hasTrig && !integral.hasIntegral()) {
2153
+
2154
+ if(!hasTrig && !integral.hasIntegral()) {
2094
2155
  var upper = {},
2095
- lower = {},
2096
- a, b;
2156
+ lower = {},
2157
+ a, b;
2097
2158
  upper[dx] = to;
2098
2159
  lower[dx] = from;
2099
-
2100
- a = get_value(integral, upper, to, dx);
2160
+
2161
+ a = get_value(integral, upper, to, dx);
2101
2162
  b = get_value(integral, lower, from, dx);
2102
2163
  retval = _.subtract(a, b);
2103
2164
  }
2104
2165
  else if(vars.length === 1 && from.isConstant() && to.isConstant()) {
2105
-
2106
- var f = core.Utils.build(symbol);
2107
- retval = new Symbol(core.Math2.num_integrate(f, Number(from), Number(to)));
2166
+
2167
+ var f = core.Utils.build(symbol);
2168
+ retval = new Symbol(core.Math2.num_integrate(f, Number(from), Number(to)));
2108
2169
  }
2109
- else
2110
- retval = _.symfunction('defint', [symbol, from , to, dx]);
2170
+ else
2171
+ retval = _.symfunction('defint', [symbol, from, to, dx]);
2111
2172
  return retval;
2112
2173
  },
2113
-
2174
+
2114
2175
  Limit: {
2115
- interval: function(start, end) {
2176
+ interval: function (start, end) {
2116
2177
  return _.parse(format('[{0}, {1}]', start, end));
2117
2178
  },
2118
- diverges: function() {
2179
+ diverges: function () {
2119
2180
  return __.Limit.interval('-Infinity', 'Infinity');
2120
2181
  },
2121
- divide: function(f, g, x, lim, depth) {
2182
+ divide: function (f, g, x, lim, depth) {
2122
2183
  if(depth++ > Settings.max_lim_depth) {
2123
2184
  return;
2124
2185
  }
2125
2186
 
2126
2187
  var fin = f.clone(), gin = g.clone();
2127
-
2188
+
2128
2189
  //But first a little "cheating". x/|x| ends up in an infinite loop since the d/dx |x| -> x/|x|
2129
2190
  //To break this loop we simply provide the answer. Keep in mind that currently limit only provides
2130
2191
  //the two-sided limit.
@@ -2135,29 +2196,29 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2135
2196
 
2136
2197
  if(lim.isInfinity)
2137
2198
  return _.multiply(new Symbol(sign), new Symbol(lim_sign));
2138
-
2199
+
2139
2200
  else if(lim.equals(0)) {
2140
2201
  var fm = _.parse(f.multiplier);
2141
2202
  var gm = _.parse(g.multiplier);
2142
- return _.divide(_.multiply(fm,__.Limit.interval('-1', '1')), gm);
2203
+ return _.divide(_.multiply(fm, __.Limit.interval('-1', '1')), gm);
2143
2204
  }
2144
2205
  else {
2145
2206
  //TODO: Support more limits
2146
2207
  __.Limit.diverges();
2147
2208
  }
2148
2209
  }
2149
-
2150
- var isInfinity = function(L) {
2210
+
2211
+ var isInfinity = function (L) {
2151
2212
  if(core.Utils.isVector(L)) {
2152
- for(var i=0; i<L.elements.length; i++)
2213
+ for(var i = 0; i < L.elements.length; i++)
2153
2214
  if(!L.elements[i].isInfinity)
2154
2215
  return false;
2155
2216
  return true;
2156
2217
  }
2157
- return L.isInfinity;
2218
+ return L.isInfinity;
2158
2219
  };
2159
2220
 
2160
- var equals = function(L, v) {
2221
+ var equals = function (L, v) {
2161
2222
  if(core.Utils.isVector(L)) {
2162
2223
  return false;
2163
2224
  }
@@ -2179,17 +2240,17 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2179
2240
  var t_symbol = _.expand(_.divide(ft, gt));
2180
2241
  f = t_symbol.getNum();
2181
2242
  g = t_symbol.getDenom();
2182
-
2243
+
2183
2244
  }
2184
2245
  }
2185
- while(indeterminate)
2246
+ while(indeterminate)
2186
2247
 
2187
2248
  //REMEMBER:
2188
2249
  //- 1/cos(x)
2189
2250
  //n/0 is still possible since we only checked for 0/0
2190
2251
  var den_is_zero = lim2.equals(0);
2191
2252
  var p = Number(gin.power);
2192
-
2253
+
2193
2254
  if(lim.isConstant(true) && den_is_zero) {
2194
2255
  retval = Symbol.infinity(core.Utils.even(p) && lim1.lessThan(0) ? -1 : undefined);
2195
2256
  }
@@ -2199,15 +2260,15 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2199
2260
  else {
2200
2261
  retval = _.divide(lim1, lim2);
2201
2262
  }
2202
-
2263
+
2203
2264
  return retval;
2204
2265
  },
2205
- rewriteToLog: function(symbol) {
2266
+ rewriteToLog: function (symbol) {
2206
2267
  var p = symbol.power.clone();
2207
2268
  symbol.toLinear();
2208
- return _.pow(new Symbol('e'), _.multiply(p, _.symfunction(Settings.LOG+'', [symbol])));
2269
+ return _.pow(new Symbol('e'), _.multiply(p, _.symfunction(Settings.LOG + '', [symbol])));
2209
2270
  },
2210
- getSubbed: function(f, x, lim) {
2271
+ getSubbed: function (f, x, lim) {
2211
2272
  var retval;
2212
2273
  //1. rewrite EX with base e
2213
2274
  if(f.group === EX) {
@@ -2221,45 +2282,46 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2221
2282
  //Nope. No go, so just return the unsubbed function so we can test the limit instead.
2222
2283
  retval = f;
2223
2284
  }
2224
-
2285
+
2225
2286
  return retval;
2226
2287
  },
2227
- isInterval: function(limit) {
2288
+ isInterval: function (limit) {
2228
2289
  return core.Utils.isVector(limit);
2229
2290
  },
2230
- isConvergent: function(limit) {
2291
+ isConvergent: function (limit) {
2231
2292
  //it's not convergent if it lies on the interval -Infinity to Infinity
2232
- if(
2233
- //It lies on the interval -Infinity to Infinity
2234
- __.Limit.isInterval(limit) && limit.elements[0].isInfinity && limit.elements[1].isInfinity ||
2235
- //We weren't able to calculate the limit
2236
- limit.containsFunction('limit')
2237
- ) {
2293
+ if(
2294
+ //It lies on the interval -Infinity to Infinity
2295
+ __.Limit.isInterval(limit) && limit.elements[0].isInfinity && limit.elements[1].isInfinity ||
2296
+ //We weren't able to calculate the limit
2297
+ limit.containsFunction('limit')
2298
+ ) {
2238
2299
  return false; //Then no
2239
2300
  }
2240
2301
  return true; //It is
2241
2302
  },
2242
- limit: function(symbol, x, lim, depth) {
2303
+ limit: function (symbol, x, lim, depth) {
2243
2304
  //Simplify the symbol
2244
2305
  if(symbol.isLinear() && symbol.isComposite()) {
2245
-
2306
+
2246
2307
  //Apply sum of limits
2247
2308
  var limit = new Symbol(0);
2248
- symbol.each(function(s) {
2309
+ symbol.each(function (s) {
2249
2310
  limit = _.add(limit, __.Limit.limit(s, x, lim, depth));
2250
2311
  }, true);
2251
-
2312
+
2252
2313
  return limit;
2253
- };
2254
-
2314
+ }
2315
+ ;
2316
+
2255
2317
  symbol = core.Algebra.Simplify.simplify(symbol);
2256
-
2318
+
2257
2319
  depth = depth || 1;
2258
-
2320
+
2259
2321
  if(depth++ > Settings.max_lim_depth) {
2260
2322
  return;
2261
2323
  }
2262
-
2324
+
2263
2325
  //store the multiplier
2264
2326
  var m = _.parse(symbol.multiplier);
2265
2327
  //strip the multiplier
@@ -2276,18 +2338,20 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2276
2338
  var point = {};
2277
2339
  point[x] = lim;
2278
2340
  //lim x as x->c = c where c
2279
-
2341
+
2280
2342
  try {
2281
-
2343
+
2282
2344
  //evaluate the function at the given limit
2283
2345
  var t = _.parse(symbol.sub(x, lim), point);
2284
2346
 
2285
2347
  //a constant or infinity is known so we're done
2286
2348
  if(t.isConstant(true) || t.isInfinity)
2287
2349
  retval = t;
2288
-
2350
+
2351
+ }
2352
+ catch(e) { /*Nothing. Maybe we tried to divide by zero.*/
2289
2353
  }
2290
- catch(e){ /*Nothing. Maybe we tried to divide by zero.*/};
2354
+ ;
2291
2355
 
2292
2356
  if(!retval) {
2293
2357
  //split the symbol in the numerator and the denominator
@@ -2318,23 +2382,23 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2318
2382
  retval = _.pow(lim_base, lim_pow);
2319
2383
  }
2320
2384
  }
2321
- else if(symbol.group === FN && symbol.args.length === 1 ) {
2385
+ else if(symbol.group === FN && symbol.args.length === 1) {
2322
2386
  var evaluates;
2323
2387
  //Squeeze theorem lim f(g(x)) = lim f(lim g))
2324
2388
  var arg = __.Limit.limit(symbol.args[0], x, lim, depth);
2325
2389
  if(core.Utils.isVector(arg)) {
2326
2390
  //get the limit over that interval
2327
- retval = arg.map(function(e) {
2391
+ retval = arg.map(function (e) {
2328
2392
  var clone = symbol.clone();
2329
2393
  clone.args[0] = e;
2330
2394
  return __.Limit.limit(_.symfunction(symbol.fname, [e]), x, lim, depth);
2331
2395
  });
2332
-
2396
+
2333
2397
  return _.multiply(m, retval);
2334
2398
  }
2335
2399
  //if the argument is constant then we're done
2336
2400
  else if(arg.isConstant(true)) {
2337
-
2401
+
2338
2402
  //double check that it evaluates
2339
2403
  var trial = _.symfunction(symbol.fname, [arg]);
2340
2404
  //trial evaluation
@@ -2343,7 +2407,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2343
2407
  evaluates = true;
2344
2408
  }
2345
2409
  catch(e) {
2346
-
2410
+
2347
2411
  evaluates = false;
2348
2412
  }
2349
2413
  }
@@ -2353,7 +2417,7 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2353
2417
  else {
2354
2418
  //if the limit converges. We'll deal with non-convergent ones later
2355
2419
  if(__.Limit.isConvergent(arg)) {
2356
- if(symbol.fname === LOG) {
2420
+ if(symbol.fname === LOG) {
2357
2421
  switch(arg.toString()) {
2358
2422
  //lim -> 0
2359
2423
  case '0':
@@ -2400,16 +2464,16 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2400
2464
  else {
2401
2465
  //odd ones don't
2402
2466
  retval = __.Limit.diverges();
2403
- }
2467
+ }
2404
2468
  }
2405
2469
  }
2406
- else if(symbol.group === CB) {
2407
-
2470
+ else if(symbol.group === CB) {
2471
+
2408
2472
  var lim1, lim2;
2409
2473
  //loop through all the symbols
2410
2474
  //thus => lim f*g*h = lim (f*g)*h = (lim f*g)*(lim h)
2411
2475
  //symbols of lower groups are generally easier to differentiatee so get them to the right by first sorting
2412
- var symbols = symbol.collectSymbols().sort(function(a, b) {
2476
+ var symbols = symbol.collectSymbols().sort(function (a, b) {
2413
2477
  return a.group - b.group;
2414
2478
  });
2415
2479
 
@@ -2423,16 +2487,16 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2423
2487
  var g = symbols.pop();
2424
2488
  //get the limit of g
2425
2489
  lim2 = evaluate(__.Limit.limit(g, x, lim, depth));
2426
-
2490
+
2427
2491
  //if the limit is in indeterminate form aplly L'Hospital by inverting g and then f/(1/g)
2428
- if((lim1.isInfinity || !__.Limit.isConvergent(lim1) && lim2.equals(0) || lim1.equals(0) && __.Limit.isConvergent(lim2))) {
2492
+ if((lim1.isInfinity || !__.Limit.isConvergent(lim1) && lim2.equals(0) || lim1.equals(0) && __.Limit.isConvergent(lim2))) {
2429
2493
  if(g.containsFunction(LOG)) {
2430
2494
  //swap them
2431
2495
  g = [f, f = g][0];
2432
2496
  }
2433
2497
  //invert the symbol
2434
2498
  g.invert();
2435
-
2499
+
2436
2500
  // Product of infinities
2437
2501
  if(lim1.isInfinity && lim2.isInfinity) {
2438
2502
  lim1 = Symbol.infinity()
@@ -2452,21 +2516,21 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2452
2516
  //Done, lim1 is the limit we're looking for
2453
2517
  retval = lim1;
2454
2518
  }
2455
- else if(symbol.isComposite()) {
2519
+ else if(symbol.isComposite()) {
2456
2520
  var _lim;
2457
2521
  if(!symbol.isLinear())
2458
2522
  symbol = _.expand(symbol);
2459
2523
  //Apply lim f+g = (lim f)+(lim g)
2460
2524
  retval = new Symbol(0);
2461
-
2462
- var symbols = symbol.collectSymbols().sort(function(a, b) {
2525
+
2526
+ var symbols = symbol.collectSymbols().sort(function (a, b) {
2463
2527
  return b.group - a.group;
2464
2528
  });
2465
2529
 
2466
2530
  var _symbols = [];
2467
2531
  //Analyze the functions first
2468
2532
  var fns = new Symbol(0);
2469
- for(var i=0, l=symbols.length; i<l; i++) {
2533
+ for(var i = 0, l = symbols.length; i < l; i++) {
2470
2534
  var sym = symbols[i].clone();
2471
2535
  if(sym.group === FN || sym.group === CB && sym.hasFunc()) {
2472
2536
  fns = _.add(fns, sym);
@@ -2475,13 +2539,13 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2475
2539
  _symbols.push(sym);
2476
2540
  }
2477
2541
  _symbols.unshift(fns);
2478
-
2542
+
2479
2543
  //make sure that we didn't just repackage the exact same symbol
2480
2544
  if(_symbols.length !== 1) {
2481
2545
  symbols = _symbols;
2482
2546
  }
2483
-
2484
- for(var i=0, l=symbols.length; i<l; i++) {
2547
+
2548
+ for(var i = 0, l = symbols.length; i < l; i++) {
2485
2549
  var sym = symbols[i];
2486
2550
  //If the addition of the limits is undefined then the limit diverges so return -infinity to infinity
2487
2551
  try {
@@ -2490,46 +2554,47 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2490
2554
  catch(e) {
2491
2555
  _lim = __.Limit.diverges();
2492
2556
  }
2493
-
2557
+
2494
2558
  try {
2495
2559
  retval = _.add(retval, _lim);
2496
2560
  }
2497
2561
  catch(e) {
2498
2562
  if(depth++ > Settings.max_lim_depth) {
2499
2563
  return;
2500
- };
2564
+ }
2565
+ ;
2501
2566
  retval = __.Limit.limit(__.diff(symbol, x), x, lim, depth);
2502
2567
  }
2503
2568
  }
2504
- }
2569
+ }
2505
2570
  }
2506
2571
  else {
2507
2572
  retval = __.Limit.divide(num, den, x, lim, depth);
2508
- }
2573
+ }
2509
2574
  }
2510
2575
  }
2511
2576
 
2512
2577
  //if we still don't have a solution
2513
2578
  if(!retval)
2514
2579
  //return it symbolically
2515
- retval = _.symfunction('limit', [symbol, x, lim]);
2580
+ retval = _.symfunction('limit', [symbol, x, lim]);
2516
2581
  }
2517
2582
  catch(e) {
2518
2583
  //if all else fails return the symbolic function
2519
- retval = _.symfunction('limit', [symbol, x, lim]);
2584
+ retval = _.symfunction('limit', [symbol, x, lim]);
2520
2585
  }
2521
-
2586
+
2522
2587
  return _.multiply(m, retval);
2523
2588
  }
2524
2589
  },
2525
2590
  Fresnel: {
2526
- S: function(x) {
2591
+ S: function (x) {
2527
2592
  if(x.isConstant(true)) {
2528
2593
  return __.defint(_.parse('sin(pi*x^2/2)'), Symbol(0), x, 'x');
2529
2594
  }
2530
2595
  return _.symfunction('S', arguments);
2531
2596
  },
2532
- C: function(x) {
2597
+ C: function (x) {
2533
2598
  if(x.isConstant(true)) {
2534
2599
  return __.defint(_.parse('cos(pi*x^2/2)'), Symbol(0), x, 'x');
2535
2600
  }
@@ -2537,58 +2602,74 @@ if((typeof module) !== 'undefined' && typeof nerdamer === 'undefined') {
2537
2602
  }
2538
2603
  }
2539
2604
  };
2540
-
2605
+
2541
2606
  nerdamer.register([
2542
2607
  {
2543
2608
  name: 'diff',
2544
2609
  visible: true,
2545
- numargs: [1,3],
2546
- build: function(){ return __.diff; }
2610
+ numargs: [1, 3],
2611
+ build: function () {
2612
+ return __.diff;
2613
+ }
2547
2614
  },
2548
2615
  {
2549
2616
  name: 'sum',
2550
2617
  visible: true,
2551
2618
  numargs: 4,
2552
- build: function(){ return __.sum; }
2619
+ build: function () {
2620
+ return __.sum;
2621
+ }
2553
2622
  },
2554
2623
  {
2555
2624
  name: 'product',
2556
2625
  visible: true,
2557
2626
  numargs: 4,
2558
- build: function(){ return __.product; }
2627
+ build: function () {
2628
+ return __.product;
2629
+ }
2559
2630
  },
2560
2631
  {
2561
2632
  name: 'integrate',
2562
2633
  visible: true,
2563
2634
  numargs: [1, 2],
2564
- build: function() { return __.integrate; }
2635
+ build: function () {
2636
+ return __.integrate;
2637
+ }
2565
2638
  },
2566
2639
  {
2567
2640
  name: 'defint',
2568
2641
  visible: true,
2569
2642
  numargs: [3, 4],
2570
- build: function() { return __.defint; }
2643
+ build: function () {
2644
+ return __.defint;
2645
+ }
2571
2646
  },
2572
2647
  {
2573
2648
  name: 'S',
2574
2649
  visible: true,
2575
2650
  numargs: 1,
2576
- build: function() { return __.Fresnel.S; }
2651
+ build: function () {
2652
+ return __.Fresnel.S;
2653
+ }
2577
2654
  },
2578
2655
  {
2579
2656
  name: 'C',
2580
2657
  visible: true,
2581
2658
  numargs: 1,
2582
- build: function() { return __.Fresnel.C; }
2659
+ build: function () {
2660
+ return __.Fresnel.C;
2661
+ }
2583
2662
  },
2584
2663
  {
2585
2664
  name: 'limit',
2586
2665
  visible: true,
2587
2666
  numargs: [3, 4],
2588
- build: function() { return __.Limit.limit; }
2667
+ build: function () {
2668
+ return __.Limit.limit;
2669
+ }
2589
2670
  }
2590
2671
  ]);
2591
2672
  //link registered functions externally
2592
- nerdamer.api();
2593
-
2594
- })();
2673
+ nerdamer.updateAPI();
2674
+
2675
+ })();