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/Extra.js CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  /* global module */
10
10
 
11
- if ((typeof module) !== 'undefined') {
11
+ if((typeof module) !== 'undefined') {
12
12
  var nerdamer = require('./nerdamer.core.js');
13
13
  require('./Calculus');
14
14
  require('./Algebra');
@@ -34,13 +34,13 @@ if ((typeof module) !== 'undefined') {
34
34
 
35
35
  Symbol.prototype.findFunction = function (fname) {
36
36
  //this is what we're looking for
37
- if (this.group === FN && this.fname === fname)
37
+ if(this.group === FN && this.fname === fname)
38
38
  return this.clone();
39
39
  var found;
40
- if (this.symbols)
41
- for (var x in this.symbols) {
40
+ if(this.symbols)
41
+ for(var x in this.symbols) {
42
42
  found = this.symbols[x].findFunction(fname);
43
- if (found)
43
+ if(found)
44
44
  break;
45
45
  }
46
46
 
@@ -48,14 +48,14 @@ if ((typeof module) !== 'undefined') {
48
48
  };
49
49
 
50
50
  var __ = core.Extra = {
51
- version: '1.4.1',
51
+ version: '1.4.2',
52
52
  //http://integral-table.com/downloads/LaplaceTable.pdf
53
53
  //Laplace assumes all coefficients to be positive
54
54
  LaPlace: {
55
55
  //Using: integral_0^oo f(t)*e^(-s*t) dt
56
56
  transform: function (symbol, t, s) {
57
57
  symbol = symbol.clone();
58
-
58
+
59
59
  t = t.toString();
60
60
  //First try a lookup for a speed boost
61
61
  symbol = Symbol.unwrapSQRT(symbol, true);
@@ -65,33 +65,33 @@ if ((typeof module) !== 'undefined') {
65
65
 
66
66
  symbol = _.divide(symbol, coeff.clone());
67
67
 
68
- if (symbol.isConstant() || !symbol.contains(t, true)) {
68
+ if(symbol.isConstant() || !symbol.contains(t, true)) {
69
69
  retval = _.parse(format('({0})/({1})', symbol, s));
70
70
  }
71
- else if (g === S && core.Utils.isInt(symbol.power)) {
71
+ else if(g === S && core.Utils.isInt(symbol.power)) {
72
72
  var n = String(symbol.power);
73
73
  retval = _.parse(format('factorial({0})/({1})^({0}+1)', n, s));
74
74
  }
75
- else if (symbol.group === S && symbol.power.equals(1 / 2)) {
75
+ else if(symbol.group === S && symbol.power.equals(1 / 2)) {
76
76
  retval = _.parse(format('sqrt(pi)/(2*({0})^(3/2))', s));
77
77
  }
78
- else if (symbol.isComposite()) {
78
+ else if(symbol.isComposite()) {
79
79
  retval = new Symbol(0);
80
80
  symbol.each(function (x) {
81
81
  retval = _.add(retval, __.LaPlace.transform(x, t, s));
82
82
  }, true);
83
83
  }
84
- else if (symbol.isE() && (symbol.power.group === S || symbol.power.group === CB)) {
84
+ else if(symbol.isE() && (symbol.power.group === S || symbol.power.group === CB)) {
85
85
  var a = symbol.power.stripVar(t);
86
86
  retval = _.parse(format('1/(({1})-({0}))', a, s));
87
87
  }
88
88
  else {
89
89
  var fns = ['sin', 'cos', 'sinh', 'cosh'];
90
90
  //support for symbols in fns with arguments in the form a*t or n*t where a = symbolic and n = Number
91
- if (symbol.group === FN && fns.indexOf(symbol.fname) !== -1 && (symbol.args[0].group === S || symbol.args[0].group === CB)) {
91
+ if(symbol.group === FN && fns.indexOf(symbol.fname) !== -1 && (symbol.args[0].group === S || symbol.args[0].group === CB)) {
92
92
  var a = symbol.args[0].stripVar(t);
93
93
 
94
- switch (symbol.fname) {
94
+ switch(symbol.fname) {
95
95
  case 'sin':
96
96
  retval = _.parse(format('({0})/(({1})^2+({0})^2)', a, s));
97
97
  break;
@@ -112,7 +112,7 @@ if ((typeof module) !== 'undefined') {
112
112
  //we need at least the Laplace integration depth
113
113
  var depth_is_lower = core.Settings.integration_depth < core.Settings.Laplace_integration_depth;
114
114
 
115
- if (depth_is_lower) {
115
+ if(depth_is_lower) {
116
116
  var integration_depth = core.Settings.integration_depth; //save the depth
117
117
  core.Settings.integration_depth = core.Settings.Laplace_integration_depth; //transforms need a little more room
118
118
  }
@@ -122,7 +122,7 @@ if ((typeof module) !== 'undefined') {
122
122
  var sym = symbol.sub(t, u);
123
123
  var integration_expr = _.parse('e^(-' + s + '*' + u + ')*' + sym);
124
124
  retval = core.Calculus.integrate(integration_expr, u);
125
- if (retval.hasIntegral())
125
+ if(retval.hasIntegral())
126
126
  return _.symfunction('laplace', arguments);
127
127
  // _.error('Unable to compute transform');
128
128
  retval = retval.sub(t, 0);
@@ -134,7 +134,7 @@ if ((typeof module) !== 'undefined') {
134
134
  return _.parse(retval);
135
135
  }, true);
136
136
 
137
- if (depth_is_lower)//put the integration depth as it was
137
+ if(depth_is_lower)//put the integration depth as it was
138
138
  core.Settings.integration_depth = integration_depth;
139
139
  }
140
140
 
@@ -146,10 +146,11 @@ if ((typeof module) !== 'undefined') {
146
146
  var input_symbol = symbol.clone();
147
147
  return core.Utils.block('POSITIVE_MULTIPLIERS', function () {
148
148
  //expand and get partial fractions
149
- if(symbol.group === CB)
149
+ if(symbol.group === CB) {
150
150
  symbol = core.Algebra.PartFrac.partfrac(_.expand(symbol), s_);
151
+ }
151
152
 
152
- if (symbol.group === S || symbol.group === CB || symbol.isComposite()) {
153
+ if(symbol.group === S || symbol.group === CB || symbol.isComposite()) {
153
154
  var finalize = function () {
154
155
  //put back the numerator
155
156
  retval = _.multiply(retval, num);
@@ -164,18 +165,19 @@ if ((typeof module) !== 'undefined') {
164
165
  //get the numerator and denominator
165
166
  num = symbol.getNum();
166
167
  den = symbol.getDenom().toUnitMultiplier();
167
-
168
+
168
169
  //TODO: Make it so factor doesn't destroy pi
169
170
  //num = core.Algebra.Factor.factor(symbol.getNum());
170
171
  //den = core.Algebra.Factor.factor(symbol.getDenom().invert(null, true));
171
172
 
172
- if (den.group === CP) {
173
+ if(den.group === CP) {
173
174
  den_p = den.power.clone();
174
175
  den.toLinear();
175
176
  }
176
- else
177
+ else {
177
178
  den_p = new core.Frac(1);
178
-
179
+ }
180
+
179
181
  //convert s to a string
180
182
  s = s_.toString();
181
183
  //split up the denominator if in the form ax+b
@@ -185,7 +187,7 @@ if ((typeof module) !== 'undefined') {
185
187
  num.multiplier = num.multiplier.multiply(m);
186
188
  //store the parts in variables for easy recognition
187
189
  //check if in the form t^n where n = integer
188
- if ((den.group === S || den.group === CB) && f.x.value === s && f.b.equals(0) && core.Utils.isInt(f.x.power)) {
190
+ if((den.group === S || den.group === CB) && f.x.value === s && f.b.equals(0) && core.Utils.isInt(f.x.power)) {
189
191
  var fact, p;
190
192
  p = f.x.power - 1;
191
193
  fact = core.Math2.factorial(p);
@@ -194,59 +196,76 @@ if ((typeof module) !== 'undefined') {
194
196
  //wrap it up
195
197
  finalize();
196
198
  }
197
- else if (den.group === CP && den_p.equals(1)) {
198
- // a/(b*s-c) -> ae^(-bt)
199
- if (f.x.isLinear() && !num.contains(s)) {
200
- t = _.divide(t, f.a.clone());
201
- retval = _.parse(format('(({0})^({3}-1)*e^(-(({2})*({0}))/({1})))/(({3}-1)!*({1})^({3}))', t, f.a, f.b, den_p));
202
- //wrap it up
203
- finalize();
199
+ else if(den.group === CP && den_p.equals(1)) {
200
+ if(f.x.group === core.groups.PL && core.Algebra.degree(den).equals(2)) {
201
+ // Possibly in the form 1/(s^2+2*s+1)
202
+ // Try factoring to get it in a more familiar form{
203
+ // Apply inverse of F(s-a)
204
+ var completed = core.Algebra.sqComplete(den, s);
205
+ var u = core.Utils.getU(den);
206
+ // Get a for the function above
207
+ var a = core.Utils.decompose_fn(completed.a, s, true).b;
208
+ var tf = __.LaPlace.inverse(_.parse(`1/((${u})^2+(${completed.c}))`), u, t);
209
+ retval = _.multiply(tf, _.parse(`(${m})*e^(-(${a})*(${t}))`));
204
210
  }
205
211
  else {
206
- if (f.x.group === S && f.x.power.equals(2)) {
207
- if (!num.contains(s)) {
208
- retval = _.parse(format('(({1})*sin((sqrt(({2})*({3}))*({0}))/({2})))/sqrt(({2})*({3}))', t, num, f.a, f.b));
209
- }
210
- // a*s/(b*s^2+c^2)
211
- else {
212
- var a = new Symbol(1);
213
- if (num.group === CB) {
214
- var new_num = new Symbol(1);
215
- num.each(function (x) {
216
- if (x.contains(s))
217
- new_num = _.multiply(new_num, x);
218
- else
219
- a = _.multiply(a, x);
220
- });
221
- num = new_num;
222
- }
223
-
224
- //we need more information about the denominator to decide
225
- var f2 = core.Utils.decompose_fn(num, s, true);
226
- var fn1, fn2, a_has_sin, b_has_cos, a_has_cos, b_has_sin;
227
- fn1 = f2.a;
228
- fn2 = f2.b;
229
- a_has_sin = fn1.containsFunction('sin');
230
- a_has_cos = fn1.containsFunction('cos');
231
- b_has_cos = fn2.containsFunction('cos');
232
- b_has_sin = fn2.containsFunction('sin');
233
- if (f2.x.value === s && f2.x.isLinear() && !((a_has_sin && b_has_cos) || (a_has_cos || b_has_sin))) {
234
- retval = _.parse(format('(({1})*cos((sqrt(({2})*({3}))*({0}))/({2})))/({2})', t, f2.a, f.a, f.b));
212
+ // a/(b*s-c) -> ae^(-bt)
213
+ if(f.x.isLinear() && !num.contains(s)) {
214
+ t = _.divide(t, f.a.clone());
215
+
216
+ // Don't add factorial of one or zero
217
+ var p = den_p - 1;
218
+ var fact = p === 0 || p === 1 ? '1' : `(${den_p}-1)!`
219
+ retval = _.parse(format('(({0})^({3}-1)*e^(-(({2})*({0}))/({1})))/(({4})*({1})^({3}))', t, f.a, f.b, den_p, fact));
220
+ //wrap it up
221
+ finalize();
222
+ }
223
+ else {
224
+ if(f.x.group === S && f.x.power.equals(2)) {
225
+ if(!num.contains(s)) {
226
+ retval = _.parse(format('(({1})*sin((sqrt(({2})*({3}))*({0}))/({2})))/sqrt(({2})*({3}))', t, num, f.a, f.b));
235
227
  }
228
+ // a*s/(b*s^2+c^2)
236
229
  else {
237
- if (a_has_sin && b_has_cos) {
238
- var sin, cos;
239
- sin = fn1.findFunction('sin');
240
- cos = fn2.findFunction('cos');
241
- //who has the s?
242
- if (sin.args[0].equals(cos.args[0]) && !sin.args[0].contains(s)) {
243
- var b, c, d, e;
244
- b = _.divide(fn2, cos.toUnitMultiplier()).toString();
245
- c = sin.args[0].toString();
246
- d = f.b;
247
- e = _.divide(fn1, sin.toUnitMultiplier());
248
- exp = '(({1})*({2})*cos({3})*sin(sqrt({4})*({0})))/sqrt({4})+({1})*sin({3})*({5})*cos(sqrt({4})*({0}))';
249
- retval = _.parse(format(exp, t, a, b, c, d, e));
230
+ var a = new Symbol(1);
231
+ if(num.group === CB) {
232
+ var new_num = new Symbol(1);
233
+ num.each(function (x) {
234
+ if(x.contains(s))
235
+ new_num = _.multiply(new_num, x);
236
+ else
237
+ a = _.multiply(a, x);
238
+ });
239
+ num = new_num;
240
+ }
241
+
242
+ //we need more information about the denominator to decide
243
+ var f2 = core.Utils.decompose_fn(num, s, true);
244
+ var fn1, fn2, a_has_sin, b_has_cos, a_has_cos, b_has_sin;
245
+ fn1 = f2.a;
246
+ fn2 = f2.b;
247
+ a_has_sin = fn1.containsFunction('sin');
248
+ a_has_cos = fn1.containsFunction('cos');
249
+ b_has_cos = fn2.containsFunction('cos');
250
+ b_has_sin = fn2.containsFunction('sin');
251
+ if(f2.x.value === s && f2.x.isLinear() && !((a_has_sin && b_has_cos) || (a_has_cos || b_has_sin))) {
252
+ retval = _.parse(format('(({1})*cos((sqrt(({2})*({3}))*({0}))/({2})))/({2})', t, f2.a, f.a, f.b));
253
+ }
254
+ else {
255
+ if(a_has_sin && b_has_cos) {
256
+ var sin, cos;
257
+ sin = fn1.findFunction('sin');
258
+ cos = fn2.findFunction('cos');
259
+ //who has the s?
260
+ if(sin.args[0].equals(cos.args[0]) && !sin.args[0].contains(s)) {
261
+ var b, c, d, e;
262
+ b = _.divide(fn2, cos.toUnitMultiplier()).toString();
263
+ c = sin.args[0].toString();
264
+ d = f.b;
265
+ e = _.divide(fn1, sin.toUnitMultiplier());
266
+ exp = '(({1})*({2})*cos({3})*sin(sqrt({4})*({0})))/sqrt({4})+({1})*sin({3})*({5})*cos(sqrt({4})*({0}))';
267
+ retval = _.parse(format(exp, t, a, b, c, d, e));
268
+ }
250
269
  }
251
270
  }
252
271
  }
@@ -254,21 +273,21 @@ if ((typeof module) !== 'undefined') {
254
273
  }
255
274
  }
256
275
  }
257
- else if (f.x.power.num && f.x.power.num.equals(3) && f.x.power.den.equals(2) && num.contains('sqrt(pi)') && !num.contains(s) && num.isLinear()) {
276
+ else if(f.x.power.num && f.x.power.num.equals(3) && f.x.power.den.equals(2) && num.contains('sqrt(pi)') && !num.contains(s) && num.isLinear()) {
258
277
  var b = _.divide(num.clone(), _.parse('sqrt(pi)'));
259
278
  retval = _.parse(format('(2*({2})*sqrt({0}))/({1})', t, f.a, b, num));
260
279
  }
261
- else if (den_p.equals(2) && f.x.power.equals(2)) {
280
+ else if(den_p.equals(2) && f.x.power.equals(2)) {
262
281
  var a, d, exp;
263
- if (!num.contains(s)) {
282
+ if(!num.contains(s)) {
264
283
  a = _.divide(num, new Symbol(2));
265
284
  exp = '(({1})*sin((sqrt(({2})*({3}))*({0}))/({2})))/(({3})*sqrt(({2})*({3})))-(({1})*({0})*cos((sqrt(({2})*({3}))*({0}))/({2})))/(({2})*({3}))';
266
285
  retval = _.parse(format(exp, t, a, f.a, f.b));
267
286
  }
268
287
  else {
269
- //decompose the numerator to check value of s
288
+ // Decompose the numerator to check value of s
270
289
  f2 = core.Utils.decompose_fn(_.expand(num.clone()), s, true);
271
- if (f2.x.isComposite()) {
290
+ if(f2.x.isComposite()) {
272
291
  var s_terms = [];
273
292
  //first collect the factors e.g. (a)(bx)(cx^2+d)
274
293
  var symbols = num.collectSymbols(function (x) {
@@ -285,20 +304,20 @@ if ((typeof module) !== 'undefined') {
285
304
  return p2 - p1;
286
305
  });
287
306
  a = new Symbol(-1);
288
- //grab only the ones which have s
289
- for (var i = 0; i < symbols.length; i++) {
307
+ // Grab only the ones which have s
308
+ for(var i = 0; i < symbols.length; i++) {
290
309
  var fc = symbols[i];
291
- if (fc.x.value === s)
310
+ if(fc.x.value === s)
292
311
  s_terms.push(fc);
293
312
  else
294
313
  a = _.multiply(a, fc.symbol);
295
314
  }
296
- //the following 2 assumptions are made
297
- //1. since the numerator was factored above then each s_term has a unique power
298
- //2. because the terms are sorted by descending powers then the first item
299
- // has the highest power
300
- //we can now check for the next type s(s^2-a^2)/(s^2+a^2)^2
301
- if (s_terms[0].x.power.equals(2) && s_terms[1].x.power.equals(1) && s_terms[1].b.equals(0) && !s_terms[0].b.equals(0)) {
315
+ // The following 2 assumptions are made
316
+ // 1. since the numerator was factored above then each s_term has a unique power
317
+ // 2. because the terms are sorted by descending powers then the first item
318
+ // has the highest power
319
+ // We can now check for the next type s(s^2-a^2)/(s^2+a^2)^2
320
+ if(s_terms[0].x.power.equals(2) && s_terms[1].x.power.equals(1) && s_terms[1].b.equals(0) && !s_terms[0].b.equals(0)) {
302
321
  b = s_terms[0].a.negate();
303
322
  exp = '-(({1})*({2})*({5})*({0})*sin((sqrt(({4})*({5}))*({0}))/({4})))/' +
304
323
  '(2*({4})^2*sqrt(({4})*({5})))-(({1})*({3})*({0})*sin((sqrt(({4})*({5}))*({0}))/({4})))' +
@@ -307,13 +326,13 @@ if ((typeof module) !== 'undefined') {
307
326
  }
308
327
  }
309
328
  else {
310
- if (f2.x.isLinear()) {
329
+ if(f2.x.isLinear()) {
311
330
  a = _.divide(f2.a, new Symbol(2));
312
331
  exp = '(({1})*({0})*sin((sqrt(({2})*({3}))*({0}))/({2})))/(({2})*sqrt(({2})*({3})))';
313
332
  retval = _.parse(format(exp, t, a, f.a, f.b));
314
333
  }
315
- else if (f2.x.power.equals(2)) {
316
- if (f2.b.equals(0)) {
334
+ else if(f2.x.power.equals(2)) {
335
+ if(f2.b.equals(0)) {
317
336
  a = _.divide(f2.a, new Symbol(2));
318
337
  exp = '(({1})*sin((sqrt(({2})*({3}))*({0}))/({2})))/(({2})*sqrt(({2})*({3})))+(({1})*({0})*cos((sqrt(({2})*({3}))*({0}))/({2})))/({2})^2';
319
338
  retval = _.parse(format(exp, t, a, f.a, f.b));
@@ -331,16 +350,23 @@ if ((typeof module) !== 'undefined') {
331
350
  }
332
351
  }
333
352
  else if(symbol.isComposite()) {
334
- retval = new Symbol(0);
335
-
336
- symbol.each(function(x) {
337
- retval = _.add(retval, __.LaPlace.inverse(x, s_, t));
338
- }, true);
353
+ // 1/(s+1)^2
354
+ if(den_p.equals(2) && f.x.group === S) {
355
+ retval = _.parse(`(${m})*(${t})*e^(-(${f.b})*(${t}))`);
356
+ }
357
+ else {
358
+ retval = new Symbol(0);
359
+
360
+ symbol.each(function (x) {
361
+ retval = _.add(retval, __.LaPlace.inverse(x, s_, t));
362
+ }, true);
363
+ }
339
364
  }
340
365
  }
341
366
 
342
- if (!retval)
367
+ if(!retval) {
343
368
  retval = _.symfunction('ilt', [input_symbol, s_, t]);
369
+ }
344
370
 
345
371
  return retval;
346
372
  }, true);
@@ -350,10 +376,10 @@ if ((typeof module) !== 'undefined') {
350
376
  frequencyMap: function (arr) {
351
377
  var map = {};
352
378
  //get the frequency map
353
- for (var i = 0, l = arr.length; i < l; i++) {
379
+ for(var i = 0, l = arr.length; i < l; i++) {
354
380
  var e = arr[i],
355
381
  key = e.toString();
356
- if (!map[key]) //default it to zero
382
+ if(!map[key]) //default it to zero
357
383
  map[key] = 0;
358
384
  map[key]++; //increment
359
385
  }
@@ -361,7 +387,7 @@ if ((typeof module) !== 'undefined') {
361
387
  },
362
388
  sort: function (arr) {
363
389
  return arr.sort(function (a, b) {
364
- if (!a.isConstant() || !b.isConstant())
390
+ if(!a.isConstant() || !b.isConstant())
365
391
  _.error('Unable to sort! All values must be numeric');
366
392
  return a.multiplier.subtract(b.multiplier);
367
393
  });
@@ -371,9 +397,9 @@ if ((typeof module) !== 'undefined') {
371
397
  },
372
398
  sum: function (arr, x_) {
373
399
  var sum = new Symbol(0);
374
- for (var i = 0, l = arr.length; i < l; i++) {
400
+ for(var i = 0, l = arr.length; i < l; i++) {
375
401
  var xi = arr[i].clone();
376
- if (x_) {
402
+ if(x_) {
377
403
  sum = _.add(_.pow(_.subtract(xi, x_.clone()), new Symbol(2)), sum);
378
404
  }
379
405
  else
@@ -385,26 +411,26 @@ if ((typeof module) !== 'undefined') {
385
411
  mean: function () {
386
412
  var args = [].slice.call(arguments);
387
413
  //handle arrays
388
- if (isVector(args[0]))
414
+ if(isVector(args[0]))
389
415
  return __.Statistics.mean.apply(this, args[0].elements);
390
416
  return _.divide(__.Statistics.sum(args), __.Statistics.count(args));
391
417
  },
392
418
  median: function () {
393
419
  var args = [].slice.call(arguments), retval;
394
420
  //handle arrays
395
- if (isVector(args[0]))
421
+ if(isVector(args[0]))
396
422
  return __.Statistics.median.apply(this, args[0].elements);
397
423
  try {
398
424
  var sorted = __.Statistics.sort(args);
399
425
  var l = args.length;
400
- if (core.Utils.even(l)) {
426
+ if(core.Utils.even(l)) {
401
427
  var mid = l / 2;
402
428
  retval = __.Statistics.mean(sorted[mid - 1], sorted[mid]);
403
429
  }
404
430
  else
405
431
  retval = sorted[Math.floor(l / 2)];
406
432
  }
407
- catch (e) {
433
+ catch(e) {
408
434
  retval = _.symfunction('median', args);
409
435
  }
410
436
  return retval;
@@ -413,26 +439,26 @@ if ((typeof module) !== 'undefined') {
413
439
  var args = [].slice.call(arguments),
414
440
  retval;
415
441
  //handle arrays
416
- if (isVector(args[0]))
442
+ if(isVector(args[0]))
417
443
  return __.Statistics.mode.apply(this, args[0].elements);
418
444
 
419
445
  var map = __.Statistics.frequencyMap(args);
420
446
 
421
447
  //the mode of 1 item is that item as per issue #310 (verified by Happypig375).
422
- if (core.Utils.keys(map).length === 1)
448
+ if(core.Utils.keys(map).length === 1)
423
449
  retval = args[0];
424
450
  else {
425
451
  //invert by arraning them according to their frequency
426
452
  var inverse = {};
427
- for (var x in map) {
453
+ for(var x in map) {
428
454
  var freq = map[x];
429
455
  //check if it's in the inverse already
430
- if (!(freq in inverse))
456
+ if(!(freq in inverse))
431
457
  inverse[freq] = x;
432
458
  else {
433
459
  var e = inverse[freq];
434
460
  //if it's already an array then just add it
435
- if (isArray(e))
461
+ if(isArray(e))
436
462
  e.push(x);
437
463
  //convert it to and array
438
464
  else
@@ -443,7 +469,7 @@ if ((typeof module) !== 'undefined') {
443
469
  var max = inverse[Math.max.apply(null, core.Utils.keys(inverse))];
444
470
  //check it's an array. If it is then map over the results and convert
445
471
  //them to Symbol
446
- if (isArray(max)) {
472
+ if(isArray(max)) {
447
473
  retval = _.symfunction('mode', max.sort());
448
474
  }
449
475
  else
@@ -460,7 +486,7 @@ if ((typeof module) !== 'undefined') {
460
486
  variance: function () {
461
487
  var args = [].slice.call(arguments);
462
488
  //handle arrays
463
- if (isVector(args[0]))
489
+ if(isVector(args[0]))
464
490
  return __.Statistics.variance.apply(this, args[0].elements);
465
491
  var k = _.divide(new Symbol(1), __.Statistics.count(args));
466
492
  return __.Statistics.gVariance(k, args);
@@ -468,7 +494,7 @@ if ((typeof module) !== 'undefined') {
468
494
  sampleVariance: function () {
469
495
  var args = [].slice.call(arguments);
470
496
  //handle arrays
471
- if (isVector(args[0]))
497
+ if(isVector(args[0]))
472
498
  return __.Statistics.sampleVariance.apply(this, args[0].elements);
473
499
 
474
500
  var k = _.divide(new Symbol(1), _.subtract(__.Statistics.count(args), new Symbol(1)));
@@ -477,14 +503,14 @@ if ((typeof module) !== 'undefined') {
477
503
  standardDeviation: function () {
478
504
  var args = [].slice.call(arguments);
479
505
  //handle arrays
480
- if (isVector(args[0]))
506
+ if(isVector(args[0]))
481
507
  return __.Statistics.standardDeviation.apply(this, args[0].elements);
482
508
  return _.pow(__.Statistics.variance.apply(__.Statistics, args), new Symbol(1 / 2));
483
509
  },
484
510
  sampleStandardDeviation: function () {
485
511
  var args = [].slice.call(arguments);
486
512
  //handle arrays
487
- if (isVector(args[0]))
513
+ if(isVector(args[0]))
488
514
  return __.Statistics.sampleStandardDeviation.apply(this, args[0].elements);
489
515
  return _.pow(__.Statistics.sampleVariance.apply(__.Statistics, args), new Symbol(1 / 2));
490
516
  },
@@ -587,5 +613,10 @@ if ((typeof module) !== 'undefined') {
587
613
  ]);
588
614
 
589
615
  //link registered functions externally
590
- nerdamer.api();
591
- }());
616
+ nerdamer.updateAPI();
617
+ }());
618
+
619
+ // Added for all.min.js
620
+ if((typeof module) !== 'undefined') {
621
+ module.exports = nerdamer;
622
+ };
package/README.md CHANGED
@@ -20,6 +20,25 @@ Load the library in your html page
20
20
  <script src="Solve.js"></script>
21
21
  <script src="Extra.js"></script>
22
22
  ```
23
+ Or import everything
24
+ ```html
25
+ <script src="all.min.js"></script> <!-- assuming you've saved the file in the root -->
26
+ ```
27
+ If you're using node.js install it using `npm i nerdamer` and then
28
+
29
+ ```javascript
30
+ // const cannot be used since nerdamer gets modified when other modules are loaded
31
+ var nerdamer = require('nerdamer');
32
+ // Load additional modules. These are not required.
33
+ require('nerdamer/Algebra');
34
+ require('nerdamer/Calculus');
35
+ require('nerdamer/Solve');
36
+ require('nerdamer/Extra');
37
+ ```
38
+ Or do a single import to import everything
39
+ ```javascript
40
+ const nerdamer = require("nerdamer/all.min")
41
+ ```
23
42
 
24
43
  Some functions have dependencies from other add-ons.
25
44
 
@@ -29,7 +48,7 @@ For full documentation go to http://nerdamer.com/documentation
29
48
 
30
49
  All operations are done using the 'nerdamer' object.
31
50
 
32
- To add an expression just add it to the nerdamer object which will return a expression object.
51
+ To add an expression just add it to the nerdamer object which will return a `Expression` object.
33
52
 
34
53
  ```javascript
35
54
  var e = nerdamer('x^2+2*(cos(x)+x*x)');
@@ -38,6 +57,16 @@ console.log(e.text());
38
57
  //result:
39
58
  //2*cos(x)+3*x^2
40
59
  ```
60
+ It is also possible to use `nerdamer` functions directly within the need for string manipulation of the input. The input will be parsed and the output will of type `Expression`. For example:
61
+ ```javascript
62
+ var ans = nerdamer.expand('(x-1)^5');
63
+ console.log(ans.text());
64
+ // -1-10*x^2-5*x^4+10*x^3+5*x+x^5
65
+
66
+ var sol = nerdamer.solve('x^2-4', 'x');
67
+ console.log(sol.text())
68
+ // [2,-2]
69
+ ```
41
70
 
42
71
  You can also pass in an object with known values as the second parameter.
43
72