UNPKG

658 kBJavaScriptView Raw
1(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2// Generated by CoffeeScript 1.12.7
3(function() {
4 var $, ABS, ADD, ADJ, AND, APPROXRATIO, ARCCOS, ARCCOSH, ARCSIN, ARCSINH, ARCTAN, ARCTANH, ARG, ASSUME_REAL_VARIABLES, ATOMIZE, AUTOEXPAND, BAKE, BESSELJ, BESSELY, BINDING, BINOMIAL, BINOM_check_args, BUF, C1, C2, C3, C4, C5, C6, CACHE_DEBUGS, CACHE_HITSMISS_DEBUGS, CEILING, CHECK, CHOOSE, CIRCEXP, CLEAR, CLEARALL, CLEARPATTERNS, CLOCK, COEFF, COFACTOR, CONDENSE, CONJ, CONS, CONTRACT, COS, COSH, Condense, DEBUG, DEBUG_ABS, DEBUG_ARG, DEBUG_CLOCKFORM, DEBUG_IMAG, DEBUG_IS, DEBUG_POWER, DEBUG_RECT, DECOMP, DEFINT, DEGREE, DENOMINATOR, DERIVATIVE, DET, DET_check_arg, DIM, DIRAC, DIVISORS, DO, DOT, DOUBLE, DRAW, DRAWX, DSOLVE, DoubleLinkedList, E, EIGEN, EIGENVAL, EIGENVEC, EIG_N, EIG_check_arg, EIG_yydd, EIG_yyqq, ENABLE_CACHING, ERF, ERFC, EVAL, EXP, EXPAND, EXPCOS, EXPSIN, Eval, Eval_Eval, Eval_abs, Eval_add, Eval_adj, Eval_and, Eval_approxratio, Eval_arccos, Eval_arccosh, Eval_arcsin, Eval_arcsinh, Eval_arctan, Eval_arctanh, Eval_arg, Eval_besselj, Eval_bessely, Eval_binding, Eval_binomial, Eval_ceiling, Eval_check, Eval_choose, Eval_circexp, Eval_clear, Eval_clearall, Eval_clearpatterns, Eval_clock, Eval_coeff, Eval_cofactor, Eval_condense, Eval_conj, Eval_cons, Eval_contract, Eval_cos, Eval_cosh, Eval_decomp, Eval_defint, Eval_degree, Eval_denominator, Eval_derivative, Eval_det, Eval_dim, Eval_dirac, Eval_divisors, Eval_do, Eval_dsolve, Eval_eigen, Eval_eigenval, Eval_eigenvec, Eval_erf, Eval_erfc, Eval_exp, Eval_expand, Eval_expcos, Eval_expsin, Eval_factor, Eval_factorial, Eval_factorpoly, Eval_filter, Eval_float, Eval_floor, Eval_for, Eval_function_reference, Eval_gamma, Eval_gcd, Eval_hermite, Eval_hilbert, Eval_imag, Eval_index, Eval_inner, Eval_integral, Eval_inv, Eval_invg, Eval_isinteger, Eval_isprime, Eval_laguerre, Eval_lcm, Eval_leading, Eval_legendre, Eval_log, Eval_lookup, Eval_mod, Eval_multiply, Eval_noexpand, Eval_not, Eval_nroots, Eval_number, Eval_numerator, Eval_operator, Eval_or, Eval_outer, Eval_pattern, Eval_patternsinfo, Eval_polar, Eval_power, Eval_predicate, Eval_prime, Eval_print, Eval_print2dascii, Eval_printfull, Eval_printlatex, Eval_printlist, Eval_printplain, Eval_product, Eval_quote, Eval_quotient, Eval_rank, Eval_rationalize, Eval_real, Eval_rect, Eval_roots, Eval_round, Eval_setq, Eval_sgn, Eval_shape, Eval_silentpattern, Eval_simfac, Eval_simplify, Eval_sin, Eval_sinh, Eval_sqrt, Eval_stop, Eval_subst, Eval_sum, Eval_sym, Eval_symbolsinfo, Eval_tan, Eval_tanh, Eval_taylor, Eval_tensor, Eval_test, Eval_testeq, Eval_testge, Eval_testgt, Eval_testle, Eval_testlt, Eval_transpose, Eval_unit, Eval_user_function, Eval_zero, Evalpoly, FACTOR, FACTORIAL, FACTORPOLY, FILTER, FLOATF, FLOOR, FOR, FUNCTION, Find, GAMMA, GCD, HERMITE, HILBERT, IMAG, INDEX, INNER, INTEGRAL, INV, INVG, INV_check_arg, INV_decomp, ISINTEGER, ISPRIME, LAGUERRE, LAST, LAST_2DASCII_PRINT, LAST_FULL_PRINT, LAST_LATEX_PRINT, LAST_LIST_PRINT, LAST_PLAIN_PRINT, LAST_PRINT, LCM, LEADING, LEGENDRE, LOG, LOOKUP, LRUCache, M, MAXDIM, MAXPRIMETAB, MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES, MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE, MAX_PROGRAM_SIZE, MEQUAL, METAA, METAB, METAX, MLENGTH, MOD, MSIGN, MULTIPLY, MZERO, N, NIL, NOT, NROOTS, NROOTS_ABS, NROOTS_DELTA, NROOTS_EPSILON, NROOTS_RANDOM, NROOTS_YMAX, NROOTS_divpoly, NSYM, NUM, NUMBER, NUMERATOR, OPERATOR, OR, OUTER, PATTERN, PATTERNSINFO, PI, POLAR, POWER, PRIME, PRINT, PRINT2DASCII, PRINTFULL, PRINTLATEX, PRINTLIST, PRINTMODE_2DASCII, PRINTMODE_FULL, PRINTMODE_LATEX, PRINTMODE_LIST, PRINTMODE_PLAIN, PRINTOUTRESULT, PRINTPLAIN, PRINT_LEAVE_E_ALONE, PRINT_LEAVE_X_ALONE, PRODUCT, QUOTE, QUOTIENT, RANK, RATIONALIZE, REAL, ROOTS, ROUND, SECRETX, SELFTEST, SETQ, SGN, SHAPE, SILENTPATTERN, SIMPLIFY, SIN, SINH, SPACE_BETWEEN_COLUMNS, SPACE_BETWEEN_ROWS, SQRT, STOP, STR, SUBST, SUM, SYM, SYMBOLSINFO, SYMBOL_A, SYMBOL_A_UNDERSCORE, SYMBOL_B, SYMBOL_B_UNDERSCORE, SYMBOL_C, SYMBOL_D, SYMBOL_I, SYMBOL_IDENTITY_MATRIX, SYMBOL_J, SYMBOL_N, SYMBOL_R, SYMBOL_S, SYMBOL_T, SYMBOL_X, SYMBOL_X_UNDERSCORE, SYMBOL_Y, SYMBOL_Z, TAN, TANH, TAYLOR, TENSOR, TEST, TESTEQ, TESTGE, TESTGT, TESTLE, TESTLT, TIMING_DEBUGS, TOS, TRACE, TRANSPOSE, T_DOUBLE, T_EQ, T_FUNCTION, T_GTEQ, T_INTEGER, T_LTEQ, T_NEQ, T_NEWLINE, T_QUOTASSIGN, T_STRING, T_SYMBOL, U, UNIT, USR_SYMBOLS, VERSION, YMAX, YYE, YYRECT, ZERO, __emit_char, __emit_str, __factor_add, __factorial, __is_negative, __is_radical_number, __lcm, __legendre, __legendre2, __legendre3, __normalize_radical_factors, __rationalize_tensor, _print, abs, absValFloat, absval, absval_tensor, add, addSymbolLeftOfAssignment, addSymbolRightOfAssignment, add_all, add_factor_to_accumulator, add_numbers, add_terms, addf, adj, alloc_tensor, allocatedId, any_denominators, approxAll, approxLogs, approxLogsOfRationals, approxOneRatioOnly, approxRadicals, approxRadicalsOfRationals, approxRationalsOfLogs, approxRationalsOfPowersOfE, approxRationalsOfPowersOfPI, approxRationalsOfRadicals, approxSineOfRationalMultiplesOfPI, approxSineOfRationals, approxTrigonometric, approx_just_an_integer, approx_logarithmsOfRationals, approx_nothingUseful, approx_radicalOfRatio, approx_ratioOfRadical, approx_rationalOfE, approx_rationalOfPi, approx_rationalsOfLogarithms, approx_sine_of_pi_times_rational, approx_sine_of_rational, approxratioRecursive, arccos, arccosh, arcsin, arcsinh, arctan, arctanh, arg, arglist, assignmentFound, avoidCalculatingPowersIntoArctans, bake, bake_poly, bake_poly_term, besselj, bessely, bigInt, bignum_factorial, bignum_float, bignum_power_number, bignum_scan_float, bignum_scan_integer, bignum_truncate, binding, binomial, buffer, build_tensor, caaddr, caadr, caar, cacheMissPenalty, cached_findDependenciesInScript, cached_runs, cadaddr, cadadr, cadar, caddaddr, caddadr, caddar, caddddr, cadddr, caddr, cadr, called_from_Algebra_block, car, cdaddr, cdadr, cdar, cddaddr, cddar, cdddaddr, cddddr, cdddr, cddr, cdr, ceiling, chainOfUserSymbolsNotFunctionsBeingEvaluated, charTabIndex, chartab, checkFloatHasWorkedOutCompletely, check_esc_flag, check_stack, check_tensor_dimensions, choose, choose_check_args, circexp, clearAlgebraEnvironment, clearRenamedVariablesToAvoidBindingToExternalScope, clear_symbols, clear_term, clearall, clockform, cmpGlyphs, cmp_args, cmp_expr, cmp_terms, cmp_terms_count, codeGen, coeff, cofactor, collectLatexStringFromReturnValue, collectUserSymbols, combine_factors, combine_gammas, combine_terms, compareState, compare_numbers, compare_rationals, compare_tensors, compatible, computeDependenciesFromAlgebra, computeResultsAndJavaScriptFromAlgebra, compute_fa, conjugate, cons, consCount, contract, convert_bignum_to_double, convert_rational_to_double, copy_tensor, cosine, cosine_of_angle, cosine_of_angle_sum, count, countOccurrencesOfSymbol, count_denominators, counter, countsize, d_scalar_scalar, d_scalar_scalar_1, d_scalar_tensor, d_tensor_scalar, d_tensor_tensor, dabs, darccos, darccosh, darcsin, darcsinh, darctan, darctanh, dbesselj0, dbesseljn, dbessely0, dbesselyn, dcos, dcosh, dd, decomp, decomp_product, decomp_sum, defineSomeHandyConstants, define_user_function, defn, defn_str, degree, denominator, derf, derfc, derivative, derivative_of_integral, det, determinant, detg, dfunction, dhermite, dirac, disableCaching, display, display_flag, displaychar, divide, divide_numbers, divisors, divisors_onstack, divpoly, dlog, do_clearPatterns, do_clearall, do_simplify_nested_radicals, dontCreateNewRadicalsInDenominatorWhenEvalingMultiplication, dotprod_unicode, doubleToReasonableString, dpow, dpower, dproduct, draw_flag, draw_stop_return, dsgn, dsin, dsinh, dsum, dtan, dtanh, dupl, eigen, elelmIndex, elem, emit_denominator, emit_denominators, emit_expr, emit_factor, emit_factorial_function, emit_flat_tensor, emit_fraction, emit_function, emit_index_function, emit_multiply, emit_number, emit_numerators, emit_numerical_fraction, emit_power, emit_string, emit_subexpr, emit_symbol, emit_tensor, emit_tensor_inner, emit_term, emit_top_expr, emit_unsigned_expr, emit_x, enableCaching, environment_printmode, equal, equaln, equalq, erfc, errorMessage, esc_flag, evaluatingAsFloats, evaluatingPolar, exec, expand, expand_get_A, expand_get_AF, expand_get_B, expand_get_C, expand_get_CF, expand_tensor, expanding, expcos, exponential, expr_level, expsin, f1, f10, f2, f3, f4, f5, f9, f_equals_a, factor, factor_a, factor_again, factor_b, factor_number, factor_small_number, factor_term, factorial, factorpoly, factors, factpoly_expo, fill_buf, filter, filter_main, filter_sum, filter_tensor, findDependenciesInScript, findPossibleClockForm, findPossibleExponentialForm, findroot, fixed_top_level_eval, fixup_fraction, fixup_power, flag, floatToRatioRoutine, fmt_index, fmt_level, fmt_x, frame, freeze, functionInvokationsScanningStack, gamma, gamma_of_sum, gammaf, gcd, gcd_expr, gcd_expr_expr, gcd_factor_term, gcd_main, gcd_numbers, gcd_term_factor, gcd_term_term, gen, getSimpleRoots, getStateHash, get_binding, get_factor_from_complex_root, get_factor_from_real_root, get_innerprod_factors, get_next_token, get_printname, get_size, get_token, getdisplaystr, glyph, gp, guess, hasImaginaryCoeff, hasNegativeRationalExponent, hermite, hilbert, i1, imag, imaginaryunit, index_function, init, initNRoots, inited, inner, inner_f, input_str, integral, integral_of_form, integral_of_product, integral_of_sum, inv, inverse, invert_number, invg, isSimpleRoot, isSymbolLeftOfAssignment, isSymbolReclaimable, is_denominator, is_factor, is_small_integer, is_square_matrix, is_usr_symbol, isadd, isalnumorunderscore, isalpha, isalphaOrUnderscore, iscomplexnumber, iscomplexnumberdouble, iscons, isdenominator, isdigit, isdouble, iseveninteger, isfactor, isfactorial, isfloating, isfraction, isidentitymatrix, isimaginarynumber, isimaginarynumberdouble, isimaginaryunit, isinnerordot, isinteger, isintegerfactor, isintegerorintegerfloat, isinv, iskeyword, isminusone, isminusoneoversqrttwo, isminusoneovertwo, ismultiply, isnegative, isnegativenumber, isnegativeterm, isnonnegativeinteger, isnpi, isnum, isnumberoneoversomething, isnumerictensor, isone, isoneover, isoneoversqrttwo, isoneovertwo, isplusone, isplustwo, ispoly, ispoly_expr, ispoly_factor, ispoly_term, isposint, ispositivenumber, ispower, isquarterturn, isrational, isspace, isstr, issymbol, issymbolic, istensor, istranspose, isunderscore, iszero, itab, j1, laguerre, laguerre2, lastFoundSymbol, latexErrorSign, lcm, leading, legendre, length, lessp, level, list, listLength, logarithm, logbuf, lookupsTotal, lu_decomp, madd, makePositive, makeSignSameAs, mask, mcmp, mcmpint, mdiv, mdivrem, meta_mode, mgcd, mini_solve, mint, mmod, mmul, mod, monic, move, moveTos, mp_clr_bit, mp_denominator, mp_numerator, mp_set_bit, mpow, mprime, mroot, mshiftright, msub, mtotal, multinomial_sum, multiply, multiply_all, multiply_all_noexpand, multiply_consecutive_constants, multiply_denominators, multiply_denominators_factor, multiply_denominators_term, multiply_noexpand, multiply_numbers, n_factor_number, negate, negate_expand, negate_noexpand, negate_number, new_string, newline_flag, nil_symbols, normaliseDots, normalisedCoeff, normalize_angle, nroots_a, nroots_b, nroots_c, nroots_df, nroots_dx, nroots_fa, nroots_fb, nroots_x, nroots_y, nterms, nthCadr, numerator, numericRootOfPolynomial, o, one, oneElement, one_as_double, out_buf, out_count, out_of_memory, outer, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, parse, parse_internal, parse_p1, parse_p2, parse_time_simplifications, partition, patternHasBeenFound, patternsinfo, peek, performing_roots, polar, polarRectAMinusOneBase, polycoeff, polyform, pop, pop_double, pop_frame, pop_integer, power, power_str, power_sum, power_tensor, predefinedSymbolsInGlobalScope_doNotTrackInDependencies, prime, primetab, print2dascii, printMode, print_ABS_latex, print_ARCCOS_codegen, print_ARCSIN_codegen, print_ARCTAN_codegen, print_BINOMIAL_latex, print_COS_codegen, print_DEFINT_latex, print_DOT_codegen, print_DOT_latex, print_DO_codegen, print_FOR_codegen, print_INV_codegen, print_INV_latex, print_PRODUCT_codegen, print_PRODUCT_latex, print_SETQ_codegen, print_SIN_codegen, print_SQRT_latex, print_SUM_codegen, print_SUM_latex, print_TAN_codegen, print_TESTEQ_latex, print_TESTGE_latex, print_TESTGT_latex, print_TESTLE_latex, print_TESTLT_latex, print_TEST_codegen, print_TEST_latex, print_TRANSPOSE_codegen, print_TRANSPOSE_latex, print_UNIT_codegen, print_a_over_b, print_base, print_base_of_denom, print_char, print_denom, print_double, print_expo_of_denom, print_exponent, print_expr, print_factor, print_factorial_function, print_glyphs, print_index_function, print_list, print_multiply_sign, print_number, print_power, print_str, print_subexpr, print_tensor, print_tensor_inner, print_tensor_inner_latex, print_tensor_latex, print_term, printchar, printchar_nowrap, printline, program_buf, promote_tensor, push, pushTryNotToDuplicate, push_cars, push_double, push_factor, push_frame, push_identity_matrix, push_integer, push_rational, push_symbol, push_term_factors, push_terms, push_zero_matrix, qadd, qdiv, qmul, qpow, qpowf, quickfactor, quickpower, rational, rationalize, rationalize_coefficients, real, reciprocate, rect, recursionLevelNestedRadicalsRemoval, recursiveDependencies, ref, ref1, rememberPrint, remove_negative_exponents, resetCache, resetCacheHitMissCounts, reset_after_error, restore, restoreMetaBindings, rewrite_args, rewrite_args_tensor, roots, roots2, roots3, run, runUserDefinedSimplifications, save, saveMetaBindings, scalar_times_tensor, scan, scan_error, scan_expression, scan_factor, scan_function_call_with_function_name, scan_function_call_without_function_name, scan_index, scan_meta, scan_power, scan_relation, scan_stmt, scan_str, scan_string, scan_subexpr, scan_symbol, scan_tensor, scan_term, scanned, scanningParameters, setM, setSignTo, set_binding, set_component, setq_indexed, sfac_product, sfac_product_f, sgn, shape, show_power_debug, sign, sign_of_term, simfac, simfac_term, simpleComplexityMeasure, simplify, simplifyForCodeGeneration, simplify_1_in_products, simplify_main, simplify_nested_radicals, simplify_polar, simplify_polarRect, simplify_rectToClock, simplify_tensor, simplify_trig, simplifyfactorials, sine, sine_of_angle, sine_of_angle_sum, skipRootVariableToBeSolved, sort_stack, square, ssqrt, stack, stackAddsCount, std_symbol, step, step2, stop, strcmp, stringsEmittedByUserPrintouts, subf, subst, subtract, subtract_numbers, swap, symbol, symbolsDependencies, symbolsHavingReassignments, symbolsInExpressionsWithoutAssignments, symbolsLeftOfAssignment, symbolsRightOfAssignment, symbolsinfo, symnum, symtab, take_care_of_nested_radicals, tangent, taylor, tensor, tensor_plus_tensor, tensor_times_scalar, testApprox, test_flag, text_metric, theRandom, token, token_buf, token_str, top, top_level_eval, tos, totalAllCachesHits, totalAllCachesMisses, transform, transpose, transpose_unicode, trigmode, trivial_divide, try_kth_prime, turnErrorMessageToLatex, ucmp, unfreeze, unique, unique_f, update_token_buf, userSimplificationsInListForm, userSimplificationsInStringForm, usr_symbol, verbosing, version, will_be_displayed_as_fraction, ybinomial, ycosh, ydirac, yerf, yerfc, yfloor, yindex, yround, ysinh, yyarg, yybesselj, yybessely, yyceiling, yycondense, yycontract, yycosh, yydegree, yydetg, yydivpoly, yyerf, yyerfc, yyexpand, yyfactorpoly, yyfloat, yyfloor, yyhermite, yyhermite2, yyinvg, yylcm, yylog, yymultiply, yyouter, yypower, yyrationalize, yyround, yysgn, yysimfac, yysinh, yytangent, zero, zzfloat,
5 slice = [].slice;
6
7 bigInt = require('big-integer');
8
9 version = "1.1.1";
10
11 SELFTEST = 1;
12
13 NSYM = 1000;
14
15 DEBUG = false;
16
17 PRINTOUTRESULT = false;
18
19 PRINTMODE_LATEX = "PRINTMODE_LATEX";
20
21 PRINTMODE_2DASCII = "PRINTMODE_2DASCII";
22
23 PRINTMODE_FULL = "PRINTMODE_FULL";
24
25 PRINTMODE_PLAIN = "PRINTMODE_PLAIN";
26
27 PRINTMODE_LIST = "PRINTMODE_LIST";
28
29 environment_printmode = PRINTMODE_PLAIN;
30
31 printMode = PRINTMODE_PLAIN;
32
33 dontCreateNewRadicalsInDenominatorWhenEvalingMultiplication = true;
34
35 recursionLevelNestedRadicalsRemoval = 0;
36
37 do_simplify_nested_radicals = true;
38
39 avoidCalculatingPowersIntoArctans = true;
40
41 rational = (function() {
42 function rational() {}
43
44 rational.prototype.a = null;
45
46 rational.prototype.b = null;
47
48 return rational;
49
50 })();
51
52 U = (function() {
53 U.prototype.cons = null;
54
55 U.prototype.printname = "";
56
57 U.prototype.str = "";
58
59 U.prototype.tensor = null;
60
61 U.prototype.q = null;
62
63 U.prototype.d = 0.0;
64
65 U.prototype.k = 0;
66
67 U.prototype.tag = 0;
68
69 U.prototype.toString = function() {
70 return print_expr(this);
71 };
72
73 U.prototype.toLatexString = function() {
74 return collectLatexStringFromReturnValue(this);
75 };
76
77 function U() {
78 this.cons = {};
79 this.cons.car = null;
80 this.cons.cdr = null;
81 this.q = new rational();
82 }
83
84 return U;
85
86 })();
87
88 errorMessage = "";
89
90 CONS = 0;
91
92 NUM = 1;
93
94 DOUBLE = 2;
95
96 STR = 3;
97
98 TENSOR = 4;
99
100 SYM = 5;
101
102 counter = 0;
103
104 ABS = counter++;
105
106 ADD = counter++;
107
108 ADJ = counter++;
109
110 AND = counter++;
111
112 APPROXRATIO = counter++;
113
114 ARCCOS = counter++;
115
116 ARCCOSH = counter++;
117
118 ARCSIN = counter++;
119
120 ARCSINH = counter++;
121
122 ARCTAN = counter++;
123
124 ARCTANH = counter++;
125
126 ARG = counter++;
127
128 ATOMIZE = counter++;
129
130 BESSELJ = counter++;
131
132 BESSELY = counter++;
133
134 BINDING = counter++;
135
136 BINOMIAL = counter++;
137
138 CEILING = counter++;
139
140 CHECK = counter++;
141
142 CHOOSE = counter++;
143
144 CIRCEXP = counter++;
145
146 CLEAR = counter++;
147
148 CLEARALL = counter++;
149
150 CLEARPATTERNS = counter++;
151
152 CLOCK = counter++;
153
154 COEFF = counter++;
155
156 COFACTOR = counter++;
157
158 CONDENSE = counter++;
159
160 CONJ = counter++;
161
162 CONTRACT = counter++;
163
164 COS = counter++;
165
166 COSH = counter++;
167
168 DECOMP = counter++;
169
170 DEFINT = counter++;
171
172 DEGREE = counter++;
173
174 DENOMINATOR = counter++;
175
176 DERIVATIVE = counter++;
177
178 DET = counter++;
179
180 DIM = counter++;
181
182 DIRAC = counter++;
183
184 DIVISORS = counter++;
185
186 DO = counter++;
187
188 DOT = counter++;
189
190 DRAW = counter++;
191
192 DSOLVE = counter++;
193
194 EIGEN = counter++;
195
196 EIGENVAL = counter++;
197
198 EIGENVEC = counter++;
199
200 ERF = counter++;
201
202 ERFC = counter++;
203
204 EVAL = counter++;
205
206 EXP = counter++;
207
208 EXPAND = counter++;
209
210 EXPCOS = counter++;
211
212 EXPSIN = counter++;
213
214 FACTOR = counter++;
215
216 FACTORIAL = counter++;
217
218 FACTORPOLY = counter++;
219
220 FILTER = counter++;
221
222 FLOATF = counter++;
223
224 FLOOR = counter++;
225
226 FOR = counter++;
227
228 FUNCTION = counter++;
229
230 GAMMA = counter++;
231
232 GCD = counter++;
233
234 HERMITE = counter++;
235
236 HILBERT = counter++;
237
238 IMAG = counter++;
239
240 INDEX = counter++;
241
242 INNER = counter++;
243
244 INTEGRAL = counter++;
245
246 INV = counter++;
247
248 INVG = counter++;
249
250 ISINTEGER = counter++;
251
252 ISPRIME = counter++;
253
254 LAGUERRE = counter++;
255
256 LCM = counter++;
257
258 LEADING = counter++;
259
260 LEGENDRE = counter++;
261
262 LOG = counter++;
263
264 LOOKUP = counter++;
265
266 MOD = counter++;
267
268 MULTIPLY = counter++;
269
270 NOT = counter++;
271
272 NROOTS = counter++;
273
274 NUMBER = counter++;
275
276 NUMERATOR = counter++;
277
278 OPERATOR = counter++;
279
280 OR = counter++;
281
282 OUTER = counter++;
283
284 PATTERN = counter++;
285
286 PATTERNSINFO = counter++;
287
288 POLAR = counter++;
289
290 POWER = counter++;
291
292 PRIME = counter++;
293
294 PRINT_LEAVE_E_ALONE = counter++;
295
296 PRINT_LEAVE_X_ALONE = counter++;
297
298 PRINT = counter++;
299
300 PRINT2DASCII = counter++;
301
302 PRINTFULL = counter++;
303
304 PRINTLATEX = counter++;
305
306 PRINTLIST = counter++;
307
308 PRINTPLAIN = counter++;
309
310 PRODUCT = counter++;
311
312 QUOTE = counter++;
313
314 QUOTIENT = counter++;
315
316 RANK = counter++;
317
318 RATIONALIZE = counter++;
319
320 REAL = counter++;
321
322 ROUND = counter++;
323
324 YYRECT = counter++;
325
326 ROOTS = counter++;
327
328 SETQ = counter++;
329
330 SGN = counter++;
331
332 SILENTPATTERN = counter++;
333
334 SIMPLIFY = counter++;
335
336 SIN = counter++;
337
338 SINH = counter++;
339
340 SHAPE = counter++;
341
342 SQRT = counter++;
343
344 STOP = counter++;
345
346 SUBST = counter++;
347
348 SUM = counter++;
349
350 SYMBOLSINFO = counter++;
351
352 TAN = counter++;
353
354 TANH = counter++;
355
356 TAYLOR = counter++;
357
358 TEST = counter++;
359
360 TESTEQ = counter++;
361
362 TESTGE = counter++;
363
364 TESTGT = counter++;
365
366 TESTLE = counter++;
367
368 TESTLT = counter++;
369
370 TRANSPOSE = counter++;
371
372 UNIT = counter++;
373
374 ZERO = counter++;
375
376 NIL = counter++;
377
378 LAST = counter++;
379
380 LAST_PRINT = counter++;
381
382 LAST_2DASCII_PRINT = counter++;
383
384 LAST_FULL_PRINT = counter++;
385
386 LAST_LATEX_PRINT = counter++;
387
388 LAST_LIST_PRINT = counter++;
389
390 LAST_PLAIN_PRINT = counter++;
391
392 AUTOEXPAND = counter++;
393
394 BAKE = counter++;
395
396 ASSUME_REAL_VARIABLES = counter++;
397
398 TRACE = counter++;
399
400 YYE = counter++;
401
402 DRAWX = counter++;
403
404 METAA = counter++;
405
406 METAB = counter++;
407
408 METAX = counter++;
409
410 SECRETX = counter++;
411
412 VERSION = counter++;
413
414 PI = counter++;
415
416 SYMBOL_A = counter++;
417
418 SYMBOL_B = counter++;
419
420 SYMBOL_C = counter++;
421
422 SYMBOL_D = counter++;
423
424 SYMBOL_I = counter++;
425
426 SYMBOL_J = counter++;
427
428 SYMBOL_N = counter++;
429
430 SYMBOL_R = counter++;
431
432 SYMBOL_S = counter++;
433
434 SYMBOL_T = counter++;
435
436 SYMBOL_X = counter++;
437
438 SYMBOL_Y = counter++;
439
440 SYMBOL_Z = counter++;
441
442 SYMBOL_IDENTITY_MATRIX = counter++;
443
444 SYMBOL_A_UNDERSCORE = counter++;
445
446 SYMBOL_B_UNDERSCORE = counter++;
447
448 SYMBOL_X_UNDERSCORE = counter++;
449
450 C1 = counter++;
451
452 C2 = counter++;
453
454 C3 = counter++;
455
456 C4 = counter++;
457
458 C5 = counter++;
459
460 C6 = counter++;
461
462 USR_SYMBOLS = counter++;
463
464 E = YYE;
465
466 TOS = 100000;
467
468 BUF = 10000;
469
470 MAX_PROGRAM_SIZE = 100001;
471
472 MAXPRIMETAB = 10000;
473
474 MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES = 5;
475
476 MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE = 10;
477
478 ENABLE_CACHING = true;
479
480 cached_runs = null;
481
482 cached_findDependenciesInScript = null;
483
484 MAXDIM = 24;
485
486 symbolsDependencies = {};
487
488 symbolsHavingReassignments = [];
489
490 symbolsInExpressionsWithoutAssignments = [];
491
492 patternHasBeenFound = false;
493
494 predefinedSymbolsInGlobalScope_doNotTrackInDependencies = ["rationalize", "abs", "e", "i", "pi", "sin", "ceiling", "cos", "roots", "integral", "derivative", "defint", "sqrt", "eig", "cov", "deig", "dcov", "float", "floor", "product", "root", "round", "sum", "test", "unit"];
495
496 parse_time_simplifications = true;
497
498 chainOfUserSymbolsNotFunctionsBeingEvaluated = [];
499
500 stringsEmittedByUserPrintouts = "";
501
502 called_from_Algebra_block = false;
503
504 tensor = (function() {
505 tensor.prototype.ndim = 0;
506
507 tensor.prototype.dim = null;
508
509 tensor.prototype.nelem = 0;
510
511 tensor.prototype.elem = null;
512
513 function tensor() {
514 this.dim = (function() {
515 var o, ref, results;
516 results = [];
517 for (o = 0, ref = MAXDIM; 0 <= ref ? o <= ref : o >= ref; 0 <= ref ? o++ : o--) {
518 results.push(0);
519 }
520 return results;
521 })();
522 this.elem = [];
523 }
524
525 return tensor;
526
527 })();
528
529 display = (function() {
530 function display() {}
531
532 display.prototype.h = 0;
533
534 display.prototype.w = 0;
535
536 display.prototype.n = 0;
537
538 display.prototype.a = [];
539
540 return display;
541
542 })();
543
544 text_metric = (function() {
545 function text_metric() {}
546
547 text_metric.prototype.ascent = 0;
548
549 text_metric.prototype.descent = 0;
550
551 text_metric.prototype.width = 0;
552
553 return text_metric;
554
555 })();
556
557 tos = 0;
558
559 expanding = 0;
560
561 evaluatingAsFloats = 0;
562
563 evaluatingPolar = 0;
564
565 fmt_x = 0;
566
567 fmt_index = 0;
568
569 fmt_level = 0;
570
571 verbosing = 0;
572
573 primetab = (function() {
574 var ceil, i, j, primes;
575 primes = [2];
576 i = 3;
577 while (primes.length < MAXPRIMETAB) {
578 j = 0;
579 ceil = Math.sqrt(i);
580 while (j < primes.length && primes[j] <= ceil) {
581 if (i % primes[j] === 0) {
582 j = -1;
583 break;
584 }
585 j++;
586 }
587 if (j !== -1) {
588 primes.push(i);
589 }
590 i += 2;
591 }
592 primes[MAXPRIMETAB] = 0;
593 return primes;
594 })();
595
596 esc_flag = 0;
597
598 draw_flag = 0;
599
600 mtotal = 0;
601
602 trigmode = 0;
603
604 logbuf = "";
605
606 program_buf = "";
607
608 symtab = [];
609
610 binding = [];
611
612 isSymbolReclaimable = [];
613
614 arglist = [];
615
616 stack = [];
617
618 frame = 0;
619
620 p0 = null;
621
622 p1 = null;
623
624 p2 = null;
625
626 p3 = null;
627
628 p4 = null;
629
630 p5 = null;
631
632 p6 = null;
633
634 p7 = null;
635
636 p8 = null;
637
638 p9 = null;
639
640 zero = null;
641
642 one = null;
643
644 one_as_double = null;
645
646 imaginaryunit = null;
647
648 out_buf = "";
649
650 out_count = 0;
651
652 test_flag = 0;
653
654 codeGen = false;
655
656 draw_stop_return = null;
657
658 userSimplificationsInListForm = [];
659
660 userSimplificationsInStringForm = [];
661
662 transpose_unicode = 7488;
663
664 dotprod_unicode = 183;
665
666 symbol = function(x) {
667 return symtab[x];
668 };
669
670 iscons = function(p) {
671 return p.k === CONS;
672 };
673
674 isrational = function(p) {
675 return p.k === NUM;
676 };
677
678 isdouble = function(p) {
679 return p.k === DOUBLE;
680 };
681
682 isnum = function(p) {
683 return isrational(p) || isdouble(p);
684 };
685
686 isstr = function(p) {
687 return p.k === STR;
688 };
689
690 istensor = function(p) {
691 if (p == null) {
692 debugger;
693 } else {
694 return p.k === TENSOR;
695 }
696 };
697
698 isnumerictensor = function(p) {
699 var a, i, n, o, ref;
700 if (isnum(p) || p === symbol(SYMBOL_IDENTITY_MATRIX)) {
701 return 1;
702 }
703 if (!istensor(p) && !isnum(p)) {
704 return 0;
705 }
706 n = p.tensor.nelem;
707 a = p.tensor.elem;
708 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
709 if (!isnumerictensor(a[i])) {
710 return 0;
711 }
712 }
713 return 1;
714 };
715
716 issymbol = function(p) {
717 return p.k === SYM;
718 };
719
720 iskeyword = function(p) {
721 return issymbol(p) && symnum(p) < NIL;
722 };
723
724 car = function(p) {
725 if (iscons(p)) {
726 return p.cons.car;
727 } else {
728 return symbol(NIL);
729 }
730 };
731
732 cdr = function(p) {
733 if (iscons(p)) {
734 return p.cons.cdr;
735 } else {
736 return symbol(NIL);
737 }
738 };
739
740 caar = function(p) {
741 return car(car(p));
742 };
743
744 cadr = function(p) {
745 return car(cdr(p));
746 };
747
748 cdar = function(p) {
749 return cdr(car(p));
750 };
751
752 cddr = function(p) {
753 return cdr(cdr(p));
754 };
755
756 caadr = function(p) {
757 return car(car(cdr(p)));
758 };
759
760 caddr = function(p) {
761 return car(cdr(cdr(p)));
762 };
763
764 cadar = function(p) {
765 return car(cdr(car(p)));
766 };
767
768 cdadr = function(p) {
769 return cdr(car(cdr(p)));
770 };
771
772 cddar = function(p) {
773 return cdr(cdr(car(p)));
774 };
775
776 cdddr = function(p) {
777 return cdr(cdr(cdr(p)));
778 };
779
780 caaddr = function(p) {
781 return car(car(cdr(cdr(p))));
782 };
783
784 cadadr = function(p) {
785 return car(cdr(car(cdr(p))));
786 };
787
788 caddar = function(p) {
789 return car(cdr(cdr(car(p))));
790 };
791
792 cdaddr = function(p) {
793 return cdr(car(cdr(cdr(p))));
794 };
795
796 cadddr = function(p) {
797 return car(cdr(cdr(cdr(p))));
798 };
799
800 cddddr = function(p) {
801 return cdr(cdr(cdr(cdr(p))));
802 };
803
804 caddddr = function(p) {
805 return car(cdr(cdr(cdr(cdr(p)))));
806 };
807
808 cadaddr = function(p) {
809 return car(cdr(car(cdr(cdr(p)))));
810 };
811
812 cddaddr = function(p) {
813 return cdr(cdr(car(cdr(cdr(p)))));
814 };
815
816 caddadr = function(p) {
817 return car(cdr(cdr(car(cdr(p)))));
818 };
819
820 cdddaddr = function(p) {
821 return cdr(cdr(cdr(car(cdr(cdr(p))))));
822 };
823
824 caddaddr = function(p) {
825 return car(cdr(cdr(car(cdr(cdr(p))))));
826 };
827
828 listLength = function(p) {
829 var startCount;
830 startCount = -1;
831 while (iscons(p)) {
832 p = cdr(p);
833 startCount++;
834 }
835 return startCount;
836 };
837
838 nthCadr = function(p, n) {
839 var startCount;
840 startCount = 0;
841 while (startCount <= n) {
842 p = cdr(p);
843 startCount++;
844 }
845 return car(p);
846 };
847
848 isadd = function(p) {
849 return car(p) === symbol(ADD);
850 };
851
852 ismultiply = function(p) {
853 return car(p) === symbol(MULTIPLY);
854 };
855
856 ispower = function(p) {
857 return car(p) === symbol(POWER);
858 };
859
860 isfactorial = function(p) {
861 return car(p) === symbol(FACTORIAL);
862 };
863
864 isinnerordot = function(p) {
865 return (car(p) === symbol(INNER)) || (car(p) === symbol(DOT));
866 };
867
868 istranspose = function(p) {
869 return car(p) === symbol(TRANSPOSE);
870 };
871
872 isinv = function(p) {
873 return car(p) === symbol(INV);
874 };
875
876 isidentitymatrix = function(p) {
877 return p === symbol(SYMBOL_IDENTITY_MATRIX);
878 };
879
880 MSIGN = function(p) {
881 if (p.isPositive()) {
882 return 1;
883 } else if (p.isZero()) {
884 return 0;
885 } else {
886 return -1;
887 }
888 };
889
890 MLENGTH = function(p) {
891 return p.toString().length;
892 };
893
894 MZERO = function(p) {
895 return p.isZero();
896 };
897
898 MEQUAL = function(p, n) {
899 if (p == null) {
900 debugger;
901 }
902 return p.equals(n);
903 };
904
905 reset_after_error = function() {
906 moveTos(0);
907 esc_flag = 0;
908 draw_flag = 0;
909 frame = TOS;
910 evaluatingAsFloats = 0;
911 return evaluatingPolar = 0;
912 };
913
914 $ = typeof exports !== "undefined" && exports !== null ? exports : this;
915
916 $.version = version;
917
918 $.isadd = isadd;
919
920 $.ismultiply = ismultiply;
921
922 $.ispower = ispower;
923
924 $.isfactorial = isfactorial;
925
926 $.car = car;
927
928 $.cdr = cdr;
929
930 $.caar = caar;
931
932 $.cadr = cadr;
933
934 $.cdar = cdar;
935
936 $.cddr = cddr;
937
938 $.caadr = caadr;
939
940 $.caddr = caddr;
941
942 $.cadar = cadar;
943
944 $.cdadr = cdadr;
945
946 $.cddar = cddar;
947
948 $.cdddr = cdddr;
949
950 $.caaddr = caaddr;
951
952 $.cadadr = cadadr;
953
954 $.caddar = caddar;
955
956 $.cdaddr = cdaddr;
957
958 $.cadddr = cadddr;
959
960 $.cddddr = cddddr;
961
962 $.caddddr = caddddr;
963
964 $.cadaddr = cadaddr;
965
966 $.cddaddr = cddaddr;
967
968 $.caddadr = caddadr;
969
970 $.cdddaddr = cdddaddr;
971
972 $.caddaddr = caddaddr;
973
974 $.symbol = symbol;
975
976 $.iscons = iscons;
977
978 $.isrational = isrational;
979
980 $.isdouble = isdouble;
981
982 $.isnum = isnum;
983
984 $.isstr = isstr;
985
986 $.istensor = istensor;
987
988 $.issymbol = issymbol;
989
990 $.iskeyword = iskeyword;
991
992 $.CONS = CONS;
993
994 $.NUM = NUM;
995
996 $.DOUBLE = DOUBLE;
997
998 $.STR = STR;
999
1000 $.TENSOR = TENSOR;
1001
1002 $.SYM = SYM;
1003
1004
1005 /* abs =====================================================================
1006
1007 Tags
1008 ----
1009 scripting, JS, internal, treenode, general concept
1010
1011 Parameters
1012 ----------
1013 x
1014
1015 General description
1016 -------------------
1017 Returns the absolute value of a real number, the magnitude of a complex number, or the vector length.
1018 */
1019
1020
1021 /*
1022 Absolute value of a number,or magnitude of complex z, or norm of a vector
1023
1024 z abs(z)
1025 - ------
1026
1027 a a
1028
1029 -a a
1030
1031 (-1)^a 1
1032
1033 exp(a + i b) exp(a)
1034
1035 a b abs(a) abs(b)
1036
1037 a + i b sqrt(a^2 + b^2)
1038
1039 Notes
1040
1041 1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3)
1042
1043 2. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then
1044
1045 abs(numerator(z)) / abs(denominator(z))
1046
1047 must be used to get the correct answer. Now the operation is
1048 automatic.
1049 */
1050
1051 DEBUG_ABS = false;
1052
1053 Eval_abs = function() {
1054 push(cadr(p1));
1055 Eval();
1056 return abs();
1057 };
1058
1059 absValFloat = function() {
1060 Eval();
1061 absval();
1062 Eval();
1063 return zzfloat();
1064 };
1065
1066 abs = function() {
1067 save();
1068 p1 = pop();
1069 push(p1);
1070 numerator();
1071 absval();
1072 push(p1);
1073 denominator();
1074 absval();
1075 divide();
1076 return restore();
1077 };
1078
1079 absval = function() {
1080 var input;
1081 save();
1082 p1 = pop();
1083 input = p1;
1084 if (DEBUG_ABS) {
1085 console.log("ABS of " + p1);
1086 }
1087 if (iszero(p1)) {
1088 if (DEBUG_ABS) {
1089 console.log(" abs: " + p1 + " just zero");
1090 }
1091 push(zero);
1092 if (DEBUG_ABS) {
1093 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1094 }
1095 restore();
1096 return;
1097 }
1098 if (isnegativenumber(p1)) {
1099 if (DEBUG_ABS) {
1100 console.log(" abs: " + p1 + " just a negative");
1101 }
1102 push(p1);
1103 negate();
1104 restore();
1105 return;
1106 }
1107 if (ispositivenumber(p1)) {
1108 if (DEBUG_ABS) {
1109 console.log(" abs: " + p1 + " just a positive");
1110 }
1111 push(p1);
1112 if (DEBUG_ABS) {
1113 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1114 }
1115 restore();
1116 return;
1117 }
1118 if (p1 === symbol(PI)) {
1119 if (DEBUG_ABS) {
1120 console.log(" abs: " + p1 + " of PI");
1121 }
1122 push(p1);
1123 if (DEBUG_ABS) {
1124 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1125 }
1126 restore();
1127 return;
1128 }
1129 if (car(p1) === symbol(ADD) && (findPossibleClockForm(p1) || findPossibleExponentialForm(p1) || Find(p1, imaginaryunit))) {
1130 if (DEBUG_ABS) {
1131 console.log(" abs: " + p1 + " is a sum");
1132 }
1133 if (DEBUG_ABS) {
1134 console.log("abs of a sum");
1135 }
1136 push(p1);
1137 rect();
1138 p1 = pop();
1139 push(p1);
1140 real();
1141 push_integer(2);
1142 power();
1143 push(p1);
1144 imag();
1145 push_integer(2);
1146 power();
1147 add();
1148 push_rational(1, 2);
1149 power();
1150 simplify_trig();
1151 if (DEBUG_ABS) {
1152 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1153 }
1154 restore();
1155 return;
1156 }
1157 if (car(p1) === symbol(POWER) && equaln(cadr(p1), -1)) {
1158 if (DEBUG_ABS) {
1159 console.log(" abs: " + p1 + " is -1 to any power");
1160 }
1161 if (evaluatingAsFloats) {
1162 if (DEBUG_ABS) {
1163 console.log(" abs: numeric, so result is 1.0");
1164 }
1165 push_double(1.0);
1166 } else {
1167 if (DEBUG_ABS) {
1168 console.log(" abs: symbolic, so result is 1");
1169 }
1170 push_integer(1);
1171 }
1172 if (DEBUG_ABS) {
1173 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1174 }
1175 restore();
1176 return;
1177 }
1178 if (car(p1) === symbol(POWER) && ispositivenumber(caddr(p1))) {
1179 if (DEBUG_ABS) {
1180 console.log(" abs: " + p1 + " is something to the power of a positive number");
1181 }
1182 push(cadr(p1));
1183 abs();
1184 push(caddr(p1));
1185 power();
1186 if (DEBUG_ABS) {
1187 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1188 }
1189 restore();
1190 return;
1191 }
1192 if (car(p1) === symbol(POWER) && cadr(p1) === symbol(E)) {
1193 if (DEBUG_ABS) {
1194 console.log(" abs: " + p1 + " is an exponential");
1195 }
1196 push(caddr(p1));
1197 real();
1198 exponential();
1199 if (DEBUG_ABS) {
1200 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1201 }
1202 restore();
1203 return;
1204 }
1205 if (car(p1) === symbol(MULTIPLY)) {
1206 if (DEBUG_ABS) {
1207 console.log(" abs: " + p1 + " is a product");
1208 }
1209 push_integer(1);
1210 p1 = cdr(p1);
1211 while (iscons(p1)) {
1212 push(car(p1));
1213 abs();
1214 multiply();
1215 p1 = cdr(p1);
1216 }
1217 if (DEBUG_ABS) {
1218 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1219 }
1220 restore();
1221 return;
1222 }
1223 if (car(p1) === symbol(ABS)) {
1224 if (DEBUG_ABS) {
1225 console.log(" abs: " + p1 + " is abs of a abs");
1226 }
1227 push_symbol(ABS);
1228 push(cadr(p1));
1229 list(2);
1230 if (DEBUG_ABS) {
1231 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1232 }
1233 restore();
1234 return;
1235 }
1236
1237 /*
1238 * Evaluation via zzfloat()
1239 * ...while this is in theory a powerful mechanism, I've commented it
1240 * out because I've refined this method enough to not need this.
1241 * Evaling via zzfloat() is in principle more problematic because it could
1242 * require further evaluations which could end up in further "abs" which
1243 * would end up in infinite loops. Better not use it if not necessary.
1244
1245 * we look directly at the float evaluation of the argument
1246 * to see if we end up with a number, which would mean that there
1247 * is no imaginary component and we can just return the input
1248 * (or its negation) as the result.
1249 push p1
1250 zzfloat()
1251 floatEvaluation = pop()
1252
1253 if (isnegativenumber(floatEvaluation))
1254 if DEBUG_ABS then console.log " abs: " + p1 + " just a negative"
1255 push(p1)
1256 negate()
1257 restore()
1258 return
1259
1260 if (ispositivenumber(floatEvaluation))
1261 if DEBUG_ABS then console.log " abs: " + p1 + " just a positive"
1262 push(p1)
1263 if DEBUG_ABS then console.log " --> ABS of " + input + " : " + stack[tos-1]
1264 restore()
1265 return
1266 */
1267 if (istensor(p1)) {
1268 absval_tensor();
1269 restore();
1270 return;
1271 }
1272 if (isnegativeterm(p1) || (car(p1) === symbol(ADD) && isnegativeterm(cadr(p1)))) {
1273 push(p1);
1274 negate();
1275 p1 = pop();
1276 }
1277 if (DEBUG_ABS) {
1278 console.log(" abs: " + p1 + " is nothing decomposable");
1279 }
1280 push_symbol(ABS);
1281 push(p1);
1282 list(2);
1283 if (DEBUG_ABS) {
1284 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1285 }
1286 return restore();
1287 };
1288
1289 absval_tensor = function() {
1290 if (p1.tensor.ndim !== 1) {
1291 stop("abs(tensor) with tensor rank > 1");
1292 }
1293 push(p1);
1294 push(p1);
1295 conjugate();
1296 inner();
1297 push_rational(1, 2);
1298 power();
1299 simplify();
1300 return Eval();
1301 };
1302
1303
1304 /*
1305 Symbolic addition
1306
1307 Terms in a sum are combined if they are identical modulo rational
1308 coefficients.
1309
1310 For example, A + 2A becomes 3A.
1311
1312 However, the sum A + sqrt(2) A is not modified.
1313
1314 Combining terms can lead to second-order effects.
1315
1316 For example, consider the case of
1317
1318 1/sqrt(2) A + 3/sqrt(2) A + sqrt(2) A
1319
1320 The first two terms are combined to yield 2 sqrt(2) A.
1321
1322 This result can now be combined with the third term to yield
1323
1324 3 sqrt(2) A
1325 */
1326
1327 flag = 0;
1328
1329 Eval_add = function() {
1330 var h;
1331 h = tos;
1332 p1 = cdr(p1);
1333 while (iscons(p1)) {
1334 push(car(p1));
1335 Eval();
1336 p2 = pop();
1337 push_terms(p2);
1338 p1 = cdr(p1);
1339 }
1340 return add_terms(tos - h);
1341 };
1342
1343 stackAddsCount = 0;
1344
1345 add_terms = function(n) {
1346 var h, i, i1, j1, o, ref, ref1, results, s, subsetOfStack;
1347 stackAddsCount++;
1348 i = 0;
1349 h = tos - n;
1350 s = h;
1351 if (DEBUG) {
1352 console.log("stack before adding terms #" + stackAddsCount);
1353 }
1354 if (DEBUG) {
1355 for (i = o = 0, ref = tos; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1356 console.log(print_list(stack[i]));
1357 }
1358 }
1359 for (i = i1 = 0; i1 < 10; i = ++i1) {
1360 if (n < 2) {
1361 break;
1362 }
1363 flag = 0;
1364 subsetOfStack = stack.slice(h, h + n);
1365 subsetOfStack.sort(cmp_terms);
1366 stack = stack.slice(0, h).concat(subsetOfStack).concat(stack.slice(h + n));
1367 if (flag === 0) {
1368 break;
1369 }
1370 n = combine_terms(h, n);
1371 }
1372 moveTos(h + n);
1373 switch (n) {
1374 case 0:
1375 if (evaluatingAsFloats) {
1376 push_double(0.0);
1377 } else {
1378 push(zero);
1379 }
1380 break;
1381 case 1:
1382 break;
1383 default:
1384 list(n);
1385 p1 = pop();
1386 push_symbol(ADD);
1387 push(p1);
1388 cons();
1389 }
1390 if (DEBUG) {
1391 console.log("stack after adding terms #" + stackAddsCount);
1392 }
1393 if (DEBUG) {
1394 results = [];
1395 for (i = j1 = 0, ref1 = tos; 0 <= ref1 ? j1 < ref1 : j1 > ref1; i = 0 <= ref1 ? ++j1 : --j1) {
1396 results.push(console.log(print_list(stack[i])));
1397 }
1398 return results;
1399 }
1400 };
1401
1402 cmp_terms_count = 0;
1403
1404 cmp_terms = function(p1, p2) {
1405 var i, o, ref, t;
1406 cmp_terms_count++;
1407 i = 0;
1408 if (isnum(p1) && isnum(p2)) {
1409 flag = 1;
1410 return 0;
1411 }
1412 if (istensor(p1) && istensor(p2)) {
1413 if (p1.tensor.ndim < p2.tensor.ndim) {
1414 return -1;
1415 }
1416 if (p1.tensor.ndim > p2.tensor.ndim) {
1417 return 1;
1418 }
1419 for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1420 if (p1.tensor.dim[i] < p2.tensor.dim[i]) {
1421 return -1;
1422 }
1423 if (p1.tensor.dim[i] > p2.tensor.dim[i]) {
1424 return 1;
1425 }
1426 }
1427 flag = 1;
1428 return 0;
1429 }
1430 if (car(p1) === symbol(MULTIPLY)) {
1431 p1 = cdr(p1);
1432 if (isnum(car(p1))) {
1433 p1 = cdr(p1);
1434 if (cdr(p1) === symbol(NIL)) {
1435 p1 = car(p1);
1436 }
1437 }
1438 }
1439 if (car(p2) === symbol(MULTIPLY)) {
1440 p2 = cdr(p2);
1441 if (isnum(car(p2))) {
1442 p2 = cdr(p2);
1443 if (cdr(p2) === symbol(NIL)) {
1444 p2 = car(p2);
1445 }
1446 }
1447 }
1448 t = cmp_expr(p1, p2);
1449 if (t === 0) {
1450 flag = 1;
1451 }
1452 return t;
1453 };
1454
1455
1456 /*
1457 Compare adjacent terms in s[] and combine if possible.
1458
1459 Returns the number of terms remaining in s[].
1460
1461 n number of terms in s[] initially
1462 */
1463
1464 combine_terms = function(s, n) {
1465 var i, i1, j, j1, l1, m1, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, t;
1466 i = 0;
1467 while (i < (n - 1)) {
1468 check_esc_flag();
1469 p3 = stack[s + i];
1470 p4 = stack[s + i + 1];
1471 if (istensor(p3) && istensor(p4)) {
1472 push(p3);
1473 push(p4);
1474 tensor_plus_tensor();
1475 p1 = pop();
1476 if (p1 !== symbol(NIL)) {
1477 stack[s + i] = p1;
1478 for (j = o = ref = i + 1, ref1 = n - 1; ref <= ref1 ? o < ref1 : o > ref1; j = ref <= ref1 ? ++o : --o) {
1479 stack[s + j] = stack[s + j + 1];
1480 }
1481 n--;
1482 i--;
1483 }
1484 i++;
1485 continue;
1486 }
1487 if (istensor(p3) || istensor(p4)) {
1488 i++;
1489 continue;
1490 }
1491 if (isnum(p3) && isnum(p4)) {
1492 push(p3);
1493 push(p4);
1494 add_numbers();
1495 p1 = pop();
1496 if (iszero(p1)) {
1497 for (j = i1 = ref2 = i, ref3 = n - 2; ref2 <= ref3 ? i1 < ref3 : i1 > ref3; j = ref2 <= ref3 ? ++i1 : --i1) {
1498 stack[s + j] = stack[s + j + 2];
1499 }
1500 n -= 2;
1501 } else {
1502 stack[s + i] = p1;
1503 for (j = j1 = ref4 = i + 1, ref5 = n - 1; ref4 <= ref5 ? j1 < ref5 : j1 > ref5; j = ref4 <= ref5 ? ++j1 : --j1) {
1504 stack[s + j] = stack[s + j + 1];
1505 }
1506 n--;
1507 }
1508 i--;
1509 i++;
1510 continue;
1511 }
1512 if (isnum(p3) || isnum(p4)) {
1513 i++;
1514 continue;
1515 }
1516 if (evaluatingAsFloats) {
1517 p1 = one_as_double;
1518 p2 = one_as_double;
1519 } else {
1520 p1 = one;
1521 p2 = one;
1522 }
1523 t = 0;
1524 if (car(p3) === symbol(MULTIPLY)) {
1525 p3 = cdr(p3);
1526 t = 1;
1527 if (isnum(car(p3))) {
1528 p1 = car(p3);
1529 p3 = cdr(p3);
1530 if (cdr(p3) === symbol(NIL)) {
1531 p3 = car(p3);
1532 t = 0;
1533 }
1534 }
1535 }
1536 if (car(p4) === symbol(MULTIPLY)) {
1537 p4 = cdr(p4);
1538 if (isnum(car(p4))) {
1539 p2 = car(p4);
1540 p4 = cdr(p4);
1541 if (cdr(p4) === symbol(NIL)) {
1542 p4 = car(p4);
1543 }
1544 }
1545 }
1546 if (!equal(p3, p4)) {
1547 i++;
1548 continue;
1549 }
1550 push(p1);
1551 push(p2);
1552 add_numbers();
1553 p1 = pop();
1554 if (iszero(p1)) {
1555 for (j = l1 = ref6 = i, ref7 = n - 2; ref6 <= ref7 ? l1 < ref7 : l1 > ref7; j = ref6 <= ref7 ? ++l1 : --l1) {
1556 stack[s + j] = stack[s + j + 2];
1557 }
1558 n -= 2;
1559 i--;
1560 i++;
1561 continue;
1562 }
1563 push(p1);
1564 if (t) {
1565 push(symbol(MULTIPLY));
1566 push(p3);
1567 cons();
1568 } else {
1569 push(p3);
1570 }
1571 multiply();
1572 stack[s + i] = pop();
1573 for (j = m1 = ref8 = i + 1, ref9 = n - 1; ref8 <= ref9 ? m1 < ref9 : m1 > ref9; j = ref8 <= ref9 ? ++m1 : --m1) {
1574 stack[s + j] = stack[s + j + 1];
1575 }
1576 n--;
1577 i--;
1578 i++;
1579 }
1580 return n;
1581 };
1582
1583 push_terms = function(p) {
1584 var results;
1585 if (car(p) === symbol(ADD)) {
1586 p = cdr(p);
1587 results = [];
1588 while (iscons(p)) {
1589 push(car(p));
1590 results.push(p = cdr(p));
1591 }
1592 return results;
1593 } else if (!iszero(p)) {
1594 return push(p);
1595 }
1596 };
1597
1598 add = function() {
1599 var h;
1600 save();
1601 p2 = pop();
1602 p1 = pop();
1603 h = tos;
1604 push_terms(p1);
1605 push_terms(p2);
1606 add_terms(tos - h);
1607 return restore();
1608 };
1609
1610 add_all = function(k) {
1611 var h, i, o, ref, s;
1612 i = 0;
1613 save();
1614 s = tos - k;
1615 h = tos;
1616 for (i = o = 0, ref = k; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1617 push_terms(stack[s + i]);
1618 }
1619 add_terms(tos - h);
1620 p1 = pop();
1621 moveTos(tos - k);
1622 push(p1);
1623 return restore();
1624 };
1625
1626 subtract = function() {
1627 negate();
1628 return add();
1629 };
1630
1631
1632 /* adj =====================================================================
1633
1634 Tags
1635 ----
1636 scripting, JS, internal, treenode, general concept
1637
1638 Parameters
1639 ----------
1640 m
1641
1642 General description
1643 -------------------
1644 Returns the adjunct of matrix m. The inverse of m is equal to adj(m) divided by det(m).
1645 */
1646
1647 Eval_adj = function() {
1648 push(cadr(p1));
1649 Eval();
1650 return adj();
1651 };
1652
1653 adj = function() {
1654 var doNothing, i, i1, j, n, o, ref, ref1;
1655 i = 0;
1656 j = 0;
1657 n = 0;
1658 save();
1659 p1 = pop();
1660 if (istensor(p1) && p1.tensor.ndim === 2 && p1.tensor.dim[0] === p1.tensor.dim[1]) {
1661 doNothing = 1;
1662 } else {
1663 stop("adj: square matrix expected");
1664 }
1665 n = p1.tensor.dim[0];
1666 p2 = alloc_tensor(n * n);
1667 p2.tensor.ndim = 2;
1668 p2.tensor.dim[0] = n;
1669 p2.tensor.dim[1] = n;
1670 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1671 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
1672 cofactor(p1, n, i, j);
1673 p2.tensor.elem[n * j + i] = pop();
1674 }
1675 }
1676 push(p2);
1677 return restore();
1678 };
1679
1680
1681 /*
1682 Guesses a rational for each float in the passed expression
1683 */
1684
1685 Eval_approxratio = function() {
1686 var theArgument;
1687 theArgument = cadr(p1);
1688 push(theArgument);
1689 return approxratioRecursive();
1690 };
1691
1692 approxratioRecursive = function() {
1693 var i, i1, o, ref, ref1;
1694 i = 0;
1695 save();
1696 p1 = pop();
1697 if (istensor(p1)) {
1698 p4 = alloc_tensor(p1.tensor.nelem);
1699 p4.tensor.ndim = p1.tensor.ndim;
1700 for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1701 p4.tensor.dim[i] = p1.tensor.dim[i];
1702 }
1703 for (i = i1 = 0, ref1 = p1.tensor.nelem; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
1704 push(p1.tensor.elem[i]);
1705 approxratioRecursive();
1706 p4.tensor.elem[i] = pop();
1707 check_tensor_dimensions(p4);
1708 }
1709 push(p4);
1710 } else if (p1.k === DOUBLE) {
1711 push(p1);
1712 approxOneRatioOnly();
1713 } else if (iscons(p1)) {
1714 push(car(p1));
1715 approxratioRecursive();
1716 push(cdr(p1));
1717 approxratioRecursive();
1718 cons();
1719 } else {
1720 push(p1);
1721 }
1722 return restore();
1723 };
1724
1725 approxOneRatioOnly = function() {
1726 var numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot, supposedlyTheFloat, theFloat, theRatio;
1727 zzfloat();
1728 supposedlyTheFloat = pop();
1729 if (supposedlyTheFloat.k === DOUBLE) {
1730 theFloat = supposedlyTheFloat.d;
1731 splitBeforeAndAfterDot = theFloat.toString().split(".");
1732 if (splitBeforeAndAfterDot.length === 2) {
1733 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1734 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1735 theRatio = floatToRatioRoutine(theFloat, precision);
1736 push_rational(theRatio[0], theRatio[1]);
1737 } else {
1738 push_integer(theFloat);
1739 }
1740 return;
1741 }
1742 push_symbol(APPROXRATIO);
1743 push(theArgument);
1744 return list(2);
1745 };
1746
1747 floatToRatioRoutine = function(decimal, AccuracyFactor) {
1748 var DecimalSign, FractionDenominator, FractionNumerator, PreviousDenominator, ScratchValue, Z, ret;
1749 FractionNumerator = void 0;
1750 FractionDenominator = void 0;
1751 DecimalSign = void 0;
1752 Z = void 0;
1753 PreviousDenominator = void 0;
1754 ScratchValue = void 0;
1755 ret = [0, 0];
1756 if (isNaN(decimal)) {
1757 return ret;
1758 }
1759 if (decimal === 2e308) {
1760 ret[0] = 1;
1761 ret[1] = 0;
1762 return ret;
1763 }
1764 if (decimal === -2e308) {
1765 ret[0] = -1;
1766 ret[1] = 0;
1767 return ret;
1768 }
1769 if (decimal < 0.0) {
1770 DecimalSign = -1.0;
1771 } else {
1772 DecimalSign = 1.0;
1773 }
1774 decimal = Math.abs(decimal);
1775 if (Math.abs(decimal - Math.floor(decimal)) < AccuracyFactor) {
1776 FractionNumerator = decimal * DecimalSign;
1777 FractionDenominator = 1.0;
1778 ret[0] = FractionNumerator;
1779 ret[1] = FractionDenominator;
1780 return ret;
1781 }
1782 if (decimal < 1.0e-19) {
1783 FractionNumerator = DecimalSign;
1784 FractionDenominator = 9999999999999999999.0;
1785 ret[0] = FractionNumerator;
1786 ret[1] = FractionDenominator;
1787 return ret;
1788 }
1789 if (decimal > 1.0e19) {
1790 FractionNumerator = 9999999999999999999.0 * DecimalSign;
1791 FractionDenominator = 1.0;
1792 ret[0] = FractionNumerator;
1793 ret[1] = FractionDenominator;
1794 return ret;
1795 }
1796 Z = decimal;
1797 PreviousDenominator = 0.0;
1798 FractionDenominator = 1.0;
1799 while (true) {
1800 Z = 1.0 / (Z - Math.floor(Z));
1801 ScratchValue = FractionDenominator;
1802 FractionDenominator = FractionDenominator * Math.floor(Z) + PreviousDenominator;
1803 PreviousDenominator = ScratchValue;
1804 FractionNumerator = Math.floor(decimal * FractionDenominator + 0.5);
1805 if (!(Math.abs(decimal - (FractionNumerator / FractionDenominator)) > AccuracyFactor && Z !== Math.floor(Z))) {
1806 break;
1807 }
1808 }
1809 FractionNumerator = DecimalSign * FractionNumerator;
1810 ret[0] = FractionNumerator;
1811 ret[1] = FractionDenominator;
1812 return ret;
1813 };
1814
1815 approx_just_an_integer = 0;
1816
1817 approx_sine_of_rational = 1;
1818
1819 approx_sine_of_pi_times_rational = 2;
1820
1821 approx_rationalOfPi = 3;
1822
1823 approx_radicalOfRatio = 4;
1824
1825 approx_nothingUseful = 5;
1826
1827 approx_ratioOfRadical = 6;
1828
1829 approx_rationalOfE = 7;
1830
1831 approx_logarithmsOfRationals = 8;
1832
1833 approx_rationalsOfLogarithms = 9;
1834
1835 approxRationalsOfRadicals = function(theFloat) {
1836 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, len, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, ref, result, splitBeforeAndAfterDot;
1837 splitBeforeAndAfterDot = theFloat.toString().split(".");
1838 if (splitBeforeAndAfterDot.length === 2) {
1839 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1840 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1841 } else {
1842 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1843 }
1844 console.log("precision: " + precision);
1845 bestResultSoFar = null;
1846 minimumComplexity = Number.MAX_VALUE;
1847 ref = [2, 3, 5, 6, 7, 8, 10];
1848 for (o = 0, len = ref.length; o < len; o++) {
1849 i = ref[o];
1850 for (j = i1 = 1; i1 <= 10; j = ++i1) {
1851 hypothesis = Math.sqrt(i) / j;
1852 if (Math.abs(hypothesis) > 1e-10) {
1853 ratio = theFloat / hypothesis;
1854 likelyMultiplier = Math.round(ratio);
1855 error = Math.abs(1 - ratio / likelyMultiplier);
1856 } else {
1857 ratio = 1;
1858 likelyMultiplier = 1;
1859 error = Math.abs(theFloat - hypothesis);
1860 }
1861 if (error < 2 * precision) {
1862 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
1863 if (complexity < minimumComplexity) {
1864 minimumComplexity = complexity;
1865 result = likelyMultiplier + " * sqrt( " + i + " ) / " + j;
1866 bestResultSoFar = [result, approx_ratioOfRadical, likelyMultiplier, i, j];
1867 }
1868 }
1869 }
1870 }
1871 return bestResultSoFar;
1872 };
1873
1874 approxRadicalsOfRationals = function(theFloat) {
1875 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, len, len1, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, ref, ref1, result, splitBeforeAndAfterDot;
1876 splitBeforeAndAfterDot = theFloat.toString().split(".");
1877 if (splitBeforeAndAfterDot.length === 2) {
1878 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1879 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1880 } else {
1881 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1882 }
1883 console.log("precision: " + precision);
1884 bestResultSoFar = null;
1885 minimumComplexity = Number.MAX_VALUE;
1886 ref = [1, 2, 3, 5, 6, 7, 8, 10];
1887 for (o = 0, len = ref.length; o < len; o++) {
1888 i = ref[o];
1889 ref1 = [1, 2, 3, 5, 6, 7, 8, 10];
1890 for (i1 = 0, len1 = ref1.length; i1 < len1; i1++) {
1891 j = ref1[i1];
1892 hypothesis = Math.sqrt(i / j);
1893 if (Math.abs(hypothesis) > 1e-10) {
1894 ratio = theFloat / hypothesis;
1895 likelyMultiplier = Math.round(ratio);
1896 error = Math.abs(1 - ratio / likelyMultiplier);
1897 } else {
1898 ratio = 1;
1899 likelyMultiplier = 1;
1900 error = Math.abs(theFloat - hypothesis);
1901 }
1902 if (error < 2 * precision) {
1903 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
1904 if (complexity < minimumComplexity) {
1905 minimumComplexity = complexity;
1906 result = likelyMultiplier + " * (sqrt( " + i + " / " + j + " )";
1907 bestResultSoFar = [result, approx_radicalOfRatio, likelyMultiplier, i, j];
1908 }
1909 }
1910 }
1911 }
1912 return bestResultSoFar;
1913 };
1914
1915 approxRadicals = function(theFloat) {
1916 var approxRadicalsOfRationalsResult, approxRationalsOfRadicalsResult, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
1917 splitBeforeAndAfterDot = theFloat.toString().split(".");
1918 if (splitBeforeAndAfterDot.length === 2) {
1919 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1920 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1921 } else {
1922 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1923 }
1924 console.log("precision: " + precision);
1925 approxRationalsOfRadicalsResult = approxRationalsOfRadicals(theFloat);
1926 if (approxRationalsOfRadicalsResult != null) {
1927 return approxRationalsOfRadicalsResult;
1928 }
1929 approxRadicalsOfRationalsResult = approxRadicalsOfRationals(theFloat);
1930 if (approxRadicalsOfRationalsResult != null) {
1931 return approxRadicalsOfRationalsResult;
1932 }
1933 return null;
1934 };
1935
1936 approxLogs = function(theFloat) {
1937 var approxLogsOfRationalsResult, approxRationalsOfLogsResult, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
1938 splitBeforeAndAfterDot = theFloat.toString().split(".");
1939 if (splitBeforeAndAfterDot.length === 2) {
1940 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1941 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1942 } else {
1943 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1944 }
1945 console.log("precision: " + precision);
1946 approxRationalsOfLogsResult = approxRationalsOfLogs(theFloat);
1947 if (approxRationalsOfLogsResult != null) {
1948 return approxRationalsOfLogsResult;
1949 }
1950 approxLogsOfRationalsResult = approxLogsOfRationals(theFloat);
1951 if (approxLogsOfRationalsResult != null) {
1952 return approxLogsOfRationalsResult;
1953 }
1954 return null;
1955 };
1956
1957 approxRationalsOfLogs = function(theFloat) {
1958 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
1959 splitBeforeAndAfterDot = theFloat.toString().split(".");
1960 if (splitBeforeAndAfterDot.length === 2) {
1961 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1962 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1963 } else {
1964 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1965 }
1966 console.log("precision: " + precision);
1967 bestResultSoFar = null;
1968 minimumComplexity = Number.MAX_VALUE;
1969 for (i = o = 2; o <= 5; i = ++o) {
1970 for (j = i1 = 1; i1 <= 5; j = ++i1) {
1971 hypothesis = Math.log(i) / j;
1972 if (Math.abs(hypothesis) > 1e-10) {
1973 ratio = theFloat / hypothesis;
1974 likelyMultiplier = Math.round(ratio);
1975 error = Math.abs(1 - ratio / likelyMultiplier);
1976 } else {
1977 ratio = 1;
1978 likelyMultiplier = 1;
1979 error = Math.abs(theFloat - hypothesis);
1980 }
1981 if (likelyMultiplier !== 1 && Math.abs(Math.floor(likelyMultiplier / j)) === Math.abs(likelyMultiplier / j)) {
1982 continue;
1983 }
1984 if (error < 2.2 * precision) {
1985 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
1986 if (complexity < minimumComplexity) {
1987 minimumComplexity = complexity;
1988 result = likelyMultiplier + " * log( " + i + " ) / " + j;
1989 bestResultSoFar = [result, approx_rationalsOfLogarithms, likelyMultiplier, i, j];
1990 }
1991 }
1992 }
1993 }
1994 return bestResultSoFar;
1995 };
1996
1997 approxLogsOfRationals = function(theFloat) {
1998 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
1999 splitBeforeAndAfterDot = theFloat.toString().split(".");
2000 if (splitBeforeAndAfterDot.length === 2) {
2001 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2002 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2003 } else {
2004 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2005 }
2006 console.log("precision: " + precision);
2007 bestResultSoFar = null;
2008 minimumComplexity = Number.MAX_VALUE;
2009 for (i = o = 1; o <= 5; i = ++o) {
2010 for (j = i1 = 1; i1 <= 5; j = ++i1) {
2011 hypothesis = Math.log(i / j);
2012 if (Math.abs(hypothesis) > 1e-10) {
2013 ratio = theFloat / hypothesis;
2014 likelyMultiplier = Math.round(ratio);
2015 error = Math.abs(1 - ratio / likelyMultiplier);
2016 } else {
2017 ratio = 1;
2018 likelyMultiplier = 1;
2019 error = Math.abs(theFloat - hypothesis);
2020 }
2021 if (error < 1.96 * precision) {
2022 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2023 if (complexity < minimumComplexity) {
2024 minimumComplexity = complexity;
2025 result = likelyMultiplier + " * log( " + i + " / " + j + " )";
2026 bestResultSoFar = [result, approx_logarithmsOfRationals, likelyMultiplier, i, j];
2027 }
2028 }
2029 }
2030 }
2031 return bestResultSoFar;
2032 };
2033
2034 approxRationalsOfPowersOfE = function(theFloat) {
2035 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2036 splitBeforeAndAfterDot = theFloat.toString().split(".");
2037 if (splitBeforeAndAfterDot.length === 2) {
2038 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2039 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2040 } else {
2041 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2042 }
2043 console.log("precision: " + precision);
2044 bestResultSoFar = null;
2045 minimumComplexity = Number.MAX_VALUE;
2046 for (i = o = 1; o <= 2; i = ++o) {
2047 for (j = i1 = 1; i1 <= 12; j = ++i1) {
2048 hypothesis = Math.pow(Math.E, i) / j;
2049 if (Math.abs(hypothesis) > 1e-10) {
2050 ratio = theFloat / hypothesis;
2051 likelyMultiplier = Math.round(ratio);
2052 error = Math.abs(1 - ratio / likelyMultiplier);
2053 } else {
2054 ratio = 1;
2055 likelyMultiplier = 1;
2056 error = Math.abs(theFloat - hypothesis);
2057 }
2058 if (error < 2 * precision) {
2059 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2060 if (complexity < minimumComplexity) {
2061 minimumComplexity = complexity;
2062 result = likelyMultiplier + " * (e ^ " + i + " ) / " + j;
2063 bestResultSoFar = [result, approx_rationalOfE, likelyMultiplier, i, j];
2064 }
2065 }
2066 }
2067 }
2068 return bestResultSoFar;
2069 };
2070
2071 approxRationalsOfPowersOfPI = function(theFloat) {
2072 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2073 splitBeforeAndAfterDot = theFloat.toString().split(".");
2074 if (splitBeforeAndAfterDot.length === 2) {
2075 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2076 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2077 } else {
2078 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2079 }
2080 console.log("precision: " + precision);
2081 bestResultSoFar = null;
2082 minimumComplexity = Number.MAX_VALUE;
2083 for (i = o = 1; o <= 5; i = ++o) {
2084 for (j = i1 = 1; i1 <= 12; j = ++i1) {
2085 hypothesis = Math.pow(Math.PI, i) / j;
2086 if (Math.abs(hypothesis) > 1e-10) {
2087 ratio = theFloat / hypothesis;
2088 likelyMultiplier = Math.round(ratio);
2089 error = Math.abs(1 - ratio / likelyMultiplier);
2090 } else {
2091 ratio = 1;
2092 likelyMultiplier = 1;
2093 error = Math.abs(theFloat - hypothesis);
2094 }
2095 if (error < 2 * precision) {
2096 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2097 if (complexity < minimumComplexity) {
2098 minimumComplexity = complexity;
2099 result = likelyMultiplier + " * (pi ^ " + i + " ) / " + j + " )";
2100 bestResultSoFar = [result, approx_rationalOfPi, likelyMultiplier, i, j];
2101 }
2102 }
2103 }
2104 }
2105 return bestResultSoFar;
2106 };
2107
2108 approxTrigonometric = function(theFloat) {
2109 var approxSineOfRationalMultiplesOfPIResult, approxSineOfRationalsResult, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
2110 splitBeforeAndAfterDot = theFloat.toString().split(".");
2111 if (splitBeforeAndAfterDot.length === 2) {
2112 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2113 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2114 } else {
2115 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2116 }
2117 console.log("precision: " + precision);
2118 approxSineOfRationalsResult = approxSineOfRationals(theFloat);
2119 if (approxSineOfRationalsResult != null) {
2120 return approxSineOfRationalsResult;
2121 }
2122 approxSineOfRationalMultiplesOfPIResult = approxSineOfRationalMultiplesOfPI(theFloat);
2123 if (approxSineOfRationalMultiplesOfPIResult != null) {
2124 return approxSineOfRationalMultiplesOfPIResult;
2125 }
2126 return null;
2127 };
2128
2129 approxSineOfRationals = function(theFloat) {
2130 var bestResultSoFar, complexity, error, fraction, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2131 splitBeforeAndAfterDot = theFloat.toString().split(".");
2132 if (splitBeforeAndAfterDot.length === 2) {
2133 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2134 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2135 } else {
2136 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2137 }
2138 console.log("precision: " + precision);
2139 bestResultSoFar = null;
2140 minimumComplexity = Number.MAX_VALUE;
2141 for (i = o = 1; o <= 4; i = ++o) {
2142 for (j = i1 = 1; i1 <= 4; j = ++i1) {
2143 fraction = i / j;
2144 hypothesis = Math.sin(fraction);
2145 if (Math.abs(hypothesis) > 1e-10) {
2146 ratio = theFloat / hypothesis;
2147 likelyMultiplier = Math.round(ratio);
2148 error = Math.abs(1 - ratio / likelyMultiplier);
2149 } else {
2150 ratio = 1;
2151 likelyMultiplier = 1;
2152 error = Math.abs(theFloat - hypothesis);
2153 }
2154 if (error < 2 * precision) {
2155 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2156 if (complexity < minimumComplexity) {
2157 minimumComplexity = complexity;
2158 result = likelyMultiplier + " * sin( " + i + "/" + j + " )";
2159 bestResultSoFar = [result, approx_sine_of_rational, likelyMultiplier, i, j];
2160 }
2161 }
2162 }
2163 }
2164 return bestResultSoFar;
2165 };
2166
2167 approxSineOfRationalMultiplesOfPI = function(theFloat) {
2168 var bestResultSoFar, complexity, error, fraction, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2169 splitBeforeAndAfterDot = theFloat.toString().split(".");
2170 if (splitBeforeAndAfterDot.length === 2) {
2171 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2172 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2173 } else {
2174 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2175 }
2176 console.log("precision: " + precision);
2177 bestResultSoFar = null;
2178 minimumComplexity = Number.MAX_VALUE;
2179 for (i = o = 1; o <= 13; i = ++o) {
2180 for (j = i1 = 1; i1 <= 13; j = ++i1) {
2181 fraction = i / j;
2182 hypothesis = Math.sin(Math.PI * fraction);
2183 if (Math.abs(hypothesis) > 1e-10) {
2184 ratio = theFloat / hypothesis;
2185 likelyMultiplier = Math.round(ratio);
2186 error = Math.abs(1 - ratio / likelyMultiplier);
2187 } else {
2188 ratio = 1;
2189 likelyMultiplier = 1;
2190 error = Math.abs(theFloat - hypothesis);
2191 }
2192 if (error < 23 * precision) {
2193 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2194 if (complexity < minimumComplexity) {
2195 minimumComplexity = complexity;
2196 result = likelyMultiplier + " * sin( " + i + "/" + j + " * pi )";
2197 bestResultSoFar = [result, approx_sine_of_pi_times_rational, likelyMultiplier, i, j];
2198 }
2199 }
2200 }
2201 }
2202 return bestResultSoFar;
2203 };
2204
2205 approxAll = function(theFloat) {
2206 var LOG_EXPLANATIONS, approxLogsResult, approxRadicalsResult, approxRationalsOfPowersOfEResult, approxRationalsOfPowersOfPIResult, approxTrigonometricResult, bestApproxSoFar, constantsSum, constantsSumMin, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
2207 splitBeforeAndAfterDot = theFloat.toString().split(".");
2208 if (splitBeforeAndAfterDot.length === 2) {
2209 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2210 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2211 } else {
2212 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2213 }
2214 console.log("precision: " + precision);
2215 constantsSumMin = Number.MAX_VALUE;
2216 constantsSum = 0;
2217 bestApproxSoFar = null;
2218 LOG_EXPLANATIONS = true;
2219 approxRadicalsResult = approxRadicals(theFloat);
2220 if (approxRadicalsResult != null) {
2221 constantsSum = simpleComplexityMeasure(approxRadicalsResult);
2222 if (constantsSum < constantsSumMin) {
2223 if (LOG_EXPLANATIONS) {
2224 console.log("better explanation by approxRadicals: " + approxRadicalsResult + " complexity: " + constantsSum);
2225 }
2226 constantsSumMin = constantsSum;
2227 bestApproxSoFar = approxRadicalsResult;
2228 } else {
2229 if (LOG_EXPLANATIONS) {
2230 console.log("subpar explanation by approxRadicals: " + approxRadicalsResult + " complexity: " + constantsSum);
2231 }
2232 }
2233 }
2234 approxLogsResult = approxLogs(theFloat);
2235 if (approxLogsResult != null) {
2236 constantsSum = simpleComplexityMeasure(approxLogsResult);
2237 if (constantsSum < constantsSumMin) {
2238 if (LOG_EXPLANATIONS) {
2239 console.log("better explanation by approxLogs: " + approxLogsResult + " complexity: " + constantsSum);
2240 }
2241 constantsSumMin = constantsSum;
2242 bestApproxSoFar = approxLogsResult;
2243 } else {
2244 if (LOG_EXPLANATIONS) {
2245 console.log("subpar explanation by approxLogs: " + approxLogsResult + " complexity: " + constantsSum);
2246 }
2247 }
2248 }
2249 approxRationalsOfPowersOfEResult = approxRationalsOfPowersOfE(theFloat);
2250 if (approxRationalsOfPowersOfEResult != null) {
2251 constantsSum = simpleComplexityMeasure(approxRationalsOfPowersOfEResult);
2252 if (constantsSum < constantsSumMin) {
2253 if (LOG_EXPLANATIONS) {
2254 console.log("better explanation by approxRationalsOfPowersOfE: " + approxRationalsOfPowersOfEResult + " complexity: " + constantsSum);
2255 }
2256 constantsSumMin = constantsSum;
2257 bestApproxSoFar = approxRationalsOfPowersOfEResult;
2258 } else {
2259 if (LOG_EXPLANATIONS) {
2260 console.log("subpar explanation by approxRationalsOfPowersOfE: " + approxRationalsOfPowersOfEResult + " complexity: " + constantsSum);
2261 }
2262 }
2263 }
2264 approxRationalsOfPowersOfPIResult = approxRationalsOfPowersOfPI(theFloat);
2265 if (approxRationalsOfPowersOfPIResult != null) {
2266 constantsSum = simpleComplexityMeasure(approxRationalsOfPowersOfPIResult);
2267 if (constantsSum < constantsSumMin) {
2268 if (LOG_EXPLANATIONS) {
2269 console.log("better explanation by approxRationalsOfPowersOfPI: " + approxRationalsOfPowersOfPIResult + " complexity: " + constantsSum);
2270 }
2271 constantsSumMin = constantsSum;
2272 bestApproxSoFar = approxRationalsOfPowersOfPIResult;
2273 } else {
2274 if (LOG_EXPLANATIONS) {
2275 console.log("subpar explanation by approxRationalsOfPowersOfPI: " + approxRationalsOfPowersOfPIResult + " complexity: " + constantsSum);
2276 }
2277 }
2278 }
2279 approxTrigonometricResult = approxTrigonometric(theFloat);
2280 if (approxTrigonometricResult != null) {
2281 constantsSum = simpleComplexityMeasure(approxTrigonometricResult);
2282 if (constantsSum < constantsSumMin) {
2283 if (LOG_EXPLANATIONS) {
2284 console.log("better explanation by approxTrigonometric: " + approxTrigonometricResult + " complexity: " + constantsSum);
2285 }
2286 constantsSumMin = constantsSum;
2287 bestApproxSoFar = approxTrigonometricResult;
2288 } else {
2289 if (LOG_EXPLANATIONS) {
2290 console.log("subpar explanation by approxTrigonometric: " + approxTrigonometricResult + " complexity: " + constantsSum);
2291 }
2292 }
2293 }
2294 return bestApproxSoFar;
2295 };
2296
2297 simpleComplexityMeasure = function(aResult, b, c) {
2298 var theSum;
2299 theSum = null;
2300 if (aResult instanceof Array) {
2301 switch (aResult[1]) {
2302 case approx_sine_of_pi_times_rational:
2303 theSum = 4;
2304 break;
2305 case approx_rationalOfPi:
2306 theSum = Math.pow(4, Math.abs(aResult[3])) * Math.abs(aResult[2]);
2307 break;
2308 case approx_rationalOfE:
2309 theSum = Math.pow(3, Math.abs(aResult[3])) * Math.abs(aResult[2]);
2310 break;
2311 default:
2312 theSum = 0;
2313 }
2314 theSum += Math.abs(aResult[2]) * (Math.abs(aResult[3]) + Math.abs(aResult[4]));
2315 } else {
2316 theSum += Math.abs(aResult) * (Math.abs(b) + Math.abs(c));
2317 }
2318 if (aResult[2] === 1) {
2319 theSum -= 1;
2320 } else {
2321 theSum += 1;
2322 }
2323 if (aResult[3] === 1) {
2324 theSum -= 1;
2325 } else {
2326 theSum += 1;
2327 }
2328 if (aResult[4] === 1) {
2329 theSum -= 1;
2330 } else {
2331 theSum += 1;
2332 }
2333 if (theSum < 0) {
2334 theSum = 0;
2335 }
2336 return theSum;
2337 };
2338
2339 testApprox = function() {
2340 var error, fraction, i, i1, i2, i3, j, j1, j2, j3, k3, l1, l2, l3, len, len1, len2, len3, len4, len5, len6, len7, m1, m2, m3, n1, n2, o, o1, o2, originalValue, q1, q2, r1, r2, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, returned, returnedFraction, returnedValue, s1, s2, t1, t2, u1, u2, v1, v2, value, x1, x2, z1, z2;
2341 ref = [2, 3, 5, 6, 7, 8, 10];
2342 for (o = 0, len = ref.length; o < len; o++) {
2343 i = ref[o];
2344 ref1 = [2, 3, 5, 6, 7, 8, 10];
2345 for (i1 = 0, len1 = ref1.length; i1 < len1; i1++) {
2346 j = ref1[i1];
2347 if (i === j) {
2348 continue;
2349 }
2350 console.log("testapproxRadicals testing: " + "1 * sqrt( " + i + " ) / " + j);
2351 fraction = i / j;
2352 value = Math.sqrt(i) / j;
2353 returned = approxRadicals(value);
2354 returnedValue = returned[2] * Math.sqrt(returned[3]) / returned[4];
2355 if (Math.abs(value - returnedValue) > 1e-15) {
2356 console.log("fail testapproxRadicals: " + "1 * sqrt( " + i + " ) / " + j + " . obtained: " + returned);
2357 }
2358 }
2359 }
2360 ref2 = [2, 3, 5, 6, 7, 8, 10];
2361 for (j1 = 0, len2 = ref2.length; j1 < len2; j1++) {
2362 i = ref2[j1];
2363 ref3 = [2, 3, 5, 6, 7, 8, 10];
2364 for (l1 = 0, len3 = ref3.length; l1 < len3; l1++) {
2365 j = ref3[l1];
2366 if (i === j) {
2367 continue;
2368 }
2369 console.log("testapproxRadicals testing with 4 digits: " + "1 * sqrt( " + i + " ) / " + j);
2370 fraction = i / j;
2371 originalValue = Math.sqrt(i) / j;
2372 value = originalValue.toFixed(4);
2373 returned = approxRadicals(value);
2374 returnedValue = returned[2] * Math.sqrt(returned[3]) / returned[4];
2375 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2376 console.log("fail testapproxRadicals with 4 digits: " + "1 * sqrt( " + i + " ) / " + j + " . obtained: " + returned);
2377 }
2378 }
2379 }
2380 ref4 = [2, 3, 5, 6, 7, 8, 10];
2381 for (m1 = 0, len4 = ref4.length; m1 < len4; m1++) {
2382 i = ref4[m1];
2383 ref5 = [2, 3, 5, 6, 7, 8, 10];
2384 for (n1 = 0, len5 = ref5.length; n1 < len5; n1++) {
2385 j = ref5[n1];
2386 if (i === j) {
2387 continue;
2388 }
2389 console.log("testapproxRadicals testing: " + "1 * sqrt( " + i + " / " + j + " )");
2390 fraction = i / j;
2391 value = Math.sqrt(i / j);
2392 returned = approxRadicals(value);
2393 if (returned != null) {
2394 returnedValue = returned[2] * Math.sqrt(returned[3] / returned[4]);
2395 if (returned[1] === approx_radicalOfRatio && Math.abs(value - returnedValue) > 1e-15) {
2396 console.log("fail testapproxRadicals: " + "1 * sqrt( " + i + " / " + j + " ) . obtained: " + returned);
2397 }
2398 }
2399 }
2400 }
2401 ref6 = [1, 2, 3, 5, 6, 7, 8, 10];
2402 for (o1 = 0, len6 = ref6.length; o1 < len6; o1++) {
2403 i = ref6[o1];
2404 ref7 = [1, 2, 3, 5, 6, 7, 8, 10];
2405 for (q1 = 0, len7 = ref7.length; q1 < len7; q1++) {
2406 j = ref7[q1];
2407 if (i === 1 && j === 1) {
2408 continue;
2409 }
2410 console.log("testapproxRadicals testing with 4 digits:: " + "1 * sqrt( " + i + " / " + j + " )");
2411 fraction = i / j;
2412 originalValue = Math.sqrt(i / j);
2413 value = originalValue.toFixed(4);
2414 returned = approxRadicals(value);
2415 returnedValue = returned[2] * Math.sqrt(returned[3] / returned[4]);
2416 if (returned[1] === approx_radicalOfRatio && Math.abs(originalValue - returnedValue) > 1e-15) {
2417 console.log("fail testapproxRadicals with 4 digits:: " + "1 * sqrt( " + i + " / " + j + " ) . obtained: " + returned);
2418 }
2419 }
2420 }
2421 for (i = r1 = 1; r1 <= 5; i = ++r1) {
2422 for (j = s1 = 1; s1 <= 5; j = ++s1) {
2423 console.log("testApproxAll testing: " + "1 * log(" + i + " ) / " + j);
2424 fraction = i / j;
2425 value = Math.log(i) / j;
2426 returned = approxAll(value);
2427 returnedValue = returned[2] * Math.log(returned[3]) / returned[4];
2428 if (Math.abs(value - returnedValue) > 1e-15) {
2429 console.log("fail testApproxAll: " + "1 * log(" + i + " ) / " + j + " . obtained: " + returned);
2430 }
2431 }
2432 }
2433 for (i = t1 = 1; t1 <= 5; i = ++t1) {
2434 for (j = u1 = 1; u1 <= 5; j = ++u1) {
2435 console.log("testApproxAll testing with 4 digits: " + "1 * log(" + i + " ) / " + j);
2436 fraction = i / j;
2437 originalValue = Math.log(i) / j;
2438 value = originalValue.toFixed(4);
2439 returned = approxAll(value);
2440 returnedValue = returned[2] * Math.log(returned[3]) / returned[4];
2441 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2442 console.log("fail testApproxAll with 4 digits: " + "1 * log(" + i + " ) / " + j + " . obtained: " + returned);
2443 }
2444 }
2445 }
2446 for (i = v1 = 1; v1 <= 5; i = ++v1) {
2447 for (j = x1 = 1; x1 <= 5; j = ++x1) {
2448 console.log("testApproxAll testing: " + "1 * log(" + i + " / " + j + " )");
2449 fraction = i / j;
2450 value = Math.log(i / j);
2451 returned = approxAll(value);
2452 returnedValue = returned[2] * Math.log(returned[3] / returned[4]);
2453 if (Math.abs(value - returnedValue) > 1e-15) {
2454 console.log("fail testApproxAll: " + "1 * log(" + i + " / " + j + " )" + " . obtained: " + returned);
2455 }
2456 }
2457 }
2458 for (i = z1 = 1; z1 <= 5; i = ++z1) {
2459 for (j = i2 = 1; i2 <= 5; j = ++i2) {
2460 console.log("testApproxAll testing with 4 digits: " + "1 * log(" + i + " / " + j + " )");
2461 fraction = i / j;
2462 originalValue = Math.log(i / j);
2463 value = originalValue.toFixed(4);
2464 returned = approxAll(value);
2465 returnedValue = returned[2] * Math.log(returned[3] / returned[4]);
2466 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2467 console.log("fail testApproxAll with 4 digits: " + "1 * log(" + i + " / " + j + " )" + " . obtained: " + returned);
2468 }
2469 }
2470 }
2471 for (i = j2 = 1; j2 <= 2; i = ++j2) {
2472 for (j = l2 = 1; l2 <= 12; j = ++l2) {
2473 console.log("testApproxAll testing: " + "1 * (e ^ " + i + " ) / " + j);
2474 fraction = i / j;
2475 value = Math.pow(Math.E, i) / j;
2476 returned = approxAll(value);
2477 returnedValue = returned[2] * Math.pow(Math.E, returned[3]) / returned[4];
2478 if (Math.abs(value - returnedValue) > 1e-15) {
2479 console.log("fail testApproxAll: " + "1 * (e ^ " + i + " ) / " + j + " . obtained: " + returned);
2480 }
2481 }
2482 }
2483 for (i = m2 = 1; m2 <= 2; i = ++m2) {
2484 for (j = n2 = 1; n2 <= 12; j = ++n2) {
2485 console.log("approxRationalsOfPowersOfE testing with 4 digits: " + "1 * (e ^ " + i + " ) / " + j);
2486 fraction = i / j;
2487 originalValue = Math.pow(Math.E, i) / j;
2488 value = originalValue.toFixed(4);
2489 returned = approxRationalsOfPowersOfE(value);
2490 returnedValue = returned[2] * Math.pow(Math.E, returned[3]) / returned[4];
2491 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2492 console.log("fail approxRationalsOfPowersOfE with 4 digits: " + "1 * (e ^ " + i + " ) / " + j + " . obtained: " + returned);
2493 }
2494 }
2495 }
2496 for (i = o2 = 1; o2 <= 2; i = ++o2) {
2497 for (j = q2 = 1; q2 <= 12; j = ++q2) {
2498 console.log("testApproxAll testing: " + "1 * pi ^ " + i + " / " + j);
2499 fraction = i / j;
2500 value = Math.pow(Math.PI, i) / j;
2501 returned = approxAll(value);
2502 returnedValue = returned[2] * Math.pow(Math.PI, returned[3]) / returned[4];
2503 if (Math.abs(value - returnedValue) > 1e-15) {
2504 console.log("fail testApproxAll: " + "1 * pi ^ " + i + " / " + j + " ) . obtained: " + returned);
2505 }
2506 }
2507 }
2508 for (i = r2 = 1; r2 <= 2; i = ++r2) {
2509 for (j = s2 = 1; s2 <= 12; j = ++s2) {
2510 console.log("approxRationalsOfPowersOfPI testing with 4 digits: " + "1 * pi ^ " + i + " / " + j);
2511 fraction = i / j;
2512 originalValue = Math.pow(Math.PI, i) / j;
2513 value = originalValue.toFixed(4);
2514 returned = approxRationalsOfPowersOfPI(value);
2515 returnedValue = returned[2] * Math.pow(Math.PI, returned[3]) / returned[4];
2516 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2517 console.log("fail approxRationalsOfPowersOfPI with 4 digits: " + "1 * pi ^ " + i + " / " + j + " ) . obtained: " + returned);
2518 }
2519 }
2520 }
2521 for (i = t2 = 1; t2 <= 4; i = ++t2) {
2522 for (j = u2 = 1; u2 <= 4; j = ++u2) {
2523 console.log("testApproxAll testing: " + "1 * sin( " + i + "/" + j + " )");
2524 fraction = i / j;
2525 value = Math.sin(fraction);
2526 returned = approxAll(value);
2527 returnedFraction = returned[3] / returned[4];
2528 returnedValue = returned[2] * Math.sin(returnedFraction);
2529 if (Math.abs(value - returnedValue) > 1e-15) {
2530 console.log("fail testApproxAll: " + "1 * sin( " + i + "/" + j + " ) . obtained: " + returned);
2531 }
2532 }
2533 }
2534 for (i = v2 = 1; v2 <= 4; i = ++v2) {
2535 for (j = x2 = 1; x2 <= 4; j = ++x2) {
2536 console.log("testApproxAll testing with 5 digits: " + "1 * sin( " + i + "/" + j + " )");
2537 fraction = i / j;
2538 originalValue = Math.sin(fraction);
2539 value = originalValue.toFixed(5);
2540 returned = approxAll(value);
2541 if (returned == null) {
2542 console.log("fail testApproxAll with 5 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: undefined ");
2543 }
2544 returnedFraction = returned[3] / returned[4];
2545 returnedValue = returned[2] * Math.sin(returnedFraction);
2546 error = Math.abs(originalValue - returnedValue);
2547 if (error > 1e-14) {
2548 console.log("fail testApproxAll with 5 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: " + returned + " error: " + error);
2549 }
2550 }
2551 }
2552 for (i = z2 = 1; z2 <= 4; i = ++z2) {
2553 for (j = i3 = 1; i3 <= 4; j = ++i3) {
2554 console.log("testApproxAll testing with 4 digits: " + "1 * sin( " + i + "/" + j + " )");
2555 fraction = i / j;
2556 originalValue = Math.sin(fraction);
2557 value = originalValue.toFixed(4);
2558 returned = approxAll(value);
2559 if (returned == null) {
2560 console.log("fail testApproxAll with 4 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: undefined ");
2561 }
2562 returnedFraction = returned[3] / returned[4];
2563 returnedValue = returned[2] * Math.sin(returnedFraction);
2564 error = Math.abs(originalValue - returnedValue);
2565 if (error > 1e-14) {
2566 console.log("fail testApproxAll with 4 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: " + returned + " error: " + error);
2567 }
2568 }
2569 }
2570 value = 0;
2571 if (approxAll(value)[0] !== "0") {
2572 console.log("fail testApproxAll: 0");
2573 }
2574 value = 0.0;
2575 if (approxAll(value)[0] !== "0") {
2576 console.log("fail testApproxAll: 0.0");
2577 }
2578 value = 0.00;
2579 if (approxAll(value)[0] !== "0") {
2580 console.log("fail testApproxAll: 0.00");
2581 }
2582 value = 0.000;
2583 if (approxAll(value)[0] !== "0") {
2584 console.log("fail testApproxAll: 0.000");
2585 }
2586 value = 0.0000;
2587 if (approxAll(value)[0] !== "0") {
2588 console.log("fail testApproxAll: 0.0000");
2589 }
2590 value = 1;
2591 if (approxAll(value)[0] !== "1") {
2592 console.log("fail testApproxAll: 1");
2593 }
2594 value = 1.0;
2595 if (approxAll(value)[0] !== "1") {
2596 console.log("fail testApproxAll: 1.0");
2597 }
2598 value = 1.00;
2599 if (approxAll(value)[0] !== "1") {
2600 console.log("fail testApproxAll: 1.00");
2601 }
2602 value = 1.000;
2603 if (approxAll(value)[0] !== "1") {
2604 console.log("fail testApproxAll: 1.000");
2605 }
2606 value = 1.0000;
2607 if (approxAll(value)[0] !== "1") {
2608 console.log("fail testApproxAll: 1.0000");
2609 }
2610 value = 1.00000;
2611 if (approxAll(value)[0] !== "1") {
2612 console.log("fail testApproxAll: 1.00000");
2613 }
2614 value = Math.sqrt(2);
2615 if (approxAll(value)[0] !== "1 * sqrt( 2 ) / 1") {
2616 console.log("fail testApproxAll: Math.sqrt(2)");
2617 }
2618 value = 1.41;
2619 if (approxAll(value)[0] !== "1 * sqrt( 2 ) / 1") {
2620 console.log("fail testApproxAll: 1.41");
2621 }
2622 value = 1.4;
2623 if (approxRadicals(value)[0] !== "1 * sqrt( 2 ) / 1") {
2624 console.log("fail approxRadicals: 1.4");
2625 }
2626 value = 0.6;
2627 if (approxLogs(value)[0] !== "1 * log( 2 ) / 1") {
2628 console.log("fail approxLogs: 0.6");
2629 }
2630 value = 0.69;
2631 if (approxLogs(value)[0] !== "1 * log( 2 ) / 1") {
2632 console.log("fail approxLogs: 0.69");
2633 }
2634 value = 0.7;
2635 if (approxLogs(value)[0] !== "1 * log( 2 ) / 1") {
2636 console.log("fail approxLogs: 0.7");
2637 }
2638 value = 1.09;
2639 if (approxLogs(value)[0] !== "1 * log( 3 ) / 1") {
2640 console.log("fail approxLogs: 1.09");
2641 }
2642 value = 1.09;
2643 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2644 console.log("fail approxAll: 1.09");
2645 }
2646 value = 1.098;
2647 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2648 console.log("fail approxAll: 1.098");
2649 }
2650 value = 1.1;
2651 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2652 console.log("fail approxAll: 1.1");
2653 }
2654 value = 1.11;
2655 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2656 console.log("fail approxAll: 1.11");
2657 }
2658 value = Math.sqrt(3);
2659 if (approxAll(value)[0] !== "1 * sqrt( 3 ) / 1") {
2660 console.log("fail testApproxAll: Math.sqrt(3)");
2661 }
2662 value = 1.0000;
2663 if (approxAll(value)[0] !== "1") {
2664 console.log("fail testApproxAll: 1.0000");
2665 }
2666 value = 3.141592;
2667 if (approxAll(value)[0] !== "1 * (pi ^ 1 ) / 1 )") {
2668 console.log("fail testApproxAll: 3.141592");
2669 }
2670 value = 31.41592;
2671 if (approxAll(value)[0] !== "10 * (pi ^ 1 ) / 1 )") {
2672 console.log("fail testApproxAll: 31.41592");
2673 }
2674 value = 314.1592;
2675 if (approxAll(value)[0] !== "100 * (pi ^ 1 ) / 1 )") {
2676 console.log("fail testApproxAll: 314.1592");
2677 }
2678 value = 31415926.53589793;
2679 if (approxAll(value)[0] !== "10000000 * (pi ^ 1 ) / 1 )") {
2680 console.log("fail testApproxAll: 31415926.53589793");
2681 }
2682 value = Math.sqrt(2);
2683 if (approxTrigonometric(value)[0] !== "2 * sin( 1/4 * pi )") {
2684 console.log("fail approxTrigonometric: Math.sqrt(2)");
2685 }
2686 value = Math.sqrt(3);
2687 if (approxTrigonometric(value)[0] !== "2 * sin( 1/3 * pi )") {
2688 console.log("fail approxTrigonometric: Math.sqrt(3)");
2689 }
2690 value = (Math.sqrt(6) - Math.sqrt(2)) / 4;
2691 if (approxAll(value)[0] !== "1 * sin( 1/12 * pi )") {
2692 console.log("fail testApproxAll: (Math.sqrt(6) - Math.sqrt(2))/4");
2693 }
2694 value = Math.sqrt(2 - Math.sqrt(2)) / 2;
2695 if (approxAll(value)[0] !== "1 * sin( 1/8 * pi )") {
2696 console.log("fail testApproxAll: Math.sqrt(2 - Math.sqrt(2))/2");
2697 }
2698 value = (Math.sqrt(6) + Math.sqrt(2)) / 4;
2699 if (approxAll(value)[0] !== "1 * sin( 5/12 * pi )") {
2700 console.log("fail testApproxAll: (Math.sqrt(6) + Math.sqrt(2))/4");
2701 }
2702 value = Math.sqrt(2 + Math.sqrt(3)) / 2;
2703 if (approxAll(value)[0] !== "1 * sin( 5/12 * pi )") {
2704 console.log("fail testApproxAll: Math.sqrt(2 + Math.sqrt(3))/2");
2705 }
2706 value = (Math.sqrt(5) - 1) / 4;
2707 if (approxAll(value)[0] !== "1 * sin( 1/10 * pi )") {
2708 console.log("fail testApproxAll: (Math.sqrt(5) - 1)/4");
2709 }
2710 value = Math.sqrt(10 - 2 * Math.sqrt(5)) / 4;
2711 if (approxAll(value)[0] !== "1 * sin( 1/5 * pi )") {
2712 console.log("fail testApproxAll: Math.sqrt(10 - 2*Math.sqrt(5))/4");
2713 }
2714 value = Math.sin(Math.PI / 7);
2715 if (approxAll(value)[0] !== "1 * sin( 1/7 * pi )") {
2716 console.log("fail testApproxAll: Math.sin(Math.PI/7)");
2717 }
2718 value = Math.sin(Math.PI / 9);
2719 if (approxAll(value)[0] !== "1 * sin( 1/9 * pi )") {
2720 console.log("fail testApproxAll: Math.sin(Math.PI/9)");
2721 }
2722 value = 1836.15267;
2723 if (approxRationalsOfPowersOfPI(value)[0] !== "6 * (pi ^ 5 ) / 1 )") {
2724 console.log("fail approxRationalsOfPowersOfPI: 1836.15267");
2725 }
2726 for (i = j3 = 1; j3 <= 13; i = ++j3) {
2727 for (j = k3 = 1; k3 <= 13; j = ++k3) {
2728 console.log("approxTrigonometric testing: " + "1 * sin( " + i + "/" + j + " * pi )");
2729 fraction = i / j;
2730 value = Math.sin(Math.PI * fraction);
2731 returned = approxTrigonometric(value);
2732 returnedFraction = returned[3] / returned[4];
2733 returnedValue = returned[2] * Math.sin(Math.PI * returnedFraction);
2734 if (Math.abs(value - returnedValue) > 1e-15) {
2735 console.log("fail approxTrigonometric: " + "1 * sin( " + i + "/" + j + " * pi ) . obtained: " + returned);
2736 }
2737 }
2738 }
2739 for (i = l3 = 1; l3 <= 13; i = ++l3) {
2740 for (j = m3 = 1; m3 <= 13; j = ++m3) {
2741 if (i === 5 && j === 11 || i === 6 && j === 11) {
2742 continue;
2743 }
2744 console.log("approxTrigonometric testing with 4 digits: " + "1 * sin( " + i + "/" + j + " * pi )");
2745 fraction = i / j;
2746 originalValue = Math.sin(Math.PI * fraction);
2747 value = originalValue.toFixed(4);
2748 returned = approxTrigonometric(value);
2749 returnedFraction = returned[3] / returned[4];
2750 returnedValue = returned[2] * Math.sin(Math.PI * returnedFraction);
2751 error = Math.abs(originalValue - returnedValue);
2752 if (error > 1e-14) {
2753 console.log("fail approxTrigonometric with 4 digits: " + "1 * sin( " + i + "/" + j + " * pi ) . obtained: " + returned + " error: " + error);
2754 }
2755 }
2756 }
2757 return console.log("testApprox done");
2758 };
2759
2760 $.approxRadicals = approxRadicals;
2761
2762 $.approxRationalsOfLogs = approxRationalsOfLogs;
2763
2764 $.approxAll = approxAll;
2765
2766 $.testApprox = testApprox;
2767
2768
2769 /* arccos =====================================================================
2770
2771 Tags
2772 ----
2773 scripting, JS, internal, treenode, general concept
2774
2775 Parameters
2776 ----------
2777 x
2778
2779 General description
2780 -------------------
2781 Returns the inverse cosine of x.
2782 */
2783
2784 Eval_arccos = function() {
2785 push(cadr(p1));
2786 Eval();
2787 return arccos();
2788 };
2789
2790 arccos = function() {
2791 var d, errno, n;
2792 n = 0;
2793 d = 0.0;
2794 save();
2795 p1 = pop();
2796 if (car(p1) === symbol(COS)) {
2797 push(cadr(p1));
2798 restore();
2799 return;
2800 }
2801 if (isdouble(p1)) {
2802 errno = 0;
2803 d = Math.acos(p1.d);
2804 if (errno) {
2805 stop("arccos function argument is not in the interval [-1,1]");
2806 }
2807 push_double(d);
2808 restore();
2809 return;
2810 }
2811 if ((isoneoversqrttwo(p1)) || (car(p1) === symbol(MULTIPLY) && equalq(car(cdr(p1)), 1, 2) && car(car(cdr(cdr(p1)))) === symbol(POWER) && equaln(car(cdr(car(cdr(cdr(p1))))), 2) && equalq(car(cdr(cdr(car(cdr(cdr(p1)))))), 1, 2))) {
2812 if (evaluatingAsFloats) {
2813 push_double(Math.PI / 4.0);
2814 } else {
2815 push_rational(1, 4);
2816 push_symbol(PI);
2817 multiply();
2818 }
2819 restore();
2820 return;
2821 }
2822 if ((isminusoneoversqrttwo(p1)) || (car(p1) === symbol(MULTIPLY) && equalq(car(cdr(p1)), -1, 2) && car(car(cdr(cdr(p1)))) === symbol(POWER) && equaln(car(cdr(car(cdr(cdr(p1))))), 2) && equalq(car(cdr(cdr(car(cdr(cdr(p1)))))), 1, 2))) {
2823 if (evaluatingAsFloats) {
2824 push_double(Math.PI * 3.0 / 4.0);
2825 } else {
2826 push_rational(3, 4);
2827 push_symbol(PI);
2828 multiply();
2829 }
2830 restore();
2831 return;
2832 }
2833 if (!isrational(p1)) {
2834 push_symbol(ARCCOS);
2835 push(p1);
2836 list(2);
2837 restore();
2838 return;
2839 }
2840 push(p1);
2841 push_integer(2);
2842 multiply();
2843 n = pop_integer();
2844 switch (n) {
2845 case -2:
2846 if (evaluatingAsFloats) {
2847 push_double(Math.PI);
2848 } else {
2849 push_symbol(PI);
2850 }
2851 break;
2852 case -1:
2853 if (evaluatingAsFloats) {
2854 push_double(Math.PI * 2.0 / 3.0);
2855 } else {
2856 push_rational(2, 3);
2857 push_symbol(PI);
2858 multiply();
2859 }
2860 break;
2861 case 0:
2862 if (evaluatingAsFloats) {
2863 push_double(Math.PI / 2.0);
2864 } else {
2865 push_rational(1, 2);
2866 push_symbol(PI);
2867 multiply();
2868 }
2869 break;
2870 case 1:
2871 if (evaluatingAsFloats) {
2872 push_double(Math.PI / 3.0);
2873 } else {
2874 push_rational(1, 3);
2875 push_symbol(PI);
2876 multiply();
2877 }
2878 break;
2879 case 2:
2880 if (evaluatingAsFloats) {
2881 push_double(0.0);
2882 } else {
2883 push(zero);
2884 }
2885 break;
2886 default:
2887 push_symbol(ARCCOS);
2888 push(p1);
2889 list(2);
2890 }
2891 return restore();
2892 };
2893
2894
2895 /* arccosh =====================================================================
2896
2897 Tags
2898 ----
2899 scripting, JS, internal, treenode, general concept
2900
2901 Parameters
2902 ----------
2903 x
2904
2905 General description
2906 -------------------
2907 Returns the inverse hyperbolic cosine of x.
2908 */
2909
2910 Eval_arccosh = function() {
2911 push(cadr(p1));
2912 Eval();
2913 return arccosh();
2914 };
2915
2916 arccosh = function() {
2917 var d;
2918 d = 0.0;
2919 save();
2920 p1 = pop();
2921 if (car(p1) === symbol(COSH)) {
2922 push(cadr(p1));
2923 restore();
2924 return;
2925 }
2926 if (isdouble(p1)) {
2927 d = p1.d;
2928 if (d < 1.0) {
2929 stop("arccosh function argument is less than 1.0");
2930 }
2931 d = Math.log(d + Math.sqrt(d * d - 1.0));
2932 push_double(d);
2933 restore();
2934 return;
2935 }
2936 if (isplusone(p1)) {
2937 push(zero);
2938 restore();
2939 return;
2940 }
2941 push_symbol(ARCCOSH);
2942 push(p1);
2943 list(2);
2944 return restore();
2945 };
2946
2947
2948 /* arcsin =====================================================================
2949
2950 Tags
2951 ----
2952 scripting, JS, internal, treenode, general concept
2953
2954 Parameters
2955 ----------
2956 x
2957
2958 General description
2959 -------------------
2960 Returns the inverse sine of x.
2961 */
2962
2963 Eval_arcsin = function() {
2964 push(cadr(p1));
2965 Eval();
2966 return arcsin();
2967 };
2968
2969 arcsin = function() {
2970 var d, errno, n;
2971 n = 0;
2972 d = 0;
2973 save();
2974 p1 = pop();
2975 if (car(p1) === symbol(SIN)) {
2976 push(cadr(p1));
2977 restore();
2978 return;
2979 }
2980 if (isdouble(p1)) {
2981 errno = 0;
2982 d = Math.asin(p1.d);
2983 if (errno) {
2984 stop("arcsin function argument is not in the interval [-1,1]");
2985 }
2986 push_double(d);
2987 restore();
2988 return;
2989 }
2990 if ((isoneoversqrttwo(p1)) || (car(p1) === symbol(MULTIPLY) && equalq(car(cdr(p1)), 1, 2) && car(car(cdr(cdr(p1)))) === symbol(POWER) && equaln(car(cdr(car(cdr(cdr(p1))))), 2) && equalq(car(cdr(cdr(car(cdr(cdr(p1)))))), 1, 2))) {
2991 push_rational(1, 4);
2992 push_symbol(PI);
2993 multiply();
2994 restore();
2995 return;
2996 }
2997 if ((isminusoneoversqrttwo(p1)) || (car(p1) === symbol(MULTIPLY) && equalq(car(cdr(p1)), -1, 2) && car(car(cdr(cdr(p1)))) === symbol(POWER) && equaln(car(cdr(car(cdr(cdr(p1))))), 2) && equalq(car(cdr(cdr(car(cdr(cdr(p1)))))), 1, 2))) {
2998 if (evaluatingAsFloats) {
2999 push_double(-Math.PI / 4.0);
3000 } else {
3001 push_rational(-1, 4);
3002 push_symbol(PI);
3003 multiply();
3004 }
3005 restore();
3006 return;
3007 }
3008 if (!isrational(p1)) {
3009 push_symbol(ARCSIN);
3010 push(p1);
3011 list(2);
3012 restore();
3013 return;
3014 }
3015 push(p1);
3016 push_integer(2);
3017 multiply();
3018 n = pop_integer();
3019 switch (n) {
3020 case -2:
3021 if (evaluatingAsFloats) {
3022 push_double(-Math.PI / 2.0);
3023 } else {
3024 push_rational(-1, 2);
3025 push_symbol(PI);
3026 multiply();
3027 }
3028 break;
3029 case -1:
3030 if (evaluatingAsFloats) {
3031 push_double(-Math.PI / 6.0);
3032 } else {
3033 push_rational(-1, 6);
3034 push_symbol(PI);
3035 multiply();
3036 }
3037 break;
3038 case 0:
3039 if (evaluatingAsFloats) {
3040 push_double(0.0);
3041 } else {
3042 push(zero);
3043 }
3044 break;
3045 case 1:
3046 if (evaluatingAsFloats) {
3047 push_double(Math.PI / 6.0);
3048 } else {
3049 push_rational(1, 6);
3050 push_symbol(PI);
3051 multiply();
3052 }
3053 break;
3054 case 2:
3055 if (evaluatingAsFloats) {
3056 push_double(Math.PI / 2.0);
3057 } else {
3058 push_rational(1, 2);
3059 push_symbol(PI);
3060 multiply();
3061 }
3062 break;
3063 default:
3064 push_symbol(ARCSIN);
3065 push(p1);
3066 list(2);
3067 }
3068 return restore();
3069 };
3070
3071
3072 /* arcsinh =====================================================================
3073
3074 Tags
3075 ----
3076 scripting, JS, internal, treenode, general concept
3077
3078 Parameters
3079 ----------
3080 x
3081
3082 General description
3083 -------------------
3084 Returns the inverse hyperbolic sine of x.
3085 */
3086
3087 Eval_arcsinh = function() {
3088 push(cadr(p1));
3089 Eval();
3090 return arcsinh();
3091 };
3092
3093 arcsinh = function() {
3094 var d;
3095 d = 0.0;
3096 save();
3097 p1 = pop();
3098 if (car(p1) === symbol(SINH)) {
3099 push(cadr(p1));
3100 restore();
3101 return;
3102 }
3103 if (isdouble(p1)) {
3104 d = p1.d;
3105 d = Math.log(d + Math.sqrt(d * d + 1.0));
3106 push_double(d);
3107 restore();
3108 return;
3109 }
3110 if (iszero(p1)) {
3111 push(zero);
3112 restore();
3113 return;
3114 }
3115 push_symbol(ARCSINH);
3116 push(p1);
3117 list(2);
3118 return restore();
3119 };
3120
3121
3122 /* arctan =====================================================================
3123
3124 Tags
3125 ----
3126 scripting, JS, internal, treenode, general concept
3127
3128 Parameters
3129 ----------
3130 x
3131
3132 General description
3133 -------------------
3134 Returns the inverse tangent of x.
3135 */
3136
3137 Eval_arctan = function() {
3138 push(cadr(p1));
3139 Eval();
3140 return arctan();
3141 };
3142
3143 arctan = function() {
3144 var d, errno;
3145 d = 0;
3146 save();
3147 p1 = pop();
3148 if (car(p1) === symbol(TAN)) {
3149 push(cadr(p1));
3150 restore();
3151 return;
3152 }
3153 if (isdouble(p1)) {
3154 errno = 0;
3155 d = Math.atan(p1.d);
3156 if (errno) {
3157 stop("arctan function error");
3158 }
3159 push_double(d);
3160 restore();
3161 return;
3162 }
3163 if (iszero(p1)) {
3164 push(zero);
3165 restore();
3166 return;
3167 }
3168 if (isnegative(p1)) {
3169 push(p1);
3170 negate();
3171 arctan();
3172 negate();
3173 restore();
3174 return;
3175 }
3176 if (Find(p1, symbol(SIN)) && Find(p1, symbol(COS))) {
3177 push(p1);
3178 numerator();
3179 p2 = pop();
3180 push(p1);
3181 denominator();
3182 p3 = pop();
3183 if (car(p2) === symbol(SIN) && car(p3) === symbol(COS) && equal(cadr(p2), cadr(p3))) {
3184 push(cadr(p2));
3185 restore();
3186 return;
3187 }
3188 }
3189 if ((car(p1) === symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), -1, 2)) || (car(p1) === symbol(MULTIPLY) && equalq(car(cdr(p1)), 1, 3) && car(car(cdr(cdr(p1)))) === symbol(POWER) && equaln(car(cdr(car(cdr(cdr(p1))))), 3) && equalq(car(cdr(cdr(car(cdr(cdr(p1)))))), 1, 2))) {
3190 push_rational(1, 6);
3191 if (evaluatingAsFloats) {
3192 push_double(Math.PI);
3193 } else {
3194 push(symbol(PI));
3195 }
3196 multiply();
3197 restore();
3198 return;
3199 }
3200 if (equaln(p1, 1)) {
3201 push_rational(1, 4);
3202 if (evaluatingAsFloats) {
3203 push_double(Math.PI);
3204 } else {
3205 push(symbol(PI));
3206 }
3207 multiply();
3208 restore();
3209 return;
3210 }
3211 if (car(p1) === symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), 1, 2)) {
3212 push_rational(1, 3);
3213 if (evaluatingAsFloats) {
3214 push_double(Math.PI);
3215 } else {
3216 push(symbol(PI));
3217 }
3218 multiply();
3219 restore();
3220 return;
3221 }
3222 push_symbol(ARCTAN);
3223 push(p1);
3224 list(2);
3225 return restore();
3226 };
3227
3228
3229 /* arctanh =====================================================================
3230
3231 Tags
3232 ----
3233 scripting, JS, internal, treenode, general concept
3234
3235 Parameters
3236 ----------
3237 x
3238
3239 General description
3240 -------------------
3241 Returns the inverse hyperbolic tangent of x.
3242 */
3243
3244 Eval_arctanh = function() {
3245 push(cadr(p1));
3246 Eval();
3247 return arctanh();
3248 };
3249
3250 arctanh = function() {
3251 var d;
3252 d = 0.0;
3253 save();
3254 p1 = pop();
3255 if (car(p1) === symbol(TANH)) {
3256 push(cadr(p1));
3257 restore();
3258 return;
3259 }
3260 if (isdouble(p1)) {
3261 d = p1.d;
3262 if (d < -1.0 || d > 1.0) {
3263 stop("arctanh function argument is not in the interval [-1,1]");
3264 }
3265 d = Math.log((1.0 + d) / (1.0 - d)) / 2.0;
3266 push_double(d);
3267 restore();
3268 return;
3269 }
3270 if (iszero(p1)) {
3271 push(zero);
3272 restore();
3273 return;
3274 }
3275 push_symbol(ARCTANH);
3276 push(p1);
3277 list(2);
3278 return restore();
3279 };
3280
3281
3282 /* arg =====================================================================
3283
3284 Tags
3285 ----
3286 scripting, JS, internal, treenode, general concept
3287
3288 Parameters
3289 ----------
3290 z
3291
3292 General description
3293 -------------------
3294 Returns the angle of complex z.
3295 */
3296
3297
3298 /*
3299 Argument (angle) of complex z
3300
3301 z arg(z)
3302 - ------
3303
3304 a 0
3305
3306 -a -pi See note 3 below
3307
3308 (-1)^a a pi
3309
3310 exp(a + i b) b
3311
3312 a b arg(a) + arg(b)
3313
3314 a + i b arctan(b/a)
3315
3316 Result by quadrant
3317
3318 z arg(z)
3319 - ------
3320
3321 1 + i 1/4 pi
3322
3323 1 - i -1/4 pi
3324
3325 -1 + i 3/4 pi
3326
3327 -1 - i -3/4 pi
3328
3329 Notes
3330
3331 1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3)
3332
3333 2. Symbols in z are assumed to be positive and real.
3334
3335 3. Negative direction adds -pi to angle.
3336
3337 Example: z = (-1)^(1/3), abs(z) = 1/3 pi, abs(-z) = -2/3 pi
3338
3339 4. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then
3340
3341 arg(numerator(z)) - arg(denominator(z))
3342
3343 must be used to get the correct answer. Now the operation is
3344 automatic.
3345 */
3346
3347 DEBUG_ARG = false;
3348
3349 Eval_arg = function() {
3350 push(cadr(p1));
3351 Eval();
3352 return arg();
3353 };
3354
3355 arg = function() {
3356 save();
3357 p1 = pop();
3358 push(p1);
3359 numerator();
3360 yyarg();
3361 push(p1);
3362 denominator();
3363 yyarg();
3364 subtract();
3365 return restore();
3366 };
3367
3368 yyarg = function() {
3369 save();
3370 p1 = pop();
3371 if (ispositivenumber(p1) || p1 === symbol(PI)) {
3372 if (isdouble(p1) || evaluatingAsFloats) {
3373 push_double(0);
3374 } else {
3375 push_integer(0);
3376 }
3377 } else if (isnegativenumber(p1)) {
3378 if (isdouble(p1) || evaluatingAsFloats) {
3379 push_double(Math.PI);
3380 } else {
3381 push(symbol(PI));
3382 }
3383 negate();
3384 } else if (issymbol(p1)) {
3385 push_symbol(ARG);
3386 push(p1);
3387 list(2);
3388 } else if (car(p1) === symbol(POWER) && equaln(cadr(p1), -1)) {
3389 if (evaluatingAsFloats) {
3390 push_double(Math.PI);
3391 } else {
3392 push(symbol(PI));
3393 }
3394 push(caddr(p1));
3395 multiply();
3396 } else if (car(p1) === symbol(POWER) && cadr(p1) === symbol(E)) {
3397 push(caddr(p1));
3398 imag();
3399 } else if (car(p1) === symbol(POWER) && isoneovertwo(caddr(p1))) {
3400 if (DEBUG_ARG) {
3401 console.log("arg of a sqrt: " + p1);
3402 }
3403 if (DEBUG_ARG) {
3404 debugger;
3405 }
3406 push(cadr(p1));
3407 arg();
3408 if (DEBUG_ARG) {
3409 console.log(" = 1/2 * " + stack[tos - 1]);
3410 }
3411 push(caddr(p1));
3412 multiply();
3413 } else if (car(p1) === symbol(MULTIPLY)) {
3414 push_integer(0);
3415 p1 = cdr(p1);
3416 while (iscons(p1)) {
3417 push(car(p1));
3418 arg();
3419 add();
3420 p1 = cdr(p1);
3421 }
3422 } else if (car(p1) === symbol(ADD)) {
3423 push(p1);
3424 rect();
3425 p1 = pop();
3426 push(p1);
3427 real();
3428 p2 = pop();
3429 push(p1);
3430 imag();
3431 p3 = pop();
3432 if (iszero(p2)) {
3433 if (evaluatingAsFloats) {
3434 push_double(Math.PI);
3435 } else {
3436 push(symbol(PI));
3437 }
3438 if (isnegative(p3)) {
3439 negate();
3440 }
3441 } else {
3442 push(p3);
3443 push(p2);
3444 divide();
3445 arctan();
3446 if (isnegative(p2)) {
3447 if (evaluatingAsFloats) {
3448 push_double(Math.PI);
3449 } else {
3450 push_symbol(PI);
3451 }
3452 if (isnegative(p3)) {
3453 subtract();
3454 } else {
3455 add();
3456 }
3457 }
3458 }
3459 } else {
3460 if (!iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
3461 push_integer(0);
3462 } else {
3463 push_symbol(ARG);
3464 push(p1);
3465 list(2);
3466 }
3467 }
3468 return restore();
3469 };
3470
3471 bake = function() {
3472 var h, s, t, x, y, z;
3473 h = 0;
3474 s = 0;
3475 t = 0;
3476 x = 0;
3477 y = 0;
3478 z = 0;
3479 expanding++;
3480 save();
3481 p1 = pop();
3482 s = ispoly(p1, symbol(SYMBOL_S));
3483 t = ispoly(p1, symbol(SYMBOL_T));
3484 x = ispoly(p1, symbol(SYMBOL_X));
3485 y = ispoly(p1, symbol(SYMBOL_Y));
3486 z = ispoly(p1, symbol(SYMBOL_Z));
3487 if (s === 1 && t === 0 && x === 0 && y === 0 && z === 0) {
3488 p2 = symbol(SYMBOL_S);
3489 bake_poly();
3490 } else if (s === 0 && t === 1 && x === 0 && y === 0 && z === 0) {
3491 p2 = symbol(SYMBOL_T);
3492 bake_poly();
3493 } else if (s === 0 && t === 0 && x === 1 && y === 0 && z === 0) {
3494 p2 = symbol(SYMBOL_X);
3495 bake_poly();
3496 } else if (s === 0 && t === 0 && x === 0 && y === 1 && z === 0) {
3497 p2 = symbol(SYMBOL_Y);
3498 bake_poly();
3499 } else if (s === 0 && t === 0 && x === 0 && y === 0 && z === 1) {
3500 p2 = symbol(SYMBOL_Z);
3501 bake_poly();
3502 } else if ((iscons(p1)) && car(p1) !== symbol(FOR)) {
3503 h = tos;
3504 push(car(p1));
3505 p1 = cdr(p1);
3506 while (iscons(p1)) {
3507 push(car(p1));
3508 bake();
3509 p1 = cdr(p1);
3510 }
3511 list(tos - h);
3512 } else {
3513 push(p1);
3514 }
3515 restore();
3516 return expanding--;
3517 };
3518
3519 polyform = function() {
3520 var h;
3521 h = 0;
3522 save();
3523 p2 = pop();
3524 p1 = pop();
3525 if (ispoly(p1, p2)) {
3526 bake_poly();
3527 } else if (iscons(p1)) {
3528 h = tos;
3529 push(car(p1));
3530 p1 = cdr(p1);
3531 while (iscons(p1)) {
3532 push(car(p1));
3533 push(p2);
3534 polyform();
3535 p1 = cdr(p1);
3536 }
3537 list(tos - h);
3538 } else {
3539 push(p1);
3540 }
3541 return restore();
3542 };
3543
3544 bake_poly = function() {
3545 var a, h, i, k, n, o, ref;
3546 h = 0;
3547 i = 0;
3548 k = 0;
3549 n = 0;
3550 a = tos;
3551 push(p1);
3552 push(p2);
3553 k = coeff();
3554 h = tos;
3555 for (i = o = ref = k - 1; o >= 0; i = o += -1) {
3556 p1 = stack[a + i];
3557 bake_poly_term(i);
3558 }
3559 n = tos - h;
3560 if (n > 1) {
3561 list(n);
3562 push(symbol(ADD));
3563 swap();
3564 cons();
3565 }
3566 p1 = pop();
3567 moveTos(tos - k);
3568 return push(p1);
3569 };
3570
3571 bake_poly_term = function(k) {
3572 var h, n;
3573 h = 0;
3574 n = 0;
3575 if (iszero(p1)) {
3576 return;
3577 }
3578 if (k === 0) {
3579 if (car(p1) === symbol(ADD)) {
3580 p1 = cdr(p1);
3581 while (iscons(p1)) {
3582 push(car(p1));
3583 p1 = cdr(p1);
3584 }
3585 } else {
3586 push(p1);
3587 }
3588 return;
3589 }
3590 h = tos;
3591 if (car(p1) === symbol(MULTIPLY)) {
3592 p1 = cdr(p1);
3593 while (iscons(p1)) {
3594 push(car(p1));
3595 p1 = cdr(p1);
3596 }
3597 } else if (!equaln(p1, 1)) {
3598 push(p1);
3599 }
3600 if (k === 1) {
3601 push(p2);
3602 } else {
3603 push(symbol(POWER));
3604 push(p2);
3605 push_integer(k);
3606 list(3);
3607 }
3608 n = tos - h;
3609 if (n > 1) {
3610 list(n);
3611 push(symbol(MULTIPLY));
3612 swap();
3613 return cons();
3614 }
3615 };
3616
3617
3618 /* besselj =====================================================================
3619
3620 Tags
3621 ----
3622 scripting, JS, internal, treenode, general concept
3623
3624 Parameters
3625 ----------
3626 x,n
3627
3628 General description
3629 -------------------
3630
3631 Returns a solution to the Bessel differential equation (Bessel function of first kind).
3632
3633 Recurrence relation:
3634
3635 besselj(x,n) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n-2)
3636
3637 besselj(x,1/2) = sqrt(2/pi/x) sin(x)
3638
3639 besselj(x,-1/2) = sqrt(2/pi/x) cos(x)
3640
3641 For negative n, reorder the recurrence relation as:
3642
3643 besselj(x,n-2) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n)
3644
3645 Substitute n+2 for n to obtain
3646
3647 besselj(x,n) = (2/x) (n+1) besselj(x,n+1) - besselj(x,n+2)
3648
3649 Examples:
3650
3651 besselj(x,3/2) = (1/x) besselj(x,1/2) - besselj(x,-1/2)
3652
3653 besselj(x,-3/2) = -(1/x) besselj(x,-1/2) - besselj(x,1/2)
3654 */
3655
3656 Eval_besselj = function() {
3657 push(cadr(p1));
3658 Eval();
3659 push(caddr(p1));
3660 Eval();
3661 return besselj();
3662 };
3663
3664 besselj = function() {
3665 save();
3666 yybesselj();
3667 return restore();
3668 };
3669
3670 yybesselj = function() {
3671 var d, n;
3672 d = 0.0;
3673 n = 0;
3674 p2 = pop();
3675 p1 = pop();
3676 push(p2);
3677 n = pop_integer();
3678 if (isdouble(p1) && !isNaN(n)) {
3679 d = jn(n, p1.d);
3680 push_double(d);
3681 return;
3682 }
3683 if (iszero(p1) && iszero(p2)) {
3684 push_integer(1);
3685 return;
3686 }
3687 if (iszero(p1) && !isNaN(n)) {
3688 push_integer(0);
3689 return;
3690 }
3691 if (p2.k === NUM && MEQUAL(p2.q.b, 2)) {
3692 if (MEQUAL(p2.q.a, 1)) {
3693 if (evaluatingAsFloats) {
3694 push_double(2.0 / Math.PI);
3695 } else {
3696 push_integer(2);
3697 push_symbol(PI);
3698 divide();
3699 }
3700 push(p1);
3701 divide();
3702 push_rational(1, 2);
3703 power();
3704 push(p1);
3705 sine();
3706 multiply();
3707 return;
3708 }
3709 if (MEQUAL(p2.q.a, -1)) {
3710 if (evaluatingAsFloats) {
3711 push_double(2.0 / Math.PI);
3712 } else {
3713 push_integer(2);
3714 push_symbol(PI);
3715 divide();
3716 }
3717 push(p1);
3718 divide();
3719 push_rational(1, 2);
3720 power();
3721 push(p1);
3722 cosine();
3723 multiply();
3724 return;
3725 }
3726 push_integer(MSIGN(p2.q.a));
3727 p3 = pop();
3728 push_integer(2);
3729 push(p1);
3730 divide();
3731 push(p2);
3732 push(p3);
3733 subtract();
3734 multiply();
3735 push(p1);
3736 push(p2);
3737 push(p3);
3738 subtract();
3739 besselj();
3740 multiply();
3741 push(p1);
3742 push(p2);
3743 push_integer(2);
3744 push(p3);
3745 multiply();
3746 subtract();
3747 besselj();
3748 subtract();
3749 return;
3750 }
3751 if (isnegativeterm(p1)) {
3752 push(p1);
3753 negate();
3754 push(p2);
3755 power();
3756 push(p1);
3757 push(p2);
3758 negate();
3759 power();
3760 multiply();
3761 push_symbol(BESSELJ);
3762 push(p1);
3763 negate();
3764 push(p2);
3765 list(3);
3766 multiply();
3767 return;
3768 }
3769 if (isnegativeterm(p2)) {
3770 push_integer(-1);
3771 push(p2);
3772 power();
3773 push_symbol(BESSELJ);
3774 push(p1);
3775 push(p2);
3776 negate();
3777 list(3);
3778 multiply();
3779 return;
3780 }
3781 push(symbol(BESSELJ));
3782 push(p1);
3783 push(p2);
3784 return list(3);
3785 };
3786
3787
3788 /* bessely =====================================================================
3789
3790 Tags
3791 ----
3792 scripting, JS, internal, treenode, general concept
3793
3794 Parameters
3795 ----------
3796 x,n
3797
3798 General description
3799 -------------------
3800
3801 Bessel function of second kind.
3802 */
3803
3804 Eval_bessely = function() {
3805 push(cadr(p1));
3806 Eval();
3807 push(caddr(p1));
3808 Eval();
3809 return bessely();
3810 };
3811
3812 bessely = function() {
3813 save();
3814 yybessely();
3815 return restore();
3816 };
3817
3818 yybessely = function() {
3819 var d, n;
3820 d = 0.0;
3821 n = 0;
3822 p2 = pop();
3823 p1 = pop();
3824 push(p2);
3825 n = pop_integer();
3826 if (isdouble(p1) && !isNaN(n)) {
3827 d = yn(n, p1.d);
3828 push_double(d);
3829 return;
3830 }
3831 if (isnegativeterm(p2)) {
3832 push_integer(-1);
3833 push(p2);
3834 power();
3835 push_symbol(BESSELY);
3836 push(p1);
3837 push(p2);
3838 negate();
3839 list(3);
3840 multiply();
3841 return;
3842 }
3843 push_symbol(BESSELY);
3844 push(p1);
3845 push(p2);
3846 list(3);
3847 };
3848
3849 mint = function(a) {
3850 return bigInt(a);
3851 };
3852
3853 setSignTo = function(a, b) {
3854 if (a.isPositive()) {
3855 if (b < 0) {
3856 return a.multiply(bigInt(-1));
3857 }
3858 } else {
3859 if (b > 0) {
3860 return a.multiply(bigInt(-1));
3861 }
3862 }
3863 return a;
3864 };
3865
3866 makeSignSameAs = function(a, b) {
3867 if (a.isPositive()) {
3868 if (b.isNegative()) {
3869 return a.multiply(bigInt(-1));
3870 }
3871 } else {
3872 if (b.isPositive()) {
3873 return a.multiply(bigInt(-1));
3874 }
3875 }
3876 return a;
3877 };
3878
3879 makePositive = function(a) {
3880 if (a.isNegative()) {
3881 return a.multiply(bigInt(-1));
3882 }
3883 return a;
3884 };
3885
3886
3887 /*
3888 mtotal = 0
3889 MP_MIN_SIZE = 2
3890 MP_MAX_FREE = 1000
3891
3892 mnew = (n) ->
3893 if (n < MP_MIN_SIZE)
3894 n = MP_MIN_SIZE
3895 if (n == MP_MIN_SIZE && mfreecount)
3896 p = free_stack[--mfreecount]
3897 else
3898 p = [] #(unsigned int *) malloc((n + 3) * sizeof (int))
3899 #if (p == 0)
3900 * stop("malloc failure")
3901 p[0] = n
3902 mtotal += n
3903 return p[3]
3904 */
3905
3906
3907 /*
3908 free_stack = []
3909
3910 mfree = (array, p) ->
3911 p -= 3
3912 mtotal -= array[p]
3913 if (array[p] == MP_MIN_SIZE && mfreecount < MP_MAX_FREE)
3914 free_stack[mfreecount++] = p
3915 else
3916 free(p)
3917 */
3918
3919
3920 /*
3921 mint = (n) ->
3922 p = mnew(1)
3923 if (n < 0)
3924 * !!! this is FU
3925 * MSIGN(p) = -1
3926 fu = true
3927 else
3928 * !!! this is FU
3929 #MSIGN(p) = 1
3930 fu = true
3931 * !!! this is FU
3932 #MLENGTH(p) = 1
3933 p[0] = Math.abs(n)
3934 return p
3935 */
3936
3937
3938 /*
3939 mcopy = (a) ->
3940 #unsigned int *b
3941
3942 b = mnew(MLENGTH(a))
3943
3944 * !!! fu
3945 #MSIGN(b) = MSIGN(a)
3946 #MLENGTH(b) = MLENGTH(a)
3947
3948 for i in [0...MLENGTH(a)]
3949 b[i] = a[i]
3950
3951 return b
3952 */
3953
3954
3955 /*
3956 *
3957 * ge not invoked from anywhere - is you need ge
3958 * just use the bigNum's ge implementation
3959 * leaving it here just in case I decide to backport to C
3960 *
3961 * a >= b ?
3962 * and and b arrays of ints, len is an int
3963 ge = (a, b, len) ->
3964 i = 0
3965 for i in [0...len]
3966 if (a[i] == b[i])
3967 continue
3968 else
3969 break
3970 if (a[i] >= b[i])
3971 return 1
3972 else
3973 return 0
3974 */
3975
3976 add_numbers = function() {
3977 var a, b, theResult;
3978 a = 1.0;
3979 b = 1.0;
3980 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
3981 qadd();
3982 return;
3983 }
3984 save();
3985 p2 = pop();
3986 p1 = pop();
3987 if (isdouble(p1)) {
3988 a = p1.d;
3989 } else {
3990 a = convert_rational_to_double(p1);
3991 }
3992 if (isdouble(p2)) {
3993 b = p2.d;
3994 } else {
3995 b = convert_rational_to_double(p2);
3996 }
3997 theResult = a + b;
3998 push_double(theResult);
3999 return restore();
4000 };
4001
4002 subtract_numbers = function() {
4003 var a, b;
4004 a = 0.0;
4005 b = 0.0;
4006 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
4007 qsub();
4008 return;
4009 }
4010 save();
4011 p2 = pop();
4012 p1 = pop();
4013 if (isdouble(p1)) {
4014 a = p1.d;
4015 } else {
4016 a = convert_rational_to_double(p1);
4017 }
4018 if (isdouble(p2)) {
4019 b = p2.d;
4020 } else {
4021 b = convert_rational_to_double(p2);
4022 }
4023 push_double(a - b);
4024 return restore();
4025 };
4026
4027 multiply_numbers = function() {
4028 var a, b;
4029 a = 0.0;
4030 b = 0.0;
4031 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
4032 qmul();
4033 return;
4034 }
4035 save();
4036 p2 = pop();
4037 p1 = pop();
4038 if (isdouble(p1)) {
4039 a = p1.d;
4040 } else {
4041 a = convert_rational_to_double(p1);
4042 }
4043 if (isdouble(p2)) {
4044 b = p2.d;
4045 } else {
4046 b = convert_rational_to_double(p2);
4047 }
4048 push_double(a * b);
4049 return restore();
4050 };
4051
4052 divide_numbers = function() {
4053 var a, b;
4054 a = 0.0;
4055 b = 0.0;
4056 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
4057 qdiv();
4058 return;
4059 }
4060 save();
4061 p2 = pop();
4062 p1 = pop();
4063 if (iszero(p2)) {
4064 stop("divide by zero");
4065 }
4066 if (isdouble(p1)) {
4067 a = p1.d;
4068 } else {
4069 a = convert_rational_to_double(p1);
4070 }
4071 if (isdouble(p2)) {
4072 b = p2.d;
4073 } else {
4074 b = convert_rational_to_double(p2);
4075 }
4076 push_double(a / b);
4077 return restore();
4078 };
4079
4080 invert_number = function() {
4081 var a, b;
4082 save();
4083 p1 = pop();
4084 if (iszero(p1)) {
4085 stop("divide by zero");
4086 }
4087 if (isdouble(p1)) {
4088 push_double(1 / p1.d);
4089 restore();
4090 return;
4091 }
4092 a = bigInt(p1.q.a);
4093 b = bigInt(p1.q.b);
4094 b = makeSignSameAs(b, a);
4095 a = setSignTo(a, 1);
4096 p1 = new U();
4097 p1.k = NUM;
4098 p1.q.a = b;
4099 p1.q.b = a;
4100 push(p1);
4101 return restore();
4102 };
4103
4104 compare_rationals = function(a, b) {
4105 var ab, ba, t;
4106 t = 0;
4107 ab = mmul(a.q.a, b.q.b);
4108 ba = mmul(a.q.b, b.q.a);
4109 t = mcmp(ab, ba);
4110 return t;
4111 };
4112
4113 compare_numbers = function(a, b) {
4114 var x, y;
4115 x = 0.0;
4116 y = 0.0;
4117 if (isrational(a) && isrational(b)) {
4118 return compare_rationals(a, b);
4119 }
4120 if (isdouble(a)) {
4121 x = a.d;
4122 } else {
4123 x = convert_rational_to_double(a);
4124 }
4125 if (isdouble(b)) {
4126 y = b.d;
4127 } else {
4128 y = convert_rational_to_double(b);
4129 }
4130 if (x < y) {
4131 return -1;
4132 }
4133 if (x > y) {
4134 return 1;
4135 }
4136 return 0;
4137 };
4138
4139 negate_number = function() {
4140 save();
4141 p1 = pop();
4142 if (iszero(p1)) {
4143 push(p1);
4144 restore();
4145 return;
4146 }
4147 switch (p1.k) {
4148 case NUM:
4149 p2 = new U();
4150 p2.k = NUM;
4151 p2.q.a = bigInt(p1.q.a.multiply(bigInt.minusOne));
4152 p2.q.b = bigInt(p1.q.b);
4153 push(p2);
4154 break;
4155 case DOUBLE:
4156 push_double(-p1.d);
4157 break;
4158 default:
4159 stop("bug caught in mp_negate_number");
4160 }
4161 return restore();
4162 };
4163
4164 bignum_truncate = function() {
4165 var a;
4166 save();
4167 p1 = pop();
4168 a = mdiv(p1.q.a, p1.q.b);
4169 p1 = new U();
4170 p1.k = NUM;
4171 p1.q.a = a;
4172 p1.q.b = bigInt(1);
4173 push(p1);
4174 return restore();
4175 };
4176
4177 mp_numerator = function() {
4178 save();
4179 p1 = pop();
4180 if (p1.k !== NUM) {
4181 push(one);
4182 restore();
4183 return;
4184 }
4185 p2 = new U();
4186 p2.k = NUM;
4187 p2.q.a = bigInt(p1.q.a);
4188 p2.q.b = bigInt(1);
4189 push(p2);
4190 return restore();
4191 };
4192
4193 mp_denominator = function() {
4194 save();
4195 p1 = pop();
4196 if (p1.k !== NUM) {
4197 push(one);
4198 restore();
4199 return;
4200 }
4201 p2 = new U();
4202 p2.k = NUM;
4203 p2.q.a = bigInt(p1.q.b);
4204 p2.q.b = bigInt(1);
4205 push(p2);
4206 return restore();
4207 };
4208
4209 bignum_power_number = function(expo) {
4210 var a, b, t;
4211 save();
4212 p1 = pop();
4213 a = mpow(p1.q.a, Math.abs(expo));
4214 b = mpow(p1.q.b, Math.abs(expo));
4215 if (expo < 0) {
4216 t = a;
4217 a = b;
4218 b = t;
4219 a = makeSignSameAs(a, b);
4220 b = setSignTo(b, 1);
4221 }
4222 p1 = new U();
4223 p1.k = NUM;
4224 p1.q.a = a;
4225 p1.q.b = b;
4226 push(p1);
4227 return restore();
4228 };
4229
4230 convert_bignum_to_double = function(p) {
4231 return p.toJSNumber();
4232 };
4233
4234 convert_rational_to_double = function(p) {
4235 var quotientAndRemainder, result;
4236 if (p.q == null) {
4237 debugger;
4238 }
4239 quotientAndRemainder = p.q.a.divmod(p.q.b);
4240 result = quotientAndRemainder.quotient + quotientAndRemainder.remainder / p.q.b.toJSNumber();
4241 return result;
4242 };
4243
4244 push_integer = function(n) {
4245 if (DEBUG) {
4246 console.log("pushing integer " + n);
4247 }
4248 save();
4249 p1 = new U();
4250 p1.k = NUM;
4251 p1.q.a = bigInt(n);
4252 p1.q.b = bigInt(1);
4253 push(p1);
4254 return restore();
4255 };
4256
4257 push_double = function(d) {
4258 save();
4259 p1 = new U();
4260 p1.k = DOUBLE;
4261 p1.d = d;
4262 push(p1);
4263 return restore();
4264 };
4265
4266 push_rational = function(a, b) {
4267
4268 /*
4269 save()
4270 p1 = new U()
4271 p1.k = NUM
4272 p1.q.a = bigInt(a)
4273 p1.q.b = bigInt(b)
4274 ## FIXME -- normalize ##
4275 push(p1)
4276 restore()
4277 */
4278 var p;
4279 p = new U();
4280 p.k = NUM;
4281 p.q.a = bigInt(a);
4282 p.q.b = bigInt(b);
4283 return push(p);
4284 };
4285
4286 pop_integer = function() {
4287 var n;
4288 n = 0/0;
4289 save();
4290 p1 = pop();
4291 switch (p1.k) {
4292 case NUM:
4293 if (isinteger(p1) && p1.q.a.isSmall) {
4294 n = p1.q.a.toJSNumber();
4295 }
4296 break;
4297 case DOUBLE:
4298 if (DEBUG) {
4299 console.log("popping integer but double is found");
4300 }
4301 if (Math.floor(p1.d) === p1.d) {
4302 if (DEBUG) {
4303 console.log("...altough it's an integer");
4304 }
4305 n = p1.d;
4306 }
4307 }
4308 restore();
4309 return n;
4310 };
4311
4312 print_double = function(p, flag) {
4313 var accumulator, buf;
4314 accumulator = "";
4315 buf = doubleToReasonableString(p.d);
4316 if (flag === 1 && buf === '-') {
4317 accumulator += print_str(buf + 1);
4318 } else {
4319 accumulator += print_str(buf);
4320 }
4321 return accumulator;
4322 };
4323
4324 bignum_scan_integer = function(s) {
4325 var a, scounter, sign_;
4326 save();
4327 scounter = 0;
4328 sign_ = s[scounter];
4329 if (sign_ === '+' || sign_ === '-') {
4330 scounter++;
4331 }
4332 a = bigInt(s.substring(scounter));
4333 p1 = new U();
4334 p1.k = NUM;
4335 p1.q.a = a;
4336 p1.q.b = bigInt(1);
4337 push(p1);
4338 if (sign_ === '-') {
4339 negate();
4340 }
4341 return restore();
4342 };
4343
4344 bignum_scan_float = function(s) {
4345 return push_double(parseFloat(s));
4346 };
4347
4348 print_number = function(p, signed) {
4349 var aAsString, accumulator, buf, denominatorString;
4350 accumulator = "";
4351 denominatorString = "";
4352 buf = "";
4353 switch (p.k) {
4354 case NUM:
4355 aAsString = p.q.a.toString();
4356 if (!signed) {
4357 if (aAsString[0] === "-") {
4358 aAsString = aAsString.substring(1);
4359 }
4360 }
4361 if (printMode === PRINTMODE_LATEX && isfraction(p)) {
4362 aAsString = "\\frac{" + aAsString + "}{";
4363 }
4364 accumulator += aAsString;
4365 if (isfraction(p)) {
4366 if (printMode !== PRINTMODE_LATEX) {
4367 accumulator += "/";
4368 }
4369 denominatorString = p.q.b.toString();
4370 if (printMode === PRINTMODE_LATEX) {
4371 denominatorString += "}";
4372 }
4373 accumulator += denominatorString;
4374 }
4375 break;
4376 case DOUBLE:
4377 aAsString = doubleToReasonableString(p.d);
4378 if (!signed) {
4379 if (aAsString[0] === "-") {
4380 aAsString = aAsString.substring(1);
4381 }
4382 }
4383 accumulator += aAsString;
4384 }
4385 return accumulator;
4386 };
4387
4388 gcd_numbers = function() {
4389 save();
4390 p2 = pop();
4391 p1 = pop();
4392 p3 = new U();
4393 p3.k = NUM;
4394 p3.q.a = mgcd(p1.q.a, p2.q.a);
4395 p3.q.b = mgcd(p1.q.b, p2.q.b);
4396 p3.q.a = setSignTo(p3.q.a, 1);
4397 push(p3);
4398 return restore();
4399 };
4400
4401 pop_double = function() {
4402 var d;
4403 d = 0.0;
4404 save();
4405 p1 = pop();
4406 switch (p1.k) {
4407 case NUM:
4408 d = convert_rational_to_double(p1);
4409 break;
4410 case DOUBLE:
4411 d = p1.d;
4412 break;
4413 default:
4414 d = 0.0;
4415 }
4416 restore();
4417 return d;
4418 };
4419
4420 bignum_float = function() {
4421 var d;
4422 d = 0.0;
4423 d = convert_rational_to_double(pop());
4424 return push_double(d);
4425 };
4426
4427 bignum_factorial = function(n) {
4428 save();
4429 p1 = new U();
4430 p1.k = NUM;
4431 p1.q.a = __factorial(n);
4432 p1.q.b = bigInt(1);
4433 push(p1);
4434 return restore();
4435 };
4436
4437 __factorial = function(n) {
4438 var a, b, i, o, ref, t;
4439 i = 0;
4440 if (n === 0 || n === 1) {
4441 a = bigInt(1);
4442 return a;
4443 }
4444 a = bigInt(2);
4445 b = bigInt(0);
4446 if (3 <= n) {
4447 for (i = o = 3, ref = n; 3 <= ref ? o <= ref : o >= ref; i = 3 <= ref ? ++o : --o) {
4448 b = bigInt(i);
4449 t = mmul(a, b);
4450 a = t;
4451 }
4452 }
4453 return a;
4454 };
4455
4456 mask = [0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000];
4457
4458 mp_set_bit = function(x, k) {
4459 console.log("not implemented yet");
4460 debugger;
4461 return x[k / 32] |= mask[k % 32];
4462 };
4463
4464 mp_clr_bit = function(x, k) {
4465 console.log("not implemented yet");
4466 debugger;
4467 return x[k / 32] &= ~mask[k % 32];
4468 };
4469
4470 mshiftright = function(a) {
4471 return a = a.shiftRight();
4472 };
4473
4474 Eval_binomial = function() {
4475 push(cadr(p1));
4476 Eval();
4477 push(caddr(p1));
4478 Eval();
4479 return binomial();
4480 };
4481
4482 binomial = function() {
4483 save();
4484 ybinomial();
4485 return restore();
4486 };
4487
4488 ybinomial = function() {
4489 p2 = pop();
4490 p1 = pop();
4491 if (BINOM_check_args() === 0) {
4492 push(zero);
4493 return;
4494 }
4495 push(p1);
4496 factorial();
4497 push(p2);
4498 factorial();
4499 divide();
4500 push(p1);
4501 push(p2);
4502 subtract();
4503 factorial();
4504 return divide();
4505 };
4506
4507 BINOM_check_args = function() {
4508 if (isnum(p1) && lessp(p1, zero)) {
4509 return 0;
4510 } else if (isnum(p2) && lessp(p2, zero)) {
4511 return 0;
4512 } else if (isnum(p1) && isnum(p2) && lessp(p1, p2)) {
4513 return 0;
4514 } else {
4515 return 1;
4516 }
4517 };
4518
4519
4520 /* ceiling =====================================================================
4521
4522 Tags
4523 ----
4524 scripting, JS, internal, treenode, general concept
4525
4526 Parameters
4527 ----------
4528 x
4529
4530 General description
4531 -------------------
4532
4533 Returns the smallest integer not less than x.
4534 */
4535
4536 Eval_ceiling = function() {
4537 push(cadr(p1));
4538 Eval();
4539 return ceiling();
4540 };
4541
4542 ceiling = function() {
4543 save();
4544 yyceiling();
4545 return restore();
4546 };
4547
4548 yyceiling = function() {
4549 var d, doNothing;
4550 d = 0.0;
4551 p1 = pop();
4552 if (!isnum(p1)) {
4553 push_symbol(CEILING);
4554 push(p1);
4555 list(2);
4556 return;
4557 }
4558 if (isdouble(p1)) {
4559 d = Math.ceil(p1.d);
4560 push_double(d);
4561 return;
4562 }
4563 if (isinteger(p1)) {
4564 push(p1);
4565 return;
4566 }
4567 p3 = new U();
4568 p3.k = NUM;
4569 p3.q.a = mdiv(p1.q.a, p1.q.b);
4570 p3.q.b = mint(1);
4571 push(p3);
4572 if (isnegativenumber(p1)) {
4573 return doNothing = 1;
4574 } else {
4575 push_integer(1);
4576 return add();
4577 }
4578 };
4579
4580
4581 /* choose =====================================================================
4582
4583 Tags
4584 ----
4585 scripting, JS, internal, treenode, general concept
4586
4587 Parameters
4588 ----------
4589 n,k
4590
4591 General description
4592 -------------------
4593
4594 Returns the number of combinations of n items taken k at a time.
4595
4596 For example, the number of five card hands is choose(52,5)
4597
4598 ```
4599 n!
4600 choose(n,k) = -------------
4601 k! (n - k)!
4602 ```
4603 */
4604
4605 Eval_choose = function() {
4606 push(cadr(p1));
4607 Eval();
4608 push(caddr(p1));
4609 Eval();
4610 return choose();
4611 };
4612
4613 choose = function() {
4614 save();
4615 p2 = pop();
4616 p1 = pop();
4617 if (choose_check_args() === 0) {
4618 push_integer(0);
4619 restore();
4620 return;
4621 }
4622 push(p1);
4623 factorial();
4624 push(p2);
4625 factorial();
4626 divide();
4627 push(p1);
4628 push(p2);
4629 subtract();
4630 factorial();
4631 divide();
4632 return restore();
4633 };
4634
4635 choose_check_args = function() {
4636 if (isnum(p1) && lessp(p1, zero)) {
4637 return 0;
4638 } else if (isnum(p2) && lessp(p2, zero)) {
4639 return 0;
4640 } else if (isnum(p1) && isnum(p2) && lessp(p1, p2)) {
4641 return 0;
4642 } else {
4643 return 1;
4644 }
4645 };
4646
4647
4648 /* circexp =====================================================================
4649
4650 Tags
4651 ----
4652 scripting, JS, internal, treenode, general concept
4653
4654 Parameters
4655 ----------
4656 x
4657
4658 General description
4659 -------------------
4660
4661 Returns expression x with circular and hyperbolic functions converted to exponential forms. Sometimes this will simplify an expression.
4662 */
4663
4664 Eval_circexp = function() {
4665 push(cadr(p1));
4666 Eval();
4667 circexp();
4668 return Eval();
4669 };
4670
4671 circexp = function() {
4672 var h, i, o, ref;
4673 i = 0;
4674 h = 0;
4675 save();
4676 p1 = pop();
4677 if (car(p1) === symbol(COS)) {
4678 push(cadr(p1));
4679 expcos();
4680 restore();
4681 return;
4682 }
4683 if (car(p1) === symbol(SIN)) {
4684 push(cadr(p1));
4685 expsin();
4686 restore();
4687 return;
4688 }
4689 if (car(p1) === symbol(TAN)) {
4690 p1 = cadr(p1);
4691 push(imaginaryunit);
4692 push(p1);
4693 multiply();
4694 exponential();
4695 p2 = pop();
4696 push(imaginaryunit);
4697 push(p1);
4698 multiply();
4699 negate();
4700 exponential();
4701 p3 = pop();
4702 push(p3);
4703 push(p2);
4704 subtract();
4705 push(imaginaryunit);
4706 multiply();
4707 push(p2);
4708 push(p3);
4709 add();
4710 divide();
4711 restore();
4712 return;
4713 }
4714 if (car(p1) === symbol(COSH)) {
4715 p1 = cadr(p1);
4716 push(p1);
4717 exponential();
4718 push(p1);
4719 negate();
4720 exponential();
4721 add();
4722 push_rational(1, 2);
4723 multiply();
4724 restore();
4725 return;
4726 }
4727 if (car(p1) === symbol(SINH)) {
4728 p1 = cadr(p1);
4729 push(p1);
4730 exponential();
4731 push(p1);
4732 negate();
4733 exponential();
4734 subtract();
4735 push_rational(1, 2);
4736 multiply();
4737 restore();
4738 return;
4739 }
4740 if (car(p1) === symbol(TANH)) {
4741 p1 = cadr(p1);
4742 push(p1);
4743 push_integer(2);
4744 multiply();
4745 exponential();
4746 p1 = pop();
4747 push(p1);
4748 push_integer(1);
4749 subtract();
4750 push(p1);
4751 push_integer(1);
4752 add();
4753 divide();
4754 restore();
4755 return;
4756 }
4757 if (iscons(p1)) {
4758 h = tos;
4759 while (iscons(p1)) {
4760 push(car(p1));
4761 circexp();
4762 p1 = cdr(p1);
4763 }
4764 list(tos - h);
4765 restore();
4766 return;
4767 }
4768 if (p1.k === TENSOR) {
4769 push(p1);
4770 copy_tensor();
4771 p1 = pop();
4772 for (i = o = 0, ref = p1.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
4773 push(p1.tensor.elem[i]);
4774 circexp();
4775 p1.tensor.elem[i] = pop();
4776 }
4777 push(p1);
4778 restore();
4779 return;
4780 }
4781 push(p1);
4782 return restore();
4783 };
4784
4785
4786 /* clearall =====================================================================
4787
4788 Tags
4789 ----
4790 scripting, JS, internal, treenode, general concept
4791
4792
4793 General description
4794 -------------------
4795
4796 Completely wipes all variables from the environment.
4797 */
4798
4799 Eval_clearall = function() {
4800 do_clearall();
4801 return push(symbol(NIL));
4802 };
4803
4804 do_clearall = function() {
4805 if (test_flag === 0) {
4806 clear_term();
4807 }
4808 do_clearPatterns();
4809 clear_symbols();
4810 defn();
4811 return codeGen = false;
4812 };
4813
4814 clearall = function() {
4815 return run("clearall");
4816 };
4817
4818 clearRenamedVariablesToAvoidBindingToExternalScope = function() {
4819 var i, o, ref, results;
4820 results = [];
4821 for (i = o = 0, ref = symtab.length; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
4822 if (symtab[i].printname.indexOf("AVOID_BINDING_TO_EXTERNAL_SCOPE_VALUE") !== -1) {
4823 symtab[i].k = SYM;
4824 symtab[i].printname = "";
4825 binding[i] = symtab[i];
4826 results.push(isSymbolReclaimable[i] = true);
4827 } else {
4828 results.push(void 0);
4829 }
4830 }
4831 return results;
4832 };
4833
4834
4835 /* clear =====================================================================
4836
4837 Tags
4838 ----
4839 scripting, JS, internal, treenode, general concept
4840
4841 Parameters
4842 ----------
4843 x
4844
4845 General description
4846 -------------------
4847
4848 Completely wipes a variable from the environment (while doing x = quote(x) just unassigns it).
4849 */
4850
4851 Eval_clear = function() {
4852 var indexFound, variableToBeCleared;
4853 p2 = cdr(p1);
4854 while (iscons(p2)) {
4855 variableToBeCleared = car(p2);
4856 if (variableToBeCleared.k !== SYM) {
4857 stop("symbol error");
4858 }
4859 indexFound = symtab.indexOf(variableToBeCleared);
4860 symtab[indexFound].k = SYM;
4861 symtab[indexFound].printname = "";
4862 binding[indexFound] = symtab[indexFound];
4863 isSymbolReclaimable[indexFound] = true;
4864 p2 = cdr(p2);
4865 }
4866 return push(symbol(NIL));
4867 };
4868
4869
4870 /*
4871 Convert complex z to clock form
4872
4873 Input: push z
4874
4875 Output: Result on stack
4876
4877 clock(z) = abs(z) * (-1) ^ (arg(z) / pi)
4878
4879 For example, clock(exp(i pi/3)) gives the result (-1)^(1/3)
4880 */
4881
4882 DEBUG_CLOCKFORM = false;
4883
4884 Eval_clock = function() {
4885 push(cadr(p1));
4886 Eval();
4887 return clockform();
4888 };
4889
4890 clockform = function() {
4891 save();
4892 p1 = pop();
4893 push(p1);
4894 abs();
4895 if (DEBUG_CLOCKFORM) {
4896 console.log("clockform: abs of " + p1 + " : " + stack[tos - 1]);
4897 }
4898 push_symbol(POWER);
4899 push_integer(-1);
4900 push(p1);
4901 arg();
4902 if (DEBUG_CLOCKFORM) {
4903 console.log("clockform: arg of " + p1 + " : " + stack[tos - 1]);
4904 }
4905 if (evaluatingAsFloats) {
4906 push_double(Math.PI);
4907 } else {
4908 push(symbol(PI));
4909 }
4910 divide();
4911 if (DEBUG_CLOCKFORM) {
4912 console.log("clockform: divide : " + stack[tos - 1]);
4913 }
4914 list(3);
4915 if (DEBUG_CLOCKFORM) {
4916 console.log("clockform: power : " + stack[tos - 1]);
4917 }
4918 multiply();
4919 if (DEBUG_CLOCKFORM) {
4920 console.log("clockform: multiply : " + stack[tos - 1]);
4921 }
4922
4923 /*
4924 p1 = pop()
4925 push(p1)
4926 abs()
4927 push(symbol(E))
4928 push(p1)
4929 arg()
4930 push(imaginaryunit)
4931 multiply()
4932 power()
4933 multiply()
4934 */
4935 return restore();
4936 };
4937
4938
4939 /* coeff =====================================================================
4940
4941 Tags
4942 ----
4943 scripting, JS, internal, treenode, general concept
4944
4945 Parameters
4946 ----------
4947 p,x,n
4948
4949 General description
4950 -------------------
4951 Returns the coefficient of x^n in polynomial p. The x argument can be omitted for polynomials in x.
4952 */
4953
4954 Eval_coeff = function() {
4955 push(cadr(p1));
4956 Eval();
4957 push(caddr(p1));
4958 Eval();
4959 push(cadddr(p1));
4960 Eval();
4961 p3 = pop();
4962 p2 = pop();
4963 p1 = pop();
4964 if (p3 === symbol(NIL)) {
4965 p3 = p2;
4966 p2 = symbol(SYMBOL_X);
4967 }
4968 push(p1);
4969 push(p2);
4970 push(p3);
4971 power();
4972 divide();
4973 push(p2);
4974 return filter();
4975 };
4976
4977 coeff = function() {
4978 var h, n, prev_expanding;
4979 save();
4980 p2 = pop();
4981 p1 = pop();
4982 h = tos;
4983 while (1) {
4984 push(p1);
4985 push(p2);
4986 push(zero);
4987 subst();
4988 Eval();
4989 p3 = pop();
4990 push(p3);
4991 push(p1);
4992 push(p3);
4993 subtract();
4994 p1 = pop();
4995 if (equal(p1, zero)) {
4996 n = tos - h;
4997 restore();
4998 return n;
4999 }
5000 push(p1);
5001 push(p2);
5002 prev_expanding = expanding;
5003 expanding = 1;
5004 divide();
5005 expanding = prev_expanding;
5006 p1 = pop();
5007 }
5008 };
5009
5010
5011 /* cofactor =====================================================================
5012
5013 Tags
5014 ----
5015 scripting, JS, internal, treenode, general concept
5016
5017 Parameters
5018 ----------
5019 m,i,j
5020
5021 General description
5022 -------------------
5023 Cofactor of a matrix component.
5024 Let c be the cofactor matrix of matrix m, i.e. tranpose(c) = adj(m).
5025 This function returns c[i,j].
5026 */
5027
5028 Eval_cofactor = function() {
5029 var doNothing, i, j, n;
5030 i = 0;
5031 j = 0;
5032 n = 0;
5033 push(cadr(p1));
5034 Eval();
5035 p2 = pop();
5036 if (istensor(p2) && p2.tensor.ndim === 2 && p2.tensor.dim[0] === p2.tensor.dim[1]) {
5037 doNothing = 1;
5038 } else {
5039 stop("cofactor: 1st arg: square matrix expected");
5040 }
5041 n = p2.tensor.dim[0];
5042 push(caddr(p1));
5043 Eval();
5044 i = pop_integer();
5045 if (i < 1 || i > n) {
5046 stop("cofactor: 2nd arg: row index expected");
5047 }
5048 push(cadddr(p1));
5049 Eval();
5050 j = pop_integer();
5051 if (j < 1 || j > n) {
5052 stop("cofactor: 3rd arg: column index expected");
5053 }
5054 return cofactor(p2, n, i - 1, j - 1);
5055 };
5056
5057 cofactor = function(p, n, row, col) {
5058 var i, i1, j, o, ref, ref1;
5059 i = 0;
5060 j = 0;
5061 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
5062 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
5063 if (i !== row && j !== col) {
5064 push(p.tensor.elem[n * i + j]);
5065 }
5066 }
5067 }
5068 determinant(n - 1);
5069 if ((row + col) % 2) {
5070 return negate();
5071 }
5072 };
5073
5074 Eval_condense = function() {
5075 push(cadr(p1));
5076 Eval();
5077 return Condense();
5078 };
5079
5080 Condense = function() {
5081 var prev_expanding;
5082 prev_expanding = expanding;
5083 expanding = 0;
5084 save();
5085 yycondense();
5086 restore();
5087 return expanding = prev_expanding;
5088 };
5089
5090 yycondense = function() {
5091 p1 = pop();
5092 if (car(p1) !== symbol(ADD)) {
5093 push(p1);
5094 return;
5095 }
5096 p3 = cdr(p1);
5097 push(car(p3));
5098 p3 = cdr(p3);
5099 while (iscons(p3)) {
5100 push(car(p3));
5101 gcd();
5102 p3 = cdr(p3);
5103 }
5104 inverse();
5105 p2 = pop();
5106 push(zero);
5107 p3 = cdr(p1);
5108 while (iscons(p3)) {
5109 push(p2);
5110 push(car(p3));
5111 multiply();
5112 add();
5113 p3 = cdr(p3);
5114 }
5115 yyexpand();
5116 push(p2);
5117 return divide();
5118 };
5119
5120
5121 /* conj =====================================================================
5122
5123 Tags
5124 ----
5125 scripting, JS, internal, treenode, general concept
5126
5127 Parameters
5128 ----------
5129 z
5130
5131 General description
5132 -------------------
5133 Returns the complex conjugate of z.
5134 */
5135
5136 Eval_conj = function() {
5137 push(cadr(p1));
5138 Eval();
5139 p1 = pop();
5140 push(p1);
5141 if (!Find(p1, imaginaryunit)) {
5142 polar();
5143 conjugate();
5144 return clockform();
5145 } else {
5146 return conjugate();
5147 }
5148 };
5149
5150 conjugate = function() {
5151 push(imaginaryunit);
5152 push(imaginaryunit);
5153 negate();
5154 subst();
5155 return Eval();
5156 };
5157
5158 consCount = 0;
5159
5160 cons = function() {
5161 var p;
5162 consCount++;
5163 if (DEBUG) {
5164 console.log("cons tos: " + tos + " # " + consCount);
5165 }
5166 p = new U();
5167 p.k = CONS;
5168 p.cons.cdr = pop();
5169 if (p === p.cons.cdr) {
5170 debugger;
5171 console.log("something wrong p == its cdr");
5172 }
5173 p.cons.car = pop();
5174
5175 /*
5176 console.log "cons new cdr.k = " + p.cons.cdr.k + "\nor more in detail:"
5177 console.log print_list p.cons.cdr
5178 console.log "cons new car.k = " + p.cons.car.k + "\nor more in detail:"
5179 console.log print_list p.cons.car
5180 */
5181 return push(p);
5182 };
5183
5184
5185 /* contract =====================================================================
5186
5187 Tags
5188 ----
5189 scripting, JS, internal, treenode, general concept
5190
5191 Parameters
5192 ----------
5193 a,i,j
5194
5195 General description
5196 -------------------
5197 Contract across tensor indices i.e. returns "a" summed over indices i and j.
5198 If i and j are omitted then 1 and 2 are used.
5199 contract(m) is equivalent to the trace of matrix m.
5200 */
5201
5202 Eval_contract = function() {
5203 push(cadr(p1));
5204 Eval();
5205 if (cddr(p1) === symbol(NIL)) {
5206 push_integer(1);
5207 push_integer(2);
5208 } else {
5209 push(caddr(p1));
5210 Eval();
5211 push(cadddr(p1));
5212 Eval();
5213 }
5214 return contract();
5215 };
5216
5217 contract = function() {
5218 save();
5219 yycontract();
5220 return restore();
5221 };
5222
5223 yycontract = function() {
5224 var a, ai, an, b, h, i, i1, j, j1, k, l, l1, m, m1, n, n1, ndim, nelem, o, o1, ref, ref1, ref2, ref3, ref4, ref5, ref6;
5225 h = 0;
5226 i = 0;
5227 j = 0;
5228 k = 0;
5229 l = 0;
5230 m = 0;
5231 n = 0;
5232 ndim = 0;
5233 nelem = 0;
5234 ai = [];
5235 an = [];
5236 p3 = pop();
5237 p2 = pop();
5238 p1 = pop();
5239 if (!istensor(p1)) {
5240 if (!iszero(p1)) {
5241 stop("contract: tensor expected, 1st arg is not a tensor");
5242 }
5243 push(zero);
5244 return;
5245 }
5246 push(p2);
5247 l = pop_integer();
5248 push(p3);
5249 m = pop_integer();
5250 ndim = p1.tensor.ndim;
5251 if (l < 1 || l > ndim || m < 1 || m > ndim || l === m || p1.tensor.dim[l - 1] !== p1.tensor.dim[m - 1]) {
5252 stop("contract: index out of range");
5253 }
5254 l--;
5255 m--;
5256 n = p1.tensor.dim[l];
5257 nelem = 1;
5258 for (i = o = 0, ref = ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
5259 if (i !== l && i !== m) {
5260 nelem *= p1.tensor.dim[i];
5261 }
5262 }
5263 p2 = alloc_tensor(nelem);
5264 p2.tensor.ndim = ndim - 2;
5265 j = 0;
5266 for (i = i1 = 0, ref1 = ndim; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
5267 if (i !== l && i !== m) {
5268 p2.tensor.dim[j++] = p1.tensor.dim[i];
5269 }
5270 }
5271 a = p1.tensor.elem;
5272 b = p2.tensor.elem;
5273 for (i = j1 = 0, ref2 = ndim; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
5274 ai[i] = 0;
5275 an[i] = p1.tensor.dim[i];
5276 }
5277 for (i = l1 = 0, ref3 = nelem; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
5278 push(zero);
5279 for (j = m1 = 0, ref4 = n; 0 <= ref4 ? m1 < ref4 : m1 > ref4; j = 0 <= ref4 ? ++m1 : --m1) {
5280 ai[l] = j;
5281 ai[m] = j;
5282 h = 0;
5283 for (k = n1 = 0, ref5 = ndim; 0 <= ref5 ? n1 < ref5 : n1 > ref5; k = 0 <= ref5 ? ++n1 : --n1) {
5284 h = (h * an[k]) + ai[k];
5285 }
5286 push(a[h]);
5287 add();
5288 }
5289 b[i] = pop();
5290 for (j = o1 = ref6 = ndim - 1; ref6 <= 0 ? o1 <= 0 : o1 >= 0; j = ref6 <= 0 ? ++o1 : --o1) {
5291 if (j === l || j === m) {
5292 continue;
5293 }
5294 if (++ai[j] < an[j]) {
5295 break;
5296 }
5297 ai[j] = 0;
5298 }
5299 }
5300 if (nelem === 1) {
5301 return push(b[0]);
5302 } else {
5303 return push(p2);
5304 }
5305 };
5306
5307
5308 /* cos =====================================================================
5309
5310 Tags
5311 ----
5312 scripting, JS, internal, treenode, general concept
5313
5314 Parameters
5315 ----------
5316 x
5317
5318 General description
5319 -------------------
5320 Returns the cosine of x.
5321 */
5322
5323 Eval_cos = function() {
5324 push(cadr(p1));
5325 Eval();
5326 return cosine();
5327 };
5328
5329 cosine = function() {
5330 save();
5331 p1 = pop();
5332 if (car(p1) === symbol(ADD)) {
5333 cosine_of_angle_sum();
5334 } else {
5335 cosine_of_angle();
5336 }
5337 return restore();
5338 };
5339
5340 cosine_of_angle_sum = function() {
5341 p2 = cdr(p1);
5342 while (iscons(p2)) {
5343 p4 = car(p2);
5344 if (isnpi(p4)) {
5345 push(p1);
5346 push(p4);
5347 subtract();
5348 p3 = pop();
5349 push(p3);
5350 cosine();
5351 push(p4);
5352 cosine();
5353 multiply();
5354 push(p3);
5355 sine();
5356 push(p4);
5357 sine();
5358 multiply();
5359 subtract();
5360 return;
5361 }
5362 p2 = cdr(p2);
5363 }
5364 return cosine_of_angle();
5365 };
5366
5367 cosine_of_angle = function() {
5368 var d, n;
5369 if (car(p1) === symbol(ARCCOS)) {
5370 push(cadr(p1));
5371 return;
5372 }
5373 if (isdouble(p1)) {
5374 d = Math.cos(p1.d);
5375 if (Math.abs(d) < 1e-10) {
5376 d = 0.0;
5377 }
5378 push_double(d);
5379 return;
5380 }
5381 if (isnegative(p1)) {
5382 push(p1);
5383 negate();
5384 p1 = pop();
5385 }
5386 if (car(p1) === symbol(ARCTAN)) {
5387 push_integer(1);
5388 push(cadr(p1));
5389 push_integer(2);
5390 power();
5391 add();
5392 push_rational(-1, 2);
5393 power();
5394 return;
5395 }
5396 push(p1);
5397 push_integer(180);
5398 multiply();
5399 if (evaluatingAsFloats) {
5400 push_double(Math.PI);
5401 } else {
5402 push_symbol(PI);
5403 }
5404 divide();
5405 n = pop_integer();
5406 if (n < 0 || isNaN(n)) {
5407 push(symbol(COS));
5408 push(p1);
5409 list(2);
5410 return;
5411 }
5412 switch (n % 360) {
5413 case 90:
5414 case 270:
5415 return push_integer(0);
5416 case 60:
5417 case 300:
5418 return push_rational(1, 2);
5419 case 120:
5420 case 240:
5421 return push_rational(-1, 2);
5422 case 45:
5423 case 315:
5424 push_rational(1, 2);
5425 push_integer(2);
5426 push_rational(1, 2);
5427 power();
5428 return multiply();
5429 case 135:
5430 case 225:
5431 push_rational(-1, 2);
5432 push_integer(2);
5433 push_rational(1, 2);
5434 power();
5435 return multiply();
5436 case 30:
5437 case 330:
5438 push_rational(1, 2);
5439 push_integer(3);
5440 push_rational(1, 2);
5441 power();
5442 return multiply();
5443 case 150:
5444 case 210:
5445 push_rational(-1, 2);
5446 push_integer(3);
5447 push_rational(1, 2);
5448 power();
5449 return multiply();
5450 case 0:
5451 return push_integer(1);
5452 case 180:
5453 return push_integer(-1);
5454 default:
5455 push(symbol(COS));
5456 push(p1);
5457 return list(2);
5458 }
5459 };
5460
5461
5462 /* cosh =====================================================================
5463
5464 Tags
5465 ----
5466 scripting, JS, internal, treenode, general concept
5467
5468 Parameters
5469 ----------
5470 x
5471
5472 General description
5473 -------------------
5474 Returns the hyperbolic cosine of x
5475
5476 ```
5477 exp(x) + exp(-x)
5478 cosh(x) = ----------------
5479 2
5480 ```
5481 */
5482
5483 Eval_cosh = function() {
5484 push(cadr(p1));
5485 Eval();
5486 return ycosh();
5487 };
5488
5489 ycosh = function() {
5490 save();
5491 yycosh();
5492 return restore();
5493 };
5494
5495 yycosh = function() {
5496 var d;
5497 d = 0.0;
5498 p1 = pop();
5499 if (car(p1) === symbol(ARCCOSH)) {
5500 push(cadr(p1));
5501 return;
5502 }
5503 if (isdouble(p1)) {
5504 d = Math.cosh(p1.d);
5505 if (Math.abs(d) < 1e-10) {
5506 d = 0.0;
5507 }
5508 push_double(d);
5509 return;
5510 }
5511 if (iszero(p1)) {
5512 push(one);
5513 return;
5514 }
5515 push_symbol(COSH);
5516 push(p1);
5517 return list(2);
5518 };
5519
5520 Eval_decomp = function() {
5521 var h;
5522 save();
5523 console.log("Eval_decomp is being called!!!!!!!!!!!!!!!!!!!!");
5524 h = tos;
5525 push(symbol(NIL));
5526 push(cadr(p1));
5527 Eval();
5528 push(caddr(p1));
5529 Eval();
5530 p1 = pop();
5531 if (p1 === symbol(NIL)) {
5532 guess();
5533 } else {
5534 push(p1);
5535 }
5536 decomp(false);
5537 list(tos - h);
5538 return restore();
5539 };
5540
5541 pushTryNotToDuplicate = function(toBePushed) {
5542 if (tos > 0) {
5543 if (DEBUG) {
5544 console.log("comparing " + toBePushed + " to: " + stack[tos - 1]);
5545 }
5546 if (equal(toBePushed, stack[tos - 1])) {
5547 if (DEBUG) {
5548 console.log("skipping " + toBePushed + " because it's already on stack ");
5549 }
5550 return;
5551 }
5552 }
5553 return push(toBePushed);
5554 };
5555
5556 decomp = function(generalTransform) {
5557 save();
5558 p2 = pop();
5559 p1 = pop();
5560 if (DEBUG) {
5561 console.log("DECOMPOSING " + p1);
5562 }
5563 if (generalTransform) {
5564 if (!iscons(p1)) {
5565 if (DEBUG) {
5566 console.log(" ground thing: " + p1);
5567 }
5568 pushTryNotToDuplicate(p1);
5569 restore();
5570 return;
5571 }
5572 } else {
5573 if (Find(p1, p2) === 0) {
5574 if (DEBUG) {
5575 console.log(" entire expression is constant");
5576 }
5577 pushTryNotToDuplicate(p1);
5578 restore();
5579 return;
5580 }
5581 }
5582 if (isadd(p1)) {
5583 decomp_sum(generalTransform);
5584 restore();
5585 return;
5586 }
5587 if (ismultiply(p1)) {
5588 decomp_product(generalTransform);
5589 restore();
5590 return;
5591 }
5592 if (DEBUG) {
5593 console.log(" naive decomp");
5594 }
5595 p3 = cdr(p1);
5596 if (DEBUG) {
5597 console.log("startig p3: " + p3);
5598 }
5599 while (iscons(p3)) {
5600 if (generalTransform) {
5601 push(car(p3));
5602 }
5603 if (DEBUG) {
5604 console.log("recursive decomposition");
5605 }
5606 push(car(p3));
5607 if (DEBUG) {
5608 console.log("car(p3): " + car(p3));
5609 }
5610 push(p2);
5611 if (DEBUG) {
5612 console.log("p2: " + p2);
5613 }
5614 decomp(generalTransform);
5615 p3 = cdr(p3);
5616 }
5617 return restore();
5618 };
5619
5620 decomp_sum = function(generalTransform) {
5621 var h;
5622 if (DEBUG) {
5623 console.log(" decomposing the sum ");
5624 }
5625 h = 0;
5626 p3 = cdr(p1);
5627 while (iscons(p3)) {
5628 if (Find(car(p3), p2) || generalTransform) {
5629 push(car(p3));
5630 push(p2);
5631 decomp(generalTransform);
5632 }
5633 p3 = cdr(p3);
5634 }
5635 h = tos;
5636 p3 = cdr(p1);
5637 while (iscons(p3)) {
5638 if (Find(car(p3), p2) === 0) {
5639 pushTryNotToDuplicate(car(p3));
5640 }
5641 p3 = cdr(p3);
5642 }
5643 if (tos - h) {
5644 add_all(tos - h);
5645 p3 = pop();
5646 pushTryNotToDuplicate(p3);
5647 push(p3);
5648 return negate();
5649 }
5650 };
5651
5652 decomp_product = function(generalTransform) {
5653 var h;
5654 if (DEBUG) {
5655 console.log(" decomposing the product ");
5656 }
5657 h = 0;
5658 p3 = cdr(p1);
5659 while (iscons(p3)) {
5660 if (Find(car(p3), p2) || generalTransform) {
5661 push(car(p3));
5662 push(p2);
5663 decomp(generalTransform);
5664 }
5665 p3 = cdr(p3);
5666 }
5667 h = tos;
5668 p3 = cdr(p1);
5669 while (iscons(p3)) {
5670 if (Find(car(p3), p2) === 0) {
5671 pushTryNotToDuplicate(car(p3));
5672 }
5673 p3 = cdr(p3);
5674 }
5675 if (tos - h) {
5676 return multiply_all(tos - h);
5677 }
5678 };
5679
5680 define_user_function = function() {
5681 p3 = caadr(p1);
5682 p4 = cdadr(p1);
5683 p5 = caddr(p1);
5684 if (!issymbol(p3)) {
5685 stop("function name?");
5686 }
5687 if (car(p5) === symbol(EVAL)) {
5688 push(cadr(p5));
5689 Eval();
5690 p5 = pop();
5691 }
5692 push_symbol(FUNCTION);
5693 push(p5);
5694 push(p4);
5695 list(3);
5696 p5 = pop();
5697 set_binding(p3, p5);
5698 return push_symbol(NIL);
5699 };
5700
5701 Eval_function_reference = function() {
5702 return push(p1);
5703 };
5704
5705
5706 /* defint =====================================================================
5707
5708 Tags
5709 ----
5710 scripting, JS, internal, treenode, general concept
5711
5712 Parameters
5713 ----------
5714 f,x,a,b[,y,c,d...]
5715
5716 General description
5717 -------------------
5718 Returns the definite integral of f with respect to x evaluated from "a" to b.
5719 The argument list can be extended for multiple integrals (or "iterated
5720 integrals"), for example a double integral (which can represent for
5721 example a volume under a surface), or a triple integral, etc. For
5722 example, defint(f,x,a,b,y,c,d).
5723 */
5724
5725 Eval_defint = function() {
5726 push(cadr(p1));
5727 Eval();
5728 p2 = pop();
5729 p1 = cddr(p1);
5730 while (iscons(p1)) {
5731 push(car(p1));
5732 p1 = cdr(p1);
5733 Eval();
5734 p3 = pop();
5735 push(car(p1));
5736 p1 = cdr(p1);
5737 Eval();
5738 p4 = pop();
5739 push(car(p1));
5740 p1 = cdr(p1);
5741 Eval();
5742 p5 = pop();
5743 push(p2);
5744 push(p3);
5745 integral();
5746 p2 = pop();
5747 push(p2);
5748 push(p3);
5749 push(p5);
5750 subst();
5751 Eval();
5752 push(p2);
5753 push(p3);
5754 push(p4);
5755 subst();
5756 Eval();
5757 subtract();
5758 p2 = pop();
5759 }
5760 return push(p2);
5761 };
5762
5763
5764 /* deg =====================================================================
5765
5766 Tags
5767 ----
5768 scripting, JS, internal, treenode, general concept
5769
5770 Parameters
5771 ----------
5772 p,x
5773
5774 General description
5775 -------------------
5776 Returns the degree of polynomial p(x).
5777 */
5778
5779 Eval_degree = function() {
5780 push(cadr(p1));
5781 Eval();
5782 push(caddr(p1));
5783 Eval();
5784 p1 = pop();
5785 if (p1 === symbol(NIL)) {
5786 guess();
5787 } else {
5788 push(p1);
5789 }
5790 return degree();
5791 };
5792
5793 degree = function() {
5794 save();
5795 p2 = pop();
5796 p1 = pop();
5797 p3 = zero;
5798 yydegree(p1);
5799 push(p3);
5800 return restore();
5801 };
5802
5803 yydegree = function(p) {
5804 var results;
5805 if (equal(p, p2)) {
5806 if (iszero(p3)) {
5807 return p3 = one;
5808 }
5809 } else if (car(p) === symbol(POWER)) {
5810 if (equal(cadr(p), p2) && isnum(caddr(p)) && lessp(p3, caddr(p))) {
5811 return p3 = caddr(p);
5812 }
5813 } else if (iscons(p)) {
5814 p = cdr(p);
5815 results = [];
5816 while (iscons(p)) {
5817 yydegree(car(p));
5818 results.push(p = cdr(p));
5819 }
5820 return results;
5821 }
5822 };
5823
5824
5825 /* denominator =====================================================================
5826
5827 Tags
5828 ----
5829 scripting, JS, internal, treenode, general concept
5830
5831 Parameters
5832 ----------
5833 x
5834
5835 General description
5836 -------------------
5837 Returns the denominator of expression x.
5838 */
5839
5840 Eval_denominator = function() {
5841 push(cadr(p1));
5842 Eval();
5843 return denominator();
5844 };
5845
5846 denominator = function() {
5847 var h;
5848 h = 0;
5849 save();
5850 p1 = pop();
5851 if (car(p1) === symbol(ADD)) {
5852 push(p1);
5853 rationalize();
5854 p1 = pop();
5855 }
5856 if (car(p1) === symbol(MULTIPLY)) {
5857 h = tos;
5858 p1 = cdr(p1);
5859 while (iscons(p1)) {
5860 push(car(p1));
5861 denominator();
5862 p1 = cdr(p1);
5863 }
5864 multiply_all(tos - h);
5865 } else if (isrational(p1)) {
5866 push(p1);
5867 mp_denominator();
5868 } else if (car(p1) === symbol(POWER) && isnegativeterm(caddr(p1))) {
5869 push(p1);
5870 reciprocate();
5871 } else {
5872 push(one);
5873 }
5874 return restore();
5875 };
5876
5877 Eval_derivative = function() {
5878 var doNothing, i, i1, n, o, ref, ref1;
5879 i = 0;
5880 p1 = cdr(p1);
5881 push(car(p1));
5882 Eval();
5883 p1 = cdr(p1);
5884 push(car(p1));
5885 Eval();
5886 p2 = pop();
5887 if (p2 === symbol(NIL)) {
5888 guess();
5889 push(symbol(NIL));
5890 } else if (isnum(p2)) {
5891 guess();
5892 push(p2);
5893 } else {
5894 push(p2);
5895 p1 = cdr(p1);
5896 push(car(p1));
5897 Eval();
5898 }
5899 p5 = pop();
5900 p4 = pop();
5901 p3 = pop();
5902 while (1) {
5903 if (isnum(p5)) {
5904 push(p5);
5905 n = pop_integer();
5906 if (isNaN(n)) {
5907 stop("nth derivative: check n");
5908 }
5909 } else {
5910 n = 1;
5911 }
5912 push(p3);
5913 if (n >= 0) {
5914 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
5915 push(p4);
5916 derivative();
5917 }
5918 } else {
5919 n = -n;
5920 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
5921 push(p4);
5922 integral();
5923 }
5924 }
5925 p3 = pop();
5926 if (p5 === symbol(NIL)) {
5927 break;
5928 }
5929 if (isnum(p5)) {
5930 p1 = cdr(p1);
5931 push(car(p1));
5932 Eval();
5933 p5 = pop();
5934 if (p5 === symbol(NIL)) {
5935 break;
5936 }
5937 if (isnum(p5)) {
5938 doNothing = 1;
5939 } else {
5940 p4 = p5;
5941 p1 = cdr(p1);
5942 push(car(p1));
5943 Eval();
5944 p5 = pop();
5945 }
5946 } else {
5947 p4 = p5;
5948 p1 = cdr(p1);
5949 push(car(p1));
5950 Eval();
5951 p5 = pop();
5952 }
5953 }
5954 return push(p3);
5955 };
5956
5957 derivative = function() {
5958 save();
5959 p2 = pop();
5960 p1 = pop();
5961 if (isnum(p2)) {
5962 stop("undefined function");
5963 }
5964 if (istensor(p1)) {
5965 if (istensor(p2)) {
5966 d_tensor_tensor();
5967 } else {
5968 d_tensor_scalar();
5969 }
5970 } else {
5971 if (istensor(p2)) {
5972 d_scalar_tensor();
5973 } else {
5974 d_scalar_scalar();
5975 }
5976 }
5977 return restore();
5978 };
5979
5980 d_scalar_scalar = function() {
5981 if (issymbol(p2)) {
5982 return d_scalar_scalar_1();
5983 } else {
5984 push(p1);
5985 push(p2);
5986 push(symbol(SECRETX));
5987 subst();
5988 push(symbol(SECRETX));
5989 derivative();
5990 push(symbol(SECRETX));
5991 push(p2);
5992 return subst();
5993 }
5994 };
5995
5996 d_scalar_scalar_1 = function() {
5997 if (equal(p1, p2)) {
5998 push(one);
5999 return;
6000 }
6001 if (!iscons(p1)) {
6002 push(zero);
6003 return;
6004 }
6005 if (isadd(p1)) {
6006 dsum();
6007 return;
6008 }
6009 if (car(p1) === symbol(MULTIPLY)) {
6010 dproduct();
6011 return;
6012 }
6013 if (car(p1) === symbol(POWER)) {
6014 dpower();
6015 return;
6016 }
6017 if (car(p1) === symbol(DERIVATIVE)) {
6018 dd();
6019 return;
6020 }
6021 if (car(p1) === symbol(LOG)) {
6022 dlog();
6023 return;
6024 }
6025 if (car(p1) === symbol(SIN)) {
6026 dsin();
6027 return;
6028 }
6029 if (car(p1) === symbol(COS)) {
6030 dcos();
6031 return;
6032 }
6033 if (car(p1) === symbol(TAN)) {
6034 dtan();
6035 return;
6036 }
6037 if (car(p1) === symbol(ARCSIN)) {
6038 darcsin();
6039 return;
6040 }
6041 if (car(p1) === symbol(ARCCOS)) {
6042 darccos();
6043 return;
6044 }
6045 if (car(p1) === symbol(ARCTAN)) {
6046 darctan();
6047 return;
6048 }
6049 if (car(p1) === symbol(SINH)) {
6050 dsinh();
6051 return;
6052 }
6053 if (car(p1) === symbol(COSH)) {
6054 dcosh();
6055 return;
6056 }
6057 if (car(p1) === symbol(TANH)) {
6058 dtanh();
6059 return;
6060 }
6061 if (car(p1) === symbol(ARCSINH)) {
6062 darcsinh();
6063 return;
6064 }
6065 if (car(p1) === symbol(ARCCOSH)) {
6066 darccosh();
6067 return;
6068 }
6069 if (car(p1) === symbol(ARCTANH)) {
6070 darctanh();
6071 return;
6072 }
6073 if (car(p1) === symbol(ABS)) {
6074 dabs();
6075 return;
6076 }
6077 if (car(p1) === symbol(SGN)) {
6078 dsgn();
6079 return;
6080 }
6081 if (car(p1) === symbol(HERMITE)) {
6082 dhermite();
6083 return;
6084 }
6085 if (car(p1) === symbol(ERF)) {
6086 derf();
6087 return;
6088 }
6089 if (car(p1) === symbol(ERFC)) {
6090 derfc();
6091 return;
6092 }
6093 if (car(p1) === symbol(BESSELJ)) {
6094 if (iszero(caddr(p1))) {
6095 dbesselj0();
6096 } else {
6097 dbesseljn();
6098 }
6099 return;
6100 }
6101 if (car(p1) === symbol(BESSELY)) {
6102 if (iszero(caddr(p1))) {
6103 dbessely0();
6104 } else {
6105 dbesselyn();
6106 }
6107 return;
6108 }
6109 if (car(p1) === symbol(INTEGRAL) && caddr(p1) === p2) {
6110 derivative_of_integral();
6111 return;
6112 }
6113 return dfunction();
6114 };
6115
6116 dsum = function() {
6117 var h;
6118 h = tos;
6119 p1 = cdr(p1);
6120 while (iscons(p1)) {
6121 push(car(p1));
6122 push(p2);
6123 derivative();
6124 p1 = cdr(p1);
6125 }
6126 return add_all(tos - h);
6127 };
6128
6129 dproduct = function() {
6130 var i, i1, j, n, o, ref, ref1;
6131 i = 0;
6132 j = 0;
6133 n = 0;
6134 n = length(p1) - 1;
6135 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6136 p3 = cdr(p1);
6137 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
6138 push(car(p3));
6139 if (i === j) {
6140 push(p2);
6141 derivative();
6142 }
6143 p3 = cdr(p3);
6144 }
6145 multiply_all(n);
6146 }
6147 return add_all(n);
6148 };
6149
6150 dpower = function() {
6151 push(caddr(p1));
6152 push(cadr(p1));
6153 divide();
6154 push(cadr(p1));
6155 push(p2);
6156 derivative();
6157 multiply();
6158 push(cadr(p1));
6159 logarithm();
6160 push(caddr(p1));
6161 push(p2);
6162 derivative();
6163 multiply();
6164 add();
6165 push(p1);
6166 return multiply();
6167 };
6168
6169 dlog = function() {
6170 push(cadr(p1));
6171 push(p2);
6172 derivative();
6173 push(cadr(p1));
6174 return divide();
6175 };
6176
6177 dd = function() {
6178 push(cadr(p1));
6179 push(p2);
6180 derivative();
6181 p3 = pop();
6182 if (car(p3) === symbol(DERIVATIVE)) {
6183 push_symbol(DERIVATIVE);
6184 push_symbol(DERIVATIVE);
6185 push(cadr(p3));
6186 if (lessp(caddr(p3), caddr(p1))) {
6187 push(caddr(p3));
6188 list(3);
6189 push(caddr(p1));
6190 } else {
6191 push(caddr(p1));
6192 list(3);
6193 push(caddr(p3));
6194 }
6195 return list(3);
6196 } else {
6197 push(p3);
6198 push(caddr(p1));
6199 return derivative();
6200 }
6201 };
6202
6203 dfunction = function() {
6204 p3 = cdr(p1);
6205 if (p3 === symbol(NIL) || Find(p3, p2)) {
6206 push_symbol(DERIVATIVE);
6207 push(p1);
6208 push(p2);
6209 return list(3);
6210 } else {
6211 return push(zero);
6212 }
6213 };
6214
6215 dsin = function() {
6216 push(cadr(p1));
6217 push(p2);
6218 derivative();
6219 push(cadr(p1));
6220 cosine();
6221 return multiply();
6222 };
6223
6224 dcos = function() {
6225 push(cadr(p1));
6226 push(p2);
6227 derivative();
6228 push(cadr(p1));
6229 sine();
6230 multiply();
6231 return negate();
6232 };
6233
6234 dtan = function() {
6235 push(cadr(p1));
6236 push(p2);
6237 derivative();
6238 push(cadr(p1));
6239 cosine();
6240 push_integer(-2);
6241 power();
6242 return multiply();
6243 };
6244
6245 darcsin = function() {
6246 push(cadr(p1));
6247 push(p2);
6248 derivative();
6249 push_integer(1);
6250 push(cadr(p1));
6251 push_integer(2);
6252 power();
6253 subtract();
6254 push_rational(-1, 2);
6255 power();
6256 return multiply();
6257 };
6258
6259 darccos = function() {
6260 push(cadr(p1));
6261 push(p2);
6262 derivative();
6263 push_integer(1);
6264 push(cadr(p1));
6265 push_integer(2);
6266 power();
6267 subtract();
6268 push_rational(-1, 2);
6269 power();
6270 multiply();
6271 return negate();
6272 };
6273
6274 darctan = function() {
6275 push(cadr(p1));
6276 push(p2);
6277 derivative();
6278 push_integer(1);
6279 push(cadr(p1));
6280 push_integer(2);
6281 power();
6282 add();
6283 inverse();
6284 multiply();
6285 return simplify();
6286 };
6287
6288 dsinh = function() {
6289 push(cadr(p1));
6290 push(p2);
6291 derivative();
6292 push(cadr(p1));
6293 ycosh();
6294 return multiply();
6295 };
6296
6297 dcosh = function() {
6298 push(cadr(p1));
6299 push(p2);
6300 derivative();
6301 push(cadr(p1));
6302 ysinh();
6303 return multiply();
6304 };
6305
6306 dtanh = function() {
6307 push(cadr(p1));
6308 push(p2);
6309 derivative();
6310 push(cadr(p1));
6311 ycosh();
6312 push_integer(-2);
6313 power();
6314 return multiply();
6315 };
6316
6317 darcsinh = function() {
6318 push(cadr(p1));
6319 push(p2);
6320 derivative();
6321 push(cadr(p1));
6322 push_integer(2);
6323 power();
6324 push_integer(1);
6325 add();
6326 push_rational(-1, 2);
6327 power();
6328 return multiply();
6329 };
6330
6331 darccosh = function() {
6332 push(cadr(p1));
6333 push(p2);
6334 derivative();
6335 push(cadr(p1));
6336 push_integer(2);
6337 power();
6338 push_integer(-1);
6339 add();
6340 push_rational(-1, 2);
6341 power();
6342 return multiply();
6343 };
6344
6345 darctanh = function() {
6346 push(cadr(p1));
6347 push(p2);
6348 derivative();
6349 push_integer(1);
6350 push(cadr(p1));
6351 push_integer(2);
6352 power();
6353 subtract();
6354 inverse();
6355 return multiply();
6356 };
6357
6358 dabs = function() {
6359 push(cadr(p1));
6360 push(p2);
6361 derivative();
6362 push(cadr(p1));
6363 sgn();
6364 return multiply();
6365 };
6366
6367 dsgn = function() {
6368 push(cadr(p1));
6369 push(p2);
6370 derivative();
6371 push(cadr(p1));
6372 dirac();
6373 multiply();
6374 push_integer(2);
6375 return multiply();
6376 };
6377
6378 dhermite = function() {
6379 push(cadr(p1));
6380 push(p2);
6381 derivative();
6382 push_integer(2);
6383 push(caddr(p1));
6384 multiply();
6385 multiply();
6386 push(cadr(p1));
6387 push(caddr(p1));
6388 push_integer(-1);
6389 add();
6390 hermite();
6391 return multiply();
6392 };
6393
6394 derf = function() {
6395 push(cadr(p1));
6396 push_integer(2);
6397 power();
6398 push_integer(-1);
6399 multiply();
6400 exponential();
6401 if (evaluatingAsFloats) {
6402 push_double(Math.PI);
6403 } else {
6404 push_symbol(PI);
6405 }
6406 push_rational(-1, 2);
6407 power();
6408 multiply();
6409 push_integer(2);
6410 multiply();
6411 push(cadr(p1));
6412 push(p2);
6413 derivative();
6414 return multiply();
6415 };
6416
6417 derfc = function() {
6418 push(cadr(p1));
6419 push_integer(2);
6420 power();
6421 push_integer(-1);
6422 multiply();
6423 exponential();
6424 if (evaluatingAsFloats) {
6425 push_double(Math.PI);
6426 } else {
6427 push_symbol(PI);
6428 }
6429 push_rational(-1, 2);
6430 power();
6431 multiply();
6432 push_integer(-2);
6433 multiply();
6434 push(cadr(p1));
6435 push(p2);
6436 derivative();
6437 return multiply();
6438 };
6439
6440 dbesselj0 = function() {
6441 push(cadr(p1));
6442 push(p2);
6443 derivative();
6444 push(cadr(p1));
6445 push_integer(1);
6446 besselj();
6447 multiply();
6448 push_integer(-1);
6449 return multiply();
6450 };
6451
6452 dbesseljn = function() {
6453 push(cadr(p1));
6454 push(p2);
6455 derivative();
6456 push(cadr(p1));
6457 push(caddr(p1));
6458 push_integer(-1);
6459 add();
6460 besselj();
6461 push(caddr(p1));
6462 push_integer(-1);
6463 multiply();
6464 push(cadr(p1));
6465 divide();
6466 push(cadr(p1));
6467 push(caddr(p1));
6468 besselj();
6469 multiply();
6470 add();
6471 return multiply();
6472 };
6473
6474 dbessely0 = function() {
6475 push(cadr(p1));
6476 push(p2);
6477 derivative();
6478 push(cadr(p1));
6479 push_integer(1);
6480 besselj();
6481 multiply();
6482 push_integer(-1);
6483 return multiply();
6484 };
6485
6486 dbesselyn = function() {
6487 push(cadr(p1));
6488 push(p2);
6489 derivative();
6490 push(cadr(p1));
6491 push(caddr(p1));
6492 push_integer(-1);
6493 add();
6494 bessely();
6495 push(caddr(p1));
6496 push_integer(-1);
6497 multiply();
6498 push(cadr(p1));
6499 divide();
6500 push(cadr(p1));
6501 push(caddr(p1));
6502 bessely();
6503 multiply();
6504 add();
6505 return multiply();
6506 };
6507
6508 derivative_of_integral = function() {
6509 return push(cadr(p1));
6510 };
6511
6512
6513 /* det =====================================================================
6514
6515 Tags
6516 ----
6517 scripting, JS, internal, treenode, general concept
6518
6519 Parameters
6520 ----------
6521 m
6522
6523 General description
6524 -------------------
6525 Returns the determinant of matrix m.
6526 Uses Gaussian elimination for numerical matrices.
6527
6528 Example:
6529
6530 det(((1,2),(3,4)))
6531 > -2
6532 */
6533
6534 DET_check_arg = function() {
6535 if (!istensor(p1)) {
6536 return 0;
6537 } else if (p1.tensor.ndim !== 2) {
6538 return 0;
6539 } else if (p1.tensor.dim[0] !== p1.tensor.dim[1]) {
6540 return 0;
6541 } else {
6542 return 1;
6543 }
6544 };
6545
6546 det = function() {
6547 var a, i, i1, n, o, ref, ref1;
6548 i = 0;
6549 n = 0;
6550 save();
6551 p1 = pop();
6552 if (DET_check_arg() === 0) {
6553 push_symbol(DET);
6554 push(p1);
6555 list(2);
6556 restore();
6557 return;
6558 }
6559 n = p1.tensor.nelem;
6560 a = p1.tensor.elem;
6561 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6562 if (!isnum(a[i])) {
6563 break;
6564 }
6565 }
6566 if (i === n) {
6567 yydetg();
6568 } else {
6569 for (i = i1 = 0, ref1 = p1.tensor.nelem; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
6570 push(p1.tensor.elem[i]);
6571 }
6572 determinant(p1.tensor.dim[0]);
6573 }
6574 return restore();
6575 };
6576
6577 determinant = function(n) {
6578 var a, breakFromOutherWhile, h, i, i1, j, k, o, q, ref, ref1, s, sign_, t;
6579 h = 0;
6580 i = 0;
6581 j = 0;
6582 k = 0;
6583 q = 0;
6584 s = 0;
6585 sign_ = 0;
6586 t = 0;
6587 a = [];
6588 h = tos - n * n;
6589 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6590 a[i] = i;
6591 a[i + n] = 0;
6592 a[i + n + n] = 1;
6593 }
6594 sign_ = 1;
6595 push(zero);
6596 while (1) {
6597 if (sign_ === 1) {
6598 push_integer(1);
6599 } else {
6600 push_integer(-1);
6601 }
6602 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
6603 k = n * a[i] + i;
6604 push(stack[h + k]);
6605 multiply();
6606 }
6607 add();
6608 j = n - 1;
6609 s = 0;
6610 breakFromOutherWhile = false;
6611 while (1) {
6612 q = a[n + j] + a[n + n + j];
6613 if (q < 0) {
6614 a[n + n + j] = -a[n + n + j];
6615 j--;
6616 continue;
6617 }
6618 if (q === j + 1) {
6619 if (j === 0) {
6620 breakFromOutherWhile = true;
6621 break;
6622 }
6623 s++;
6624 a[n + n + j] = -a[n + n + j];
6625 j--;
6626 continue;
6627 }
6628 break;
6629 }
6630 if (breakFromOutherWhile) {
6631 break;
6632 }
6633 t = a[j - a[n + j] + s];
6634 a[j - a[n + j] + s] = a[j - q + s];
6635 a[j - q + s] = t;
6636 a[n + j] = q;
6637 sign_ = -sign_;
6638 }
6639 stack[h] = stack[tos - 1];
6640 return moveTos(h + 1);
6641 };
6642
6643 detg = function() {
6644 save();
6645 p1 = pop();
6646 if (DET_check_arg() === 0) {
6647 push_symbol(DET);
6648 push(p1);
6649 list(2);
6650 restore();
6651 return;
6652 }
6653 yydetg();
6654 return restore();
6655 };
6656
6657 yydetg = function() {
6658 var i, n, o, ref;
6659 i = 0;
6660 n = 0;
6661 n = p1.tensor.dim[0];
6662 for (i = o = 0, ref = n * n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6663 push(p1.tensor.elem[i]);
6664 }
6665 lu_decomp(n);
6666 moveTos(tos - n * n);
6667 return push(p1);
6668 };
6669
6670 M = function(h, n, i, j) {
6671 return stack[h + n * i + j];
6672 };
6673
6674 setM = function(h, n, i, j, value) {
6675 return stack[h + n * i + j] = value;
6676 };
6677
6678 lu_decomp = function(n) {
6679 var d, h, i, i1, j, j1, l1, m1, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8;
6680 d = 0;
6681 h = 0;
6682 i = 0;
6683 j = 0;
6684 h = tos - n * n;
6685 p1 = one;
6686 for (d = o = 0, ref = n - 1; 0 <= ref ? o < ref : o > ref; d = 0 <= ref ? ++o : --o) {
6687 if (equal(M(h, n, d, d), zero)) {
6688 for (i = i1 = ref1 = d + 1, ref2 = n; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
6689 if (!equal(M(h, n, i, d), zero)) {
6690 break;
6691 }
6692 }
6693 if (i === n) {
6694 p1 = zero;
6695 break;
6696 }
6697 for (j = j1 = ref3 = d, ref4 = n; ref3 <= ref4 ? j1 < ref4 : j1 > ref4; j = ref3 <= ref4 ? ++j1 : --j1) {
6698 p2 = M(h, n, d, j);
6699 setM(h, n, d, j, M(h, n, i, j));
6700 setM(h, n, i, j, p2);
6701 }
6702 push(p1);
6703 negate();
6704 p1 = pop();
6705 }
6706 push(p1);
6707 push(M(h, n, d, d));
6708 multiply();
6709 p1 = pop();
6710 for (i = l1 = ref5 = d + 1, ref6 = n; ref5 <= ref6 ? l1 < ref6 : l1 > ref6; i = ref5 <= ref6 ? ++l1 : --l1) {
6711 push(M(h, n, i, d));
6712 push(M(h, n, d, d));
6713 divide();
6714 negate();
6715 p2 = pop();
6716 setM(h, n, i, d, zero);
6717 for (j = m1 = ref7 = d + 1, ref8 = n; ref7 <= ref8 ? m1 < ref8 : m1 > ref8; j = ref7 <= ref8 ? ++m1 : --m1) {
6718 push(M(h, n, d, j));
6719 push(p2);
6720 multiply();
6721 push(M(h, n, i, j));
6722 add();
6723 setM(h, n, i, j, pop());
6724 }
6725 }
6726 }
6727 push(p1);
6728 push(M(h, n, n - 1, n - 1));
6729 multiply();
6730 return p1 = pop();
6731 };
6732
6733 Eval_dirac = function() {
6734 push(cadr(p1));
6735 Eval();
6736 return dirac();
6737 };
6738
6739 dirac = function() {
6740 save();
6741 ydirac();
6742 return restore();
6743 };
6744
6745 ydirac = function() {
6746 p1 = pop();
6747 if (isdouble(p1)) {
6748 if (p1.d === 0) {
6749 push_integer(1);
6750 return;
6751 } else {
6752 push_integer(0);
6753 return;
6754 }
6755 }
6756 if (isrational(p1)) {
6757 if (MZERO(mmul(p1.q.a, p1.q.b))) {
6758 push_integer(1);
6759 return;
6760 } else {
6761 push_integer(0);
6762 return;
6763 }
6764 }
6765 if (car(p1) === symbol(POWER)) {
6766 push_symbol(DIRAC);
6767 push(cadr(p1));
6768 list(2);
6769 return;
6770 }
6771 if (isnegativeterm(p1)) {
6772 push_symbol(DIRAC);
6773 push(p1);
6774 negate();
6775 list(2);
6776 return;
6777 }
6778 if (isnegativeterm(p1) || (car(p1) === symbol(ADD) && isnegativeterm(cadr(p1)))) {
6779 push(p1);
6780 negate();
6781 p1 = pop();
6782 }
6783 push_symbol(DIRAC);
6784 push(p1);
6785 return list(2);
6786 };
6787
6788 divisors = function() {
6789 var h, i, n, o, ref, subsetOfStack;
6790 i = 0;
6791 h = 0;
6792 n = 0;
6793 save();
6794 h = tos - 1;
6795 divisors_onstack();
6796 n = tos - h;
6797 subsetOfStack = stack.slice(h, h + n);
6798 subsetOfStack.sort(cmp_expr);
6799 stack = stack.slice(0, h).concat(subsetOfStack).concat(stack.slice(h + n));
6800 p1 = alloc_tensor(n);
6801 p1.tensor.ndim = 1;
6802 p1.tensor.dim[0] = n;
6803 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6804 p1.tensor.elem[i] = stack[h + i];
6805 }
6806 moveTos(h);
6807 push(p1);
6808 return restore();
6809 };
6810
6811 divisors_onstack = function() {
6812 var h, i, k, n, o, ref;
6813 h = 0;
6814 i = 0;
6815 k = 0;
6816 n = 0;
6817 save();
6818 p1 = pop();
6819 h = tos;
6820 if (isnum(p1)) {
6821 push(p1);
6822 factor_small_number();
6823 } else if (car(p1) === symbol(ADD)) {
6824 push(p1);
6825 __factor_add();
6826 } else if (car(p1) === symbol(MULTIPLY)) {
6827 p1 = cdr(p1);
6828 if (isnum(car(p1))) {
6829 push(car(p1));
6830 factor_small_number();
6831 p1 = cdr(p1);
6832 }
6833 while (iscons(p1)) {
6834 p2 = car(p1);
6835 if (car(p2) === symbol(POWER)) {
6836 push(cadr(p2));
6837 push(caddr(p2));
6838 } else {
6839 push(p2);
6840 push(one);
6841 }
6842 p1 = cdr(p1);
6843 }
6844 } else if (car(p1) === symbol(POWER)) {
6845 push(cadr(p1));
6846 push(caddr(p1));
6847 } else {
6848 push(p1);
6849 push(one);
6850 }
6851 k = tos;
6852 push(one);
6853 gen(h, k);
6854 n = tos - k;
6855 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6856 stack[h + i] = stack[k + i];
6857 }
6858 moveTos(h + n);
6859 return restore();
6860 };
6861
6862 gen = function(h, k) {
6863 var expo, i, o, ref;
6864 expo = 0;
6865 i = 0;
6866 save();
6867 p1 = pop();
6868 if (h === k) {
6869 push(p1);
6870 restore();
6871 return;
6872 }
6873 p2 = stack[h + 0];
6874 p3 = stack[h + 1];
6875 push(p3);
6876 expo = pop_integer();
6877 if (!isNaN(expo)) {
6878 for (i = o = 0, ref = Math.abs(expo); 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) {
6879 push(p1);
6880 push(p2);
6881 push_integer(sign(expo) * i);
6882 power();
6883 multiply();
6884 gen(h + 2, k);
6885 }
6886 }
6887 return restore();
6888 };
6889
6890 __factor_add = function() {
6891 save();
6892 p1 = pop();
6893 p3 = cdr(p1);
6894 push(car(p3));
6895 p3 = cdr(p3);
6896 while (iscons(p3)) {
6897 push(car(p3));
6898 gcd();
6899 p3 = cdr(p3);
6900 }
6901 p2 = pop();
6902 if (isplusone(p2)) {
6903 push(p1);
6904 push(one);
6905 restore();
6906 return;
6907 }
6908 if (isnum(p2)) {
6909 push(p2);
6910 factor_small_number();
6911 } else if (car(p2) === symbol(MULTIPLY)) {
6912 p3 = cdr(p2);
6913 if (isnum(car(p3))) {
6914 push(car(p3));
6915 factor_small_number();
6916 } else {
6917 push(car(p3));
6918 push(one);
6919 }
6920 p3 = cdr(p3);
6921 while (iscons(p3)) {
6922 push(car(p3));
6923 push(one);
6924 p3 = cdr(p3);
6925 }
6926 } else {
6927 push(p2);
6928 push(one);
6929 }
6930 push(p2);
6931 inverse();
6932 p2 = pop();
6933 push(zero);
6934 p3 = cdr(p1);
6935 while (iscons(p3)) {
6936 push(p2);
6937 push(car(p3));
6938 multiply();
6939 add();
6940 p3 = cdr(p3);
6941 }
6942 push(one);
6943 return restore();
6944 };
6945
6946 dpow = function() {
6947 var a, b, base, expo, result, theta;
6948 a = 0.0;
6949 b = 0.0;
6950 base = 0.0;
6951 expo = 0.0;
6952 result = 0.0;
6953 theta = 0.0;
6954 expo = pop_double();
6955 base = pop_double();
6956 if (base === 0.0 && expo < 0.0) {
6957 stop("divide by zero");
6958 }
6959 if (base >= 0.0 || (expo % 1.0) === 0.0) {
6960 result = Math.pow(base, expo);
6961 push_double(result);
6962 return;
6963 }
6964 result = Math.pow(Math.abs(base), expo);
6965 theta = Math.PI * expo;
6966 if ((expo % 0.5) === 0.0) {
6967 a = 0.0;
6968 b = Math.sin(theta);
6969 } else {
6970 a = Math.cos(theta);
6971 b = Math.sin(theta);
6972 }
6973 push_double(a * result);
6974 push_double(b * result);
6975 push(imaginaryunit);
6976 multiply();
6977 return add();
6978 };
6979
6980
6981 /* eigen =====================================================================
6982
6983 Tags
6984 ----
6985 scripting, JS, internal, treenode, general concept
6986
6987 Parameters
6988 ----------
6989 m
6990
6991 General description
6992 -------------------
6993 Compute eigenvalues and eigenvectors. Matrix m must be both numerical and symmetric.
6994 The eigenval function returns a matrix with the eigenvalues along the diagonal.
6995 The eigenvec function returns a matrix with the eigenvectors arranged as row vectors.
6996 The eigen function does not return anything but stores the eigenvalue matrix in D
6997 and the eigenvector matrix in Q.
6998
6999 Input: stack[tos - 1] symmetric matrix
7000
7001 Output: D diagnonal matrix
7002 Q eigenvector matrix
7003
7004 D and Q have the property that
7005
7006 A == dot(transpose(Q),D,Q)
7007
7008 where A is the original matrix.
7009
7010 The eigenvalues are on the diagonal of D.
7011 The eigenvectors are row vectors in Q.
7012
7013 The eigenvalue relation:
7014
7015 A X = lambda X
7016
7017 can be checked as follows:
7018
7019 lambda = D[1,1]
7020 X = Q[1]
7021 dot(A,X) - lambda X
7022
7023 Example 1. Check the relation AX = lambda X where lambda is an eigenvalue and X is the associated eigenvector.
7024
7025 Enter:
7026
7027 A = hilbert(3)
7028
7029 eigen(A)
7030
7031 lambda = D[1,1]
7032
7033 X = Q[1]
7034
7035 dot(A,X) - lambda X
7036
7037 Result:
7038
7039 -1.16435e-14
7040
7041 -6.46705e-15
7042
7043 -4.55191e-15
7044
7045 Example 2: Check the relation A = QTDQ.
7046
7047 Enter:
7048
7049 A - dot(transpose(Q),D,Q)
7050
7051 Result:
7052
7053 6.27365e-12 -1.58236e-11 1.81902e-11
7054
7055 -1.58236e-11 -1.95365e-11 2.56514e-12
7056
7057 1.81902e-11 2.56514e-12 1.32627e-11
7058 */
7059
7060 EIG_N = 0;
7061
7062 EIG_yydd = [];
7063
7064 EIG_yyqq = [];
7065
7066 Eval_eigen = function() {
7067 if (EIG_check_arg() === 0) {
7068 stop("eigen: argument is not a square matrix");
7069 }
7070 eigen(EIGEN);
7071 p1 = usr_symbol("D");
7072 set_binding(p1, p2);
7073 p1 = usr_symbol("Q");
7074 set_binding(p1, p3);
7075 return push(symbol(NIL));
7076 };
7077
7078
7079 /* eigenval =====================================================================
7080
7081 Tags
7082 ----
7083 scripting, JS, internal, treenode, general concept
7084
7085 Parameters
7086 ----------
7087 m
7088
7089 General description
7090 -------------------
7091 Compute eigenvalues of m. See "eigen" for more info.
7092 */
7093
7094 Eval_eigenval = function() {
7095 if (EIG_check_arg() === 0) {
7096 push_symbol(EIGENVAL);
7097 push(p1);
7098 list(2);
7099 return;
7100 }
7101 eigen(EIGENVAL);
7102 return push(p2);
7103 };
7104
7105
7106 /* eigenvec =====================================================================
7107
7108 Tags
7109 ----
7110 scripting, JS, internal, treenode, general concept
7111
7112 Parameters
7113 ----------
7114 m
7115
7116 General description
7117 -------------------
7118 Compute eigenvectors of m. See "eigen" for more info.
7119 */
7120
7121 Eval_eigenvec = function() {
7122 if (EIG_check_arg() === 0) {
7123 push_symbol(EIGENVEC);
7124 push(p1);
7125 list(2);
7126 return;
7127 }
7128 eigen(EIGENVEC);
7129 return push(p3);
7130 };
7131
7132 EIG_check_arg = function() {
7133 var i, i1, j, j1, l1, o, ref, ref1, ref2, ref3, ref4;
7134 i = 0;
7135 j = 0;
7136 push(cadr(p1));
7137 Eval();
7138 yyfloat();
7139 Eval();
7140 p1 = pop();
7141 if (!istensor(p1)) {
7142 return 0;
7143 }
7144 if (p1.tensor.ndim !== 2 || p1.tensor.dim[0] !== p1.tensor.dim[1]) {
7145 stop("eigen: argument is not a square matrix");
7146 }
7147 EIG_N = p1.tensor.dim[0];
7148 for (i = o = 0, ref = EIG_N; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
7149 for (j = i1 = 0, ref1 = EIG_N; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
7150 if (!isdouble(p1.tensor.elem[EIG_N * i + j])) {
7151 stop("eigen: matrix is not numerical");
7152 }
7153 }
7154 }
7155 for (i = j1 = 0, ref2 = EIG_N - 1; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
7156 for (j = l1 = ref3 = i + 1, ref4 = EIG_N; ref3 <= ref4 ? l1 < ref4 : l1 > ref4; j = ref3 <= ref4 ? ++l1 : --l1) {
7157 if (Math.abs(p1.tensor.elem[EIG_N * i + j].d - p1.tensor.elem[EIG_N * j + i].d) > 1e-10) {
7158 stop("eigen: matrix is not symmetrical");
7159 }
7160 }
7161 }
7162 return 1;
7163 };
7164
7165 eigen = function(op) {
7166 var i, i1, j, j1, l1, m1, n1, o, o1, q1, r1, ref, ref1, ref10, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, results, s1;
7167 i = 0;
7168 j = 0;
7169 for (i = o = 0, ref = EIG_N * EIG_N; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
7170 EIG_yydd[i] = 0.0;
7171 }
7172 for (i = i1 = 0, ref1 = EIG_N * EIG_N; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
7173 EIG_yyqq[i] = 0.0;
7174 }
7175 for (i = j1 = 0, ref2 = EIG_N; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
7176 EIG_yydd[EIG_N * i + i] = p1.tensor.elem[EIG_N * i + i].d;
7177 for (j = l1 = ref3 = i + 1, ref4 = EIG_N; ref3 <= ref4 ? l1 < ref4 : l1 > ref4; j = ref3 <= ref4 ? ++l1 : --l1) {
7178 EIG_yydd[EIG_N * i + j] = p1.tensor.elem[EIG_N * i + j].d;
7179 EIG_yydd[EIG_N * j + i] = p1.tensor.elem[EIG_N * i + j].d;
7180 }
7181 }
7182 for (i = m1 = 0, ref5 = EIG_N; 0 <= ref5 ? m1 < ref5 : m1 > ref5; i = 0 <= ref5 ? ++m1 : --m1) {
7183 EIG_yyqq[EIG_N * i + i] = 1.0;
7184 for (j = n1 = ref6 = i + 1, ref7 = EIG_N; ref6 <= ref7 ? n1 < ref7 : n1 > ref7; j = ref6 <= ref7 ? ++n1 : --n1) {
7185 EIG_yyqq[EIG_N * i + j] = 0.0;
7186 EIG_yyqq[EIG_N * j + i] = 0.0;
7187 }
7188 }
7189 for (i = o1 = 0; o1 < 100; i = ++o1) {
7190 if (step() === 0) {
7191 break;
7192 }
7193 }
7194 if (i === 100) {
7195 printstr("\nnote: eigen did not converge\n");
7196 }
7197 if (op === EIGEN || op === EIGENVAL) {
7198 push(p1);
7199 copy_tensor();
7200 p2 = pop();
7201 for (i = q1 = 0, ref8 = EIG_N; 0 <= ref8 ? q1 < ref8 : q1 > ref8; i = 0 <= ref8 ? ++q1 : --q1) {
7202 for (j = r1 = 0, ref9 = EIG_N; 0 <= ref9 ? r1 < ref9 : r1 > ref9; j = 0 <= ref9 ? ++r1 : --r1) {
7203 push_double(EIG_yydd[EIG_N * i + j]);
7204 p2.tensor.elem[EIG_N * i + j] = pop();
7205 }
7206 }
7207 }
7208 if (op === EIGEN || op === EIGENVEC) {
7209 push(p1);
7210 copy_tensor();
7211 p3 = pop();
7212 results = [];
7213 for (i = s1 = 0, ref10 = EIG_N; 0 <= ref10 ? s1 < ref10 : s1 > ref10; i = 0 <= ref10 ? ++s1 : --s1) {
7214 results.push((function() {
7215 var ref11, results1, t1;
7216 results1 = [];
7217 for (j = t1 = 0, ref11 = EIG_N; 0 <= ref11 ? t1 < ref11 : t1 > ref11; j = 0 <= ref11 ? ++t1 : --t1) {
7218 push_double(EIG_yyqq[EIG_N * i + j]);
7219 results1.push(p3.tensor.elem[EIG_N * i + j] = pop());
7220 }
7221 return results1;
7222 })());
7223 }
7224 return results;
7225 }
7226 };
7227
7228 step = function() {
7229 var count, i, i1, j, o, ref, ref1, ref2;
7230 i = 0;
7231 j = 0;
7232 count = 0;
7233 for (i = o = 0, ref = EIG_N - 1; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
7234 for (j = i1 = ref1 = i + 1, ref2 = EIG_N; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; j = ref1 <= ref2 ? ++i1 : --i1) {
7235 if (EIG_yydd[EIG_N * i + j] !== 0.0) {
7236 step2(i, j);
7237 count++;
7238 }
7239 }
7240 }
7241 return count;
7242 };
7243
7244 step2 = function(p, q) {
7245 var c, cc, i1, j1, k, o, ref, ref1, ref2, s, ss, t, theta;
7246 k = 0;
7247 t = 0.0;
7248 theta = 0.0;
7249 c = 0.0;
7250 cc = 0.0;
7251 s = 0.0;
7252 ss = 0.0;
7253 theta = 0.5 * (EIG_yydd[EIG_N * p + p] - EIG_yydd[EIG_N * q + q]) / EIG_yydd[EIG_N * p + q];
7254 t = 1.0 / (Math.abs(theta) + Math.sqrt(theta * theta + 1.0));
7255 if (theta < 0.0) {
7256 t = -t;
7257 }
7258 c = 1.0 / Math.sqrt(t * t + 1.0);
7259 s = t * c;
7260 for (k = o = 0, ref = EIG_N; 0 <= ref ? o < ref : o > ref; k = 0 <= ref ? ++o : --o) {
7261 cc = EIG_yydd[EIG_N * p + k];
7262 ss = EIG_yydd[EIG_N * q + k];
7263 EIG_yydd[EIG_N * p + k] = c * cc + s * ss;
7264 EIG_yydd[EIG_N * q + k] = c * ss - s * cc;
7265 }
7266 for (k = i1 = 0, ref1 = EIG_N; 0 <= ref1 ? i1 < ref1 : i1 > ref1; k = 0 <= ref1 ? ++i1 : --i1) {
7267 cc = EIG_yydd[EIG_N * k + p];
7268 ss = EIG_yydd[EIG_N * k + q];
7269 EIG_yydd[EIG_N * k + p] = c * cc + s * ss;
7270 EIG_yydd[EIG_N * k + q] = c * ss - s * cc;
7271 }
7272 for (k = j1 = 0, ref2 = EIG_N; 0 <= ref2 ? j1 < ref2 : j1 > ref2; k = 0 <= ref2 ? ++j1 : --j1) {
7273 cc = EIG_yyqq[EIG_N * p + k];
7274 ss = EIG_yyqq[EIG_N * q + k];
7275 EIG_yyqq[EIG_N * p + k] = c * cc + s * ss;
7276 EIG_yyqq[EIG_N * q + k] = c * ss - s * cc;
7277 }
7278 EIG_yydd[EIG_N * p + q] = 0.0;
7279 return EIG_yydd[EIG_N * q + p] = 0.0;
7280 };
7281
7282
7283 /* erf =====================================================================
7284
7285 Tags
7286 ----
7287 scripting, JS, internal, treenode, general concept
7288
7289 Authors
7290 -------
7291 philippe.billet@noos.fr
7292
7293 Parameters
7294 ----------
7295 x
7296
7297 General description
7298 -------------------
7299 Error function erf(x).
7300 erf(-x)=erf(x)
7301 */
7302
7303 Eval_erf = function() {
7304 push(cadr(p1));
7305 Eval();
7306 return yerf();
7307 };
7308
7309 yerf = function() {
7310 save();
7311 yyerf();
7312 return restore();
7313 };
7314
7315 yyerf = function() {
7316 var d;
7317 d = 0.0;
7318 p1 = pop();
7319 if (isdouble(p1)) {
7320 d = 1.0 - erfc(p1.d);
7321 push_double(d);
7322 return;
7323 }
7324 if (isnegativeterm(p1)) {
7325 push_symbol(ERF);
7326 push(p1);
7327 negate();
7328 list(2);
7329 negate();
7330 return;
7331 }
7332 push_symbol(ERF);
7333 push(p1);
7334 list(2);
7335 };
7336
7337 Eval_erfc = function() {
7338 push(cadr(p1));
7339 Eval();
7340 return yerfc();
7341 };
7342
7343 yerfc = function() {
7344 save();
7345 yyerfc();
7346 return restore();
7347 };
7348
7349 yyerfc = function() {
7350 var d;
7351 d = 0.0;
7352 p1 = pop();
7353 if (isdouble(p1)) {
7354 d = erfc(p1.d);
7355 push_double(d);
7356 return;
7357 }
7358 push_symbol(ERFC);
7359 push(p1);
7360 list(2);
7361 };
7362
7363 erfc = function(x) {
7364 var ans, t, z;
7365 t = 0.0;
7366 z = 0.0;
7367 ans = 0.0;
7368 z = Math.abs(x);
7369 t = 1.0 / (1.0 + 0.5 * z);
7370 ans = t * Math.exp(-z * z - 1.26551223 + t * (1.00002368 + t * (0.37409196 + t * (0.09678418 + t * (-0.18628806 + t * (0.27886807 + t * (-1.13520398 + t * (1.48851587 + t * (-0.82215223 + t * 0.17087277)))))))));
7371 if (x >= 0.0) {
7372 return ans;
7373 } else {
7374 return 2.0 - ans;
7375 }
7376 };
7377
7378
7379 /*
7380 * commented-out test
7381 "float(erfc(1))",
7382 "0.157299",
7383 */
7384
7385 Eval = function() {
7386 var willEvaluateAsFloats;
7387 check_esc_flag();
7388 save();
7389 p1 = pop();
7390 if (p1 == null) {
7391 debugger;
7392 }
7393 if (!evaluatingAsFloats && isfloating(p1)) {
7394 willEvaluateAsFloats = true;
7395 evaluatingAsFloats++;
7396 }
7397 switch (p1.k) {
7398 case CONS:
7399 Eval_cons();
7400 break;
7401 case NUM:
7402 if (evaluatingAsFloats) {
7403 push_double(convert_rational_to_double(p1));
7404 } else {
7405 push(p1);
7406 }
7407 break;
7408 case DOUBLE:
7409 case STR:
7410 push(p1);
7411 break;
7412 case TENSOR:
7413 Eval_tensor();
7414 break;
7415 case SYM:
7416 Eval_sym();
7417 break;
7418 default:
7419 stop("atom?");
7420 }
7421 if (willEvaluateAsFloats) {
7422 evaluatingAsFloats--;
7423 }
7424 return restore();
7425 };
7426
7427 Eval_sym = function() {
7428 var cycleString, i, o, positionIfSymbolAlreadyBeingEvaluated, ref, ref1;
7429 if (iskeyword(p1)) {
7430 push(p1);
7431 push(symbol(LAST));
7432 list(2);
7433 Eval();
7434 return;
7435 } else if (p1 === symbol(PI) && evaluatingAsFloats) {
7436 push_double(Math.PI);
7437 return;
7438 }
7439 p2 = get_binding(p1);
7440 if (DEBUG) {
7441 console.log("looked up: " + p1 + " which contains: " + p2);
7442 }
7443 push(p2);
7444 if (p1 !== p2) {
7445 positionIfSymbolAlreadyBeingEvaluated = chainOfUserSymbolsNotFunctionsBeingEvaluated.indexOf(p1);
7446 if (positionIfSymbolAlreadyBeingEvaluated !== -1) {
7447 cycleString = "";
7448 for (i = o = ref = positionIfSymbolAlreadyBeingEvaluated, ref1 = chainOfUserSymbolsNotFunctionsBeingEvaluated.length; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
7449 cycleString += chainOfUserSymbolsNotFunctionsBeingEvaluated[i].printname + " -> ";
7450 }
7451 cycleString += p1.printname;
7452 stop("recursive evaluation of symbols: " + cycleString);
7453 return;
7454 }
7455 chainOfUserSymbolsNotFunctionsBeingEvaluated.push(p1);
7456 Eval();
7457 return chainOfUserSymbolsNotFunctionsBeingEvaluated.pop();
7458 }
7459 };
7460
7461 Eval_cons = function() {
7462 var cons_head;
7463 cons_head = car(p1);
7464 if (car(cons_head) === symbol(EVAL)) {
7465 Eval_user_function();
7466 return;
7467 }
7468 if (!issymbol(cons_head)) {
7469 stop("cons?");
7470 }
7471 switch (symnum(cons_head)) {
7472 case ABS:
7473 return Eval_abs();
7474 case ADD:
7475 return Eval_add();
7476 case ADJ:
7477 return Eval_adj();
7478 case AND:
7479 return Eval_and();
7480 case ARCCOS:
7481 return Eval_arccos();
7482 case ARCCOSH:
7483 return Eval_arccosh();
7484 case ARCSIN:
7485 return Eval_arcsin();
7486 case ARCSINH:
7487 return Eval_arcsinh();
7488 case ARCTAN:
7489 return Eval_arctan();
7490 case ARCTANH:
7491 return Eval_arctanh();
7492 case ARG:
7493 return Eval_arg();
7494 case ATOMIZE:
7495 return Eval_atomize();
7496 case BESSELJ:
7497 return Eval_besselj();
7498 case BESSELY:
7499 return Eval_bessely();
7500 case BINDING:
7501 return Eval_binding();
7502 case BINOMIAL:
7503 return Eval_binomial();
7504 case CEILING:
7505 return Eval_ceiling();
7506 case CHECK:
7507 return Eval_check();
7508 case CHOOSE:
7509 return Eval_choose();
7510 case CIRCEXP:
7511 return Eval_circexp();
7512 case CLEAR:
7513 return Eval_clear();
7514 case CLEARALL:
7515 return Eval_clearall();
7516 case CLEARPATTERNS:
7517 return Eval_clearpatterns();
7518 case CLOCK:
7519 return Eval_clock();
7520 case COEFF:
7521 return Eval_coeff();
7522 case COFACTOR:
7523 return Eval_cofactor();
7524 case CONDENSE:
7525 return Eval_condense();
7526 case CONJ:
7527 return Eval_conj();
7528 case CONTRACT:
7529 return Eval_contract();
7530 case COS:
7531 return Eval_cos();
7532 case COSH:
7533 return Eval_cosh();
7534 case DECOMP:
7535 return Eval_decomp();
7536 case DEGREE:
7537 return Eval_degree();
7538 case DEFINT:
7539 return Eval_defint();
7540 case DENOMINATOR:
7541 return Eval_denominator();
7542 case DERIVATIVE:
7543 return Eval_derivative();
7544 case DET:
7545 return Eval_det();
7546 case DIM:
7547 return Eval_dim();
7548 case DIRAC:
7549 return Eval_dirac();
7550 case DIVISORS:
7551 return Eval_divisors();
7552 case DO:
7553 return Eval_do();
7554 case DOT:
7555 return Eval_inner();
7556 case DRAW:
7557 return Eval_draw();
7558 case DSOLVE:
7559 return Eval_dsolve();
7560 case EIGEN:
7561 return Eval_eigen();
7562 case EIGENVAL:
7563 return Eval_eigenval();
7564 case EIGENVEC:
7565 return Eval_eigenvec();
7566 case ERF:
7567 return Eval_erf();
7568 case ERFC:
7569 return Eval_erfc();
7570 case EVAL:
7571 return Eval_Eval();
7572 case EXP:
7573 return Eval_exp();
7574 case EXPAND:
7575 return Eval_expand();
7576 case EXPCOS:
7577 return Eval_expcos();
7578 case EXPSIN:
7579 return Eval_expsin();
7580 case FACTOR:
7581 return Eval_factor();
7582 case FACTORIAL:
7583 return Eval_factorial();
7584 case FACTORPOLY:
7585 return Eval_factorpoly();
7586 case FILTER:
7587 return Eval_filter();
7588 case FLOATF:
7589 return Eval_float();
7590 case APPROXRATIO:
7591 return Eval_approxratio();
7592 case FLOOR:
7593 return Eval_floor();
7594 case FOR:
7595 return Eval_for();
7596 case FUNCTION:
7597 return Eval_function_reference();
7598 case GAMMA:
7599 return Eval_gamma();
7600 case GCD:
7601 return Eval_gcd();
7602 case HERMITE:
7603 return Eval_hermite();
7604 case HILBERT:
7605 return Eval_hilbert();
7606 case IMAG:
7607 return Eval_imag();
7608 case INDEX:
7609 return Eval_index();
7610 case INNER:
7611 return Eval_inner();
7612 case INTEGRAL:
7613 return Eval_integral();
7614 case INV:
7615 return Eval_inv();
7616 case INVG:
7617 return Eval_invg();
7618 case ISINTEGER:
7619 return Eval_isinteger();
7620 case ISPRIME:
7621 return Eval_isprime();
7622 case LAGUERRE:
7623 return Eval_laguerre();
7624 case LCM:
7625 return Eval_lcm();
7626 case LEADING:
7627 return Eval_leading();
7628 case LEGENDRE:
7629 return Eval_legendre();
7630 case LOG:
7631 return Eval_log();
7632 case LOOKUP:
7633 return Eval_lookup();
7634 case MOD:
7635 return Eval_mod();
7636 case MULTIPLY:
7637 return Eval_multiply();
7638 case NOT:
7639 return Eval_not();
7640 case NROOTS:
7641 return Eval_nroots();
7642 case NUMBER:
7643 return Eval_number();
7644 case NUMERATOR:
7645 return Eval_numerator();
7646 case OPERATOR:
7647 return Eval_operator();
7648 case OR:
7649 return Eval_or();
7650 case OUTER:
7651 return Eval_outer();
7652 case PATTERN:
7653 return Eval_pattern();
7654 case PATTERNSINFO:
7655 return Eval_patternsinfo();
7656 case POLAR:
7657 return Eval_polar();
7658 case POWER:
7659 return Eval_power();
7660 case PRIME:
7661 return Eval_prime();
7662 case PRINT:
7663 return Eval_print();
7664 case PRINT2DASCII:
7665 return Eval_print2dascii();
7666 case PRINTFULL:
7667 return Eval_printfull();
7668 case PRINTLATEX:
7669 return Eval_printlatex();
7670 case PRINTLIST:
7671 return Eval_printlist();
7672 case PRINTPLAIN:
7673 return Eval_printplain();
7674 case PRODUCT:
7675 return Eval_product();
7676 case QUOTE:
7677 return Eval_quote();
7678 case QUOTIENT:
7679 return Eval_quotient();
7680 case RANK:
7681 return Eval_rank();
7682 case RATIONALIZE:
7683 return Eval_rationalize();
7684 case REAL:
7685 return Eval_real();
7686 case ROUND:
7687 return Eval_round();
7688 case YYRECT:
7689 return Eval_rect();
7690 case ROOTS:
7691 return Eval_roots();
7692 case SETQ:
7693 return Eval_setq();
7694 case SGN:
7695 return Eval_sgn();
7696 case SILENTPATTERN:
7697 return Eval_silentpattern();
7698 case SIMPLIFY:
7699 return Eval_simplify();
7700 case SIN:
7701 return Eval_sin();
7702 case SINH:
7703 return Eval_sinh();
7704 case SHAPE:
7705 return Eval_shape();
7706 case SQRT:
7707 return Eval_sqrt();
7708 case STOP:
7709 return Eval_stop();
7710 case SUBST:
7711 return Eval_subst();
7712 case SUM:
7713 return Eval_sum();
7714 case SYMBOLSINFO:
7715 return Eval_symbolsinfo();
7716 case TAN:
7717 return Eval_tan();
7718 case TANH:
7719 return Eval_tanh();
7720 case TAYLOR:
7721 return Eval_taylor();
7722 case TEST:
7723 return Eval_test();
7724 case TESTEQ:
7725 return Eval_testeq();
7726 case TESTGE:
7727 return Eval_testge();
7728 case TESTGT:
7729 return Eval_testgt();
7730 case TESTLE:
7731 return Eval_testle();
7732 case TESTLT:
7733 return Eval_testlt();
7734 case TRANSPOSE:
7735 return Eval_transpose();
7736 case UNIT:
7737 return Eval_unit();
7738 case ZERO:
7739 return Eval_zero();
7740 default:
7741 return Eval_user_function();
7742 }
7743 };
7744
7745 Eval_binding = function() {
7746 return push(get_binding(cadr(p1)));
7747 };
7748
7749
7750 /* check =====================================================================
7751
7752 Tags
7753 ----
7754 scripting, JS, internal, treenode, general concept
7755
7756 Parameters
7757 ----------
7758 p
7759
7760 General description
7761 -------------------
7762 Checks the predicate p, e.g. check(a = b)
7763 Note how "check" can turn what normally would be an assignment into a test,
7764 so in the case above "a" is not assigned anything.
7765 */
7766
7767 Eval_check = function() {
7768 push(cadr(p1));
7769 Eval_predicate();
7770 p1 = pop();
7771 return push(p1);
7772 };
7773
7774 Eval_det = function() {
7775 push(cadr(p1));
7776 Eval();
7777 return det();
7778 };
7779
7780
7781 /* dim =====================================================================
7782
7783 Tags
7784 ----
7785 scripting, JS, internal, treenode, general concept
7786
7787 Parameters
7788 ----------
7789 m,n
7790
7791 General description
7792 -------------------
7793 Returns the cardinality of the nth index of tensor "m".
7794 */
7795
7796 Eval_dim = function() {
7797 var n;
7798 push(cadr(p1));
7799 Eval();
7800 p2 = pop();
7801 if (iscons(cddr(p1))) {
7802 push(caddr(p1));
7803 Eval();
7804 n = pop_integer();
7805 } else {
7806 n = 1;
7807 }
7808 if (!istensor(p2)) {
7809 return push_integer(1);
7810 } else if (n < 1 || n > p2.tensor.ndim) {
7811 return push(p1);
7812 } else {
7813 return push_integer(p2.tensor.dim[n - 1]);
7814 }
7815 };
7816
7817 Eval_divisors = function() {
7818 push(cadr(p1));
7819 Eval();
7820 return divisors();
7821 };
7822
7823
7824 /* do =====================================================================
7825
7826 Tags
7827 ----
7828 scripting, JS, internal, treenode, general concept
7829
7830 Parameters
7831 ----------
7832 a,b,...
7833
7834 General description
7835 -------------------
7836 Evaluates each argument from left to right. Returns the result of the last argument.
7837 */
7838
7839 Eval_do = function() {
7840 var results;
7841 push(car(p1));
7842 p1 = cdr(p1);
7843 results = [];
7844 while (iscons(p1)) {
7845 pop();
7846 push(car(p1));
7847 Eval();
7848 results.push(p1 = cdr(p1));
7849 }
7850 return results;
7851 };
7852
7853 Eval_dsolve = function() {
7854 push(cadr(p1));
7855 Eval();
7856 push(caddr(p1));
7857 Eval();
7858 push(cadddr(p1));
7859 Eval();
7860 return dsolve();
7861 };
7862
7863 Eval_Eval = function() {
7864 push(cadr(p1));
7865 Eval();
7866 p1 = cddr(p1);
7867 while (iscons(p1)) {
7868 push(car(p1));
7869 Eval();
7870 push(cadr(p1));
7871 Eval();
7872 subst();
7873 p1 = cddr(p1);
7874 }
7875 return Eval();
7876 };
7877
7878 Eval_exp = function() {
7879 push(cadr(p1));
7880 Eval();
7881 return exponential();
7882 };
7883
7884 Eval_factorial = function() {
7885 push(cadr(p1));
7886 Eval();
7887 return factorial();
7888 };
7889
7890 Eval_factorpoly = function() {
7891 var results;
7892 p1 = cdr(p1);
7893 push(car(p1));
7894 Eval();
7895 p1 = cdr(p1);
7896 push(car(p1));
7897 Eval();
7898 factorpoly();
7899 p1 = cdr(p1);
7900 results = [];
7901 while (iscons(p1)) {
7902 push(car(p1));
7903 Eval();
7904 factorpoly();
7905 results.push(p1 = cdr(p1));
7906 }
7907 return results;
7908 };
7909
7910 Eval_hermite = function() {
7911 push(cadr(p1));
7912 Eval();
7913 push(caddr(p1));
7914 Eval();
7915 return hermite();
7916 };
7917
7918 Eval_hilbert = function() {
7919 push(cadr(p1));
7920 Eval();
7921 return hilbert();
7922 };
7923
7924 Eval_index = function() {
7925 var h, orig, theTensor;
7926 h = tos;
7927 orig = p1;
7928 p1 = cdr(p1);
7929 push(car(p1));
7930 Eval();
7931 theTensor = stack[tos - 1];
7932 if (isnum(theTensor)) {
7933 stop("trying to access a scalar as a tensor");
7934 }
7935 if (!istensor(theTensor)) {
7936 moveTos(h);
7937 push(orig);
7938 return;
7939 }
7940 p1 = cdr(p1);
7941 while (iscons(p1)) {
7942 push(car(p1));
7943 Eval();
7944 if (!isintegerorintegerfloat(stack[tos - 1])) {
7945 moveTos(h);
7946 push(orig);
7947 return;
7948 }
7949 p1 = cdr(p1);
7950 }
7951 return index_function(tos - h);
7952 };
7953
7954 Eval_inv = function() {
7955 push(cadr(p1));
7956 Eval();
7957 return inv();
7958 };
7959
7960 Eval_invg = function() {
7961 push(cadr(p1));
7962 Eval();
7963 return invg();
7964 };
7965
7966 Eval_isinteger = function() {
7967 var n;
7968 push(cadr(p1));
7969 Eval();
7970 p1 = pop();
7971 if (isrational(p1)) {
7972 if (isinteger(p1)) {
7973 push(one);
7974 } else {
7975 push(zero);
7976 }
7977 return;
7978 }
7979 if (isdouble(p1)) {
7980 n = Math.floor(p1.d);
7981 if (n === p1.d) {
7982 push(one);
7983 } else {
7984 push(zero);
7985 }
7986 return;
7987 }
7988 push_symbol(ISINTEGER);
7989 push(p1);
7990 return list(2);
7991 };
7992
7993 Eval_number = function() {
7994 push(cadr(p1));
7995 Eval();
7996 p1 = pop();
7997 if (p1.k === NUM || p1.k === DOUBLE) {
7998 return push_integer(1);
7999 } else {
8000 return push_integer(0);
8001 }
8002 };
8003
8004 Eval_operator = function() {
8005 var h;
8006 h = tos;
8007 push_symbol(OPERATOR);
8008 p1 = cdr(p1);
8009 while (iscons(p1)) {
8010 push(car(p1));
8011 Eval();
8012 p1 = cdr(p1);
8013 }
8014 return list(tos - h);
8015 };
8016
8017 Eval_quote = function() {
8018 return push(cadr(p1));
8019 };
8020
8021 Eval_rank = function() {
8022 push(cadr(p1));
8023 Eval();
8024 p1 = pop();
8025 if (istensor(p1)) {
8026 return push_integer(p1.tensor.ndim);
8027 } else {
8028 return push(zero);
8029 }
8030 };
8031
8032 Eval_setq = function() {
8033 if (caadr(p1) === symbol(INDEX)) {
8034 setq_indexed();
8035 return;
8036 }
8037 if (iscons(cadr(p1))) {
8038 define_user_function();
8039 return;
8040 }
8041 if (!issymbol(cadr(p1))) {
8042 stop("symbol assignment: error in symbol");
8043 }
8044 push(caddr(p1));
8045 Eval();
8046 p2 = pop();
8047 set_binding(cadr(p1), p2);
8048 return push(symbol(NIL));
8049 };
8050
8051 setq_indexed = function() {
8052 var h;
8053 p4 = cadadr(p1);
8054 if (!issymbol(p4)) {
8055 stop("indexed assignment: error in symbol");
8056 }
8057 h = tos;
8058 push(caddr(p1));
8059 Eval();
8060 p2 = cdadr(p1);
8061 while (iscons(p2)) {
8062 push(car(p2));
8063 Eval();
8064 p2 = cdr(p2);
8065 }
8066 set_component(tos - h);
8067 p3 = pop();
8068 set_binding(p4, p3);
8069 return push(symbol(NIL));
8070 };
8071
8072 Eval_sqrt = function() {
8073 push(cadr(p1));
8074 Eval();
8075 push_rational(1, 2);
8076 return power();
8077 };
8078
8079 Eval_stop = function() {
8080 return stop("user stop");
8081 };
8082
8083 Eval_subst = function() {
8084 push(cadddr(p1));
8085 Eval();
8086 push(caddr(p1));
8087 Eval();
8088 push(cadr(p1));
8089 Eval();
8090 subst();
8091 return Eval();
8092 };
8093
8094 Eval_unit = function() {
8095 var i, n, o, ref;
8096 i = 0;
8097 n = 0;
8098 push(cadr(p1));
8099 Eval();
8100 n = pop_integer();
8101 if (isNaN(n)) {
8102 push(p1);
8103 return;
8104 }
8105 if (n < 1) {
8106 push(p1);
8107 return;
8108 }
8109 p1 = alloc_tensor(n * n);
8110 p1.tensor.ndim = 2;
8111 p1.tensor.dim[0] = n;
8112 p1.tensor.dim[1] = n;
8113 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8114 p1.tensor.elem[n * i + i] = one;
8115 }
8116 check_tensor_dimensions(p1);
8117 return push(p1);
8118 };
8119
8120 Eval_noexpand = function() {
8121 var prev_expanding;
8122 prev_expanding = expanding;
8123 expanding = 0;
8124 Eval();
8125 return expanding = prev_expanding;
8126 };
8127
8128 Eval_predicate = function() {
8129 save();
8130 p1 = top();
8131 if (car(p1) === symbol(SETQ)) {
8132 pop();
8133 push_symbol(TESTEQ);
8134 push(cadr(p1));
8135 push(caddr(p1));
8136 list(3);
8137 }
8138 Eval();
8139 return restore();
8140 };
8141
8142 Eval_expand = function() {
8143 push(cadr(p1));
8144 Eval();
8145 push(caddr(p1));
8146 Eval();
8147 p2 = pop();
8148 if (p2 === symbol(NIL)) {
8149 guess();
8150 } else {
8151 push(p2);
8152 }
8153 return expand();
8154 };
8155
8156 expand = function() {
8157 var prev_expanding;
8158 save();
8159 p9 = pop();
8160 p5 = pop();
8161 if (istensor(p5)) {
8162 expand_tensor();
8163 restore();
8164 return;
8165 }
8166 if (car(p5) === symbol(ADD)) {
8167 push_integer(0);
8168 p1 = cdr(p5);
8169 while (iscons(p1)) {
8170 push(car(p1));
8171 push(p9);
8172 expand();
8173 add();
8174 p1 = cdr(p1);
8175 }
8176 restore();
8177 return;
8178 }
8179 push(p5);
8180 numerator();
8181 p3 = pop();
8182 push(p5);
8183 denominator();
8184 p2 = pop();
8185 remove_negative_exponents();
8186 push(p3);
8187 push(p2);
8188 push(p9);
8189 if (isone(p3) || isone(p2)) {
8190 if (!ispoly(p2, p9) || isone(p2)) {
8191 pop();
8192 pop();
8193 pop();
8194 push(p5);
8195 restore();
8196 return;
8197 }
8198 }
8199 divpoly();
8200 p7 = pop();
8201 push(p3);
8202 push(p2);
8203 push(p7);
8204 multiply();
8205 subtract();
8206 p3 = pop();
8207 if (iszero(p3)) {
8208 push(p7);
8209 restore();
8210 return;
8211 }
8212 push(p2);
8213 push(p9);
8214 factorpoly();
8215 p2 = pop();
8216 expand_get_C();
8217 expand_get_B();
8218 expand_get_A();
8219 if (istensor(p4)) {
8220 push(p4);
8221 prev_expanding = expanding;
8222 expanding = 1;
8223 inv();
8224 expanding = prev_expanding;
8225 push(p3);
8226 inner();
8227 push(p2);
8228 inner();
8229 } else {
8230 push(p3);
8231 push(p4);
8232 prev_expanding = expanding;
8233 expanding = 1;
8234 divide();
8235 expanding = prev_expanding;
8236 push(p2);
8237 multiply();
8238 }
8239 push(p7);
8240 add();
8241 return restore();
8242 };
8243
8244 expand_tensor = function() {
8245 var i, o, ref;
8246 i = 0;
8247 push(p5);
8248 copy_tensor();
8249 p5 = pop();
8250 for (i = o = 0, ref = p5.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8251 push(p5.tensor.elem[i]);
8252 push(p9);
8253 expand();
8254 p5.tensor.elem[i] = pop();
8255 }
8256 return push(p5);
8257 };
8258
8259 remove_negative_exponents = function() {
8260 var h, i, j, k, n, o, ref;
8261 h = 0;
8262 i = 0;
8263 j = 0;
8264 k = 0;
8265 n = 0;
8266 h = tos;
8267 factors(p2);
8268 factors(p3);
8269 n = tos - h;
8270 j = 0;
8271 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8272 p1 = stack[h + i];
8273 if (car(p1) !== symbol(POWER)) {
8274 continue;
8275 }
8276 if (cadr(p1) !== p9) {
8277 continue;
8278 }
8279 push(caddr(p1));
8280 k = pop_integer();
8281 if (isNaN(k)) {
8282 continue;
8283 }
8284 if (k < j) {
8285 j = k;
8286 }
8287 }
8288 moveTos(h);
8289 if (j === 0) {
8290 return;
8291 }
8292 push(p2);
8293 push(p9);
8294 push_integer(-j);
8295 power();
8296 multiply();
8297 p2 = pop();
8298 push(p3);
8299 push(p9);
8300 push_integer(-j);
8301 power();
8302 multiply();
8303 return p3 = pop();
8304 };
8305
8306 expand_get_C = function() {
8307 var a, h, i, i1, j, n, o, prev_expanding, ref, ref1;
8308 h = 0;
8309 i = 0;
8310 j = 0;
8311 n = 0;
8312 h = tos;
8313 if (car(p2) === symbol(MULTIPLY)) {
8314 p1 = cdr(p2);
8315 while (iscons(p1)) {
8316 p5 = car(p1);
8317 expand_get_CF();
8318 p1 = cdr(p1);
8319 }
8320 } else {
8321 p5 = p2;
8322 expand_get_CF();
8323 }
8324 n = tos - h;
8325 if (n === 1) {
8326 p4 = pop();
8327 return;
8328 }
8329 p4 = alloc_tensor(n * n);
8330 p4.tensor.ndim = 2;
8331 p4.tensor.dim[0] = n;
8332 p4.tensor.dim[1] = n;
8333 a = h;
8334 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8335 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
8336 push(stack[a + j]);
8337 push(p9);
8338 push_integer(i);
8339 power();
8340 prev_expanding = expanding;
8341 expanding = 1;
8342 divide();
8343 expanding = prev_expanding;
8344 push(p9);
8345 filter();
8346 p4.tensor.elem[n * i + j] = pop();
8347 }
8348 }
8349 return moveTos(tos - n);
8350 };
8351
8352 expand_get_CF = function() {
8353 var d, i, j, n, o, prev_expanding, ref, results;
8354 d = 0;
8355 i = 0;
8356 j = 0;
8357 n = 0;
8358 if (!Find(p5, p9)) {
8359 return;
8360 }
8361 prev_expanding = expanding;
8362 expanding = 1;
8363 trivial_divide();
8364 expanding = prev_expanding;
8365 if (car(p5) === symbol(POWER)) {
8366 push(caddr(p5));
8367 n = pop_integer();
8368 p6 = cadr(p5);
8369 } else {
8370 n = 1;
8371 p6 = p5;
8372 }
8373 push(p6);
8374 push(p9);
8375 degree();
8376 d = pop_integer();
8377 results = [];
8378 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8379 results.push((function() {
8380 var i1, ref1, results1;
8381 results1 = [];
8382 for (j = i1 = 0, ref1 = d; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
8383 push(p8);
8384 push(p6);
8385 push_integer(i);
8386 power();
8387 prev_expanding = expanding;
8388 expanding = 1;
8389 multiply();
8390 expanding = prev_expanding;
8391 push(p9);
8392 push_integer(j);
8393 power();
8394 prev_expanding = expanding;
8395 expanding = 1;
8396 multiply();
8397 results1.push(expanding = prev_expanding);
8398 }
8399 return results1;
8400 })());
8401 }
8402 return results;
8403 };
8404
8405 trivial_divide = function() {
8406 var h;
8407 h = 0;
8408 if (car(p2) === symbol(MULTIPLY)) {
8409 h = tos;
8410 p0 = cdr(p2);
8411 while (iscons(p0)) {
8412 if (!equal(car(p0), p5)) {
8413 push(car(p0));
8414 Eval();
8415 }
8416 p0 = cdr(p0);
8417 }
8418 multiply_all(tos - h);
8419 } else {
8420 push_integer(1);
8421 }
8422 return p8 = pop();
8423 };
8424
8425 expand_get_B = function() {
8426 var i, n, o, prev_expanding, ref;
8427 i = 0;
8428 n = 0;
8429 if (!istensor(p4)) {
8430 return;
8431 }
8432 n = p4.tensor.dim[0];
8433 p8 = alloc_tensor(n);
8434 p8.tensor.ndim = 1;
8435 p8.tensor.dim[0] = n;
8436 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8437 push(p3);
8438 push(p9);
8439 push_integer(i);
8440 power();
8441 prev_expanding = expanding;
8442 expanding = 1;
8443 divide();
8444 expanding = prev_expanding;
8445 push(p9);
8446 filter();
8447 p8.tensor.elem[i] = pop();
8448 }
8449 return p3 = p8;
8450 };
8451
8452 expand_get_A = function() {
8453 var h, i, n, o, ref;
8454 h = 0;
8455 i = 0;
8456 n = 0;
8457 if (!istensor(p4)) {
8458 push(p2);
8459 reciprocate();
8460 p2 = pop();
8461 return;
8462 }
8463 h = tos;
8464 if (car(p2) === symbol(MULTIPLY)) {
8465 p8 = cdr(p2);
8466 while (iscons(p8)) {
8467 p5 = car(p8);
8468 expand_get_AF();
8469 p8 = cdr(p8);
8470 }
8471 } else {
8472 p5 = p2;
8473 expand_get_AF();
8474 }
8475 n = tos - h;
8476 p8 = alloc_tensor(n);
8477 p8.tensor.ndim = 1;
8478 p8.tensor.dim[0] = n;
8479 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8480 p8.tensor.elem[i] = stack[h + i];
8481 }
8482 moveTos(h);
8483 return p2 = p8;
8484 };
8485
8486 expand_get_AF = function() {
8487 var d, i, j, n, o, ref, results;
8488 d = 0;
8489 i = 0;
8490 j = 0;
8491 n = 1;
8492 if (!Find(p5, p9)) {
8493 return;
8494 }
8495 if (car(p5) === symbol(POWER)) {
8496 push(caddr(p5));
8497 n = pop_integer();
8498 p5 = cadr(p5);
8499 }
8500 push(p5);
8501 push(p9);
8502 degree();
8503 d = pop_integer();
8504 results = [];
8505 for (i = o = ref = n; ref <= 0 ? o < 0 : o > 0; i = ref <= 0 ? ++o : --o) {
8506 results.push((function() {
8507 var i1, ref1, results1;
8508 results1 = [];
8509 for (j = i1 = 0, ref1 = d; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
8510 push(p5);
8511 push_integer(i);
8512 power();
8513 reciprocate();
8514 push(p9);
8515 push_integer(j);
8516 power();
8517 results1.push(multiply());
8518 }
8519 return results1;
8520 })());
8521 }
8522 return results;
8523 };
8524
8525 Eval_expcos = function() {
8526 push(cadr(p1));
8527 Eval();
8528 return expcos();
8529 };
8530
8531 expcos = function() {
8532 save();
8533 p1 = pop();
8534 push(imaginaryunit);
8535 push(p1);
8536 multiply();
8537 exponential();
8538 push_rational(1, 2);
8539 multiply();
8540 push(imaginaryunit);
8541 negate();
8542 push(p1);
8543 multiply();
8544 exponential();
8545 push_rational(1, 2);
8546 multiply();
8547 add();
8548 return restore();
8549 };
8550
8551 Eval_expsin = function() {
8552 push(cadr(p1));
8553 Eval();
8554 return expsin();
8555 };
8556
8557 expsin = function() {
8558 save();
8559 p1 = pop();
8560 push(imaginaryunit);
8561 push(p1);
8562 multiply();
8563 exponential();
8564 push(imaginaryunit);
8565 divide();
8566 push_rational(1, 2);
8567 multiply();
8568 push(imaginaryunit);
8569 negate();
8570 push(p1);
8571 multiply();
8572 exponential();
8573 push(imaginaryunit);
8574 divide();
8575 push_rational(1, 2);
8576 multiply();
8577 subtract();
8578 return restore();
8579 };
8580
8581 Eval_factor = function() {
8582 var results;
8583 push(cadr(p1));
8584 Eval();
8585 push(caddr(p1));
8586 Eval();
8587 p2 = pop();
8588 if (p2 === symbol(NIL)) {
8589 guess();
8590 } else {
8591 push(p2);
8592 }
8593 factor();
8594 p1 = cdddr(p1);
8595 results = [];
8596 while (iscons(p1)) {
8597 push(car(p1));
8598 Eval();
8599 factor_again();
8600 results.push(p1 = cdr(p1));
8601 }
8602 return results;
8603 };
8604
8605 factor_again = function() {
8606 var h, n;
8607 save();
8608 p2 = pop();
8609 p1 = pop();
8610 h = tos;
8611 if (car(p1) === symbol(MULTIPLY)) {
8612 p1 = cdr(p1);
8613 while (iscons(p1)) {
8614 push(car(p1));
8615 push(p2);
8616 factor_term();
8617 p1 = cdr(p1);
8618 }
8619 } else {
8620 push(p1);
8621 push(p2);
8622 factor_term();
8623 }
8624 n = tos - h;
8625 if (n > 1) {
8626 multiply_all_noexpand(n);
8627 }
8628 return restore();
8629 };
8630
8631 factor_term = function() {
8632 save();
8633 factorpoly();
8634 p1 = pop();
8635 if (car(p1) === symbol(MULTIPLY)) {
8636 p1 = cdr(p1);
8637 while (iscons(p1)) {
8638 push(car(p1));
8639 p1 = cdr(p1);
8640 }
8641 } else {
8642 push(p1);
8643 }
8644 return restore();
8645 };
8646
8647 factor = function() {
8648 save();
8649 p2 = pop();
8650 p1 = pop();
8651 if (isinteger(p1)) {
8652 push(p1);
8653 factor_number();
8654 } else {
8655 push(p1);
8656 push(p2);
8657 factorpoly();
8658 }
8659 return restore();
8660 };
8661
8662 factor_small_number = function() {
8663 var d, expo, i, n, o, ref;
8664 i = 0;
8665 save();
8666 n = pop_integer();
8667 if (isNaN(n)) {
8668 stop("number too big to factor");
8669 }
8670 if (n < 0) {
8671 n = -n;
8672 }
8673 for (i = o = 0, ref = MAXPRIMETAB; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8674 d = primetab[i];
8675 if (d > n / d) {
8676 break;
8677 }
8678 expo = 0;
8679 while (n % d === 0) {
8680 n /= d;
8681 expo++;
8682 }
8683 if (expo) {
8684 push_integer(d);
8685 push_integer(expo);
8686 }
8687 }
8688 if (n > 1) {
8689 push_integer(n);
8690 push_integer(1);
8691 }
8692 return restore();
8693 };
8694
8695 factorial = function() {
8696 var n;
8697 n = 0;
8698 save();
8699 p1 = pop();
8700 push(p1);
8701 n = pop_integer();
8702 if (n < 0 || isNaN(n)) {
8703 push_symbol(FACTORIAL);
8704 push(p1);
8705 list(2);
8706 restore();
8707 return;
8708 }
8709 bignum_factorial(n);
8710 return restore();
8711 };
8712
8713 simplifyfactorials = function() {
8714 var x;
8715 x = 0;
8716 save();
8717 x = expanding;
8718 expanding = 0;
8719 p1 = pop();
8720 if (car(p1) === symbol(ADD)) {
8721 push(zero);
8722 p1 = cdr(p1);
8723 while (iscons(p1)) {
8724 push(car(p1));
8725 simplifyfactorials();
8726 add();
8727 p1 = cdr(p1);
8728 }
8729 expanding = x;
8730 restore();
8731 return;
8732 }
8733 if (car(p1) === symbol(MULTIPLY)) {
8734 sfac_product();
8735 expanding = x;
8736 restore();
8737 return;
8738 }
8739 push(p1);
8740 expanding = x;
8741 return restore();
8742 };
8743
8744 sfac_product = function() {
8745 var i, i1, j, j1, n, o, ref, ref1, ref2, ref3, s;
8746 i = 0;
8747 j = 0;
8748 n = 0;
8749 s = tos;
8750 p1 = cdr(p1);
8751 n = 0;
8752 while (iscons(p1)) {
8753 push(car(p1));
8754 p1 = cdr(p1);
8755 n++;
8756 }
8757 for (i = o = 0, ref = n - 1; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8758 if (stack[s + i] === symbol(NIL)) {
8759 continue;
8760 }
8761 for (j = i1 = ref1 = i + 1, ref2 = n; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; j = ref1 <= ref2 ? ++i1 : --i1) {
8762 if (stack[s + j] === symbol(NIL)) {
8763 continue;
8764 }
8765 sfac_product_f(s, i, j);
8766 }
8767 }
8768 push(one);
8769 for (i = j1 = 0, ref3 = n; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
8770 if (stack[s + i] === symbol(NIL)) {
8771 continue;
8772 }
8773 push(stack[s + i]);
8774 multiply();
8775 }
8776 p1 = pop();
8777 moveTos(tos - n);
8778 return push(p1);
8779 };
8780
8781 sfac_product_f = function(s, a, b) {
8782 var i, n, o, ref;
8783 i = 0;
8784 n = 0;
8785 p1 = stack[s + a];
8786 p2 = stack[s + b];
8787 if (ispower(p1)) {
8788 p3 = caddr(p1);
8789 p1 = cadr(p1);
8790 } else {
8791 p3 = one;
8792 }
8793 if (ispower(p2)) {
8794 p4 = caddr(p2);
8795 p2 = cadr(p2);
8796 } else {
8797 p4 = one;
8798 }
8799 if (isfactorial(p1) && isfactorial(p2)) {
8800 push(p3);
8801 push(p4);
8802 add();
8803 yyexpand();
8804 n = pop_integer();
8805 if (n !== 0) {
8806 return;
8807 }
8808 push(cadr(p1));
8809 push(cadr(p2));
8810 subtract();
8811 yyexpand();
8812 n = pop_integer();
8813 if (n === 0 || isNaN(n)) {
8814 return;
8815 }
8816 if (n < 0) {
8817 n = -n;
8818 p5 = p1;
8819 p1 = p2;
8820 p2 = p5;
8821 p5 = p3;
8822 p3 = p4;
8823 p4 = p5;
8824 }
8825 push(one);
8826 for (i = o = 1, ref = n; 1 <= ref ? o <= ref : o >= ref; i = 1 <= ref ? ++o : --o) {
8827 push(cadr(p2));
8828 push_integer(i);
8829 add();
8830 push(p3);
8831 power();
8832 multiply();
8833 }
8834 stack[s + a] = pop();
8835 return stack[s + b] = symbol(NIL);
8836 }
8837 };
8838
8839 polycoeff = 0;
8840
8841 factpoly_expo = 0;
8842
8843 factorpoly = function() {
8844 save();
8845 p2 = pop();
8846 p1 = pop();
8847 if (!Find(p1, p2)) {
8848 push(p1);
8849 restore();
8850 return;
8851 }
8852 if (!ispoly(p1, p2)) {
8853 push(p1);
8854 restore();
8855 return;
8856 }
8857 if (!issymbol(p2)) {
8858 push(p1);
8859 restore();
8860 return;
8861 }
8862 push(p1);
8863 push(p2);
8864 yyfactorpoly();
8865 return restore();
8866 };
8867
8868 yyfactorpoly = function() {
8869 var checkingTheDivision, dividend, foundComplexRoot, foundRealRoot, h, i, i1, j1, l1, o, prev_expanding, previousFactorisation, ref, ref1, ref2, ref3, remainingPoly, whichRootsAreWeFinding;
8870 h = 0;
8871 i = 0;
8872 save();
8873 p2 = pop();
8874 p1 = pop();
8875 h = tos;
8876 if (isfloating(p1)) {
8877 stop("floating point numbers in polynomial");
8878 }
8879 polycoeff = tos;
8880 push(p1);
8881 push(p2);
8882 factpoly_expo = coeff() - 1;
8883 rationalize_coefficients(h);
8884 whichRootsAreWeFinding = "real";
8885 remainingPoly = null;
8886 while (factpoly_expo > 0) {
8887 if (iszero(stack[polycoeff + 0])) {
8888 push_integer(1);
8889 p4 = pop();
8890 push_integer(0);
8891 p5 = pop();
8892 } else {
8893 if (whichRootsAreWeFinding === "real") {
8894 foundRealRoot = get_factor_from_real_root();
8895 } else if (whichRootsAreWeFinding === "complex") {
8896 foundComplexRoot = get_factor_from_complex_root(remainingPoly);
8897 }
8898 }
8899 if (whichRootsAreWeFinding === "real") {
8900 if (foundRealRoot === 0) {
8901 whichRootsAreWeFinding = "complex";
8902 continue;
8903 } else {
8904 push(p4);
8905 push(p2);
8906 multiply();
8907 push(p5);
8908 add();
8909 p8 = pop();
8910 if (DEBUG) {
8911 console.log("success\nFACTOR=" + p8);
8912 }
8913
8914 /*
8915 if (isnegativeterm(p4))
8916 push(p8)
8917 negate()
8918 p8 = pop()
8919 push(p7)
8920 negate_noexpand()
8921 p7 = pop()
8922 */
8923 push(p7);
8924 push(p8);
8925 multiply_noexpand();
8926 p7 = pop();
8927 yydivpoly();
8928 while (factpoly_expo && iszero(stack[polycoeff + factpoly_expo])) {
8929 factpoly_expo--;
8930 }
8931 push(zero);
8932 for (i = o = 0, ref = factpoly_expo; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) {
8933 push(stack[polycoeff + i]);
8934 push(p2);
8935 push_integer(i);
8936 power();
8937 multiply();
8938 add();
8939 }
8940 remainingPoly = pop();
8941 }
8942 } else if (whichRootsAreWeFinding === "complex") {
8943 if (foundComplexRoot === 0) {
8944 break;
8945 } else {
8946 push(p4);
8947 push(p2);
8948 subtract();
8949 push(p4);
8950 conjugate();
8951 push(p2);
8952 subtract();
8953 multiply();
8954 p8 = pop();
8955 if (DEBUG) {
8956 console.log("success\nFACTOR=" + p8);
8957 }
8958
8959 /*
8960 if (isnegativeterm(p4))
8961 push(p8)
8962 negate()
8963 p8 = pop()
8964 push(p7)
8965 negate_noexpand()
8966 p7 = pop()
8967 */
8968 push(p7);
8969 previousFactorisation = pop();
8970 push(p7);
8971 push(p8);
8972 multiply_noexpand();
8973 p7 = pop();
8974 if (remainingPoly == null) {
8975 push(zero);
8976 for (i = i1 = 0, ref1 = factpoly_expo; 0 <= ref1 ? i1 <= ref1 : i1 >= ref1; i = 0 <= ref1 ? ++i1 : --i1) {
8977 push(stack[polycoeff + i]);
8978 push(p2);
8979 push_integer(i);
8980 power();
8981 multiply();
8982 add();
8983 }
8984 remainingPoly = pop();
8985 }
8986 dividend = remainingPoly;
8987 push(dividend);
8988 push(p8);
8989 push(p2);
8990 divpoly();
8991 remainingPoly = pop();
8992 push(remainingPoly);
8993 push(p8);
8994 multiply();
8995 checkingTheDivision = pop();
8996 if (!equal(checkingTheDivision, dividend)) {
8997 if (DEBUG) {
8998 console.log("we found a polynomial based on complex root and its conj but it doesn't divide the poly, quitting");
8999 }
9000 if (DEBUG) {
9001 console.log("so just returning previousFactorisation times dividend: " + previousFactorisation + " * " + dividend);
9002 }
9003 push(previousFactorisation);
9004 push(dividend);
9005 prev_expanding = expanding;
9006 expanding = 0;
9007 yycondense();
9008 expanding = prev_expanding;
9009 multiply_noexpand();
9010 p7 = pop();
9011 stack[h] = p7;
9012 moveTos(h + 1);
9013 restore();
9014 return;
9015 }
9016
9017 /*
9018 if compare_numbers(startingDegree, remainingDegree)
9019 * ok even if we found a complex root that
9020 * together with the conjugate generates a poly in Z,
9021 * that doesn't mean that the division would end up in Z.
9022 * Example: 1+x^2+x^4+x^6 has +i and -i as one of its roots
9023 * so a factor is 1+x^2 ( = (x+i)*(x-i))
9024 * BUT
9025 */
9026 for (i = j1 = 0, ref2 = factpoly_expo; 0 <= ref2 ? j1 <= ref2 : j1 >= ref2; i = 0 <= ref2 ? ++j1 : --j1) {
9027 pop();
9028 }
9029 push(remainingPoly);
9030 push(p2);
9031 coeff();
9032 factpoly_expo -= 2;
9033 }
9034 }
9035 }
9036 push(zero);
9037 for (i = l1 = 0, ref3 = factpoly_expo; 0 <= ref3 ? l1 <= ref3 : l1 >= ref3; i = 0 <= ref3 ? ++l1 : --l1) {
9038 push(stack[polycoeff + i]);
9039 push(p2);
9040 push_integer(i);
9041 power();
9042 multiply();
9043 add();
9044 }
9045 p1 = pop();
9046 if (DEBUG) {
9047 console.log("POLY=" + p1);
9048 }
9049 push(p1);
9050 prev_expanding = expanding;
9051 expanding = 0;
9052 yycondense();
9053 expanding = prev_expanding;
9054 p1 = pop();
9055 if (factpoly_expo > 0 && isnegativeterm(stack[polycoeff + factpoly_expo])) {
9056 push(p1);
9057 negate();
9058 p1 = pop();
9059 push(p7);
9060 negate_noexpand();
9061 p7 = pop();
9062 }
9063 push(p7);
9064 push(p1);
9065 multiply_noexpand();
9066 p7 = pop();
9067 if (DEBUG) {
9068 console.log("RESULT=" + p7);
9069 }
9070 stack[h] = p7;
9071 moveTos(h + 1);
9072 return restore();
9073 };
9074
9075 rationalize_coefficients = function(h) {
9076 var i, i1, o, ref, ref1, ref2, ref3;
9077 i = 0;
9078 p7 = one;
9079 for (i = o = ref = h, ref1 = tos; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
9080 push(stack[i]);
9081 denominator();
9082 push(p7);
9083 lcm();
9084 p7 = pop();
9085 }
9086 for (i = i1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? i1 < ref3 : i1 > ref3; i = ref2 <= ref3 ? ++i1 : --i1) {
9087 push(p7);
9088 push(stack[i]);
9089 multiply();
9090 stack[i] = pop();
9091 }
9092 push(p7);
9093 reciprocate();
9094 p7 = pop();
9095 if (DEBUG) {
9096 return console.log("rationalize_coefficients result");
9097 }
9098 };
9099
9100 get_factor_from_real_root = function() {
9101 var a0, an, h, i, i1, j, j1, l1, m1, na0, nan, o, ref, ref1, ref2, ref3, ref4, rootsTries_i, rootsTries_j;
9102 i = 0;
9103 j = 0;
9104 h = 0;
9105 a0 = 0;
9106 an = 0;
9107 na0 = 0;
9108 nan = 0;
9109 if (DEBUG) {
9110 push(zero);
9111 for (i = o = 0, ref = factpoly_expo; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) {
9112 push(stack[polycoeff + i]);
9113 push(p2);
9114 push_integer(i);
9115 power();
9116 multiply();
9117 add();
9118 }
9119 p1 = pop();
9120 console.log("POLY=" + p1);
9121 }
9122 h = tos;
9123 an = tos;
9124 push(stack[polycoeff + factpoly_expo]);
9125 divisors_onstack();
9126 nan = tos - an;
9127 a0 = tos;
9128 push(stack[polycoeff + 0]);
9129 divisors_onstack();
9130 na0 = tos - a0;
9131 if (DEBUG) {
9132 console.log("divisors of base term");
9133 for (i = i1 = 0, ref1 = na0; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
9134 console.log(", " + stack[a0 + i]);
9135 }
9136 console.log("divisors of leading term");
9137 for (i = j1 = 0, ref2 = nan; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
9138 console.log(", " + stack[an + i]);
9139 }
9140 }
9141 for (rootsTries_i = l1 = 0, ref3 = nan; 0 <= ref3 ? l1 < ref3 : l1 > ref3; rootsTries_i = 0 <= ref3 ? ++l1 : --l1) {
9142 for (rootsTries_j = m1 = 0, ref4 = na0; 0 <= ref4 ? m1 < ref4 : m1 > ref4; rootsTries_j = 0 <= ref4 ? ++m1 : --m1) {
9143 p4 = stack[an + rootsTries_i];
9144 p5 = stack[a0 + rootsTries_j];
9145 push(p5);
9146 push(p4);
9147 divide();
9148 negate();
9149 p3 = pop();
9150 Evalpoly();
9151 if (DEBUG) {
9152 console.log("try A=" + p4);
9153 console.log(", B=" + p5);
9154 console.log(", root " + p2);
9155 console.log("=-B/A=" + p3);
9156 console.log(", POLY(" + p3);
9157 console.log(")=" + p6);
9158 }
9159 if (iszero(p6)) {
9160 moveTos(h);
9161 if (DEBUG) {
9162 console.log("get_factor_from_real_root returning 1");
9163 }
9164 return 1;
9165 }
9166 push(p5);
9167 negate();
9168 p5 = pop();
9169 push(p3);
9170 negate();
9171 p3 = pop();
9172 Evalpoly();
9173 if (DEBUG) {
9174 console.log("try A=" + p4);
9175 console.log(", B=" + p5);
9176 console.log(", root " + p2);
9177 console.log("=-B/A=" + p3);
9178 console.log(", POLY(" + p3);
9179 console.log(")=" + p6);
9180 }
9181 if (iszero(p6)) {
9182 moveTos(h);
9183 if (DEBUG) {
9184 console.log("get_factor_from_real_root returning 1");
9185 }
9186 return 1;
9187 }
9188 }
9189 }
9190 moveTos(h);
9191 if (DEBUG) {
9192 console.log("get_factor_from_real_root returning 0");
9193 }
9194 return 0;
9195 };
9196
9197 get_factor_from_complex_root = function(remainingPoly) {
9198 var a0, an, h, i, i1, j, na0, nan, o, rootsTries_i, rootsTries_j;
9199 i = 0;
9200 j = 0;
9201 h = 0;
9202 a0 = 0;
9203 an = 0;
9204 na0 = 0;
9205 nan = 0;
9206 if (factpoly_expo <= 2) {
9207 if (DEBUG) {
9208 console.log("no more factoring via complex roots to be found in polynomial of degree <= 2");
9209 }
9210 return 0;
9211 }
9212 p1 = remainingPoly;
9213 if (DEBUG) {
9214 console.log("complex root finding for POLY=" + p1);
9215 }
9216 h = tos;
9217 an = tos;
9218 push_integer(-1);
9219 push_rational(2, 3);
9220 power();
9221 rect();
9222 p4 = pop();
9223 if (DEBUG) {
9224 console.log("complex root finding: trying with " + p4);
9225 }
9226 push(p4);
9227 p3 = pop();
9228 push(p3);
9229 Evalpoly();
9230 if (DEBUG) {
9231 console.log("complex root finding result: " + p6);
9232 }
9233 if (iszero(p6)) {
9234 moveTos(h);
9235 if (DEBUG) {
9236 console.log("get_factor_from_complex_root returning 1");
9237 }
9238 return 1;
9239 }
9240 push_integer(1);
9241 push_rational(2, 3);
9242 power();
9243 rect();
9244 p4 = pop();
9245 if (DEBUG) {
9246 console.log("complex root finding: trying with " + p4);
9247 }
9248 push(p4);
9249 p3 = pop();
9250 push(p3);
9251 Evalpoly();
9252 if (DEBUG) {
9253 console.log("complex root finding result: " + p6);
9254 }
9255 if (iszero(p6)) {
9256 moveTos(h);
9257 if (DEBUG) {
9258 console.log("get_factor_from_complex_root returning 1");
9259 }
9260 return 1;
9261 }
9262 for (rootsTries_i = o = -10; o <= 10; rootsTries_i = ++o) {
9263 for (rootsTries_j = i1 = 1; i1 <= 5; rootsTries_j = ++i1) {
9264 push_integer(rootsTries_i);
9265 push_integer(rootsTries_j);
9266 push(imaginaryunit);
9267 multiply();
9268 add();
9269 rect();
9270 p4 = pop();
9271 push(p4);
9272 p3 = pop();
9273 push(p3);
9274 Evalpoly();
9275 if (iszero(p6)) {
9276 moveTos(h);
9277 if (DEBUG) {
9278 console.log("found complex root: " + p6);
9279 }
9280 return 1;
9281 }
9282 }
9283 }
9284 moveTos(h);
9285 if (DEBUG) {
9286 console.log("get_factor_from_complex_root returning 0");
9287 }
9288 return 0;
9289 };
9290
9291 yydivpoly = function() {
9292 var i, o, ref;
9293 i = 0;
9294 p6 = zero;
9295 for (i = o = ref = factpoly_expo; ref <= 0 ? o < 0 : o > 0; i = ref <= 0 ? ++o : --o) {
9296 push(stack[polycoeff + i]);
9297 stack[polycoeff + i] = p6;
9298 push(p4);
9299 divide();
9300 p6 = pop();
9301 push(stack[polycoeff + i - 1]);
9302 push(p6);
9303 push(p5);
9304 multiply();
9305 subtract();
9306 stack[polycoeff + i - 1] = pop();
9307 }
9308 stack[polycoeff + 0] = p6;
9309 if (DEBUG) {
9310 return console.log("yydivpoly Q:");
9311 }
9312 };
9313
9314 Evalpoly = function() {
9315 var i, o, ref;
9316 i = 0;
9317 push(zero);
9318 for (i = o = ref = factpoly_expo; ref <= 0 ? o <= 0 : o >= 0; i = ref <= 0 ? ++o : --o) {
9319 push(p3);
9320 multiply();
9321 push(stack[polycoeff + i]);
9322 if (DEBUG) {
9323 console.log("Evalpoly top of stack:");
9324 console.log(print_list(stack[tos - i]));
9325 }
9326 add();
9327 }
9328 return p6 = pop();
9329 };
9330
9331 factors = function(p) {
9332 var h;
9333 h = tos;
9334 if (car(p) === symbol(ADD)) {
9335 p = cdr(p);
9336 while (iscons(p)) {
9337 push_term_factors(car(p));
9338 p = cdr(p);
9339 }
9340 } else {
9341 push_term_factors(p);
9342 }
9343 return tos - h;
9344 };
9345
9346 push_term_factors = function(p) {
9347 var results;
9348 if (car(p) === symbol(MULTIPLY)) {
9349 p = cdr(p);
9350 results = [];
9351 while (iscons(p)) {
9352 push(car(p));
9353 results.push(p = cdr(p));
9354 }
9355 return results;
9356 } else {
9357 return push(p);
9358 }
9359 };
9360
9361
9362 /*
9363 Remove terms that involve a given symbol or expression. For example...
9364
9365 filter(x^2 + x + 1, x) => 1
9366
9367 filter(x^2 + x + 1, x^2) => x + 1
9368 */
9369
9370 Eval_filter = function() {
9371 var results;
9372 p1 = cdr(p1);
9373 push(car(p1));
9374 Eval();
9375 p1 = cdr(p1);
9376 results = [];
9377 while (iscons(p1)) {
9378 push(car(p1));
9379 Eval();
9380 filter();
9381 results.push(p1 = cdr(p1));
9382 }
9383 return results;
9384 };
9385
9386
9387 /*
9388 For example...
9389
9390 push(F)
9391 push(X)
9392 filter()
9393 F = pop()
9394 */
9395
9396 filter = function() {
9397 save();
9398 p2 = pop();
9399 p1 = pop();
9400 filter_main();
9401 return restore();
9402 };
9403
9404 filter_main = function() {
9405 if (car(p1) === symbol(ADD)) {
9406 return filter_sum();
9407 } else if (istensor(p1)) {
9408 return filter_tensor();
9409 } else if (Find(p1, p2)) {
9410 return push_integer(0);
9411 } else {
9412 return push(p1);
9413 }
9414 };
9415
9416 filter_sum = function() {
9417 var results;
9418 push_integer(0);
9419 p1 = cdr(p1);
9420 results = [];
9421 while (iscons(p1)) {
9422 push(car(p1));
9423 push(p2);
9424 filter();
9425 add();
9426 results.push(p1 = cdr(p1));
9427 }
9428 return results;
9429 };
9430
9431 filter_tensor = function() {
9432 var i, i1, n, o, ref, ref1;
9433 i = 0;
9434 n = 0;
9435 n = p1.tensor.nelem;
9436 p3 = alloc_tensor(n);
9437 p3.tensor.ndim = p1.tensor.ndim;
9438 for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
9439 p3.tensor.dim[i] = p1.tensor.dim[i];
9440 }
9441 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
9442 push(p1.tensor.elem[i]);
9443 push(p2);
9444 filter();
9445 p3.tensor.elem[i] = pop();
9446 }
9447 return push(p3);
9448 };
9449
9450 Eval_float = function() {
9451 evaluatingAsFloats++;
9452 push(cadr(p1));
9453 Eval();
9454 yyfloat();
9455 Eval();
9456 return evaluatingAsFloats--;
9457 };
9458
9459 checkFloatHasWorkedOutCompletely = function(nodeToCheck) {
9460 var numberOfEs, numberOfMults, numberOfPIs, numberOfPowers, numberOfSums;
9461 numberOfPowers = countOccurrencesOfSymbol(symbol(POWER), nodeToCheck);
9462 numberOfPIs = countOccurrencesOfSymbol(symbol(PI), nodeToCheck);
9463 numberOfEs = countOccurrencesOfSymbol(symbol(E), nodeToCheck);
9464 numberOfMults = countOccurrencesOfSymbol(symbol(MULTIPLY), nodeToCheck);
9465 numberOfSums = countOccurrencesOfSymbol(symbol(ADD), nodeToCheck);
9466 if (DEBUG) {
9467 console.log(" ... numberOfPowers: " + numberOfPowers);
9468 console.log(" ... numberOfPIs: " + numberOfPIs);
9469 console.log(" ... numberOfEs: " + numberOfEs);
9470 console.log(" ... numberOfMults: " + numberOfMults);
9471 console.log(" ... numberOfSums: " + numberOfSums);
9472 }
9473 if (numberOfPowers > 1 || numberOfPIs > 0 || numberOfEs > 0 || numberOfMults > 1 || numberOfSums > 1) {
9474 return stop("float: some unevalued parts in " + nodeToCheck);
9475 }
9476 };
9477
9478 zzfloat = function() {
9479 save();
9480 evaluatingAsFloats++;
9481 Eval();
9482 yyfloat();
9483 Eval();
9484 evaluatingAsFloats--;
9485 return restore();
9486 };
9487
9488 yyfloat = function() {
9489 var h, i, o, ref;
9490 i = 0;
9491 h = 0;
9492 evaluatingAsFloats++;
9493 save();
9494 p1 = pop();
9495 if (iscons(p1)) {
9496 h = tos;
9497 while (iscons(p1)) {
9498 push(car(p1));
9499 yyfloat();
9500 p1 = cdr(p1);
9501 }
9502 list(tos - h);
9503 } else if (p1.k === TENSOR) {
9504 push(p1);
9505 copy_tensor();
9506 p1 = pop();
9507 for (i = o = 0, ref = p1.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
9508 push(p1.tensor.elem[i]);
9509 yyfloat();
9510 p1.tensor.elem[i] = pop();
9511 }
9512 push(p1);
9513 } else if (p1.k === NUM) {
9514 push(p1);
9515 bignum_float();
9516 } else if (p1 === symbol(PI)) {
9517 push_double(Math.PI);
9518 } else if (p1 === symbol(E)) {
9519 push_double(Math.E);
9520 } else {
9521 push(p1);
9522 }
9523 restore();
9524 return evaluatingAsFloats--;
9525 };
9526
9527 Eval_floor = function() {
9528 push(cadr(p1));
9529 Eval();
9530 return yfloor();
9531 };
9532
9533 yfloor = function() {
9534 save();
9535 yyfloor();
9536 return restore();
9537 };
9538
9539 yyfloor = function() {
9540 var d;
9541 d = 0.0;
9542 p1 = pop();
9543 if (!isnum(p1)) {
9544 push_symbol(FLOOR);
9545 push(p1);
9546 list(2);
9547 return;
9548 }
9549 if (isdouble(p1)) {
9550 d = Math.floor(p1.d);
9551 push_double(d);
9552 return;
9553 }
9554 if (isinteger(p1)) {
9555 push(p1);
9556 return;
9557 }
9558 p3 = new U();
9559 p3.k = NUM;
9560 p3.q.a = mdiv(p1.q.a, p1.q.b);
9561 p3.q.b = mint(1);
9562 push(p3);
9563 if (isnegativenumber(p1)) {
9564 push_integer(-1);
9565 return add();
9566 }
9567 };
9568
9569
9570 /*
9571 x=0
9572 y=2
9573 for(do(x=sqrt(2+x),y=2*y/x),k,1,9)
9574 float(y)
9575
9576 X: k
9577 B: 1...9
9578
9579 1st parameter is the body
9580 2nd parameter is the variable to loop with
9581 3rd and 4th are the limits
9582 */
9583
9584 Eval_for = function() {
9585 var i, j, k, loopingVariable, o, ref, ref1;
9586 i = 0;
9587 j = 0;
9588 k = 0;
9589 loopingVariable = caddr(p1);
9590 if (!issymbol(loopingVariable)) {
9591 stop("for: 2nd arg should be the variable to loop over");
9592 }
9593 push(cadddr(p1));
9594 Eval();
9595 j = pop_integer();
9596 if (isNaN(j)) {
9597 push(p1);
9598 return;
9599 }
9600 push(caddddr(p1));
9601 Eval();
9602 k = pop_integer();
9603 if (isNaN(k)) {
9604 push(p1);
9605 return;
9606 }
9607 p4 = get_binding(loopingVariable);
9608 for (i = o = ref = j, ref1 = k; ref <= ref1 ? o <= ref1 : o >= ref1; i = ref <= ref1 ? ++o : --o) {
9609 push_integer(i);
9610 p5 = pop();
9611 set_binding(loopingVariable, p5);
9612 push(cadr(p1));
9613 Eval();
9614 pop();
9615 }
9616 set_binding(loopingVariable, p4);
9617 return push_symbol(NIL);
9618 };
9619
9620 Eval_gamma = function() {
9621 push(cadr(p1));
9622 Eval();
9623 return gamma();
9624 };
9625
9626 gamma = function() {
9627 save();
9628 gammaf();
9629 return restore();
9630 };
9631
9632 gammaf = function() {
9633 p1 = pop();
9634 if (isrational(p1) && MEQUAL(p1.q.a, 1) && MEQUAL(p1.q.b, 2)) {
9635 if (evaluatingAsFloats) {
9636 push_double(Math.PI);
9637 } else {
9638 push_symbol(PI);
9639 }
9640 push_rational(1, 2);
9641 power();
9642 return;
9643 }
9644 if (isrational(p1) && MEQUAL(p1.q.a, 3) && MEQUAL(p1.q.b, 2)) {
9645 if (evaluatingAsFloats) {
9646 push_double(Math.PI);
9647 } else {
9648 push_symbol(PI);
9649 }
9650 push_rational(1, 2);
9651 power();
9652 push_rational(1, 2);
9653 multiply();
9654 return;
9655 }
9656 if (isnegativeterm(p1)) {
9657 if (evaluatingAsFloats) {
9658 push_double(Math.PI);
9659 } else {
9660 push_symbol(PI);
9661 }
9662 push_integer(-1);
9663 multiply();
9664 if (evaluatingAsFloats) {
9665 push_double(Math.PI);
9666 } else {
9667 push_symbol(PI);
9668 }
9669 push(p1);
9670 multiply();
9671 sine();
9672 push(p1);
9673 multiply();
9674 push(p1);
9675 negate();
9676 gamma();
9677 multiply();
9678 divide();
9679 return;
9680 }
9681 if (car(p1) === symbol(ADD)) {
9682 gamma_of_sum();
9683 return;
9684 }
9685 push_symbol(GAMMA);
9686 push(p1);
9687 list(2);
9688 };
9689
9690 gamma_of_sum = function() {
9691 p3 = cdr(p1);
9692 if (isrational(car(p3)) && MEQUAL(car(p3).q.a, 1) && MEQUAL(car(p3).q.b, 1)) {
9693 push(cadr(p3));
9694 push(cadr(p3));
9695 gamma();
9696 return multiply();
9697 } else {
9698 if (isrational(car(p3)) && MEQUAL(car(p3).q.a, -1) && MEQUAL(car(p3).q.b, 1)) {
9699 push(cadr(p3));
9700 gamma();
9701 push(cadr(p3));
9702 push_integer(-1);
9703 add();
9704 return divide();
9705 } else {
9706 push_symbol(GAMMA);
9707 push(p1);
9708 list(2);
9709 }
9710 }
9711 };
9712
9713 Eval_gcd = function() {
9714 var results;
9715 p1 = cdr(p1);
9716 push(car(p1));
9717 Eval();
9718 p1 = cdr(p1);
9719 results = [];
9720 while (iscons(p1)) {
9721 push(car(p1));
9722 Eval();
9723 gcd();
9724 results.push(p1 = cdr(p1));
9725 }
9726 return results;
9727 };
9728
9729 gcd = function() {
9730 var prev_expanding;
9731 prev_expanding = expanding;
9732 save();
9733 gcd_main();
9734 restore();
9735 return expanding = prev_expanding;
9736 };
9737
9738 gcd_main = function() {
9739 expanding = 1;
9740 p2 = pop();
9741 p1 = pop();
9742 if (equal(p1, p2)) {
9743 push(p1);
9744 return;
9745 }
9746 if (isrational(p1) && isrational(p2)) {
9747 push(p1);
9748 push(p2);
9749 gcd_numbers();
9750 return;
9751 }
9752 if (car(p1) === symbol(ADD) && car(p2) === symbol(ADD)) {
9753 gcd_expr_expr();
9754 return;
9755 }
9756 if (car(p1) === symbol(ADD)) {
9757 gcd_expr(p1);
9758 p1 = pop();
9759 }
9760 if (car(p2) === symbol(ADD)) {
9761 gcd_expr(p2);
9762 p2 = pop();
9763 }
9764 if (car(p1) === symbol(MULTIPLY) && car(p2) === symbol(MULTIPLY)) {
9765 gcd_term_term();
9766 return;
9767 }
9768 if (car(p1) === symbol(MULTIPLY)) {
9769 gcd_term_factor();
9770 return;
9771 }
9772 if (car(p2) === symbol(MULTIPLY)) {
9773 gcd_factor_term();
9774 return;
9775 }
9776 if (car(p1) === symbol(POWER)) {
9777 p3 = caddr(p1);
9778 p1 = cadr(p1);
9779 } else {
9780 p3 = one;
9781 }
9782 if (car(p2) === symbol(POWER)) {
9783 p4 = caddr(p2);
9784 p2 = cadr(p2);
9785 } else {
9786 p4 = one;
9787 }
9788 if (!equal(p1, p2)) {
9789 push(one);
9790 return;
9791 }
9792 if (isnum(p3) && isnum(p4)) {
9793 push(p1);
9794 if (lessp(p3, p4)) {
9795 push(p3);
9796 } else {
9797 push(p4);
9798 }
9799 power();
9800 return;
9801 }
9802 push(p3);
9803 push(p4);
9804 divide();
9805 p5 = pop();
9806 if (isnum(p5)) {
9807 push(p1);
9808 if (car(p3) === symbol(MULTIPLY) && isnum(cadr(p3))) {
9809 p5 = cadr(p3);
9810 } else {
9811 p5 = one;
9812 }
9813 if (car(p4) === symbol(MULTIPLY) && isnum(cadr(p4))) {
9814 p6 = cadr(p4);
9815 } else {
9816 p6 = one;
9817 }
9818 if (lessp(p5, p6)) {
9819 push(p3);
9820 } else {
9821 push(p4);
9822 }
9823 power();
9824 return;
9825 }
9826 push(p3);
9827 push(p4);
9828 subtract();
9829 p5 = pop();
9830 if (!isnum(p5)) {
9831 push(one);
9832 return;
9833 }
9834 push(p1);
9835 if (isnegativenumber(p5)) {
9836 push(p3);
9837 } else {
9838 push(p4);
9839 }
9840 return power();
9841 };
9842
9843 gcd_expr_expr = function() {
9844 if (length(p1) !== length(p2)) {
9845 push(one);
9846 return;
9847 }
9848 p3 = cdr(p1);
9849 push(car(p3));
9850 p3 = cdr(p3);
9851 while (iscons(p3)) {
9852 push(car(p3));
9853 gcd();
9854 p3 = cdr(p3);
9855 }
9856 p3 = pop();
9857 p4 = cdr(p2);
9858 push(car(p4));
9859 p4 = cdr(p4);
9860 while (iscons(p4)) {
9861 push(car(p4));
9862 gcd();
9863 p4 = cdr(p4);
9864 }
9865 p4 = pop();
9866 push(p1);
9867 push(p3);
9868 divide();
9869 p5 = pop();
9870 push(p2);
9871 push(p4);
9872 divide();
9873 p6 = pop();
9874 if (equal(p5, p6)) {
9875 push(p5);
9876 push(p3);
9877 push(p4);
9878 gcd();
9879 return multiply();
9880 } else {
9881 return push(one);
9882 }
9883 };
9884
9885 gcd_expr = function(p) {
9886 var results;
9887 p = cdr(p);
9888 push(car(p));
9889 p = cdr(p);
9890 results = [];
9891 while (iscons(p)) {
9892 push(car(p));
9893 gcd();
9894 results.push(p = cdr(p));
9895 }
9896 return results;
9897 };
9898
9899 gcd_term_term = function() {
9900 var results;
9901 push(one);
9902 p3 = cdr(p1);
9903 results = [];
9904 while (iscons(p3)) {
9905 p4 = cdr(p2);
9906 while (iscons(p4)) {
9907 push(car(p3));
9908 push(car(p4));
9909 gcd();
9910 multiply();
9911 p4 = cdr(p4);
9912 }
9913 results.push(p3 = cdr(p3));
9914 }
9915 return results;
9916 };
9917
9918 gcd_term_factor = function() {
9919 var results;
9920 push(one);
9921 p3 = cdr(p1);
9922 results = [];
9923 while (iscons(p3)) {
9924 push(car(p3));
9925 push(p2);
9926 gcd();
9927 multiply();
9928 results.push(p3 = cdr(p3));
9929 }
9930 return results;
9931 };
9932
9933 gcd_factor_term = function() {
9934 var results;
9935 push(one);
9936 p4 = cdr(p2);
9937 results = [];
9938 while (iscons(p4)) {
9939 push(p1);
9940 push(car(p4));
9941 gcd();
9942 multiply();
9943 results.push(p4 = cdr(p4));
9944 }
9945 return results;
9946 };
9947
9948 guess = function() {
9949 var p;
9950 p = pop();
9951 push(p);
9952 if (Find(p, symbol(SYMBOL_X))) {
9953 return push_symbol(SYMBOL_X);
9954 } else if (Find(p, symbol(SYMBOL_Y))) {
9955 return push_symbol(SYMBOL_Y);
9956 } else if (Find(p, symbol(SYMBOL_Z))) {
9957 return push_symbol(SYMBOL_Z);
9958 } else if (Find(p, symbol(SYMBOL_T))) {
9959 return push_symbol(SYMBOL_T);
9960 } else if (Find(p, symbol(SYMBOL_S))) {
9961 return push_symbol(SYMBOL_S);
9962 } else {
9963 return push_symbol(SYMBOL_X);
9964 }
9965 };
9966
9967 hermite = function() {
9968 save();
9969 yyhermite();
9970 return restore();
9971 };
9972
9973 yyhermite = function() {
9974 var n;
9975 n = 0;
9976 p2 = pop();
9977 p1 = pop();
9978 push(p2);
9979 n = pop_integer();
9980 if (n < 0 || isNaN(n)) {
9981 push_symbol(HERMITE);
9982 push(p1);
9983 push(p2);
9984 list(3);
9985 return;
9986 }
9987 if (issymbol(p1)) {
9988 return yyhermite2(n);
9989 } else {
9990 p3 = p1;
9991 p1 = symbol(SECRETX);
9992 yyhermite2(n);
9993 p1 = p3;
9994 push(symbol(SECRETX));
9995 push(p1);
9996 subst();
9997 return Eval();
9998 }
9999 };
10000
10001 yyhermite2 = function(n) {
10002 var i, o, ref, results;
10003 i = 0;
10004 push_integer(1);
10005 push_integer(0);
10006 p4 = pop();
10007 results = [];
10008 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10009 p5 = p4;
10010 p4 = pop();
10011 push(p1);
10012 push(p4);
10013 multiply();
10014 push_integer(i);
10015 push(p5);
10016 multiply();
10017 subtract();
10018 push_integer(2);
10019 results.push(multiply());
10020 }
10021 return results;
10022 };
10023
10024 hilbert = function() {
10025 var i, i1, j, n, o, ref, ref1;
10026 i = 0;
10027 j = 0;
10028 n = 0;
10029 save();
10030 p2 = pop();
10031 push(p2);
10032 n = pop_integer();
10033 if (n < 2) {
10034 push_symbol(HILBERT);
10035 push(p2);
10036 list(2);
10037 restore();
10038 return;
10039 }
10040 push_zero_matrix(n, n);
10041 p1 = pop();
10042 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10043 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
10044 push_integer(i + j + 1);
10045 inverse();
10046 p1.tensor.elem[i * n + j] = pop();
10047 }
10048 }
10049 push(p1);
10050 return restore();
10051 };
10052
10053
10054 /*
10055 Returns the coefficient of the imaginary part of complex z
10056
10057 z imag(z)
10058 - -------
10059
10060 a + i b b
10061
10062 exp(i a) sin(a)
10063 */
10064
10065 DEBUG_IMAG = false;
10066
10067 Eval_imag = function() {
10068 push(cadr(p1));
10069 Eval();
10070 return imag();
10071 };
10072
10073 imag = function() {
10074 save();
10075 rect();
10076 p1 = pop();
10077 if (DEBUG_IMAG) {
10078 console.log("IMAGE of " + p1);
10079 }
10080 push(p1);
10081 push(p1);
10082 conjugate();
10083 if (DEBUG_IMAG) {
10084 console.log(" image: conjugate result: " + stack[tos - 1]);
10085 }
10086 subtract();
10087 push_integer(2);
10088 divide();
10089 if (DEBUG_IMAG) {
10090 console.log(" image: 1st divide result: " + stack[tos - 1]);
10091 }
10092 push(imaginaryunit);
10093 divide();
10094 if (DEBUG_IMAG) {
10095 console.log(" image: 2nd divide result: " + stack[tos - 1]);
10096 }
10097 return restore();
10098 };
10099
10100 index_function = function(n) {
10101 var i, i1, j1, k, l1, m, m1, ndim, nelem, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, s, t;
10102 i = 0;
10103 k = 0;
10104 m = 0;
10105 ndim = 0;
10106 nelem = 0;
10107 t = 0;
10108 save();
10109 s = tos - n;
10110 p1 = stack[s];
10111 ndim = p1.tensor.ndim;
10112 m = n - 1;
10113 if (m > ndim) {
10114 stop("too many indices for tensor");
10115 }
10116 k = 0;
10117 for (i = o = 0, ref = m; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10118 push(stack[s + i + 1]);
10119 t = pop_integer();
10120 if (t < 1 || t > p1.tensor.dim[i]) {
10121 stop("index out of range");
10122 }
10123 k = k * p1.tensor.dim[i] + t - 1;
10124 }
10125 if (ndim === m) {
10126 moveTos(tos - n);
10127 push(p1.tensor.elem[k]);
10128 restore();
10129 return;
10130 }
10131 for (i = i1 = ref1 = m, ref2 = ndim; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
10132 k = k * p1.tensor.dim[i] + 0;
10133 }
10134 nelem = 1;
10135 for (i = j1 = ref3 = m, ref4 = ndim; ref3 <= ref4 ? j1 < ref4 : j1 > ref4; i = ref3 <= ref4 ? ++j1 : --j1) {
10136 nelem *= p1.tensor.dim[i];
10137 }
10138 p2 = alloc_tensor(nelem);
10139 p2.tensor.ndim = ndim - m;
10140 for (i = l1 = ref5 = m, ref6 = ndim; ref5 <= ref6 ? l1 < ref6 : l1 > ref6; i = ref5 <= ref6 ? ++l1 : --l1) {
10141 p2.tensor.dim[i - m] = p1.tensor.dim[i];
10142 }
10143 for (i = m1 = 0, ref7 = nelem; 0 <= ref7 ? m1 < ref7 : m1 > ref7; i = 0 <= ref7 ? ++m1 : --m1) {
10144 p2.tensor.elem[i] = p1.tensor.elem[k + i];
10145 }
10146 check_tensor_dimensions(p1);
10147 check_tensor_dimensions(p2);
10148 moveTos(tos - n);
10149 push(p2);
10150 return restore();
10151 };
10152
10153 set_component = function(n) {
10154 var i, i1, j1, k, l1, m, m1, n1, ndim, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, s, t;
10155 i = 0;
10156 k = 0;
10157 m = 0;
10158 ndim = 0;
10159 t = 0;
10160 save();
10161 if (n < 3) {
10162 stop("error in indexed assign");
10163 }
10164 s = tos - n;
10165 p2 = stack[s];
10166 p1 = stack[s + 1];
10167 if (!istensor(p1)) {
10168 stop("error in indexed assign");
10169 }
10170 ndim = p1.tensor.ndim;
10171 m = n - 2;
10172 if (m > ndim) {
10173 stop("error in indexed assign");
10174 }
10175 k = 0;
10176 for (i = o = 0, ref = m; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10177 push(stack[s + i + 2]);
10178 t = pop_integer();
10179 if (t < 1 || t > p1.tensor.dim[i]) {
10180 stop("error in indexed assign\n");
10181 }
10182 k = k * p1.tensor.dim[i] + t - 1;
10183 }
10184 for (i = i1 = ref1 = m, ref2 = ndim; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
10185 k = k * p1.tensor.dim[i] + 0;
10186 }
10187 p3 = alloc_tensor(p1.tensor.nelem);
10188 p3.tensor.ndim = p1.tensor.ndim;
10189 for (i = j1 = 0, ref3 = p1.tensor.ndim; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
10190 p3.tensor.dim[i] = p1.tensor.dim[i];
10191 }
10192 for (i = l1 = 0, ref4 = p1.tensor.nelem; 0 <= ref4 ? l1 < ref4 : l1 > ref4; i = 0 <= ref4 ? ++l1 : --l1) {
10193 p3.tensor.elem[i] = p1.tensor.elem[i];
10194 }
10195 check_tensor_dimensions(p1);
10196 check_tensor_dimensions(p3);
10197 p1 = p3;
10198 if (ndim === m) {
10199 if (istensor(p2)) {
10200 stop("error in indexed assign");
10201 }
10202 p1.tensor.elem[k] = p2;
10203 check_tensor_dimensions(p1);
10204 moveTos(tos - n);
10205 push(p1);
10206 restore();
10207 return;
10208 }
10209 if (!istensor(p2)) {
10210 stop("error in indexed assign");
10211 }
10212 if (ndim - m !== p2.tensor.ndim) {
10213 stop("error in indexed assign");
10214 }
10215 for (i = m1 = 0, ref5 = p2.tensor.ndim; 0 <= ref5 ? m1 < ref5 : m1 > ref5; i = 0 <= ref5 ? ++m1 : --m1) {
10216 if (p1.tensor.dim[m + i] !== p2.tensor.dim[i]) {
10217 stop("error in indexed assign");
10218 }
10219 }
10220 for (i = n1 = 0, ref6 = p2.tensor.nelem; 0 <= ref6 ? n1 < ref6 : n1 > ref6; i = 0 <= ref6 ? ++n1 : --n1) {
10221 p1.tensor.elem[k + i] = p2.tensor.elem[i];
10222 }
10223 check_tensor_dimensions(p1);
10224 check_tensor_dimensions(p2);
10225 moveTos(tos - n);
10226 push(p1);
10227 return restore();
10228 };
10229
10230
10231 /* dot =====================================================================
10232
10233 Tags
10234 ----
10235 scripting, JS, internal, treenode, general concept
10236
10237 Parameters
10238 ----------
10239 a,b,...
10240
10241 General description
10242 -------------------
10243
10244 The inner (or dot) operator gives products of vectors,
10245 matrices, and tensors.
10246
10247 Note that for Algebrite, the elements of a vector/matrix
10248 can only be scalars. This allows for example to flesh out
10249 matrix multiplication using the usual multiplication.
10250 So for example block-representations are not allowed.
10251
10252 There is an aweful lot of confusion between sw packages on
10253 what dot and inner do.
10254
10255 First off, the "dot" operator is different from the
10256 mathematical notion of dot product, which can be
10257 slightly confusing.
10258
10259 The mathematical notion of dot product is here:
10260 http://mathworld.wolfram.com/DotProduct.html
10261
10262 However, "dot" does that and a bunch of other things,
10263 i.e. in Algebrite
10264 dot/inner does what the dot of Mathematica does, i.e.:
10265
10266 scalar product of vectors:
10267
10268 inner((a, b, c), (x, y, z))
10269 > a x + b y + c z
10270
10271 products of matrices and vectors:
10272
10273 inner(((a, b), (c,d)), (x, y))
10274 > (a x + b y,c x + d y)
10275
10276 inner((x, y), ((a, b), (c,d)))
10277 > (a x + c y,b x + d y)
10278
10279 inner((x, y), ((a, b), (c,d)), (r, s))
10280 > a r x + b s x + c r y + d s y
10281
10282 matrix product:
10283
10284 inner(((a,b),(c,d)),((r,s),(t,u)))
10285 > ((a r + b t,a s + b u),(c r + d t,c s + d u))
10286
10287 the "dot/inner" operator is associative and
10288 distributive but not commutative.
10289
10290 In Mathematica, Inner is a generalisation of Dot where
10291 the user can specify the multiplication and the addition
10292 operators.
10293 But here in Algebrite they do the same thing.
10294
10295 https://reference.wolfram.com/language/ref/Dot.html
10296 https://reference.wolfram.com/language/ref/Inner.html
10297
10298 http://uk.mathworks.com/help/matlab/ref/dot.html
10299 http://uk.mathworks.com/help/matlab/ref/mtimes.html
10300 */
10301
10302 Eval_inner = function() {
10303 var difference, i, i1, j1, l1, moretheArguments, o, operands, ref, ref1, ref2, ref3, refinedOperands, results, secondArgument, shift, theArguments;
10304 theArguments = [];
10305 theArguments.push(car(cdr(p1)));
10306 secondArgument = car(cdr(cdr(p1)));
10307 if (secondArgument === symbol(NIL)) {
10308 stop("pattern needs at least a template and a transformed version");
10309 }
10310 moretheArguments = cdr(cdr(p1));
10311 while (moretheArguments !== symbol(NIL)) {
10312 theArguments.push(car(moretheArguments));
10313 moretheArguments = cdr(moretheArguments);
10314 }
10315 if (theArguments.length > 2) {
10316 push_symbol(INNER);
10317 push(theArguments[theArguments.length - 2]);
10318 push(theArguments[theArguments.length - 1]);
10319 list(3);
10320 for (i = o = 2, ref = theArguments.length; 2 <= ref ? o < ref : o > ref; i = 2 <= ref ? ++o : --o) {
10321 push_symbol(INNER);
10322 swap();
10323 push(theArguments[theArguments.length - i - 1]);
10324 swap();
10325 list(3);
10326 }
10327 p1 = pop();
10328 Eval_inner();
10329 return;
10330 }
10331 operands = [];
10332 get_innerprod_factors(p1, operands);
10333 refinedOperands = [];
10334 for (i = i1 = 0, ref1 = operands.length; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
10335 if (operands[i] === symbol(SYMBOL_IDENTITY_MATRIX)) {
10336 continue;
10337 } else {
10338 refinedOperands.push(operands[i]);
10339 }
10340 }
10341 operands = refinedOperands;
10342 refinedOperands = [];
10343 if (operands.length > 1) {
10344 shift = 0;
10345 for (i = j1 = 0, ref2 = operands.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
10346 if ((i + shift + 1) <= (operands.length - 1)) {
10347 if (!(isnumerictensor(operands[i + shift]) || isnumerictensor(operands[i + shift + 1]))) {
10348 push(operands[i + shift]);
10349 Eval();
10350 inv();
10351 push(operands[i + shift + 1]);
10352 Eval();
10353 subtract();
10354 difference = pop();
10355 if (iszero(difference)) {
10356 shift += 1;
10357 } else {
10358 refinedOperands.push(operands[i + shift]);
10359 }
10360 } else {
10361 refinedOperands.push(operands[i + shift]);
10362 }
10363 } else {
10364 break;
10365 }
10366 if (i + shift === operands.length - 2) {
10367 refinedOperands.push(operands[operands.length - 1]);
10368 }
10369 if (i + shift >= operands.length - 1) {
10370 break;
10371 }
10372 }
10373 operands = refinedOperands;
10374 }
10375 push(symbol(INNER));
10376 if (operands.length > 0) {
10377 for (i = l1 = 0, ref3 = operands.length; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
10378 push(operands[i]);
10379 }
10380 } else {
10381 pop();
10382 push(symbol(SYMBOL_IDENTITY_MATRIX));
10383 return;
10384 }
10385 list(operands.length + 1);
10386 p1 = pop();
10387 p1 = cdr(p1);
10388 push(car(p1));
10389 Eval();
10390 p1 = cdr(p1);
10391 results = [];
10392 while (iscons(p1)) {
10393 push(car(p1));
10394 Eval();
10395 inner();
10396 results.push(p1 = cdr(p1));
10397 }
10398 return results;
10399 };
10400
10401 inner = function() {
10402 var arg1, arg2, arg3, subtractionResult;
10403 save();
10404 p2 = pop();
10405 p1 = pop();
10406 if (isnegativeterm(p2) && isnegativeterm(p1)) {
10407 push(p2);
10408 negate();
10409 p2 = pop();
10410 push(p1);
10411 negate();
10412 p1 = pop();
10413 }
10414 if (isinnerordot(p1)) {
10415 arg1 = car(cdr(p1));
10416 arg2 = car(cdr(cdr(p1)));
10417 arg3 = p2;
10418 p1 = arg1;
10419 push(arg2);
10420 push(arg3);
10421 inner();
10422 p2 = pop();
10423 }
10424 if (p1 === symbol(SYMBOL_IDENTITY_MATRIX)) {
10425 push(p2);
10426 restore();
10427 return;
10428 } else if (p2 === symbol(SYMBOL_IDENTITY_MATRIX)) {
10429 push(p1);
10430 restore();
10431 return;
10432 }
10433 if (istensor(p1) && istensor(p2)) {
10434 inner_f();
10435 } else {
10436 if (!(isnumerictensor(p1) || isnumerictensor(p2))) {
10437 push(p1);
10438 push(p2);
10439 inv();
10440 subtract();
10441 subtractionResult = pop();
10442 if (iszero(subtractionResult)) {
10443 push_symbol(SYMBOL_IDENTITY_MATRIX);
10444 restore();
10445 return;
10446 }
10447 }
10448 if (expanding && isadd(p1)) {
10449 p1 = cdr(p1);
10450 push(zero);
10451 while (iscons(p1)) {
10452 push(car(p1));
10453 push(p2);
10454 inner();
10455 add();
10456 p1 = cdr(p1);
10457 }
10458 restore();
10459 return;
10460 }
10461 if (expanding && isadd(p2)) {
10462 p2 = cdr(p2);
10463 push(zero);
10464 while (iscons(p2)) {
10465 push(p1);
10466 push(car(p2));
10467 inner();
10468 add();
10469 p2 = cdr(p2);
10470 }
10471 restore();
10472 return;
10473 }
10474 push(p1);
10475 push(p2);
10476 if (istensor(p1) && isnum(p2)) {
10477 tensor_times_scalar();
10478 } else if (isnum(p1) && istensor(p2)) {
10479 scalar_times_tensor();
10480 } else {
10481 if (isnum(p1) || isnum(p2)) {
10482 multiply();
10483 } else {
10484 pop();
10485 pop();
10486 push_symbol(INNER);
10487 push(p1);
10488 push(p2);
10489 list(3);
10490 restore();
10491 return;
10492 }
10493 }
10494 }
10495 return restore();
10496 };
10497
10498 inner_f = function() {
10499 var a, ak, b, bk, c, i, i1, j, j1, k, l1, m1, n, n1, ndim, o, o1, ref, ref1, ref2, ref3, ref4, ref5, ref6;
10500 i = 0;
10501 n = p1.tensor.dim[p1.tensor.ndim - 1];
10502 if (n !== p2.tensor.dim[0]) {
10503 debugger;
10504 stop("inner: tensor dimension check");
10505 }
10506 ndim = p1.tensor.ndim + p2.tensor.ndim - 2;
10507 if (ndim > MAXDIM) {
10508 stop("inner: rank of result exceeds maximum");
10509 }
10510 a = p1.tensor.elem;
10511 b = p2.tensor.elem;
10512 ak = 1;
10513 for (i = o = 0, ref = p1.tensor.ndim - 1; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10514 ak *= p1.tensor.dim[i];
10515 }
10516 bk = 1;
10517 for (i = i1 = 1, ref1 = p2.tensor.ndim; 1 <= ref1 ? i1 < ref1 : i1 > ref1; i = 1 <= ref1 ? ++i1 : --i1) {
10518 bk *= p2.tensor.dim[i];
10519 }
10520 p3 = alloc_tensor(ak * bk);
10521 c = p3.tensor.elem;
10522 for (i = j1 = 0, ref2 = ak; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
10523 for (j = l1 = 0, ref3 = n; 0 <= ref3 ? l1 < ref3 : l1 > ref3; j = 0 <= ref3 ? ++l1 : --l1) {
10524 if (iszero(a[i * n + j])) {
10525 continue;
10526 }
10527 for (k = m1 = 0, ref4 = bk; 0 <= ref4 ? m1 < ref4 : m1 > ref4; k = 0 <= ref4 ? ++m1 : --m1) {
10528 push(a[i * n + j]);
10529 push(b[j * bk + k]);
10530 multiply();
10531 push(c[i * bk + k]);
10532 add();
10533 c[i * bk + k] = pop();
10534 }
10535 }
10536 }
10537 if (ndim === 0) {
10538 return push(p3.tensor.elem[0]);
10539 } else {
10540 p3.tensor.ndim = ndim;
10541 j = 0;
10542 for (i = n1 = 0, ref5 = p1.tensor.ndim - 1; 0 <= ref5 ? n1 < ref5 : n1 > ref5; i = 0 <= ref5 ? ++n1 : --n1) {
10543 p3.tensor.dim[i] = p1.tensor.dim[i];
10544 }
10545 j = p1.tensor.ndim - 1;
10546 for (i = o1 = 0, ref6 = p2.tensor.ndim - 1; 0 <= ref6 ? o1 < ref6 : o1 > ref6; i = 0 <= ref6 ? ++o1 : --o1) {
10547 p3.tensor.dim[j + i] = p2.tensor.dim[i + 1];
10548 }
10549 return push(p3);
10550 }
10551 };
10552
10553 get_innerprod_factors = function(tree, factors_accumulator) {
10554 if (!iscons(tree)) {
10555 add_factor_to_accumulator(tree, factors_accumulator);
10556 return;
10557 }
10558 if (cdr(tree) === symbol(NIL)) {
10559 tree = get_innerprod_factors(car(tree), factors_accumulator);
10560 return;
10561 }
10562 if (isinnerordot(tree)) {
10563 get_innerprod_factors(car(cdr(tree)), factors_accumulator);
10564 get_innerprod_factors(cdr(cdr(tree)), factors_accumulator);
10565 return;
10566 }
10567 return add_factor_to_accumulator(tree, factors_accumulator);
10568 };
10569
10570 add_factor_to_accumulator = function(tree, factors_accumulator) {
10571 if (tree !== symbol(NIL)) {
10572 return factors_accumulator.push(tree);
10573 }
10574 };
10575
10576
10577 /*
10578 Table of integrals
10579
10580 The symbol f is just a dummy symbol for creating a list f(A,B,C,C,...) where
10581
10582 A is the template expression
10583
10584 B is the result expression
10585
10586 C is an optional list of conditional expressions
10587 */
10588
10589 itab = ["f(a,a*x)", "f(1/x,log(x))", "f(x^a,x^(a+1)/(a+1))", "f(exp(a*x),1/a*exp(a*x))", "f(exp(a*x+b),1/a*exp(a*x+b))", "f(x*exp(a*x^2),exp(a*x^2)/(2*a))", "f(x*exp(a*x^2+b),exp(a*x^2+b)/(2*a))", "f(log(a*x),x*log(a*x)-x)", "f(a^x,a^x/log(a),or(not(number(a)),a>0))", "f(1/(a+x^2),1/sqrt(a)*arctan(x/sqrt(a)),or(not(number(a)),a>0))", "f(1/(a-x^2),1/sqrt(a)*arctanh(x/sqrt(a)))", "f(1/sqrt(a-x^2),arcsin(x/(sqrt(a))))", "f(1/sqrt(a+x^2),log(x+sqrt(a+x^2)))", "f(1/(a+b*x),1/b*log(a+b*x))", "f(1/(a+b*x)^2,-1/(b*(a+b*x)))", "f(1/(a+b*x)^3,-1/(2*b)*1/(a+b*x)^2)", "f(x/(a+b*x),x/b-a*log(a+b*x)/b/b)", "f(x/(a+b*x)^2,1/b^2*(log(a+b*x)+a/(a+b*x)))", "f(x^2/(a+b*x),1/b^2*(1/2*(a+b*x)^2-2*a*(a+b*x)+a^2*log(a+b*x)))", "f(x^2/(a+b*x)^2,1/b^3*(a+b*x-2*a*log(a+b*x)-a^2/(a+b*x)))", "f(x^2/(a+b*x)^3,1/b^3*(log(a+b*x)+2*a/(a+b*x)-1/2*a^2/(a+b*x)^2))", "f(1/x*1/(a+b*x),-1/a*log((a+b*x)/x))", "f(1/x*1/(a+b*x)^2,1/a*1/(a+b*x)-1/a^2*log((a+b*x)/x))", "f(1/x*1/(a+b*x)^3,1/a^3*(1/2*((2*a+b*x)/(a+b*x))^2+log(x/(a+b*x))))", "f(1/x^2*1/(a+b*x),-1/(a*x)+b/a^2*log((a+b*x)/x))", "f(1/x^3*1/(a+b*x),(2*b*x-a)/(2*a^2*x^2)+b^2/a^3*log(x/(a+b*x)))", "f(1/x^2*1/(a+b*x)^2,-(a+2*b*x)/(a^2*x*(a+b*x))+2*b/a^3*log((a+b*x)/x))", "f(1/(a+b*x^2),1/sqrt(a*b)*arctan(x*sqrt(a*b)/a),or(not(number(a*b)),a*b>0))", "f(1/(a+b*x^2),1/(2*sqrt(-a*b))*log((a+x*sqrt(-a*b))/(a-x*sqrt(-a*b))),or(not(number(a*b)),a*b<0))", "f(x/(a+b*x^2),1/2*1/b*log(a+b*x^2))", "f(x^2/(a+b*x^2),x/b-a/b*integral(1/(a+b*x^2),x))", "f(1/(a+b*x^2)^2,x/(2*a*(a+b*x^2))+1/2*1/a*integral(1/(a+b*x^2),x))", "f(1/x*1/(a+b*x^2),1/2*1/a*log(x^2/(a+b*x^2)))", "f(1/x^2*1/(a+b*x^2),-1/(a*x)-b/a*integral(1/(a+b*x^2),x))", "f(1/(a+b*x^3),1/3*1/a*(a/b)^(1/3)*(1/2*log(((a/b)^(1/3)+x)^3/(a+b*x^3))+sqrt(3)*arctan((2*x-(a/b)^(1/3))*(a/b)^(-1/3)/sqrt(3))))", "f(x^2/(a+b*x^3),1/3*1/b*log(a+b*x^3))", "f(x/(a+b*x^4),1/2*sqrt(b/a)/b*arctan(x^2*sqrt(b/a)),or(not(number(a*b)),a*b>0))", "f(x/(a+b*x^4),1/4*sqrt(-b/a)/b*log((x^2-sqrt(-a/b))/(x^2+sqrt(-a/b))),or(not(number(a*b)),a*b<0))", "f(x^3/(a+b*x^4),1/4*1/b*log(a+b*x^4))", "f(sqrt(a+b*x),2/3*1/b*sqrt((a+b*x)^3))", "f(x*sqrt(a+b*x),-2*(2*a-3*b*x)*sqrt((a+b*x)^3)/15/b^2)", "f(x^2*sqrt(a+b*x),2*(8*a^2-12*a*b*x+15*b^2*x^2)*sqrt((a+b*x)^3)/105/b^3)", "f(sqrt(a+b*x)/x,2*sqrt(a+b*x)+a*integral(1/x*1/sqrt(a+b*x),x))", "f(sqrt(a+b*x)/x^2,-sqrt(a+b*x)/x+b/2*integral(1/x*1/sqrt(a+b*x),x))", "f(1/sqrt(a+b*x),2*sqrt(a+b*x)/b)", "f(x/sqrt(a+b*x),-2/3*(2*a-b*x)*sqrt(a+b*x)/b^2)", "f(x^2/sqrt(a+b*x),2/15*(8*a^2-4*a*b*x+3*b^2*x^2)*sqrt(a+b*x)/b^3)", "f(1/x*1/sqrt(a+b*x),1/sqrt(a)*log((sqrt(a+b*x)-sqrt(a))/(sqrt(a+b*x)+sqrt(a))),or(not(number(a)),a>0))", "f(1/x*1/sqrt(a+b*x),2/sqrt(-a)*arctan(sqrt(-(a+b*x)/a)),or(not(number(a)),a<0))", "f(1/x^2*1/sqrt(a+b*x),-sqrt(a+b*x)/a/x-1/2*b/a*integral(1/x*1/sqrt(a+b*x),x))", "f(sqrt(x^2+a),1/2*(x*sqrt(x^2+a)+a*log(x+sqrt(x^2+a))))", "f(1/sqrt(x^2+a),log(x+sqrt(x^2+a)))", "f(1/x*1/sqrt(x^2+a),arcsec(x/sqrt(-a))/sqrt(-a),or(not(number(a)),a<0))", "f(1/x*1/sqrt(x^2+a),-1/sqrt(a)*log((sqrt(a)+sqrt(x^2+a))/x),or(not(number(a)),a>0))", "f(sqrt(x^2+a)/x,sqrt(x^2+a)-sqrt(a)*log((sqrt(a)+sqrt(x^2+a))/x),or(not(number(a)),a>0))", "f(sqrt(x^2+a)/x,sqrt(x^2+a)-sqrt(-a)*arcsec(x/sqrt(-a)),or(not(number(a)),a<0))", "f(x/sqrt(x^2+a),sqrt(x^2+a))", "f(x*sqrt(x^2+a),1/3*sqrt((x^2+a)^3))", "f(sqrt(a+x^6+3*a^(1/3)*x^4+3*a^(2/3)*x^2),1/4*(x*sqrt((x^2+a^(1/3))^3)+3/2*a^(1/3)*x*sqrt(x^2+a^(1/3))+3/2*a^(2/3)*log(x+sqrt(x^2+a^(1/3)))))", "f(sqrt(-a+x^6-3*a^(1/3)*x^4+3*a^(2/3)*x^2),1/4*(x*sqrt((x^2-a^(1/3))^3)-3/2*a^(1/3)*x*sqrt(x^2-a^(1/3))+3/2*a^(2/3)*log(x+sqrt(x^2-a^(1/3)))))", "f(1/sqrt(a+x^6+3*a^(1/3)*x^4+3*a^(2/3)*x^2),x/a^(1/3)/sqrt(x^2+a^(1/3)))", "f(x/sqrt(a+x^6+3*a^(1/3)*x^4+3*a^(2/3)*x^2),-1/sqrt(x^2+a^(1/3)))", "f(x*sqrt(a+x^6+3*a^(1/3)*x^4+3*a^(2/3)*x^2),1/5*sqrt((x^2+a^(1/3))^5))", "f(x^2*sqrt(x^2+a),1/4*x*sqrt((x^2+a)^3)-1/8*a*x*sqrt(x^2+a)-1/8*a^2*log(x+sqrt(x^2+a)))", "f(x^3*sqrt(x^2+a),(1/5*x^2-2/15*a)*sqrt((x^2+a)^3),and(number(a),a>0))", "f(x^3*sqrt(x^2+a),sqrt((x^2+a)^5)/5-a*sqrt((x^2+a)^3)/3,and(number(a),a<0))", "f(x^2/sqrt(x^2+a),1/2*x*sqrt(x^2+a)-1/2*a*log(x+sqrt(x^2+a)))", "f(x^3/sqrt(x^2+a),1/3*sqrt((x^2+a)^3)-a*sqrt(x^2+a))", "f(1/x^2*1/sqrt(x^2+a),-sqrt(x^2+a)/a/x)", "f(1/x^3*1/sqrt(x^2+a),-1/2*sqrt(x^2+a)/a/x^2+1/2*log((sqrt(a)+sqrt(x^2+a))/x)/a^(3/2),or(not(number(a)),a>0))", "f(1/x^3*1/sqrt(x^2-a),1/2*sqrt(x^2-a)/a/x^2+1/2*1/(a^(3/2))*arcsec(x/(a^(1/2))),or(not(number(a)),a>0))", "f(x^2*sqrt(a+x^6+3*a^(1/3)*x^4+3*a^(2/3)*x^2),1/6*x*sqrt((x^2+a^(1/3))^5)-1/24*a^(1/3)*x*sqrt((x^2+a^(1/3))^3)-1/16*a^(2/3)*x*sqrt(x^2+a^(1/3))-1/16*a*log(x+sqrt(x^2+a^(1/3))),or(not(number(a)),a>0))", "f(x^2*sqrt(-a-3*a^(1/3)*x^4+3*a^(2/3)*x^2+x^6),1/6*x*sqrt((x^2-a^(1/3))^5)+1/24*a^(1/3)*x*sqrt((x^2-a^(1/3))^3)-1/16*a^(2/3)*x*sqrt(x^2-a^(1/3))+1/16*a*log(x+sqrt(x^2-a^(1/3))),or(not(number(a)),a>0))", "f(x^3*sqrt(a+x^6+3*a^(1/3)*x^4+3*a^(2/3)*x^2),1/7*sqrt((x^2+a^(1/3))^7)-1/5*a^(1/3)*sqrt((x^2+a^(1/3))^5),or(not(number(a)),a>0))", "f(x^3*sqrt(-a-3*a^(1/3)*x^4+3*a^(2/3)*x^2+x^6),1/7*sqrt((x^2-a^(1/3))^7)+1/5*a^(1/3)*sqrt((x^2-a^(1/3))^5),or(not(number(a)),a>0))", "f(1/(x-a)/sqrt(x^2-a^2),-sqrt(x^2-a^2)/a/(x-a))", "f(1/(x+a)/sqrt(x^2-a^2),sqrt(x^2-a^2)/a/(x+a))", "f(sqrt(a-x^2),1/2*(x*sqrt(a-x^2)+a*arcsin(x/sqrt(abs(a)))))", "f(1/x*1/sqrt(a-x^2),-1/sqrt(a)*log((sqrt(a)+sqrt(a-x^2))/x),or(not(number(a)),a>0))", "f(sqrt(a-x^2)/x,sqrt(a-x^2)-sqrt(a)*log((sqrt(a)+sqrt(a-x^2))/x),or(not(number(a)),a>0))", "f(x/sqrt(a-x^2),-sqrt(a-x^2))", "f(x*sqrt(a-x^2),-1/3*sqrt((a-x^2)^3))", "f(x^2*sqrt(a-x^2),-x/4*sqrt((a-x^2)^3)+1/8*a*(x*sqrt(a-x^2)+a*arcsin(x/sqrt(a))),or(not(number(a)),a>0))", "f(x^3*sqrt(a-x^2),(-1/5*x^2-2/15*a)*sqrt((a-x^2)^3),or(not(number(a)),a>0))", "f(x^2/sqrt(a-x^2),-x/2*sqrt(a-x^2)+a/2*arcsin(x/sqrt(a)),or(not(number(a)),a>0))", "f(1/x^2*1/sqrt(a-x^2),-sqrt(a-x^2)/a/x,or(not(number(a)),a>0))", "f(sqrt(a-x^2)/x^2,-sqrt(a-x^2)/x-arcsin(x/sqrt(a)),or(not(number(a)),a>0))", "f(sqrt(a-x^2)/x^3,-1/2*sqrt(a-x^2)/x^2+1/2*log((sqrt(a)+sqrt(a-x^2))/x)/sqrt(a),or(not(number(a)),a>0))", "f(sqrt(a-x^2)/x^4,-1/3*sqrt((a-x^2)^3)/a/x^3,or(not(number(a)),a>0))", "f(sqrt(a*x^2+b),x*sqrt(a*x^2+b)/2+b*log(x*sqrt(a)+sqrt(a*x^2+b))/2/sqrt(a),and(number(a),a>0))", "f(sqrt(a*x^2+b),x*sqrt(a*x^2+b)/2+b*arcsin(x*sqrt(-a/b))/2/sqrt(-a),and(number(a),a<0))", "f(sin(a*x),-cos(a*x)/a)", "f(cos(a*x),sin(a*x)/a)", "f(tan(a*x),-log(cos(a*x))/a)", "f(1/tan(a*x),log(sin(a*x))/a)", "f(1/cos(a*x),log(tan(pi/4+a*x/2))/a)", "f(1/sin(a*x),log(tan(a*x/2))/a)", "f(sin(a*x)^2,x/2-sin(2*a*x)/(4*a))", "f(sin(a*x)^3,-cos(a*x)*(sin(a*x)^2+2)/(3*a))", "f(sin(a*x)^4,3/8*x-sin(2*a*x)/(4*a)+sin(4*a*x)/(32*a))", "f(cos(a*x)^2,x/2+sin(2*a*x)/(4*a))", "f(cos(a*x)^3,sin(a*x)*(cos(a*x)^2+2)/(3*a))", "f(cos(a*x)^4,3/8*x+sin(2*a*x)/(4*a)+sin(4*a*x)/(32*a))", "f(1/sin(a*x)^2,-1/(a*tan(a*x)))", "f(1/cos(a*x)^2,tan(a*x)/a)", "f(sin(a*x)*cos(a*x),sin(a*x)^2/(2*a))", "f(sin(a*x)^2*cos(a*x)^2,-sin(4*a*x)/(32*a)+x/8)", "f(sin(a*x)/cos(a*x)^2,1/(a*cos(a*x)))", "f(sin(a*x)^2/cos(a*x),(log(tan(pi/4+a*x/2))-sin(a*x))/a)", "f(cos(a*x)/sin(a*x)^2,-1/(a*sin(a*x)))", "f(1/(sin(a*x)*cos(a*x)),log(tan(a*x))/a)", "f(1/(sin(a*x)*cos(a*x)^2),(1/cos(a*x)+log(tan(a*x/2)))/a)", "f(1/(sin(a*x)^2*cos(a*x)),(log(tan(pi/4+a*x/2))-1/sin(a*x))/a)", "f(1/(sin(a*x)^2*cos(a*x)^2),-2/(a*tan(2*a*x)))", "f(sin(a+b*x),-cos(a+b*x)/b)", "f(cos(a+b*x),sin(a+b*x)/b)", "f(1/(b+b*sin(a*x)),-tan(pi/4-a*x/2)/a/b)", "f(1/(b-b*sin(a*x)),tan(pi/4+a*x/2)/a/b)", "f(1/(b+b*cos(a*x)),tan(a*x/2)/a/b)", "f(1/(b-b*cos(a*x)),-1/tan(a*x/2)/a/b)", "f(1/(a+b*sin(x)),1/sqrt(b^2-a^2)*log((a*tan(x/2)+b-sqrt(b^2-a^2))/(a*tan(x/2)+b+sqrt(b^2-a^2))),b^2-a^2)", "f(1/(a+b*cos(x)),1/sqrt(b^2-a^2)*log((sqrt(b^2-a^2)*tan(x/2)+a+b)/(sqrt(b^2-a^2)*tan(x/2)-a-b)),b^2-a^2)", "f(x*sin(a*x),sin(a*x)/a^2-x*cos(a*x)/a)", "f(x^2*sin(a*x),2*x*sin(a*x)/a^2-(a^2*x^2-2)*cos(a*x)/a^3)", "f(x*cos(a*x),cos(a*x)/a^2+x*sin(a*x)/a)", "f(x^2*cos(a*x),2*x*cos(a*x)/a^2+(a^2*x^2-2)*sin(a*x)/a^3)", "f(arcsin(a*x),x*arcsin(a*x)+sqrt(1-a^2*x^2)/a)", "f(arccos(a*x),x*arccos(a*x)-sqrt(1-a^2*x^2)/a)", "f(arctan(a*x),x*arctan(a*x)-1/2*log(1+a^2*x^2)/a)", "f(log(a*x),x*log(a*x)-x)", "f(x*log(a*x),x^2*log(a*x)/2-x^2/4)", "f(x^2*log(a*x),x^3*log(a*x)/3-1/9*x^3)", "f(log(x)^2,x*log(x)^2-2*x*log(x)+2*x)", "f(1/x*1/(a+log(x)),log(a+log(x)))", "f(log(a*x+b),(a*x+b)*log(a*x+b)/a-x)", "f(log(a*x+b)/x^2,a/b*log(x)-(a*x+b)*log(a*x+b)/b/x)", "f(sinh(x),cosh(x))", "f(cosh(x),sinh(x))", "f(tanh(x),log(cosh(x)))", "f(x*sinh(x),x*cosh(x)-sinh(x))", "f(x*cosh(x),x*sinh(x)-cosh(x))", "f(sinh(x)^2,sinh(2*x)/4-x/2)", "f(tanh(x)^2,x-tanh(x))", "f(cosh(x)^2,sinh(2*x)/4+x/2)", "f(x^3*exp(a*x^2),exp(a*x^2)*(x^2/a-1/(a^2))/2)", "f(x^3*exp(a*x^2+b),exp(a*x^2)*exp(b)*(x^2/a-1/(a^2))/2)", "f(exp(a*x^2),-i*sqrt(pi)*erf(i*sqrt(a)*x)/sqrt(a)/2)", "f(erf(a*x),x*erf(a*x)+exp(-a^2*x^2)/a/sqrt(pi))", "f(x^2*(1-x^2)^(3/2),(x*sqrt(1-x^2)*(-8*x^4+14*x^2-3)+3*arcsin(x))/48)", "f(x^2*(1-x^2)^(5/2),(x*sqrt(1-x^2)*(48*x^6-136*x^4+118*x^2-15)+15*arcsin(x))/384)", "f(x^4*(1-x^2)^(3/2),(-x*sqrt(1-x^2)*(16*x^6-24*x^4+2*x^2+3)+3*arcsin(x))/128)", "f(x*exp(a*x),exp(a*x)*(a*x-1)/(a^2))", "f(x*exp(a*x+b),exp(a*x+b)*(a*x-1)/(a^2))", "f(x^2*exp(a*x),exp(a*x)*(a^2*x^2-2*a*x+2)/(a^3))", "f(x^2*exp(a*x+b),exp(a*x+b)*(a^2*x^2-2*a*x+2)/(a^3))", "f(x^3*exp(a*x),exp(a*x)*x^3/a-3/a*integral(x^2*exp(a*x),x))", "f(x^3*exp(a*x+b),exp(a*x+b)*x^3/a-3/a*integral(x^2*exp(a*x+b),x))", 0];
10590
10591 Eval_integral = function() {
10592 var doNothing, i, i1, n, o, ref, ref1;
10593 i = 0;
10594 n = 0;
10595 p1 = cdr(p1);
10596 push(car(p1));
10597 Eval();
10598 p1 = cdr(p1);
10599 push(car(p1));
10600 Eval();
10601 p2 = pop();
10602 if (p2 === symbol(NIL)) {
10603 guess();
10604 push(symbol(NIL));
10605 } else if (isnum(p2)) {
10606 guess();
10607 push(p2);
10608 } else {
10609 push(p2);
10610 p1 = cdr(p1);
10611 push(car(p1));
10612 Eval();
10613 }
10614 p5 = pop();
10615 p4 = pop();
10616 p3 = pop();
10617 while (1) {
10618 if (isnum(p5)) {
10619 push(p5);
10620 n = pop_integer();
10621 if (isNaN(n)) {
10622 stop("nth integral: check n");
10623 }
10624 } else {
10625 n = 1;
10626 }
10627 push(p3);
10628 if (n >= 0) {
10629 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10630 push(p4);
10631 integral();
10632 }
10633 } else {
10634 n = -n;
10635 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
10636 push(p4);
10637 derivative();
10638 }
10639 }
10640 p3 = pop();
10641 if (p5 === symbol(NIL)) {
10642 break;
10643 }
10644 if (isnum(p5)) {
10645 p1 = cdr(p1);
10646 push(car(p1));
10647 Eval();
10648 p5 = pop();
10649 if (p5 === symbol(NIL)) {
10650 break;
10651 }
10652 if (isnum(p5)) {
10653 doNothing = 1;
10654 } else {
10655 p4 = p5;
10656 p1 = cdr(p1);
10657 push(car(p1));
10658 Eval();
10659 p5 = pop();
10660 }
10661 } else {
10662 p4 = p5;
10663 p1 = cdr(p1);
10664 push(car(p1));
10665 Eval();
10666 p5 = pop();
10667 }
10668 }
10669 return push(p3);
10670 };
10671
10672 integral = function() {
10673 save();
10674 p2 = pop();
10675 p1 = pop();
10676 if (car(p1) === symbol(ADD)) {
10677 integral_of_sum();
10678 } else if (car(p1) === symbol(MULTIPLY)) {
10679 integral_of_product();
10680 } else {
10681 integral_of_form();
10682 }
10683 p1 = pop();
10684 if (Find(p1, symbol(INTEGRAL))) {
10685 stop("integral: sorry, could not find a solution");
10686 }
10687 push(p1);
10688 simplify();
10689 Eval();
10690 return restore();
10691 };
10692
10693 integral_of_sum = function() {
10694 var results;
10695 p1 = cdr(p1);
10696 push(car(p1));
10697 push(p2);
10698 integral();
10699 p1 = cdr(p1);
10700 results = [];
10701 while (iscons(p1)) {
10702 push(car(p1));
10703 push(p2);
10704 integral();
10705 add();
10706 results.push(p1 = cdr(p1));
10707 }
10708 return results;
10709 };
10710
10711 integral_of_product = function() {
10712 push(p1);
10713 push(p2);
10714 partition();
10715 p1 = pop();
10716 integral_of_form();
10717 return multiply();
10718 };
10719
10720 integral_of_form = function() {
10721 push(p1);
10722 push(p2);
10723 transform(itab, false);
10724 p3 = pop();
10725 if (p3 === symbol(NIL)) {
10726 push_symbol(INTEGRAL);
10727 push(p1);
10728 push(p2);
10729 return list(3);
10730 } else {
10731 return push(p3);
10732 }
10733 };
10734
10735 INV_check_arg = function() {
10736 if (!istensor(p1)) {
10737 return 0;
10738 } else if (p1.tensor.ndim !== 2) {
10739 return 0;
10740 } else if (p1.tensor.dim[0] !== p1.tensor.dim[1]) {
10741 return 0;
10742 } else {
10743 return 1;
10744 }
10745 };
10746
10747 inv = function() {
10748 var accumulator, eachEntry, i, n, o, ref;
10749 i = 0;
10750 n = 0;
10751 save();
10752 p1 = pop();
10753 if (isinv(p1)) {
10754 push(car(cdr(p1)));
10755 restore();
10756 return;
10757 }
10758 if (isidentitymatrix(p1)) {
10759 push(p1);
10760 restore();
10761 return;
10762 }
10763 if (expanding && isinnerordot(p1)) {
10764 p1 = cdr(p1);
10765 accumulator = [];
10766 while (iscons(p1)) {
10767 accumulator.push(car(p1));
10768 p1 = cdr(p1);
10769 }
10770 for (eachEntry = o = ref = accumulator.length - 1; ref <= 0 ? o <= 0 : o >= 0; eachEntry = ref <= 0 ? ++o : --o) {
10771 push(accumulator[eachEntry]);
10772 inv();
10773 if (eachEntry !== accumulator.length - 1) {
10774 inner();
10775 }
10776 }
10777 restore();
10778 return;
10779 }
10780 if (INV_check_arg() === 0) {
10781 push_symbol(INV);
10782 push(p1);
10783 list(2);
10784 restore();
10785 return;
10786 }
10787 if (isnumerictensor(p1)) {
10788 yyinvg();
10789 } else {
10790 push(p1);
10791 adj();
10792 push(p1);
10793 det();
10794 p2 = pop();
10795 if (iszero(p2)) {
10796 stop("inverse of singular matrix");
10797 }
10798 push(p2);
10799 divide();
10800 }
10801 return restore();
10802 };
10803
10804 invg = function() {
10805 save();
10806 p1 = pop();
10807 if (INV_check_arg() === 0) {
10808 push_symbol(INVG);
10809 push(p1);
10810 list(2);
10811 restore();
10812 return;
10813 }
10814 yyinvg();
10815 return restore();
10816 };
10817
10818 yyinvg = function() {
10819 var h, i, i1, j, j1, l1, n, o, ref, ref1, ref2, ref3;
10820 h = 0;
10821 i = 0;
10822 j = 0;
10823 n = 0;
10824 n = p1.tensor.dim[0];
10825 h = tos;
10826 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10827 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
10828 if (i === j) {
10829 push(one);
10830 } else {
10831 push(zero);
10832 }
10833 }
10834 }
10835 for (i = j1 = 0, ref2 = n * n; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
10836 push(p1.tensor.elem[i]);
10837 }
10838 INV_decomp(n);
10839 p1 = alloc_tensor(n * n);
10840 p1.tensor.ndim = 2;
10841 p1.tensor.dim[0] = n;
10842 p1.tensor.dim[1] = n;
10843 for (i = l1 = 0, ref3 = n * n; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
10844 p1.tensor.elem[i] = stack[h + i];
10845 }
10846 moveTos(tos - 2 * n * n);
10847 return push(p1);
10848 };
10849
10850 INV_decomp = function(n) {
10851 var a, d, i, i1, j, j1, l1, o, ref, ref1, ref2, ref3, ref4, results, u;
10852 a = 0;
10853 d = 0;
10854 i = 0;
10855 j = 0;
10856 u = 0;
10857 a = tos - n * n;
10858 u = a - n * n;
10859 results = [];
10860 for (d = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; d = 0 <= ref ? ++o : --o) {
10861 if (equal(stack[a + n * d + d], zero)) {
10862 for (i = i1 = ref1 = d + 1, ref2 = n; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
10863 if (!equal(stack[a + n * i + d], zero)) {
10864 break;
10865 }
10866 }
10867 if (i === n) {
10868 stop("inverse of singular matrix");
10869 }
10870 for (j = j1 = 0, ref3 = n; 0 <= ref3 ? j1 < ref3 : j1 > ref3; j = 0 <= ref3 ? ++j1 : --j1) {
10871 p2 = stack[a + n * d + j];
10872 stack[a + n * d + j] = stack[a + n * i + j];
10873 stack[a + n * i + j] = p2;
10874 p2 = stack[u + n * d + j];
10875 stack[u + n * d + j] = stack[u + n * i + j];
10876 stack[u + n * i + j] = p2;
10877 }
10878 }
10879 p2 = stack[a + n * d + d];
10880 for (j = l1 = 0, ref4 = n; 0 <= ref4 ? l1 < ref4 : l1 > ref4; j = 0 <= ref4 ? ++l1 : --l1) {
10881 if (j > d) {
10882 push(stack[a + n * d + j]);
10883 push(p2);
10884 divide();
10885 stack[a + n * d + j] = pop();
10886 }
10887 push(stack[u + n * d + j]);
10888 push(p2);
10889 divide();
10890 stack[u + n * d + j] = pop();
10891 }
10892 results.push((function() {
10893 var m1, ref5, results1;
10894 results1 = [];
10895 for (i = m1 = 0, ref5 = n; 0 <= ref5 ? m1 < ref5 : m1 > ref5; i = 0 <= ref5 ? ++m1 : --m1) {
10896 if (i === d) {
10897 continue;
10898 }
10899 p2 = stack[a + n * i + d];
10900 results1.push((function() {
10901 var n1, ref6, results2;
10902 results2 = [];
10903 for (j = n1 = 0, ref6 = n; 0 <= ref6 ? n1 < ref6 : n1 > ref6; j = 0 <= ref6 ? ++n1 : --n1) {
10904 if (j > d) {
10905 push(stack[a + n * i + j]);
10906 push(stack[a + n * d + j]);
10907 push(p2);
10908 multiply();
10909 subtract();
10910 stack[a + n * i + j] = pop();
10911 }
10912 push(stack[u + n * i + j]);
10913 push(stack[u + n * d + j]);
10914 push(p2);
10915 multiply();
10916 subtract();
10917 results2.push(stack[u + n * i + j] = pop());
10918 }
10919 return results2;
10920 })());
10921 }
10922 return results1;
10923 })());
10924 }
10925 return results;
10926 };
10927
10928 DEBUG_IS = false;
10929
10930 iszero = function(p) {
10931 var i, o, ref;
10932 i = 0;
10933 switch (p.k) {
10934 case NUM:
10935 if (MZERO(p.q.a)) {
10936 return 1;
10937 }
10938 break;
10939 case DOUBLE:
10940 if (p.d === 0.0) {
10941 return 1;
10942 }
10943 break;
10944 case TENSOR:
10945 for (i = o = 0, ref = p.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10946 if (!iszero(p.tensor.elem[i])) {
10947 return 0;
10948 }
10949 }
10950 return 1;
10951 }
10952 return 0;
10953 };
10954
10955 isnegativenumber = function(p) {
10956 switch (p.k) {
10957 case NUM:
10958 if (MSIGN(p.q.a) === -1) {
10959 return 1;
10960 }
10961 break;
10962 case DOUBLE:
10963 if (p.d < 0.0) {
10964 return 1;
10965 }
10966 }
10967 return 0;
10968 };
10969
10970 ispositivenumber = function(p) {
10971 switch (p.k) {
10972 case NUM:
10973 if (MSIGN(p.q.a) === 1) {
10974 return 1;
10975 }
10976 break;
10977 case DOUBLE:
10978 if (p.d > 0.0) {
10979 return 1;
10980 }
10981 }
10982 return 0;
10983 };
10984
10985 isplustwo = function(p) {
10986 switch (p.k) {
10987 case NUM:
10988 if (MEQUAL(p.q.a, 2) && MEQUAL(p.q.b, 1)) {
10989 return 1;
10990 }
10991 break;
10992 case DOUBLE:
10993 if (p.d === 2.0) {
10994 return 1;
10995 }
10996 }
10997 return 0;
10998 };
10999
11000 isplusone = function(p) {
11001 switch (p.k) {
11002 case NUM:
11003 if (MEQUAL(p.q.a, 1) && MEQUAL(p.q.b, 1)) {
11004 return 1;
11005 }
11006 break;
11007 case DOUBLE:
11008 if (p.d === 1.0) {
11009 return 1;
11010 }
11011 }
11012 return 0;
11013 };
11014
11015 isminusone = function(p) {
11016 switch (p.k) {
11017 case NUM:
11018 if (MEQUAL(p.q.a, -1) && MEQUAL(p.q.b, 1)) {
11019 return 1;
11020 }
11021 break;
11022 case DOUBLE:
11023 if (p.d === -1.0) {
11024 return 1;
11025 }
11026 }
11027 return 0;
11028 };
11029
11030 isone = function(p) {
11031 return isplusone(p) || isminusone(p);
11032 };
11033
11034 isinteger = function(p) {
11035 if (p.k === NUM && MEQUAL(p.q.b, 1)) {
11036 return 1;
11037 } else {
11038 return 0;
11039 }
11040 };
11041
11042 isintegerorintegerfloat = function(p) {
11043 if (p.k === DOUBLE) {
11044 if (p.d === Math.round(p.d)) {
11045 return 1;
11046 }
11047 return 0;
11048 }
11049 return isinteger(p);
11050 };
11051
11052 isnonnegativeinteger = function(p) {
11053 if (isrational(p) && MEQUAL(p.q.b, 1) && MSIGN(p.q.a) === 1) {
11054 return 1;
11055 } else {
11056 return 0;
11057 }
11058 };
11059
11060 isposint = function(p) {
11061 if (isinteger(p) && MSIGN(p.q.a) === 1) {
11062 return 1;
11063 } else {
11064 return 0;
11065 }
11066 };
11067
11068 ispoly = function(p, x) {
11069 if (Find(p, x)) {
11070 return ispoly_expr(p, x);
11071 } else {
11072 return 0;
11073 }
11074 };
11075
11076 ispoly_expr = function(p, x) {
11077 if (car(p) === symbol(ADD)) {
11078 p = cdr(p);
11079 while (iscons(p)) {
11080 if (!ispoly_term(car(p), x)) {
11081 return 0;
11082 }
11083 p = cdr(p);
11084 }
11085 return 1;
11086 } else {
11087 return ispoly_term(p, x);
11088 }
11089 };
11090
11091 ispoly_term = function(p, x) {
11092 if (car(p) === symbol(MULTIPLY)) {
11093 p = cdr(p);
11094 while (iscons(p)) {
11095 if (!ispoly_factor(car(p), x)) {
11096 return 0;
11097 }
11098 p = cdr(p);
11099 }
11100 return 1;
11101 } else {
11102 return ispoly_factor(p, x);
11103 }
11104 };
11105
11106 ispoly_factor = function(p, x) {
11107 if (equal(p, x)) {
11108 return 1;
11109 }
11110 if (car(p) === symbol(POWER) && equal(cadr(p), x)) {
11111 if (isposint(caddr(p))) {
11112 return 1;
11113 } else {
11114 return 0;
11115 }
11116 }
11117 if (Find(p, x)) {
11118 return 0;
11119 } else {
11120 return 1;
11121 }
11122 };
11123
11124 isnegativeterm = function(p) {
11125 if (isnegativenumber(p)) {
11126 return 1;
11127 } else if (car(p) === symbol(MULTIPLY) && isnegativenumber(cadr(p))) {
11128 return 1;
11129 } else {
11130 return 0;
11131 }
11132 };
11133
11134 hasNegativeRationalExponent = function(p) {
11135 if (car(p) === symbol(POWER) && isrational(car(cdr(cdr(p)))) && isnegativenumber(car(cdr(p)))) {
11136 if (DEBUG_IS) {
11137 console.log("hasNegativeRationalExponent: " + p.toString() + " has imaginary component");
11138 }
11139 return 1;
11140 } else {
11141 if (DEBUG_IS) {
11142 console.log("hasNegativeRationalExponent: " + p.toString() + " has NO imaginary component");
11143 }
11144 return 0;
11145 }
11146 };
11147
11148 isimaginarynumberdouble = function(p) {
11149 if ((car(p) === symbol(MULTIPLY) && length(p) === 3 && isdouble(cadr(p)) && hasNegativeRationalExponent(caddr(p))) || equal(p, imaginaryunit)) {
11150 return 1;
11151 } else {
11152 return 0;
11153 }
11154 };
11155
11156 isimaginarynumber = function(p) {
11157 if ((car(p) === symbol(MULTIPLY) && length(p) === 3 && isnum(cadr(p)) && equal(caddr(p), imaginaryunit)) || equal(p, imaginaryunit) || hasNegativeRationalExponent(caddr(p))) {
11158 if (DEBUG_IS) {
11159 console.log("isimaginarynumber: " + p.toString() + " is imaginary number");
11160 }
11161 return 1;
11162 } else {
11163 if (DEBUG_IS) {
11164 console.log("isimaginarynumber: " + p.toString() + " isn't an imaginary number");
11165 }
11166 return 0;
11167 }
11168 };
11169
11170 iscomplexnumberdouble = function(p) {
11171 if ((car(p) === symbol(ADD) && length(p) === 3 && isdouble(cadr(p)) && isimaginarynumberdouble(caddr(p))) || isimaginarynumberdouble(p)) {
11172 return 1;
11173 } else {
11174 return 0;
11175 }
11176 };
11177
11178 iscomplexnumber = function(p) {
11179 if (DEBUG_IS) {
11180 debugger;
11181 }
11182 if ((car(p) === symbol(ADD) && length(p) === 3 && isnum(cadr(p)) && isimaginarynumber(caddr(p))) || isimaginarynumber(p)) {
11183 if (DEBUG) {
11184 console.log("iscomplexnumber: " + p.toString() + " is imaginary number");
11185 }
11186 return 1;
11187 } else {
11188 if (DEBUG) {
11189 console.log("iscomplexnumber: " + p.toString() + " is imaginary number");
11190 }
11191 return 0;
11192 }
11193 };
11194
11195 iseveninteger = function(p) {
11196 if (isinteger(p) && p.q.a.isEven()) {
11197 return 1;
11198 } else {
11199 return 0;
11200 }
11201 };
11202
11203 isnegative = function(p) {
11204 if (car(p) === symbol(ADD) && isnegativeterm(cadr(p))) {
11205 return 1;
11206 } else if (isnegativeterm(p)) {
11207 return 1;
11208 } else {
11209 return 0;
11210 }
11211 };
11212
11213 issymbolic = function(p) {
11214 if (issymbol(p)) {
11215 return 1;
11216 } else {
11217 while (iscons(p)) {
11218 if (issymbolic(car(p))) {
11219 return 1;
11220 }
11221 p = cdr(p);
11222 }
11223 return 0;
11224 }
11225 };
11226
11227 isintegerfactor = function(p) {
11228 if (isinteger(p) || car(p) === symbol(POWER) && isinteger(cadr(p)) && isinteger(caddr(p))) {
11229 return 1;
11230 } else {
11231 return 0;
11232 }
11233 };
11234
11235 isnumberoneoversomething = function(p) {
11236 if (isfraction(p) && Math.abs(p.q.a.value) === 1) {
11237 return 1;
11238 } else {
11239 return 0;
11240 }
11241 };
11242
11243 isoneover = function(p) {
11244 if (car(p) === symbol(POWER) && isminusone(caddr(p))) {
11245 return 1;
11246 } else {
11247 return 0;
11248 }
11249 };
11250
11251 isfraction = function(p) {
11252 if (p.k === NUM && !MEQUAL(p.q.b, 1)) {
11253 return 1;
11254 } else {
11255 return 0;
11256 }
11257 };
11258
11259 equaln = function(p, n) {
11260 switch (p.k) {
11261 case NUM:
11262 if (MEQUAL(p.q.a, n) && MEQUAL(p.q.b, 1)) {
11263 return 1;
11264 }
11265 break;
11266 case DOUBLE:
11267 if (p.d === n) {
11268 return 1;
11269 }
11270 }
11271 return 0;
11272 };
11273
11274 equalq = function(p, a, b) {
11275 switch (p.k) {
11276 case NUM:
11277 if (MEQUAL(p.q.a, a) && MEQUAL(p.q.b, b)) {
11278 return 1;
11279 }
11280 break;
11281 case DOUBLE:
11282 if (p.d === a / b) {
11283 return 1;
11284 }
11285 }
11286 return 0;
11287 };
11288
11289 isoneovertwo = function(p) {
11290 if (equalq(p, 1, 2)) {
11291 return 1;
11292 } else {
11293 return 0;
11294 }
11295 };
11296
11297 isminusoneovertwo = function(p) {
11298 if (equalq(p, -1, 2)) {
11299 return 1;
11300 } else {
11301 return 0;
11302 }
11303 };
11304
11305 isoneoversqrttwo = function(p) {
11306 if (car(p) === symbol(POWER) && equaln(cadr(p), 2) && equalq(caddr(p), -1, 2)) {
11307 return 1;
11308 } else {
11309 return 0;
11310 }
11311 };
11312
11313 isminusoneoversqrttwo = function(p) {
11314 if (car(p) === symbol(MULTIPLY) && equaln(cadr(p), -1) && isoneoversqrttwo(caddr(p)) && length(p) === 3) {
11315 return 1;
11316 } else {
11317 return 0;
11318 }
11319 };
11320
11321 isfloating = function(p) {
11322 if (p.k === DOUBLE || p === symbol(FLOATF)) {
11323 return 1;
11324 }
11325 while (iscons(p)) {
11326 if (isfloating(car(p))) {
11327 return 1;
11328 }
11329 p = cdr(p);
11330 }
11331 return 0;
11332 };
11333
11334 isimaginaryunit = function(p) {
11335 if (equal(p, imaginaryunit)) {
11336 return 1;
11337 } else {
11338 return 0;
11339 }
11340 };
11341
11342 isquarterturn = function(p) {
11343 var minussign, n;
11344 n = 0;
11345 minussign = 0;
11346 if (car(p) !== symbol(MULTIPLY)) {
11347 return 0;
11348 }
11349 if (equal(cadr(p), imaginaryunit)) {
11350 if (caddr(p) !== symbol(PI)) {
11351 return 0;
11352 }
11353 if (length(p) !== 3) {
11354 return 0;
11355 }
11356 return 2;
11357 }
11358 if (!isnum(cadr(p))) {
11359 return 0;
11360 }
11361 if (!equal(caddr(p), imaginaryunit)) {
11362 return 0;
11363 }
11364 if (cadddr(p) !== symbol(PI)) {
11365 return 0;
11366 }
11367 if (length(p) !== 4) {
11368 return 0;
11369 }
11370 push(cadr(p));
11371 push_integer(2);
11372 multiply();
11373 n = pop_integer();
11374 if (isNaN(n)) {
11375 return 0;
11376 }
11377 if (n < 1) {
11378 minussign = 1;
11379 n = -n;
11380 }
11381 switch (n % 4) {
11382 case 0:
11383 n = 1;
11384 break;
11385 case 1:
11386 if (minussign) {
11387 n = 4;
11388 } else {
11389 n = 3;
11390 }
11391 break;
11392 case 2:
11393 n = 2;
11394 break;
11395 case 3:
11396 if (minussign) {
11397 n = 3;
11398 } else {
11399 n = 4;
11400 }
11401 }
11402 return n;
11403 };
11404
11405 isnpi = function(p) {
11406 var doNothing, n;
11407 n = 0;
11408 if (p === symbol(PI)) {
11409 return 2;
11410 }
11411 if (car(p) === symbol(MULTIPLY) && isnum(cadr(p)) && caddr(p) === symbol(PI) && length(p) === 3) {
11412 doNothing = 0;
11413 } else {
11414 return 0;
11415 }
11416 push(cadr(p));
11417 push_integer(2);
11418 multiply();
11419 n = pop_integer();
11420 if (isNaN(n)) {
11421 return 0;
11422 }
11423 if (n < 0) {
11424 n = 4 - (-n) % 4;
11425 } else {
11426 n = 1 + (n - 1) % 4;
11427 }
11428 return n;
11429 };
11430
11431 $.iszero = iszero;
11432
11433 $.isnegativenumber = isnegativenumber;
11434
11435 $.isplusone = isplusone;
11436
11437 $.isminusone = isminusone;
11438
11439 $.isinteger = isinteger;
11440
11441 $.isnonnegativeinteger = isnonnegativeinteger;
11442
11443 $.isposint = isposint;
11444
11445 $.isnegativeterm = isnegativeterm;
11446
11447 $.isimaginarynumber = isimaginarynumber;
11448
11449 $.iscomplexnumber = iscomplexnumber;
11450
11451 $.iseveninteger = iseveninteger;
11452
11453 $.isnegative = isnegative;
11454
11455 $.issymbolic = issymbolic;
11456
11457 $.isintegerfactor = isintegerfactor;
11458
11459 $.isoneover = isoneover;
11460
11461 $.isfraction = isfraction;
11462
11463 $.isoneoversqrttwo = isoneoversqrttwo;
11464
11465 $.isminusoneoversqrttwo = isminusoneoversqrttwo;
11466
11467 $.isfloating = isfloating;
11468
11469 $.isimaginaryunit = isimaginaryunit;
11470
11471 $.isquarterturn = isquarterturn;
11472
11473 $.isnpi = isnpi;
11474
11475 Eval_isprime = function() {
11476 push(cadr(p1));
11477 Eval();
11478 p1 = pop();
11479 if (isnonnegativeinteger(p1) && mprime(p1.q.a)) {
11480 return push_integer(1);
11481 } else {
11482 return push_integer(0);
11483 }
11484 };
11485
11486
11487 /*
11488 Laguerre function
11489
11490 Example
11491
11492 laguerre(x,3)
11493
11494 Result
11495
11496 1 3 3 2
11497 - --- x + --- x - 3 x + 1
11498 6 2
11499
11500 The computation uses the following recurrence relation.
11501
11502 L(x,0,k) = 1
11503
11504 L(x,1,k) = -x + k + 1
11505
11506 n*L(x,n,k) = (2*(n-1)+1-x+k)*L(x,n-1,k) - (n-1+k)*L(x,n-2,k)
11507
11508 In the "for" loop i = n-1 so the recurrence relation becomes
11509
11510 (i+1)*L(x,n,k) = (2*i+1-x+k)*L(x,n-1,k) - (i+k)*L(x,n-2,k)
11511 */
11512
11513 Eval_laguerre = function() {
11514 push(cadr(p1));
11515 Eval();
11516 push(caddr(p1));
11517 Eval();
11518 push(cadddr(p1));
11519 Eval();
11520 p2 = pop();
11521 if (p2 === symbol(NIL)) {
11522 push_integer(0);
11523 } else {
11524 push(p2);
11525 }
11526 return laguerre();
11527 };
11528
11529 laguerre = function() {
11530 var n;
11531 n = 0;
11532 save();
11533 p3 = pop();
11534 p2 = pop();
11535 p1 = pop();
11536 push(p2);
11537 n = pop_integer();
11538 if (n < 0 || isNaN(n)) {
11539 push_symbol(LAGUERRE);
11540 push(p1);
11541 push(p2);
11542 push(p3);
11543 list(4);
11544 restore();
11545 return;
11546 }
11547 if (issymbol(p1)) {
11548 laguerre2(n);
11549 } else {
11550 p4 = p1;
11551 p1 = symbol(SECRETX);
11552 laguerre2(n);
11553 p1 = p4;
11554 push(symbol(SECRETX));
11555 push(p1);
11556 subst();
11557 Eval();
11558 }
11559 return restore();
11560 };
11561
11562 laguerre2 = function(n) {
11563 var i, o, ref, results;
11564 i = 0;
11565 push_integer(1);
11566 push_integer(0);
11567 p6 = pop();
11568 results = [];
11569 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
11570 p5 = p6;
11571 p6 = pop();
11572 push_integer(2 * i + 1);
11573 push(p1);
11574 subtract();
11575 push(p3);
11576 add();
11577 push(p6);
11578 multiply();
11579 push_integer(i);
11580 push(p3);
11581 add();
11582 push(p5);
11583 multiply();
11584 subtract();
11585 push_integer(i + 1);
11586 results.push(divide());
11587 }
11588 return results;
11589 };
11590
11591 Eval_lcm = function() {
11592 var results;
11593 p1 = cdr(p1);
11594 push(car(p1));
11595 Eval();
11596 p1 = cdr(p1);
11597 results = [];
11598 while (iscons(p1)) {
11599 push(car(p1));
11600 Eval();
11601 lcm();
11602 results.push(p1 = cdr(p1));
11603 }
11604 return results;
11605 };
11606
11607 lcm = function() {
11608 var prev_expanding;
11609 prev_expanding = expanding;
11610 save();
11611 yylcm();
11612 restore();
11613 return expanding = prev_expanding;
11614 };
11615
11616 yylcm = function() {
11617 expanding = 1;
11618 p2 = pop();
11619 p1 = pop();
11620 push(p1);
11621 push(p2);
11622 gcd();
11623 push(p1);
11624 divide();
11625 push(p2);
11626 divide();
11627 return inverse();
11628 };
11629
11630
11631 /*
11632 Return the leading coefficient of a polynomial.
11633
11634 Example
11635
11636 leading(5x^2+x+1,x)
11637
11638 Result
11639
11640 5
11641
11642 The result is undefined if P is not a polynomial.
11643 */
11644
11645 Eval_leading = function() {
11646 push(cadr(p1));
11647 Eval();
11648 push(caddr(p1));
11649 Eval();
11650 p1 = pop();
11651 if (p1 === symbol(NIL)) {
11652 guess();
11653 } else {
11654 push(p1);
11655 }
11656 return leading();
11657 };
11658
11659 leading = function() {
11660 save();
11661 p2 = pop();
11662 p1 = pop();
11663 push(p1);
11664 push(p2);
11665 degree();
11666 p3 = pop();
11667 push(p1);
11668 push(p2);
11669 push(p3);
11670 power();
11671 divide();
11672 push(p2);
11673 filter();
11674 return restore();
11675 };
11676
11677
11678 /*
11679 Legendre function
11680
11681 Example
11682
11683 legendre(x,3,0)
11684
11685 Result
11686
11687 5 3 3
11688 --- x - --- x
11689 2 2
11690
11691 The computation uses the following recurrence relation.
11692
11693 P(x,0) = 1
11694
11695 P(x,1) = x
11696
11697 n*P(x,n) = (2*(n-1)+1)*x*P(x,n-1) - (n-1)*P(x,n-2)
11698
11699 In the "for" loop we have i = n-1 so the recurrence relation becomes
11700
11701 (i+1)*P(x,n) = (2*i+1)*x*P(x,n-1) - i*P(x,n-2)
11702
11703 For m > 0
11704
11705 P(x,n,m) = (-1)^m * (1-x^2)^(m/2) * d^m/dx^m P(x,n)
11706 */
11707
11708 Eval_legendre = function() {
11709 push(cadr(p1));
11710 Eval();
11711 push(caddr(p1));
11712 Eval();
11713 push(cadddr(p1));
11714 Eval();
11715 p2 = pop();
11716 if (p2 === symbol(NIL)) {
11717 push_integer(0);
11718 } else {
11719 push(p2);
11720 }
11721 return legendre();
11722 };
11723
11724 legendre = function() {
11725 save();
11726 __legendre();
11727 return restore();
11728 };
11729
11730 __legendre = function() {
11731 var m, n;
11732 m = 0;
11733 n = 0;
11734 p3 = pop();
11735 p2 = pop();
11736 p1 = pop();
11737 push(p2);
11738 n = pop_integer();
11739 push(p3);
11740 m = pop_integer();
11741 if (n < 0 || isNaN(n) || m < 0 || isNaN(m)) {
11742 push_symbol(LEGENDRE);
11743 push(p1);
11744 push(p2);
11745 push(p3);
11746 list(4);
11747 return;
11748 }
11749 if (issymbol(p1)) {
11750 __legendre2(n, m);
11751 } else {
11752 p4 = p1;
11753 p1 = symbol(SECRETX);
11754 __legendre2(n, m);
11755 p1 = p4;
11756 push(symbol(SECRETX));
11757 push(p1);
11758 subst();
11759 Eval();
11760 }
11761 return __legendre3(m);
11762 };
11763
11764 __legendre2 = function(n, m) {
11765 var i, i1, o, ref, ref1, results;
11766 i = 0;
11767 push_integer(1);
11768 push_integer(0);
11769 p6 = pop();
11770 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
11771 p5 = p6;
11772 p6 = pop();
11773 push_integer(2 * i + 1);
11774 push(p1);
11775 multiply();
11776 push(p6);
11777 multiply();
11778 push_integer(i);
11779 push(p5);
11780 multiply();
11781 subtract();
11782 push_integer(i + 1);
11783 divide();
11784 }
11785 results = [];
11786 for (i = i1 = 0, ref1 = m; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
11787 push(p1);
11788 results.push(derivative());
11789 }
11790 return results;
11791 };
11792
11793 __legendre3 = function(m) {
11794 if (m === 0) {
11795 return;
11796 }
11797 if (car(p1) === symbol(COS)) {
11798 push(cadr(p1));
11799 sine();
11800 square();
11801 } else if (car(p1) === symbol(SIN)) {
11802 push(cadr(p1));
11803 cosine();
11804 square();
11805 } else {
11806 push_integer(1);
11807 push(p1);
11808 square();
11809 subtract();
11810 }
11811 push_integer(m);
11812 push_rational(1, 2);
11813 multiply();
11814 power();
11815 multiply();
11816 if (m % 2) {
11817 return negate();
11818 }
11819 };
11820
11821 list = function(n) {
11822 var listIterator, o, ref, results;
11823 listIterator = 0;
11824 push(symbol(NIL));
11825 results = [];
11826 for (listIterator = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; listIterator = 0 <= ref ? ++o : --o) {
11827 results.push(cons());
11828 }
11829 return results;
11830 };
11831
11832 Eval_log = function() {
11833 push(cadr(p1));
11834 Eval();
11835 return logarithm();
11836 };
11837
11838 logarithm = function() {
11839 save();
11840 yylog();
11841 return restore();
11842 };
11843
11844 yylog = function() {
11845 var d;
11846 d = 0.0;
11847 p1 = pop();
11848 if (p1 === symbol(E)) {
11849 push_integer(1);
11850 return;
11851 }
11852 if (equaln(p1, 1)) {
11853 push_integer(0);
11854 return;
11855 }
11856 if (isnegativenumber(p1)) {
11857 push(p1);
11858 negate();
11859 logarithm();
11860 push(imaginaryunit);
11861 if (evaluatingAsFloats) {
11862 push_double(Math.PI);
11863 } else {
11864 push_symbol(PI);
11865 }
11866 multiply();
11867 add();
11868 return;
11869 }
11870 if (isdouble(p1)) {
11871 d = Math.log(p1.d);
11872 push_double(d);
11873 return;
11874 }
11875 if (isfraction(p1)) {
11876 push(p1);
11877 numerator();
11878 logarithm();
11879 push(p1);
11880 denominator();
11881 logarithm();
11882 subtract();
11883 return;
11884 }
11885 if (car(p1) === symbol(POWER)) {
11886 push(caddr(p1));
11887 push(cadr(p1));
11888 logarithm();
11889 multiply();
11890 return;
11891 }
11892 if (car(p1) === symbol(MULTIPLY)) {
11893 push_integer(0);
11894 p1 = cdr(p1);
11895 while (iscons(p1)) {
11896 push(car(p1));
11897 logarithm();
11898 add();
11899 p1 = cdr(p1);
11900 }
11901 return;
11902 }
11903 push_symbol(LOG);
11904 push(p1);
11905 return list(2);
11906 };
11907
11908 Eval_lookup = function() {
11909 p1 = cadr(p1);
11910 if (!iscons(p1) && cadr(p1).k === SYM) {
11911 p1 = get_binding(p1);
11912 }
11913 return push(p1);
11914 };
11915
11916 madd = function(a, b) {
11917 return a.add(b);
11918 };
11919
11920 msub = function(a, b) {
11921 return a.subtract(b);
11922 };
11923
11924 addf = function(a, b) {
11925 return a.add(b);
11926 };
11927
11928 subf = function(a, b) {
11929 return a.subtract(b);
11930 };
11931
11932 ucmp = function(a, b) {
11933 return a.compareAbs(b);
11934 };
11935
11936 mgcd = function(u, v) {
11937 return bigInt.gcd(u, v);
11938 };
11939
11940 new_string = function(s) {
11941 save();
11942 p1 = new U();
11943 p1.k = STR;
11944 p1.str = s;
11945 push(p1);
11946 return restore();
11947 };
11948
11949 out_of_memory = function() {
11950 return stop("out of memory");
11951 };
11952
11953 push_zero_matrix = function(i, j) {
11954 push(alloc_tensor(i * j));
11955 stack[tos - 1].tensor.ndim = 2;
11956 stack[tos - 1].tensor.dim[0] = i;
11957 return stack[tos - 1].tensor.dim[1] = j;
11958 };
11959
11960 push_identity_matrix = function(n) {
11961 var i, o, ref;
11962 push_zero_matrix(n, n);
11963 i = 0;
11964 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
11965 stack[tos - 1].tensor.elem[i * n + i] = one;
11966 }
11967 return check_tensor_dimensions(stack[tos - 1]);
11968 };
11969
11970 push_cars = function(p) {
11971 var results;
11972 results = [];
11973 while (iscons(p)) {
11974 push(car(p));
11975 results.push(p = cdr(p));
11976 }
11977 return results;
11978 };
11979
11980 peek = function() {
11981 save();
11982 p1 = pop();
11983 push(p1);
11984 return restore();
11985 };
11986
11987 equal = function(p1, p2) {
11988 if (cmp_expr(p1, p2) === 0) {
11989 return 1;
11990 } else {
11991 return 0;
11992 }
11993 };
11994
11995 lessp = function(p1, p2) {
11996 if (cmp_expr(p1, p2) < 0) {
11997 return 1;
11998 } else {
11999 return 0;
12000 }
12001 };
12002
12003 sign = function(n) {
12004 if (n < 0) {
12005 return -1;
12006 } else if (n > 0) {
12007 return 1;
12008 } else {
12009 return 0;
12010 }
12011 };
12012
12013 cmp_expr = function(p1, p2) {
12014 var n;
12015 n = 0;
12016 if (p1 === p2) {
12017 return 0;
12018 }
12019 if (p1 === symbol(NIL)) {
12020 return -1;
12021 }
12022 if (p2 === symbol(NIL)) {
12023 return 1;
12024 }
12025 if (isnum(p1) && isnum(p2)) {
12026 return sign(compare_numbers(p1, p2));
12027 }
12028 if (isnum(p1)) {
12029 return -1;
12030 }
12031 if (isnum(p2)) {
12032 return 1;
12033 }
12034 if (isstr(p1) && isstr(p2)) {
12035 return sign(strcmp(p1.str, p2.str));
12036 }
12037 if (isstr(p1)) {
12038 return -1;
12039 }
12040 if (isstr(p2)) {
12041 return 1;
12042 }
12043 if (issymbol(p1) && issymbol(p2)) {
12044 return sign(strcmp(get_printname(p1), get_printname(p2)));
12045 }
12046 if (issymbol(p1)) {
12047 return -1;
12048 }
12049 if (issymbol(p2)) {
12050 return 1;
12051 }
12052 if (istensor(p1) && istensor(p2)) {
12053 return compare_tensors(p1, p2);
12054 }
12055 if (istensor(p1)) {
12056 return -1;
12057 }
12058 if (istensor(p2)) {
12059 return 1;
12060 }
12061 while (iscons(p1) && iscons(p2)) {
12062 n = cmp_expr(car(p1), car(p2));
12063 if (n !== 0) {
12064 return n;
12065 }
12066 p1 = cdr(p1);
12067 p2 = cdr(p2);
12068 }
12069 if (iscons(p2)) {
12070 return -1;
12071 }
12072 if (iscons(p1)) {
12073 return 1;
12074 }
12075 return 0;
12076 };
12077
12078 length = function(p) {
12079 var n;
12080 n = 0;
12081 while (iscons(p)) {
12082 p = cdr(p);
12083 n++;
12084 }
12085 return n;
12086 };
12087
12088 unique = function(p) {
12089 save();
12090 p1 = symbol(NIL);
12091 p2 = symbol(NIL);
12092 unique_f(p);
12093 if (p2 !== symbol(NIL)) {
12094 p1 = symbol(NIL);
12095 }
12096 p = p1;
12097 restore();
12098 return p;
12099 };
12100
12101 unique_f = function(p) {
12102 if (isstr(p)) {
12103 if (p1 === symbol(NIL)) {
12104 p1 = p;
12105 } else if (p !== p1) {
12106 p2 = p;
12107 }
12108 return;
12109 }
12110 while (iscons(p)) {
12111 unique_f(car(p));
12112 if (p2 !== symbol(NIL)) {
12113 return;
12114 }
12115 p = cdr(p);
12116 }
12117 };
12118
12119 ssqrt = function() {
12120 push_rational(1, 2);
12121 return power();
12122 };
12123
12124 yyexpand = function() {
12125 var prev_expanding;
12126 prev_expanding = expanding;
12127 expanding = 1;
12128 Eval();
12129 return expanding = prev_expanding;
12130 };
12131
12132 exponential = function() {
12133 push_symbol(E);
12134 swap();
12135 return power();
12136 };
12137
12138 square = function() {
12139 push_integer(2);
12140 return power();
12141 };
12142
12143 sort_stack = function(n) {
12144 var h, subsetOfStack;
12145 h = tos - n;
12146 subsetOfStack = stack.slice(h, h + n);
12147 subsetOfStack.sort(cmp_expr);
12148 return stack = stack.slice(0, h).concat(subsetOfStack).concat(stack.slice(h + n));
12149 };
12150
12151 $.equal = equal;
12152
12153 $.length = length;
12154
12155 mmul = function(a, b) {
12156 return a.multiply(b);
12157 };
12158
12159 mdiv = function(a, b) {
12160 return a.divide(b);
12161 };
12162
12163
12164 /*
12165 static void
12166 addf(unsigned int *a, unsigned int *b, int len)
12167 {
12168 int i
12169 long long t = 0; # can be signed or unsigned
12170 for (i = 0; i < len; i++) {
12171 t += (long long) a[i] + b[i]
12172 a[i] = (unsigned int) t
12173 t >>= 32
12174 }
12175 }
12176
12177 // a = a - b
12178
12179 static void
12180 subf(unsigned int *a, unsigned int *b, int len)
12181 {
12182 int i
12183 long long t = 0; # must be signed
12184 for (i = 0; i < len; i++) {
12185 t += (long long) a[i] - b[i]
12186 a[i] = (unsigned int) t
12187 t >>= 32
12188 }
12189 }
12190
12191 // a = b * c
12192
12193 // 0xffffffff + 0xffffffff * 0xffffffff == 0xffffffff00000000
12194
12195 static void
12196 mulf(unsigned int *a, unsigned int *b, int len, unsigned int c)
12197 {
12198 int i
12199 unsigned long long t = 0; # must be unsigned
12200 for (i = 0; i < len; i++) {
12201 t += (unsigned long long) b[i] * c
12202 a[i] = (unsigned int) t
12203 t >>= 32
12204 }
12205 a[i] = (unsigned int) t
12206 }
12207 */
12208
12209 mmod = function(a, b) {
12210 return a.mod(b);
12211 };
12212
12213 mdivrem = function(a, b) {
12214 var toReturn;
12215 toReturn = a.divmod(b);
12216 return [toReturn.quotient, toReturn.remainder];
12217 };
12218
12219 Eval_mod = function() {
12220 push(cadr(p1));
12221 Eval();
12222 push(caddr(p1));
12223 Eval();
12224 return mod();
12225 };
12226
12227 mod = function() {
12228 var n;
12229 n = 0;
12230 save();
12231 p2 = pop();
12232 p1 = pop();
12233 if (iszero(p2)) {
12234 stop("mod function: divide by zero");
12235 }
12236 if (!isnum(p1) || !isnum(p2)) {
12237 push_symbol(MOD);
12238 push(p1);
12239 push(p2);
12240 list(3);
12241 restore();
12242 return;
12243 }
12244 if (isdouble(p1)) {
12245 push(p1);
12246 n = pop_integer();
12247 if (isNaN(n)) {
12248 stop("mod function: cannot convert float value to integer");
12249 }
12250 push_integer(n);
12251 p1 = pop();
12252 }
12253 if (isdouble(p2)) {
12254 push(p2);
12255 n = pop_integer();
12256 if (isNaN(n)) {
12257 stop("mod function: cannot convert float value to integer");
12258 }
12259 push_integer(n);
12260 p2 = pop();
12261 }
12262 if (!isinteger(p1) || !isinteger(p2)) {
12263 stop("mod function: integer arguments expected");
12264 }
12265 p3 = new U();
12266 p3.k = NUM;
12267 p3.q.a = mmod(p1.q.a, p2.q.a);
12268 p3.q.b = mint(1);
12269 push(p3);
12270 return restore();
12271 };
12272
12273 mpow = function(a, n) {
12274 return a.pow(n);
12275 };
12276
12277 mprime = function(n) {
12278 return n.isProbablePrime();
12279 };
12280
12281 mroot = function(n, index) {
12282 var i, j, k, o, ref, x, y;
12283 n = n.abs();
12284 i = 0;
12285 j = 0;
12286 k = 0;
12287 if (index === 0) {
12288 stop("root index is zero");
12289 }
12290 k = 0;
12291 while (n.shiftRight(k) > 0) {
12292 k++;
12293 }
12294 if (k === 0) {
12295 return mint(0);
12296 }
12297 k = Math.floor((k - 1) / index);
12298 j = Math.floor(k / 32 + 1);
12299 x = bigInt(j);
12300 for (i = o = 0, ref = j; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
12301 x = x.and(bigInt(1).shiftLeft(i).not());
12302 }
12303 while (k >= 0) {
12304 x = x.or(bigInt(1).shiftLeft(k));
12305 y = mpow(x, index);
12306 switch (mcmp(y, n)) {
12307 case 0:
12308 return x;
12309 case 1:
12310 x = x.and(bigInt(1).shiftLeft(k).not());
12311 }
12312 k--;
12313 }
12314 return 0;
12315 };
12316
12317 Eval_multiply = function() {
12318 var results;
12319 push(cadr(p1));
12320 Eval();
12321 p1 = cddr(p1);
12322 results = [];
12323 while (iscons(p1)) {
12324 push(car(p1));
12325 Eval();
12326 multiply();
12327 results.push(p1 = cdr(p1));
12328 }
12329 return results;
12330 };
12331
12332 multiply = function() {
12333 if (esc_flag) {
12334 stop("escape key stop");
12335 }
12336 if (isnum(stack[tos - 2]) && isnum(stack[tos - 1])) {
12337 return multiply_numbers();
12338 } else {
12339 save();
12340 yymultiply();
12341 return restore();
12342 }
12343 };
12344
12345 yymultiply = function() {
12346 var h, i, n, o, ref, ref1;
12347 h = 0;
12348 i = 0;
12349 n = 0;
12350 p2 = pop();
12351 p1 = pop();
12352 h = tos;
12353 if (iszero(p1) || iszero(p2)) {
12354 if (evaluatingAsFloats) {
12355 push_double(0.0);
12356 } else {
12357 push(zero);
12358 }
12359 return;
12360 }
12361 if (expanding && isadd(p1)) {
12362 p1 = cdr(p1);
12363 if (evaluatingAsFloats) {
12364 push_double(0.0);
12365 } else {
12366 push(zero);
12367 }
12368 while (iscons(p1)) {
12369 push(car(p1));
12370 push(p2);
12371 multiply();
12372 add();
12373 p1 = cdr(p1);
12374 }
12375 return;
12376 }
12377 if (expanding && isadd(p2)) {
12378 p2 = cdr(p2);
12379 if (evaluatingAsFloats) {
12380 push_double(0.0);
12381 } else {
12382 push(zero);
12383 }
12384 while (iscons(p2)) {
12385 push(p1);
12386 push(car(p2));
12387 multiply();
12388 add();
12389 p2 = cdr(p2);
12390 }
12391 return;
12392 }
12393 if (!istensor(p1) && istensor(p2)) {
12394 push(p1);
12395 push(p2);
12396 scalar_times_tensor();
12397 return;
12398 }
12399 if (istensor(p1) && !istensor(p2)) {
12400 push(p1);
12401 push(p2);
12402 tensor_times_scalar();
12403 return;
12404 }
12405 if (car(p1) === symbol(MULTIPLY)) {
12406 p1 = cdr(p1);
12407 } else {
12408 push(p1);
12409 list(1);
12410 p1 = pop();
12411 }
12412 if (car(p2) === symbol(MULTIPLY)) {
12413 p2 = cdr(p2);
12414 } else {
12415 push(p2);
12416 list(1);
12417 p2 = pop();
12418 }
12419 if (isnum(car(p1)) && isnum(car(p2))) {
12420 push(car(p1));
12421 push(car(p2));
12422 multiply_numbers();
12423 p1 = cdr(p1);
12424 p2 = cdr(p2);
12425 } else if (isnum(car(p1))) {
12426 push(car(p1));
12427 p1 = cdr(p1);
12428 } else if (isnum(car(p2))) {
12429 push(car(p2));
12430 p2 = cdr(p2);
12431 } else {
12432 if (evaluatingAsFloats) {
12433 push_double(1.0);
12434 } else {
12435 push(one);
12436 }
12437 }
12438 parse_p1();
12439 parse_p2();
12440 while (iscons(p1) && iscons(p2)) {
12441 if (caar(p1) === symbol(OPERATOR) && caar(p2) === symbol(OPERATOR)) {
12442 push_symbol(OPERATOR);
12443 push(cdar(p1));
12444 push(cdar(p2));
12445 append();
12446 cons();
12447 p1 = cdr(p1);
12448 p2 = cdr(p2);
12449 parse_p1();
12450 parse_p2();
12451 continue;
12452 }
12453 switch (cmp_expr(p3, p4)) {
12454 case -1:
12455 push(car(p1));
12456 p1 = cdr(p1);
12457 parse_p1();
12458 break;
12459 case 1:
12460 push(car(p2));
12461 p2 = cdr(p2);
12462 parse_p2();
12463 break;
12464 case 0:
12465 combine_factors(h);
12466 p1 = cdr(p1);
12467 p2 = cdr(p2);
12468 parse_p1();
12469 parse_p2();
12470 break;
12471 default:
12472 stop("internal error 2");
12473 }
12474 }
12475 while (iscons(p1)) {
12476 push(car(p1));
12477 p1 = cdr(p1);
12478 }
12479 while (iscons(p2)) {
12480 push(car(p2));
12481 p2 = cdr(p2);
12482 }
12483 __normalize_radical_factors(h);
12484 if (expanding) {
12485 for (i = o = ref = h, ref1 = tos; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
12486 if (isadd(stack[i])) {
12487 multiply_all(tos - h);
12488 return;
12489 }
12490 }
12491 }
12492 n = tos - h;
12493 if (n === 1) {
12494 return;
12495 }
12496 if (isrational(stack[h]) && equaln(stack[h], 1)) {
12497 if (n === 2) {
12498 p7 = pop();
12499 pop();
12500 push(p7);
12501 } else {
12502 stack[h] = symbol(MULTIPLY);
12503 list(n);
12504 }
12505 return;
12506 }
12507 list(n);
12508 p7 = pop();
12509 push_symbol(MULTIPLY);
12510 push(p7);
12511 return cons();
12512 };
12513
12514 parse_p1 = function() {
12515 p3 = car(p1);
12516 p5 = evaluatingAsFloats ? one_as_double : one;
12517 if (car(p3) === symbol(POWER)) {
12518 p5 = caddr(p3);
12519 return p3 = cadr(p3);
12520 }
12521 };
12522
12523 parse_p2 = function() {
12524 p4 = car(p2);
12525 p6 = evaluatingAsFloats ? one_as_double : one;
12526 if (car(p4) === symbol(POWER)) {
12527 p6 = caddr(p4);
12528 return p4 = cadr(p4);
12529 }
12530 };
12531
12532 combine_factors = function(h) {
12533 push(p4);
12534 push(p5);
12535 push(p6);
12536 add();
12537 power();
12538 p7 = pop();
12539 if (isnum(p7)) {
12540 push(stack[h]);
12541 push(p7);
12542 multiply_numbers();
12543 return stack[h] = pop();
12544 } else if (car(p7) === symbol(MULTIPLY)) {
12545 if (isnum(cadr(p7)) && cdddr(p7) === symbol(NIL)) {
12546 push(stack[h]);
12547 push(cadr(p7));
12548 multiply_numbers();
12549 stack[h] = pop();
12550 return push(caddr(p7));
12551 } else {
12552 return push(p7);
12553 }
12554 } else {
12555 return push(p7);
12556 }
12557 };
12558
12559 gp = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, -6, -7, -8, -3, -4, -5, 13, 14, 15, -16, 9, 10, 11, -12], [0, 0, 6, -1, -11, 10, -2, -15, 14, 12, -5, 4, -9, 16, -8, 7, -13], [0, 0, 7, 11, -1, -9, 15, -2, -13, 5, 12, -3, -10, 8, 16, -6, -14], [0, 0, 8, -10, 9, -1, -14, 13, -2, -4, 3, 12, -11, -7, 6, 16, -15], [0, 0, 3, 2, 15, -14, 1, 11, -10, 16, -8, 7, 13, 12, -5, 4, 9], [0, 0, 4, -15, 2, 13, -11, 1, 9, 8, 16, -6, 14, 5, 12, -3, 10], [0, 0, 5, 14, -13, 2, 10, -9, 1, -7, 6, 16, 15, -4, 3, 12, 11], [0, 0, 13, 12, -5, 4, 16, -8, 7, -1, -11, 10, -3, -2, -15, 14, -6], [0, 0, 14, 5, 12, -3, 8, 16, -6, 11, -1, -9, -4, 15, -2, -13, -7], [0, 0, 15, -4, 3, 12, -7, 6, 16, -10, 9, -1, -5, -14, 13, -2, -8], [0, 0, 16, -9, -10, -11, -13, -14, -15, -3, -4, -5, 1, -6, -7, -8, 2], [0, 0, 9, -16, 8, -7, -12, 5, -4, -2, -15, 14, 6, -1, -11, 10, 3], [0, 0, 10, -8, -16, 6, -5, -12, 3, 15, -2, -13, 7, 11, -1, -9, 4], [0, 0, 11, 7, -6, -16, 4, -3, -12, -14, 13, -2, 8, -10, 9, -1, 5], [0, 0, 12, 13, 14, 15, 9, 10, 11, -6, -7, -8, -2, -3, -4, -5, -1]];
12560
12561 combine_gammas = function(h) {
12562 var n;
12563 n = gp[Math.floor(p1.gamma)][Math.floor(p2.gamma)];
12564 if (n < 0) {
12565 n = -n;
12566 push(stack[h]);
12567 negate();
12568 stack[h] = pop();
12569 }
12570 if (n > 1) {
12571 return push(_gamma[n]);
12572 }
12573 };
12574
12575 multiply_noexpand = function() {
12576 var prev_expanding;
12577 prev_expanding = expanding;
12578 expanding = 0;
12579 multiply();
12580 return expanding = prev_expanding;
12581 };
12582
12583 multiply_all = function(n) {
12584 var h, i, o, ref;
12585 i = 0;
12586 if (n === 1) {
12587 return;
12588 }
12589 if (n === 0) {
12590 push(evaluatingAsFloats ? one_as_double : one);
12591 return;
12592 }
12593 h = tos - n;
12594 push(stack[h]);
12595 for (i = o = 1, ref = n; 1 <= ref ? o < ref : o > ref; i = 1 <= ref ? ++o : --o) {
12596 push(stack[h + i]);
12597 multiply();
12598 }
12599 stack[h] = pop();
12600 return moveTos(h + 1);
12601 };
12602
12603 multiply_all_noexpand = function(n) {
12604 var prev_expanding;
12605 prev_expanding = expanding;
12606 expanding = 0;
12607 multiply_all(n);
12608 return expanding = prev_expanding;
12609 };
12610
12611 divide = function() {
12612 if (isnum(stack[tos - 2]) && isnum(stack[tos - 1])) {
12613 return divide_numbers();
12614 } else {
12615 inverse();
12616 return multiply();
12617 }
12618 };
12619
12620 inverse = function() {
12621 if (isnum(stack[tos - 1])) {
12622 return invert_number();
12623 } else {
12624 push_integer(-1);
12625 return power();
12626 }
12627 };
12628
12629 reciprocate = function() {
12630 return inverse();
12631 };
12632
12633 negate = function() {
12634 if (isnum(stack[tos - 1])) {
12635 return negate_number();
12636 } else {
12637 if (evaluatingAsFloats) {
12638 push_double(-1.0);
12639 } else {
12640 push_integer(-1);
12641 }
12642 return multiply();
12643 }
12644 };
12645
12646 negate_expand = function() {
12647 var prev_expanding;
12648 prev_expanding = expanding;
12649 expanding = 1;
12650 negate();
12651 return expanding = prev_expanding;
12652 };
12653
12654 negate_noexpand = function() {
12655 var prev_expanding;
12656 prev_expanding = expanding;
12657 expanding = 0;
12658 negate();
12659 return expanding = prev_expanding;
12660 };
12661
12662 __normalize_radical_factors = function(h) {
12663 var i, i1, j1, o, ref, ref1, ref2, ref3, ref4, ref5;
12664 i = 0;
12665 if (isplusone(stack[h]) || isminusone(stack[h]) || isdouble(stack[h])) {
12666 return;
12667 }
12668 for (i = o = ref = h + 1, ref1 = tos; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
12669 if (__is_radical_number(stack[i])) {
12670 break;
12671 }
12672 }
12673 if (i === tos) {
12674 return;
12675 }
12676 save();
12677 push(stack[h]);
12678 mp_numerator();
12679 p1 = pop();
12680 for (i = i1 = ref2 = h + 1, ref3 = tos; ref2 <= ref3 ? i1 < ref3 : i1 > ref3; i = ref2 <= ref3 ? ++i1 : --i1) {
12681 if (isplusone(p1) || isminusone(p1)) {
12682 break;
12683 }
12684 if (!__is_radical_number(stack[i])) {
12685 continue;
12686 }
12687 p3 = cadr(stack[i]);
12688 p4 = caddr(stack[i]);
12689 if (!isnegativenumber(p4)) {
12690 continue;
12691 }
12692 push(p1);
12693 push(p3);
12694 divide();
12695 p5 = pop();
12696 if (!isinteger(p5)) {
12697 continue;
12698 }
12699 p1 = p5;
12700 push_symbol(POWER);
12701 push(p3);
12702 push(evaluatingAsFloats ? one_as_double : one);
12703 push(p4);
12704 add();
12705 list(3);
12706 stack[i] = pop();
12707 }
12708 push(stack[h]);
12709 mp_denominator();
12710 p2 = pop();
12711 for (i = j1 = ref4 = h + 1, ref5 = tos; ref4 <= ref5 ? j1 < ref5 : j1 > ref5; i = ref4 <= ref5 ? ++j1 : --j1) {
12712 if (isplusone(p2)) {
12713 break;
12714 }
12715 if (!__is_radical_number(stack[i])) {
12716 continue;
12717 }
12718 p3 = cadr(stack[i]);
12719 p4 = caddr(stack[i]);
12720 if (isnegativenumber(p4)) {
12721 continue;
12722 }
12723 push(p2);
12724 push(p3);
12725 divide();
12726 p5 = pop();
12727 if (!isinteger(p5)) {
12728 continue;
12729 }
12730 p2 = p5;
12731 push_symbol(POWER);
12732 push(p3);
12733 push(p4);
12734 push(one);
12735 subtract();
12736 if (dontCreateNewRadicalsInDenominatorWhenEvalingMultiplication) {
12737 if (isinteger(p3) && !isinteger(stack[tos - 1]) && isnegativenumber(stack[tos - 1])) {
12738 pop();
12739 pop();
12740 pop();
12741 push(p1);
12742 push(p3);
12743 divide();
12744 p1 = pop();
12745 break;
12746 }
12747 }
12748 list(3);
12749 stack[i] = pop();
12750 }
12751 push(p1);
12752 push(p2);
12753 divide();
12754 stack[h] = pop();
12755 return restore();
12756 };
12757
12758 __is_radical_number = function(p) {
12759 if (car(p) === symbol(POWER) && isnum(cadr(p)) && isnum(caddr(p)) && !isminusone(cadr(p))) {
12760 return 1;
12761 } else {
12762 return 0;
12763 }
12764 };
12765
12766 NROOTS_YMAX = 101;
12767
12768 NROOTS_DELTA = 1.0e-6;
12769
12770 NROOTS_EPSILON = 1.0e-9;
12771
12772 NROOTS_ABS = function(z) {
12773 return Math.sqrt(z.r * z.r + z.i * z.i);
12774 };
12775
12776 theRandom = 0.0;
12777
12778 NROOTS_RANDOM = function() {
12779 return 4.0 * Math.random() - 2.0;
12780 };
12781
12782 numericRootOfPolynomial = (function() {
12783 function numericRootOfPolynomial() {}
12784
12785 numericRootOfPolynomial.prototype.r = 0.0;
12786
12787 numericRootOfPolynomial.prototype.i = 0.0;
12788
12789 return numericRootOfPolynomial;
12790
12791 })();
12792
12793 nroots_a = new numericRootOfPolynomial();
12794
12795 nroots_b = new numericRootOfPolynomial();
12796
12797 nroots_x = new numericRootOfPolynomial();
12798
12799 nroots_y = new numericRootOfPolynomial();
12800
12801 nroots_fa = new numericRootOfPolynomial();
12802
12803 nroots_fb = new numericRootOfPolynomial();
12804
12805 nroots_dx = new numericRootOfPolynomial();
12806
12807 nroots_df = new numericRootOfPolynomial();
12808
12809 nroots_c = [];
12810
12811 for (initNRoots = o = 0, ref = NROOTS_YMAX; 0 <= ref ? o < ref : o > ref; initNRoots = 0 <= ref ? ++o : --o) {
12812 nroots_c[initNRoots] = new numericRootOfPolynomial();
12813 }
12814
12815 Eval_nroots = function() {
12816 var h, i, i1, j1, k, l1, n, ref1, ref2, ref3;
12817 h = 0;
12818 i = 0;
12819 k = 0;
12820 n = 0;
12821 push(cadr(p1));
12822 Eval();
12823 push(caddr(p1));
12824 Eval();
12825 p2 = pop();
12826 if (p2 === symbol(NIL)) {
12827 guess();
12828 } else {
12829 push(p2);
12830 }
12831 p2 = pop();
12832 p1 = pop();
12833 if (!ispoly(p1, p2)) {
12834 stop("nroots: polynomial?");
12835 }
12836 h = tos;
12837 push(p1);
12838 push(p2);
12839 n = coeff();
12840 if (n > NROOTS_YMAX) {
12841 stop("nroots: degree?");
12842 }
12843 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
12844 push(stack[h + i]);
12845 real();
12846 yyfloat();
12847 Eval();
12848 p1 = pop();
12849 push(stack[h + i]);
12850 imag();
12851 yyfloat();
12852 Eval();
12853 p2 = pop();
12854 if (!isdouble(p1) || !isdouble(p2)) {
12855 stop("nroots: coefficients?");
12856 }
12857 nroots_c[i].r = p1.d;
12858 nroots_c[i].i = p2.d;
12859 }
12860 moveTos(h);
12861 monic(n);
12862 for (k = j1 = ref2 = n; j1 > 1; k = j1 += -1) {
12863 findroot(k);
12864 if (Math.abs(nroots_a.r) < NROOTS_DELTA) {
12865 nroots_a.r = 0.0;
12866 }
12867 if (Math.abs(nroots_a.i) < NROOTS_DELTA) {
12868 nroots_a.i = 0.0;
12869 }
12870 push_double(nroots_a.r);
12871 push_double(nroots_a.i);
12872 push(imaginaryunit);
12873 multiply();
12874 add();
12875 NROOTS_divpoly(k);
12876 }
12877 n = tos - h;
12878 if (n > 1) {
12879 sort_stack(n);
12880 p1 = alloc_tensor(n);
12881 p1.tensor.ndim = 1;
12882 p1.tensor.dim[0] = n;
12883 for (i = l1 = 0, ref3 = n; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
12884 p1.tensor.elem[i] = stack[h + i];
12885 }
12886 moveTos(h);
12887 return push(p1);
12888 }
12889 };
12890
12891 monic = function(n) {
12892 var i1, k, ref1, t;
12893 k = 0;
12894 t = 0.0;
12895 nroots_y.r = nroots_c[n - 1].r;
12896 nroots_y.i = nroots_c[n - 1].i;
12897 t = nroots_y.r * nroots_y.r + nroots_y.i * nroots_y.i;
12898 for (k = i1 = 0, ref1 = n - 1; 0 <= ref1 ? i1 < ref1 : i1 > ref1; k = 0 <= ref1 ? ++i1 : --i1) {
12899 nroots_c[k].r = (nroots_c[k].r * nroots_y.r + nroots_c[k].i * nroots_y.i) / t;
12900 nroots_c[k].i = (nroots_c[k].i * nroots_y.r - nroots_c[k].r * nroots_y.i) / t;
12901 }
12902 nroots_c[n - 1].r = 1.0;
12903 return nroots_c[n - 1].i = 0.0;
12904 };
12905
12906 findroot = function(n) {
12907 var i1, j, j1, k, nrabs, t;
12908 j = 0;
12909 k = 0;
12910 t = 0.0;
12911 if (NROOTS_ABS(nroots_c[0]) < NROOTS_DELTA) {
12912 nroots_a.r = 0.0;
12913 nroots_a.i = 0.0;
12914 return;
12915 }
12916 for (j = i1 = 0; i1 < 100; j = ++i1) {
12917 nroots_a.r = NROOTS_RANDOM();
12918 nroots_a.i = NROOTS_RANDOM();
12919 compute_fa(n);
12920 nroots_b.r = nroots_a.r;
12921 nroots_b.i = nroots_a.i;
12922 nroots_fb.r = nroots_fa.r;
12923 nroots_fb.i = nroots_fa.i;
12924 nroots_a.r = NROOTS_RANDOM();
12925 nroots_a.i = NROOTS_RANDOM();
12926 for (k = j1 = 0; j1 < 1000; k = ++j1) {
12927 compute_fa(n);
12928 nrabs = NROOTS_ABS(nroots_fa);
12929 if (DEBUG) {
12930 console.log("nrabs: " + nrabs);
12931 }
12932 if (nrabs < NROOTS_EPSILON) {
12933 return;
12934 }
12935 if (NROOTS_ABS(nroots_fa) < NROOTS_ABS(nroots_fb)) {
12936 nroots_x.r = nroots_a.r;
12937 nroots_x.i = nroots_a.i;
12938 nroots_a.r = nroots_b.r;
12939 nroots_a.i = nroots_b.i;
12940 nroots_b.r = nroots_x.r;
12941 nroots_b.i = nroots_x.i;
12942 nroots_x.r = nroots_fa.r;
12943 nroots_x.i = nroots_fa.i;
12944 nroots_fa.r = nroots_fb.r;
12945 nroots_fa.i = nroots_fb.i;
12946 nroots_fb.r = nroots_x.r;
12947 nroots_fb.i = nroots_x.i;
12948 }
12949 nroots_dx.r = nroots_b.r - nroots_a.r;
12950 nroots_dx.i = nroots_b.i - nroots_a.i;
12951 nroots_df.r = nroots_fb.r - nroots_fa.r;
12952 nroots_df.i = nroots_fb.i - nroots_fa.i;
12953 t = nroots_df.r * nroots_df.r + nroots_df.i * nroots_df.i;
12954 if (t === 0.0) {
12955 break;
12956 }
12957 nroots_y.r = (nroots_dx.r * nroots_df.r + nroots_dx.i * nroots_df.i) / t;
12958 nroots_y.i = (nroots_dx.i * nroots_df.r - nroots_dx.r * nroots_df.i) / t;
12959 nroots_a.r = nroots_b.r - (nroots_y.r * nroots_fb.r - nroots_y.i * nroots_fb.i);
12960 nroots_a.i = nroots_b.i - (nroots_y.r * nroots_fb.i + nroots_y.i * nroots_fb.r);
12961 }
12962 }
12963 return stop("nroots: convergence error");
12964 };
12965
12966 compute_fa = function(n) {
12967 var i1, k, ref1, results, t;
12968 k = 0;
12969 t = 0.0;
12970 nroots_x.r = nroots_a.r;
12971 nroots_x.i = nroots_a.i;
12972 nroots_fa.r = nroots_c[0].r + nroots_c[1].r * nroots_x.r - nroots_c[1].i * nroots_x.i;
12973 nroots_fa.i = nroots_c[0].i + nroots_c[1].r * nroots_x.i + nroots_c[1].i * nroots_x.r;
12974 results = [];
12975 for (k = i1 = 2, ref1 = n; 2 <= ref1 ? i1 < ref1 : i1 > ref1; k = 2 <= ref1 ? ++i1 : --i1) {
12976 t = nroots_a.r * nroots_x.r - nroots_a.i * nroots_x.i;
12977 nroots_x.i = nroots_a.r * nroots_x.i + nroots_a.i * nroots_x.r;
12978 nroots_x.r = t;
12979 nroots_fa.r += nroots_c[k].r * nroots_x.r - nroots_c[k].i * nroots_x.i;
12980 results.push(nroots_fa.i += nroots_c[k].r * nroots_x.i + nroots_c[k].i * nroots_x.r);
12981 }
12982 return results;
12983 };
12984
12985 NROOTS_divpoly = function(n) {
12986 var i1, j1, k, ref1, ref2, results;
12987 k = 0;
12988 for (k = i1 = ref1 = n - 1; ref1 <= 0 ? i1 < 0 : i1 > 0; k = ref1 <= 0 ? ++i1 : --i1) {
12989 nroots_c[k - 1].r += nroots_c[k].r * nroots_a.r - nroots_c[k].i * nroots_a.i;
12990 nroots_c[k - 1].i += nroots_c[k].i * nroots_a.r + nroots_c[k].r * nroots_a.i;
12991 }
12992 if (NROOTS_ABS(nroots_c[0]) > NROOTS_DELTA) {
12993 stop("nroots: residual error");
12994 }
12995 results = [];
12996 for (k = j1 = 0, ref2 = n - 1; 0 <= ref2 ? j1 < ref2 : j1 > ref2; k = 0 <= ref2 ? ++j1 : --j1) {
12997 nroots_c[k].r = nroots_c[k + 1].r;
12998 results.push(nroots_c[k].i = nroots_c[k + 1].i);
12999 }
13000 return results;
13001 };
13002
13003 Eval_numerator = function() {
13004 push(cadr(p1));
13005 Eval();
13006 return numerator();
13007 };
13008
13009 numerator = function() {
13010 var h;
13011 h = 0;
13012 save();
13013 p1 = pop();
13014 if (car(p1) === symbol(ADD)) {
13015 push(p1);
13016 rationalize();
13017 p1 = pop();
13018 }
13019 if (car(p1) === symbol(MULTIPLY)) {
13020 h = tos;
13021 p1 = cdr(p1);
13022 while (iscons(p1)) {
13023 push(car(p1));
13024 numerator();
13025 p1 = cdr(p1);
13026 }
13027 multiply_all(tos - h);
13028 } else if (isrational(p1)) {
13029 push(p1);
13030 mp_numerator();
13031 } else if (car(p1) === symbol(POWER) && isnegativeterm(caddr(p1))) {
13032 push(one);
13033 } else {
13034 push(p1);
13035 }
13036 return restore();
13037 };
13038
13039 Eval_outer = function() {
13040 var results;
13041 p1 = cdr(p1);
13042 push(car(p1));
13043 Eval();
13044 p1 = cdr(p1);
13045 results = [];
13046 while (iscons(p1)) {
13047 push(car(p1));
13048 Eval();
13049 outer();
13050 results.push(p1 = cdr(p1));
13051 }
13052 return results;
13053 };
13054
13055 outer = function() {
13056 save();
13057 p2 = pop();
13058 p1 = pop();
13059 if (istensor(p1) && istensor(p2)) {
13060 yyouter();
13061 } else {
13062 push(p1);
13063 push(p2);
13064 if (istensor(p1)) {
13065 tensor_times_scalar();
13066 } else if (istensor(p2)) {
13067 scalar_times_tensor();
13068 } else {
13069 multiply();
13070 }
13071 }
13072 return restore();
13073 };
13074
13075 yyouter = function() {
13076 var i, i1, j, j1, k, l1, m1, ndim, nelem, ref1, ref2, ref3, ref4;
13077 i = 0;
13078 j = 0;
13079 k = 0;
13080 ndim = 0;
13081 nelem = 0;
13082 ndim = p1.tensor.ndim + p2.tensor.ndim;
13083 if (ndim > MAXDIM) {
13084 stop("outer: rank of result exceeds maximum");
13085 }
13086 nelem = p1.tensor.nelem * p2.tensor.nelem;
13087 p3 = alloc_tensor(nelem);
13088 p3.tensor.ndim = ndim;
13089 for (i = i1 = 0, ref1 = p1.tensor.ndim; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
13090 p3.tensor.dim[i] = p1.tensor.dim[i];
13091 }
13092 j = i;
13093 for (i = j1 = 0, ref2 = p2.tensor.ndim; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
13094 p3.tensor.dim[j + i] = p2.tensor.dim[i];
13095 }
13096 k = 0;
13097 for (i = l1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
13098 for (j = m1 = 0, ref4 = p2.tensor.nelem; 0 <= ref4 ? m1 < ref4 : m1 > ref4; j = 0 <= ref4 ? ++m1 : --m1) {
13099 push(p1.tensor.elem[i]);
13100 push(p2.tensor.elem[j]);
13101 multiply();
13102 p3.tensor.elem[k++] = pop();
13103 }
13104 }
13105 return push(p3);
13106 };
13107
13108
13109 /*
13110 Partition a term
13111
13112 Input stack:
13113
13114 term (factor or product of factors)
13115
13116 free variable
13117
13118 Output stack:
13119
13120 constant expression
13121
13122 variable expression
13123 */
13124
13125 partition = function() {
13126 save();
13127 p2 = pop();
13128 p1 = pop();
13129 push_integer(1);
13130 p3 = pop();
13131 p4 = p3;
13132 p1 = cdr(p1);
13133 while (iscons(p1)) {
13134 if (Find(car(p1), p2)) {
13135 push(p4);
13136 push(car(p1));
13137 multiply();
13138 p4 = pop();
13139 } else {
13140 push(p3);
13141 push(car(p1));
13142 multiply();
13143 p3 = pop();
13144 }
13145 p1 = cdr(p1);
13146 }
13147 push(p3);
13148 push(p4);
13149 return restore();
13150 };
13151
13152
13153 /*
13154 Add a pattern i.e. a substitution rule.
13155 Substitution rule needs a template as first argument
13156 and what to transform it to as second argument.
13157 Optional third argument is a boolean test which
13158 adds conditions to when the rule is applied.
13159 */
13160
13161 Eval_silentpattern = function() {
13162 Eval_pattern();
13163 pop();
13164 return push_symbol(NIL);
13165 };
13166
13167 Eval_pattern = function() {
13168 var firstArgument, patternPosition, secondArgument, stringKey, thirdArgument;
13169 if (!iscons(cdr(p1))) {
13170 stop("pattern needs at least a template and a transformed version");
13171 }
13172 firstArgument = car(cdr(p1));
13173 secondArgument = car(cdr(cdr(p1)));
13174 if (secondArgument === symbol(NIL)) {
13175 stop("pattern needs at least a template and a transformed version");
13176 }
13177 if (!iscons(cdr(cdr(p1)))) {
13178 thirdArgument = symbol(NIL);
13179 } else {
13180 thirdArgument = car(cdr(cdr(cdr(p1))));
13181 }
13182 if (equal(firstArgument, secondArgument)) {
13183 stop("recursive pattern");
13184 }
13185 stringKey = "template: " + print_list(firstArgument);
13186 stringKey += " tests: " + print_list(thirdArgument);
13187 if (DEBUG) {
13188 console.log("pattern stringkey: " + stringKey);
13189 }
13190 patternPosition = userSimplificationsInStringForm.indexOf(stringKey);
13191 if (patternPosition === -1) {
13192 userSimplificationsInStringForm.push(stringKey);
13193 userSimplificationsInListForm.push(cdr(p1));
13194 } else {
13195 if (DEBUG) {
13196 console.log("pattern already exists, replacing. " + cdr(p1));
13197 }
13198 userSimplificationsInStringForm[patternPosition] = stringKey;
13199 userSimplificationsInListForm[patternPosition] = cdr(p1);
13200 }
13201 push_symbol(PATTERN);
13202 push(cdr(p1));
13203 return list(2);
13204 };
13205
13206
13207 /*
13208 Clear all patterns
13209 */
13210
13211 do_clearPatterns = function() {
13212 userSimplificationsInListForm = [];
13213 return userSimplificationsInStringForm = [];
13214 };
13215
13216 Eval_clearpatterns = function() {
13217 do_clearPatterns();
13218 return push_symbol(NIL);
13219 };
13220
13221 Eval_patternsinfo = function() {
13222 var patternsinfoToBePrinted;
13223 patternsinfoToBePrinted = patternsinfo();
13224 if (patternsinfoToBePrinted !== "") {
13225 return new_string(patternsinfoToBePrinted);
13226 } else {
13227 return push_symbol(NIL);
13228 }
13229 };
13230
13231 patternsinfo = function() {
13232 var i, i1, len, patternsinfoToBePrinted;
13233 patternsinfoToBePrinted = "";
13234 for (i1 = 0, len = userSimplificationsInListForm.length; i1 < len; i1++) {
13235 i = userSimplificationsInListForm[i1];
13236 patternsinfoToBePrinted += userSimplificationsInListForm + "\n";
13237 }
13238 return patternsinfoToBePrinted;
13239 };
13240
13241
13242 /*
13243 Convert complex z to polar form
13244
13245 Input: push z
13246
13247 Output: Result on stack
13248
13249 polar(z) = abs(z) * exp(i * arg(z))
13250 */
13251
13252 Eval_polar = function() {
13253 push(cadr(p1));
13254 Eval();
13255 return polar();
13256 };
13257
13258 polar = function() {
13259 evaluatingPolar++;
13260 save();
13261 p1 = pop();
13262 push(p1);
13263 abs();
13264 push(imaginaryunit);
13265 push(p1);
13266 arg();
13267 multiply();
13268 exponential();
13269 multiply();
13270 evaluatingPolar--;
13271 return restore();
13272 };
13273
13274 n_factor_number = 0;
13275
13276 factor_number = function() {
13277 var h;
13278 h = 0;
13279 save();
13280 p1 = pop();
13281 if (equaln(p1, 0) || equaln(p1, 1) || equaln(p1, -1)) {
13282 push(p1);
13283 restore();
13284 return;
13285 }
13286 n_factor_number = p1.q.a;
13287 h = tos;
13288 factor_a();
13289 if (tos - h > 1) {
13290 list(tos - h);
13291 push_symbol(MULTIPLY);
13292 swap();
13293 cons();
13294 }
13295 return restore();
13296 };
13297
13298 factor_a = function() {
13299 var i1, k;
13300 k = 0;
13301 if (n_factor_number.isNegative()) {
13302 n_factor_number = setSignTo(n_factor_number, 1);
13303 push_integer(-1);
13304 }
13305 for (k = i1 = 0; i1 < 10000; k = ++i1) {
13306 try_kth_prime(k);
13307 if (n_factor_number.compare(1) === 0) {
13308 return;
13309 }
13310 }
13311 return factor_b();
13312 };
13313
13314 try_kth_prime = function(k) {
13315 var count, d, q, r, ref1;
13316 count = 0;
13317 d = mint(primetab[k]);
13318 count = 0;
13319 while (1) {
13320 if (n_factor_number.compare(1) === 0) {
13321 if (count) {
13322 push_factor(d, count);
13323 }
13324 return;
13325 }
13326 ref1 = mdivrem(n_factor_number, d), q = ref1[0], r = ref1[1];
13327 if (r.isZero()) {
13328 count++;
13329 n_factor_number = q;
13330 } else {
13331 break;
13332 }
13333 }
13334 if (count) {
13335 push_factor(d, count);
13336 }
13337 if (mcmp(q, d) === -1) {
13338 push_factor(n_factor_number, 1);
13339 return n_factor_number = mint(1);
13340 }
13341 };
13342
13343 factor_b = function() {
13344 var bigint_one, g, k, l, t, x, xprime;
13345 k = 0;
13346 l = 0;
13347 bigint_one = mint(1);
13348 x = mint(5);
13349 xprime = mint(2);
13350 k = 1;
13351 l = 1;
13352 while (1) {
13353 if (mprime(n_factor_number)) {
13354 push_factor(n_factor_number, 1);
13355 return 0;
13356 }
13357 while (1) {
13358 if (esc_flag) {
13359 stop("esc");
13360 }
13361 t = msub(xprime, x);
13362 t = setSignTo(t, 1);
13363 g = mgcd(t, n_factor_number);
13364 if (MEQUAL(g, 1)) {
13365 if (--k === 0) {
13366 xprime = x;
13367 l *= 2;
13368 k = l;
13369 }
13370 t = mmul(x, x);
13371 x = madd(t, bigint_one);
13372 t = mmod(x, n_factor_number);
13373 x = t;
13374 continue;
13375 }
13376 push_factor(g, 1);
13377 if (mcmp(g, n_factor_number) === 0) {
13378 return -1;
13379 }
13380 t = mdiv(n_factor_number, g);
13381 n_factor_number = t;
13382 t = mmod(x, n_factor_number);
13383 x = t;
13384 t = mmod(xprime, n_factor_number);
13385 xprime = t;
13386 break;
13387 }
13388 }
13389 };
13390
13391 push_factor = function(d, count) {
13392 p1 = new U();
13393 p1.k = NUM;
13394 p1.q.a = d;
13395 p1.q.b = mint(1);
13396 push(p1);
13397 if (count > 1) {
13398 push_symbol(POWER);
13399 swap();
13400 p1 = new U();
13401 p1.k = NUM;
13402 p1.q.a = mint(count);
13403 p1.q.b = mint(1);
13404 push(p1);
13405 return list(3);
13406 }
13407 };
13408
13409
13410 /* Power function
13411
13412 Input: push Base
13413
13414 push Exponent
13415
13416 Output: Result on stack
13417 */
13418
13419 DEBUG_POWER = false;
13420
13421 Eval_power = function() {
13422 if (DEBUG_POWER) {
13423 debugger;
13424 }
13425 push(cadr(p1));
13426 Eval();
13427 push(caddr(p1));
13428 Eval();
13429 return power();
13430 };
13431
13432 power = function() {
13433 save();
13434 yypower();
13435 return restore();
13436 };
13437
13438 yypower = function() {
13439 var b_isEven_and_c_isItsInverse, hopefullySimplified, inputBase, inputExp, isThisOne, is_a_moreThanZero, n;
13440 if (DEBUG_POWER) {
13441 debugger;
13442 }
13443 n = 0;
13444 p2 = pop();
13445 p1 = pop();
13446 inputExp = p2;
13447 inputBase = p1;
13448 if (DEBUG_POWER) {
13449 console.log("POWER: " + p1 + " ^ " + p2);
13450 }
13451 if (equal(p1, one) || iszero(p2)) {
13452 if (evaluatingAsFloats) {
13453 push_double(1.0);
13454 } else {
13455 push(one);
13456 }
13457 if (DEBUG_POWER) {
13458 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13459 }
13460 return;
13461 }
13462 if (equal(p2, one)) {
13463 push(p1);
13464 if (DEBUG_POWER) {
13465 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13466 }
13467 return;
13468 }
13469 if (isminusone(p1) && isminusone(p2)) {
13470 if (evaluatingAsFloats) {
13471 push_double(1.0);
13472 } else {
13473 push(one);
13474 }
13475 negate();
13476 if (DEBUG_POWER) {
13477 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13478 }
13479 return;
13480 }
13481 if (isminusone(p1) && (isoneovertwo(p2))) {
13482 push(imaginaryunit);
13483 if (DEBUG_POWER) {
13484 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13485 }
13486 return;
13487 }
13488 if (isminusone(p1) && isminusoneovertwo(p2)) {
13489 push(imaginaryunit);
13490 negate();
13491 if (DEBUG_POWER) {
13492 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13493 }
13494 return;
13495 }
13496 if (isminusone(p1) && !isdouble(p1) && isrational(p2) && !isinteger(p2) && ispositivenumber(p2) && !evaluatingAsFloats) {
13497 if (DEBUG_POWER) {
13498 console.log(" power: -1 ^ rational");
13499 }
13500 if (DEBUG_POWER) {
13501 console.log(" trick: p2.q.a , p2.q.b " + p2.q.a + " , " + p2.q.b);
13502 }
13503 if (p2.q.a < p2.q.b) {
13504 push_symbol(POWER);
13505 push(p1);
13506 push(p2);
13507 list(3);
13508 } else {
13509 push_symbol(MULTIPLY);
13510 push(p1);
13511 push_symbol(POWER);
13512 push(p1);
13513 push_rational(p2.q.a.mod(p2.q.b), p2.q.b);
13514 list(3);
13515 list(3);
13516 if (DEBUG_POWER) {
13517 console.log(" trick applied : " + stack[tos - 1]);
13518 }
13519 }
13520 rect();
13521 if (DEBUG_POWER) {
13522 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13523 }
13524 return;
13525 }
13526 if (isrational(p1) && isrational(p2)) {
13527 if (DEBUG_POWER) {
13528 console.log(" power: isrational(p1) && isrational(p2)");
13529 }
13530 push(p1);
13531 push(p2);
13532 qpow();
13533 if (DEBUG_POWER) {
13534 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13535 }
13536 return;
13537 }
13538 if (isnum(p1) && isnum(p2)) {
13539 if (DEBUG_POWER) {
13540 console.log(" power: both base and exponent are either rational or double ");
13541 }
13542 if (DEBUG_POWER) {
13543 console.log("POWER - isnum(p1) && isnum(p2)");
13544 }
13545 push(p1);
13546 push(p2);
13547 dpow();
13548 if (DEBUG_POWER) {
13549 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13550 }
13551 return;
13552 }
13553 if (istensor(p1)) {
13554 if (DEBUG_POWER) {
13555 console.log(" power: istensor(p1) ");
13556 }
13557 power_tensor();
13558 if (DEBUG_POWER) {
13559 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13560 }
13561 return;
13562 }
13563 if (car(p1) === symbol(ABS) && iseveninteger(p2) && !iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
13564 if (DEBUG_POWER) {
13565 console.log(" power: even power of absolute of real value ");
13566 }
13567 push(cadr(p1));
13568 push(p2);
13569 power();
13570 if (DEBUG_POWER) {
13571 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13572 }
13573 return;
13574 }
13575 if (p1 === symbol(E) && car(p2) === symbol(LOG)) {
13576 push(cadr(p2));
13577 if (DEBUG_POWER) {
13578 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13579 }
13580 return;
13581 }
13582 if (p1 === symbol(E) && isdouble(p2)) {
13583 if (DEBUG_POWER) {
13584 console.log(" power: p1 == symbol(E) && isdouble(p2) ");
13585 }
13586 push_double(Math.exp(p2.d));
13587 if (DEBUG_POWER) {
13588 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13589 }
13590 return;
13591 }
13592 if (p1 === symbol(E) && Find(p2, imaginaryunit) !== 0 && Find(p2, symbol(PI)) !== 0 && !evaluatingPolar) {
13593 push_symbol(POWER);
13594 push(p1);
13595 push(p2);
13596 list(3);
13597 if (DEBUG_POWER) {
13598 console.log(" power: turning complex exponential to rect: " + stack[tos - 1]);
13599 }
13600 rect();
13601 hopefullySimplified = pop();
13602 if (Find(hopefullySimplified, symbol(PI)) === 0) {
13603 if (DEBUG_POWER) {
13604 console.log(" power: turned complex exponential to rect: " + hopefullySimplified);
13605 }
13606 push(hopefullySimplified);
13607 return;
13608 }
13609 }
13610 if (car(p1) === symbol(MULTIPLY) && isinteger(p2)) {
13611 if (DEBUG_POWER) {
13612 console.log(" power: (a * b) ^ c -> (a ^ c) * (b ^ c) ");
13613 }
13614 p1 = cdr(p1);
13615 push(car(p1));
13616 push(p2);
13617 power();
13618 p1 = cdr(p1);
13619 while (iscons(p1)) {
13620 push(car(p1));
13621 push(p2);
13622 power();
13623 multiply();
13624 p1 = cdr(p1);
13625 }
13626 if (DEBUG_POWER) {
13627 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13628 }
13629 return;
13630 }
13631 is_a_moreThanZero = false;
13632 if (isnum(cadr(p1))) {
13633 is_a_moreThanZero = sign(compare_numbers(cadr(p1), zero));
13634 }
13635 if (car(p1) === symbol(POWER) && (isinteger(p2) || is_a_moreThanZero)) {
13636 push(cadr(p1));
13637 push(caddr(p1));
13638 push(p2);
13639 multiply();
13640 power();
13641 if (DEBUG_POWER) {
13642 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13643 }
13644 return;
13645 }
13646 b_isEven_and_c_isItsInverse = false;
13647 if (iseveninteger(caddr(p1))) {
13648 push(caddr(p1));
13649 push(p2);
13650 multiply();
13651 isThisOne = pop();
13652 if (isone(isThisOne)) {
13653 b_isEven_and_c_isItsInverse = true;
13654 }
13655 }
13656 if (car(p1) === symbol(POWER) && b_isEven_and_c_isItsInverse) {
13657 if (DEBUG_POWER) {
13658 console.log(" power: car(p1) == symbol(POWER) && b_isEven_and_c_isItsInverse ");
13659 }
13660 push(cadr(p1));
13661 abs();
13662 if (DEBUG_POWER) {
13663 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13664 }
13665 return;
13666 }
13667 if (expanding && isadd(p1) && isnum(p2)) {
13668 push(p2);
13669 n = pop_integer();
13670 if (n > 1 && !isNaN(n)) {
13671 if (DEBUG_POWER) {
13672 console.log(" power: expanding && isadd(p1) && isnum(p2) ");
13673 }
13674 power_sum(n);
13675 if (DEBUG_POWER) {
13676 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13677 }
13678 return;
13679 }
13680 }
13681 if (trigmode === 1 && car(p1) === symbol(SIN) && iseveninteger(p2)) {
13682 if (DEBUG_POWER) {
13683 console.log(" power: trigmode == 1 && car(p1) == symbol(SIN) && iseveninteger(p2) ");
13684 }
13685 push_integer(1);
13686 push(cadr(p1));
13687 cosine();
13688 push_integer(2);
13689 power();
13690 subtract();
13691 push(p2);
13692 push_rational(1, 2);
13693 multiply();
13694 power();
13695 if (DEBUG_POWER) {
13696 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13697 }
13698 return;
13699 }
13700 if (trigmode === 2 && car(p1) === symbol(COS) && iseveninteger(p2)) {
13701 if (DEBUG_POWER) {
13702 console.log(" power: trigmode == 2 && car(p1) == symbol(COS) && iseveninteger(p2) ");
13703 }
13704 push_integer(1);
13705 push(cadr(p1));
13706 sine();
13707 push_integer(2);
13708 power();
13709 subtract();
13710 push(p2);
13711 push_rational(1, 2);
13712 multiply();
13713 power();
13714 if (DEBUG_POWER) {
13715 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13716 }
13717 return;
13718 }
13719 if (iscomplexnumber(p1)) {
13720 if (DEBUG_POWER) {
13721 console.log(" power - handling the case (a + ib) ^ n");
13722 }
13723 if (isinteger(p2)) {
13724 push(p1);
13725 conjugate();
13726 p3 = pop();
13727 push(p3);
13728 push(p3);
13729 push(p1);
13730 multiply();
13731 divide();
13732 if (!isone(p2)) {
13733 push(p2);
13734 negate();
13735 power();
13736 }
13737 if (DEBUG_POWER) {
13738 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13739 }
13740 return;
13741 }
13742 if (isnum(p2)) {
13743 push(p1);
13744 abs();
13745 push(p2);
13746 power();
13747 push_integer(-1);
13748 push(p1);
13749 arg();
13750 push(p2);
13751 multiply();
13752 if (evaluatingAsFloats || (iscomplexnumberdouble(p1) && isdouble(p2))) {
13753 push_double(Math.PI);
13754 } else {
13755 push(symbol(PI));
13756 }
13757 divide();
13758 power();
13759 multiply();
13760 if (avoidCalculatingPowersIntoArctans) {
13761 if (Find(stack[tos - 1], symbol(ARCTAN))) {
13762 pop();
13763 push_symbol(POWER);
13764 push(p1);
13765 push(p2);
13766 list(3);
13767 }
13768 }
13769 if (DEBUG_POWER) {
13770 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13771 }
13772 return;
13773 }
13774 }
13775 if (simplify_polar()) {
13776 if (DEBUG_POWER) {
13777 console.log(" power: using simplify_polar");
13778 }
13779 return;
13780 }
13781 if (DEBUG_POWER) {
13782 console.log(" power: nothing can be done ");
13783 }
13784 push_symbol(POWER);
13785 push(p1);
13786 push(p2);
13787 list(3);
13788 if (DEBUG_POWER) {
13789 return console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13790 }
13791 };
13792
13793 power_sum = function(n) {
13794 var a, i, i1, j, j1, k, l1, ref1, ref2, ref3;
13795 a = [];
13796 i = 0;
13797 j = 0;
13798 k = 0;
13799 k = length(p1) - 1;
13800 push_frame(k * (n + 1));
13801 p1 = cdr(p1);
13802 for (i = i1 = 0, ref1 = k; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
13803 for (j = j1 = 0, ref2 = n; 0 <= ref2 ? j1 <= ref2 : j1 >= ref2; j = 0 <= ref2 ? ++j1 : --j1) {
13804 push(car(p1));
13805 push_integer(j);
13806 power();
13807 stack[frame + i * (n + 1) + j] = pop();
13808 }
13809 p1 = cdr(p1);
13810 }
13811 push_integer(n);
13812 factorial();
13813 p1 = pop();
13814 for (i = l1 = 0, ref3 = k; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
13815 a[i] = 0;
13816 }
13817 push(zero);
13818 multinomial_sum(k, n, a, 0, n);
13819 return pop_frame(k * (n + 1));
13820 };
13821
13822 multinomial_sum = function(k, n, a, i, m) {
13823 var i1, j, j1, l1, ref1, ref2, ref3;
13824 j = 0;
13825 if (i < k - 1) {
13826 for (j = i1 = 0, ref1 = m; 0 <= ref1 ? i1 <= ref1 : i1 >= ref1; j = 0 <= ref1 ? ++i1 : --i1) {
13827 a[i] = j;
13828 multinomial_sum(k, n, a, i + 1, m - j);
13829 }
13830 return;
13831 }
13832 a[i] = m;
13833 push(p1);
13834 for (j = j1 = 0, ref2 = k; 0 <= ref2 ? j1 < ref2 : j1 > ref2; j = 0 <= ref2 ? ++j1 : --j1) {
13835 push_integer(a[j]);
13836 factorial();
13837 divide();
13838 }
13839 for (j = l1 = 0, ref3 = k; 0 <= ref3 ? l1 < ref3 : l1 > ref3; j = 0 <= ref3 ? ++l1 : --l1) {
13840 push(stack[frame + j * (n + 1) + a[j]]);
13841 multiply();
13842 }
13843 return add();
13844 };
13845
13846 simplify_polar = function() {
13847 var doNothing, n;
13848 n = 0;
13849 n = isquarterturn(p2);
13850 switch (n) {
13851 case 0:
13852 doNothing = 1;
13853 break;
13854 case 1:
13855 push_integer(1);
13856 return 1;
13857 case 2:
13858 push_integer(-1);
13859 return 1;
13860 case 3:
13861 push(imaginaryunit);
13862 return 1;
13863 case 4:
13864 push(imaginaryunit);
13865 negate();
13866 return 1;
13867 }
13868 if (car(p2) === symbol(ADD)) {
13869 p3 = cdr(p2);
13870 while (iscons(p3)) {
13871 n = isquarterturn(car(p3));
13872 if (n) {
13873 break;
13874 }
13875 p3 = cdr(p3);
13876 }
13877 switch (n) {
13878 case 0:
13879 return 0;
13880 case 1:
13881 push_integer(1);
13882 break;
13883 case 2:
13884 push_integer(-1);
13885 break;
13886 case 3:
13887 push(imaginaryunit);
13888 break;
13889 case 4:
13890 push(imaginaryunit);
13891 negate();
13892 }
13893 push(p2);
13894 push(car(p3));
13895 subtract();
13896 exponential();
13897 multiply();
13898 return 1;
13899 }
13900 return 0;
13901 };
13902
13903 Eval_prime = function() {
13904 push(cadr(p1));
13905 Eval();
13906 return prime();
13907 };
13908
13909 prime = function() {
13910 var n;
13911 n = 0;
13912 n = pop_integer();
13913 if (n < 1 || n > MAXPRIMETAB) {
13914 stop("prime: Argument out of range.");
13915 }
13916 n = primetab[n - 1];
13917 return push_integer(n);
13918 };
13919
13920 power_str = "^";
13921
13922 codeGen = false;
13923
13924 Eval_print = function() {
13925 stringsEmittedByUserPrintouts += _print(cdr(p1), environment_printmode);
13926 return push(symbol(NIL));
13927 };
13928
13929 Eval_print2dascii = function() {
13930 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_2DASCII);
13931 return push(symbol(NIL));
13932 };
13933
13934 Eval_printfull = function() {
13935 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_FULL);
13936 return push(symbol(NIL));
13937 };
13938
13939 Eval_printlatex = function() {
13940 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_LATEX);
13941 return push(symbol(NIL));
13942 };
13943
13944 Eval_printplain = function() {
13945 var original_test_flag;
13946 original_test_flag = test_flag;
13947 test_flag = 0;
13948 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_PLAIN);
13949 test_flag = original_test_flag;
13950 return push(symbol(NIL));
13951 };
13952
13953 Eval_printlist = function() {
13954 var beenPrinted;
13955 beenPrinted = _print(cdr(p1), PRINTMODE_LIST);
13956 stringsEmittedByUserPrintouts += beenPrinted;
13957 return push(symbol(NIL));
13958 };
13959
13960 _print = function(p, passedPrintMode) {
13961 var accumulator, origPrintMode;
13962 accumulator = "";
13963 while (iscons(p)) {
13964 push(car(p));
13965 Eval();
13966 p2 = pop();
13967
13968 /*
13969 if (issymbol(car(p)) && car(p) != p2)
13970 push_symbol(SETQ);
13971 push(car(p));
13972 push(p2);
13973 list(3);
13974 p2 = pop();
13975 */
13976 origPrintMode = printMode;
13977 if (passedPrintMode === PRINTMODE_FULL) {
13978 printMode = PRINTMODE_FULL;
13979 accumulator = printline(p2);
13980 rememberPrint(accumulator, LAST_FULL_PRINT);
13981 } else if (passedPrintMode === PRINTMODE_PLAIN) {
13982 printMode = PRINTMODE_PLAIN;
13983 accumulator = printline(p2);
13984 rememberPrint(accumulator, LAST_PLAIN_PRINT);
13985 } else if (passedPrintMode === PRINTMODE_2DASCII) {
13986 printMode = PRINTMODE_2DASCII;
13987 accumulator = print2dascii(p2);
13988 rememberPrint(accumulator, LAST_2DASCII_PRINT);
13989 } else if (passedPrintMode === PRINTMODE_LATEX) {
13990 printMode = PRINTMODE_LATEX;
13991 accumulator = printline(p2);
13992 rememberPrint(accumulator, LAST_LATEX_PRINT);
13993 } else if (passedPrintMode === PRINTMODE_LIST) {
13994 printMode = PRINTMODE_LIST;
13995 accumulator = print_list(p2);
13996 rememberPrint(accumulator, LAST_LIST_PRINT);
13997 }
13998 printMode = origPrintMode;
13999 p = cdr(p);
14000 }
14001 if (DEBUG) {
14002 console.log("emttedString from display: " + stringsEmittedByUserPrintouts);
14003 }
14004 return accumulator;
14005 };
14006
14007 rememberPrint = function(theString, theTypeOfPrint) {
14008 var parsedString;
14009 scan('"' + theString + '"');
14010 parsedString = pop();
14011 return set_binding(symbol(theTypeOfPrint), parsedString);
14012 };
14013
14014 print_str = function(s) {
14015 if (DEBUG) {
14016 console.log("emttedString from print_str: " + stringsEmittedByUserPrintouts);
14017 }
14018 return s;
14019 };
14020
14021 print_char = function(c) {
14022 return c;
14023 };
14024
14025 collectLatexStringFromReturnValue = function(p) {
14026 var origPrintMode, originalCodeGen, returnedString;
14027 origPrintMode = printMode;
14028 printMode = PRINTMODE_LATEX;
14029 originalCodeGen = codeGen;
14030 codeGen = false;
14031 returnedString = print_expr(p);
14032 returnedString = returnedString.replace(/_/g, "\\_");
14033 printMode = origPrintMode;
14034 codeGen = originalCodeGen;
14035 if (DEBUG) {
14036 console.log("emttedString from collectLatexStringFromReturnValue: " + stringsEmittedByUserPrintouts);
14037 }
14038 return returnedString;
14039 };
14040
14041 printline = function(p) {
14042 var accumulator;
14043 accumulator = "";
14044 accumulator += print_expr(p);
14045 return accumulator;
14046 };
14047
14048 print_base_of_denom = function(p1) {
14049 var accumulator;
14050 accumulator = "";
14051 if (isfraction(p1) || car(p1) === symbol(ADD) || car(p1) === symbol(MULTIPLY) || car(p1) === symbol(POWER) || lessp(p1, zero)) {
14052 accumulator += print_char('(');
14053 accumulator += print_expr(p1);
14054 accumulator += print_char(')');
14055 } else {
14056 accumulator += print_expr(p1);
14057 }
14058 return accumulator;
14059 };
14060
14061 print_expo_of_denom = function(p2) {
14062 var accumulator;
14063 accumulator = "";
14064 if (isfraction(p2) || car(p2) === symbol(ADD) || car(p2) === symbol(MULTIPLY) || car(p2) === symbol(POWER)) {
14065 accumulator += print_char('(');
14066 accumulator += print_expr(p2);
14067 accumulator += print_char(')');
14068 } else {
14069 accumulator += print_expr(p2);
14070 }
14071 return accumulator;
14072 };
14073
14074 print_denom = function(p, d) {
14075 var accumulator;
14076 accumulator = "";
14077 save();
14078 p1 = cadr(p);
14079 p2 = caddr(p);
14080 if (isminusone(p2)) {
14081 accumulator += print_base_of_denom(p1);
14082 restore();
14083 return accumulator;
14084 }
14085 if (d === 1) {
14086 accumulator += print_char('(');
14087 }
14088 push(p2);
14089 negate();
14090 p2 = pop();
14091 accumulator += print_power(p1, p2);
14092 if (d === 1) {
14093 accumulator += print_char(')');
14094 }
14095 restore();
14096 return accumulator;
14097 };
14098
14099 print_a_over_b = function(p) {
14100 var accumulator, d, doNothing, n;
14101 accumulator = "";
14102 flag = 0;
14103 n = 0;
14104 d = 0;
14105 save();
14106 n = 0;
14107 d = 0;
14108 p1 = cdr(p);
14109 p2 = car(p1);
14110 if (isrational(p2)) {
14111 push(p2);
14112 mp_numerator();
14113 absval();
14114 p3 = pop();
14115 push(p2);
14116 mp_denominator();
14117 p4 = pop();
14118 if (!isplusone(p3)) {
14119 n++;
14120 }
14121 if (!isplusone(p4)) {
14122 d++;
14123 }
14124 p1 = cdr(p1);
14125 } else {
14126 p3 = one;
14127 p4 = one;
14128 }
14129 while (iscons(p1)) {
14130 p2 = car(p1);
14131 if (is_denominator(p2)) {
14132 d++;
14133 } else {
14134 n++;
14135 }
14136 p1 = cdr(p1);
14137 }
14138 if (printMode === PRINTMODE_LATEX) {
14139 accumulator += print_str('\\frac{');
14140 }
14141 if (n === 0) {
14142 accumulator += print_char('1');
14143 } else {
14144 flag = 0;
14145 p1 = cdr(p);
14146 if (isrational(car(p1))) {
14147 p1 = cdr(p1);
14148 }
14149 if (!isplusone(p3)) {
14150 accumulator += print_factor(p3);
14151 flag = 1;
14152 }
14153 while (iscons(p1)) {
14154 p2 = car(p1);
14155 if (is_denominator(p2)) {
14156 doNothing = 1;
14157 } else {
14158 if (flag) {
14159 accumulator += print_multiply_sign();
14160 }
14161 accumulator += print_factor(p2);
14162 flag = 1;
14163 }
14164 p1 = cdr(p1);
14165 }
14166 }
14167 if (printMode === PRINTMODE_LATEX) {
14168 accumulator += print_str('}{');
14169 } else if (printMode === PRINTMODE_PLAIN && !test_flag) {
14170 accumulator += print_str(" / ");
14171 } else {
14172 accumulator += print_str("/");
14173 }
14174 if (d > 1 && printMode !== PRINTMODE_LATEX) {
14175 accumulator += print_char('(');
14176 }
14177 flag = 0;
14178 p1 = cdr(p);
14179 if (isrational(car(p1))) {
14180 p1 = cdr(p1);
14181 }
14182 if (!isplusone(p4)) {
14183 accumulator += print_factor(p4);
14184 flag = 1;
14185 }
14186 while (iscons(p1)) {
14187 p2 = car(p1);
14188 if (is_denominator(p2)) {
14189 if (flag) {
14190 accumulator += print_multiply_sign();
14191 }
14192 accumulator += print_denom(p2, d);
14193 flag = 1;
14194 }
14195 p1 = cdr(p1);
14196 }
14197 if (d > 1 && printMode !== PRINTMODE_LATEX) {
14198 accumulator += print_char(')');
14199 }
14200 if (printMode === PRINTMODE_LATEX) {
14201 accumulator += print_str('}');
14202 }
14203 restore();
14204 return accumulator;
14205 };
14206
14207 print_expr = function(p) {
14208 var accumulator;
14209 accumulator = "";
14210 if (isadd(p)) {
14211 p = cdr(p);
14212 if (sign_of_term(car(p)) === '-') {
14213 accumulator += print_str("-");
14214 }
14215 accumulator += print_term(car(p));
14216 p = cdr(p);
14217 while (iscons(p)) {
14218 if (sign_of_term(car(p)) === '+') {
14219 if (printMode === PRINTMODE_PLAIN && !test_flag) {
14220 accumulator += print_str(" + ");
14221 } else {
14222 accumulator += print_str("+");
14223 }
14224 } else {
14225 if (printMode === PRINTMODE_PLAIN && !test_flag) {
14226 accumulator += print_str(" - ");
14227 } else {
14228 accumulator += print_str("-");
14229 }
14230 }
14231 accumulator += print_term(car(p));
14232 p = cdr(p);
14233 }
14234 } else {
14235 if (sign_of_term(p) === '-') {
14236 accumulator += print_str("-");
14237 }
14238 accumulator += print_term(p);
14239 }
14240 return accumulator;
14241 };
14242
14243 sign_of_term = function(p) {
14244 var accumulator;
14245 accumulator = "";
14246 if (car(p) === symbol(MULTIPLY) && isnum(cadr(p)) && lessp(cadr(p), zero)) {
14247 accumulator += '-';
14248 } else if (isnum(p) && lessp(p, zero)) {
14249 accumulator += '-';
14250 } else {
14251 accumulator += '+';
14252 }
14253 return accumulator;
14254 };
14255
14256 print_term = function(p) {
14257 var accumulator, denom, numberOneOverSomething, origAccumulator, previousFactorWasANumber;
14258 accumulator = "";
14259 if (car(p) === symbol(MULTIPLY) && any_denominators(p)) {
14260 accumulator += print_a_over_b(p);
14261 return accumulator;
14262 }
14263 if (car(p) === symbol(MULTIPLY)) {
14264 p = cdr(p);
14265 if (isminusone(car(p))) {
14266 p = cdr(p);
14267 }
14268 previousFactorWasANumber = false;
14269 if (isnum(car(p))) {
14270 previousFactorWasANumber = true;
14271 }
14272 numberOneOverSomething = false;
14273 if (printMode === PRINTMODE_LATEX && iscons(cdr(p)) && isnumberoneoversomething(car(p))) {
14274 numberOneOverSomething = true;
14275 denom = car(p).q.b.toString();
14276 }
14277 if (numberOneOverSomething) {
14278 origAccumulator = accumulator;
14279 accumulator = "";
14280 } else {
14281 accumulator += print_factor(car(p));
14282 }
14283 p = cdr(p);
14284 while (iscons(p)) {
14285 if (printMode === PRINTMODE_LATEX) {
14286 if (previousFactorWasANumber) {
14287 if (caar(p) === symbol(POWER)) {
14288 if (isnum(car(cdr(car(p))))) {
14289 if (!isfraction(car(cdr(cdr(car(p)))))) {
14290 accumulator += " \\cdot ";
14291 }
14292 }
14293 }
14294 }
14295 }
14296 accumulator += print_multiply_sign();
14297 accumulator += print_factor(car(p));
14298 previousFactorWasANumber = false;
14299 if (isnum(car(p))) {
14300 previousFactorWasANumber = true;
14301 }
14302 p = cdr(p);
14303 }
14304 if (numberOneOverSomething) {
14305 accumulator = origAccumulator + "\\frac{" + accumulator + "}{" + denom + "}";
14306 }
14307 } else {
14308 accumulator += print_factor(p);
14309 }
14310 return accumulator;
14311 };
14312
14313 print_subexpr = function(p) {
14314 var accumulator;
14315 accumulator = "";
14316 accumulator += print_char('(');
14317 accumulator += print_expr(p);
14318 accumulator += print_char(')');
14319 return accumulator;
14320 };
14321
14322 print_factorial_function = function(p) {
14323 var accumulator;
14324 accumulator = "";
14325 p = cadr(p);
14326 if (car(p) === symbol(ADD) || car(p) === symbol(MULTIPLY) || car(p) === symbol(POWER) || car(p) === symbol(FACTORIAL)) {
14327 accumulator += print_subexpr(p);
14328 } else {
14329 accumulator += print_expr(p);
14330 }
14331 accumulator += print_char('!');
14332 return accumulator;
14333 };
14334
14335 print_ABS_latex = function(p) {
14336 var accumulator;
14337 accumulator = "";
14338 accumulator += print_str("\\left |");
14339 accumulator += print_expr(cadr(p));
14340 accumulator += print_str(" \\right |");
14341 return accumulator;
14342 };
14343
14344 print_BINOMIAL_latex = function(p) {
14345 var accumulator;
14346 accumulator = "";
14347 accumulator += print_str("\\binom{");
14348 accumulator += print_expr(cadr(p));
14349 accumulator += print_str("}{");
14350 accumulator += print_expr(caddr(p));
14351 accumulator += print_str("} ");
14352 return accumulator;
14353 };
14354
14355 print_DOT_latex = function(p) {
14356 var accumulator;
14357 accumulator = "";
14358 accumulator += print_expr(cadr(p));
14359 accumulator += print_str(" \\cdot ");
14360 accumulator += print_expr(caddr(p));
14361 return accumulator;
14362 };
14363
14364 print_DOT_codegen = function(p) {
14365 var accumulator;
14366 accumulator = "dot(";
14367 accumulator += print_expr(cadr(p));
14368 accumulator += ", ";
14369 accumulator += print_expr(caddr(p));
14370 accumulator += ")";
14371 return accumulator;
14372 };
14373
14374 print_SIN_codegen = function(p) {
14375 var accumulator;
14376 accumulator = "Math.sin(";
14377 accumulator += print_expr(cadr(p));
14378 accumulator += ")";
14379 return accumulator;
14380 };
14381
14382 print_COS_codegen = function(p) {
14383 var accumulator;
14384 accumulator = "Math.cos(";
14385 accumulator += print_expr(cadr(p));
14386 accumulator += ")";
14387 return accumulator;
14388 };
14389
14390 print_TAN_codegen = function(p) {
14391 var accumulator;
14392 accumulator = "Math.tan(";
14393 accumulator += print_expr(cadr(p));
14394 accumulator += ")";
14395 return accumulator;
14396 };
14397
14398 print_ARCSIN_codegen = function(p) {
14399 var accumulator;
14400 accumulator = "Math.asin(";
14401 accumulator += print_expr(cadr(p));
14402 accumulator += ")";
14403 return accumulator;
14404 };
14405
14406 print_ARCCOS_codegen = function(p) {
14407 var accumulator;
14408 accumulator = "Math.acos(";
14409 accumulator += print_expr(cadr(p));
14410 accumulator += ")";
14411 return accumulator;
14412 };
14413
14414 print_ARCTAN_codegen = function(p) {
14415 var accumulator;
14416 accumulator = "Math.atan(";
14417 accumulator += print_expr(cadr(p));
14418 accumulator += ")";
14419 return accumulator;
14420 };
14421
14422 print_SQRT_latex = function(p) {
14423 var accumulator;
14424 accumulator = "";
14425 accumulator += print_str("\\sqrt{");
14426 accumulator += print_expr(cadr(p));
14427 accumulator += print_str("} ");
14428 return accumulator;
14429 };
14430
14431 print_TRANSPOSE_latex = function(p) {
14432 var accumulator;
14433 accumulator = "";
14434 accumulator += print_str("{");
14435 if (iscons(cadr(p))) {
14436 accumulator += print_str('(');
14437 }
14438 accumulator += print_expr(cadr(p));
14439 if (iscons(cadr(p))) {
14440 accumulator += print_str(')');
14441 }
14442 accumulator += print_str("}");
14443 accumulator += print_str("^T");
14444 return accumulator;
14445 };
14446
14447 print_TRANSPOSE_codegen = function(p) {
14448 var accumulator;
14449 accumulator = "";
14450 accumulator += print_str("transpose(");
14451 accumulator += print_expr(cadr(p));
14452 accumulator += print_str(')');
14453 return accumulator;
14454 };
14455
14456 print_UNIT_codegen = function(p) {
14457 var accumulator;
14458 accumulator = "";
14459 accumulator += print_str("identity(");
14460 accumulator += print_expr(cadr(p));
14461 accumulator += print_str(')');
14462 return accumulator;
14463 };
14464
14465 print_INV_latex = function(p) {
14466 var accumulator;
14467 accumulator = "";
14468 accumulator += print_str("{");
14469 if (iscons(cadr(p))) {
14470 accumulator += print_str('(');
14471 }
14472 accumulator += print_expr(cadr(p));
14473 if (iscons(cadr(p))) {
14474 accumulator += print_str(')');
14475 }
14476 accumulator += print_str("}");
14477 accumulator += print_str("^{-1}");
14478 return accumulator;
14479 };
14480
14481 print_INV_codegen = function(p) {
14482 var accumulator;
14483 accumulator = "";
14484 accumulator += print_str("inv(");
14485 accumulator += print_expr(cadr(p));
14486 accumulator += print_str(')');
14487 return accumulator;
14488 };
14489
14490 print_DEFINT_latex = function(p) {
14491 var accumulator, functionBody, i, i1, numberOfIntegrals, originalIntegral, ref1, theIntegral, theVariable;
14492 accumulator = "";
14493 functionBody = car(cdr(p));
14494 p = cdr(p);
14495 originalIntegral = p;
14496 numberOfIntegrals = 0;
14497 while (iscons(cdr(cdr(p)))) {
14498 numberOfIntegrals++;
14499 theIntegral = cdr(cdr(p));
14500 accumulator += print_str("\\int^{");
14501 accumulator += print_expr(car(cdr(theIntegral)));
14502 accumulator += print_str("}_{");
14503 accumulator += print_expr(car(theIntegral));
14504 accumulator += print_str("} \\! ");
14505 p = cdr(theIntegral);
14506 }
14507 accumulator += print_expr(functionBody);
14508 accumulator += print_str(" \\,");
14509 p = originalIntegral;
14510 for (i = i1 = 1, ref1 = numberOfIntegrals; 1 <= ref1 ? i1 <= ref1 : i1 >= ref1; i = 1 <= ref1 ? ++i1 : --i1) {
14511 theVariable = cdr(p);
14512 accumulator += print_str(" \\mathrm{d} ");
14513 accumulator += print_expr(car(theVariable));
14514 if (i < numberOfIntegrals) {
14515 accumulator += print_str(" \\, ");
14516 }
14517 p = cdr(cdr(theVariable));
14518 }
14519 return accumulator;
14520 };
14521
14522 print_tensor = function(p) {
14523 var accumulator;
14524 accumulator = "";
14525 accumulator += print_tensor_inner(p, 0, 0)[1];
14526 return accumulator;
14527 };
14528
14529 print_tensor_inner = function(p, j, k) {
14530 var accumulator, i, i1, j1, ref1, ref2, ref3, retString;
14531 accumulator = "";
14532 accumulator += print_str("[");
14533 if (j < p.tensor.ndim - 1) {
14534 for (i = i1 = 0, ref1 = p.tensor.dim[j]; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
14535 ref2 = print_tensor_inner(p, j + 1, k), k = ref2[0], retString = ref2[1];
14536 accumulator += retString;
14537 if (i !== p.tensor.dim[j] - 1) {
14538 accumulator += print_str(",");
14539 }
14540 }
14541 } else {
14542 for (i = j1 = 0, ref3 = p.tensor.dim[j]; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
14543 accumulator += print_expr(p.tensor.elem[k]);
14544 if (i !== p.tensor.dim[j] - 1) {
14545 accumulator += print_str(",");
14546 }
14547 k++;
14548 }
14549 }
14550 accumulator += print_str("]");
14551 return [k, accumulator];
14552 };
14553
14554 print_tensor_latex = function(p) {
14555 var accumulator;
14556 accumulator = "";
14557 if (p.tensor.ndim <= 2) {
14558 accumulator += print_tensor_inner_latex(true, p, 0, 0)[1];
14559 }
14560 return accumulator;
14561 };
14562
14563 print_tensor_inner_latex = function(firstLevel, p, j, k) {
14564 var accumulator, i, i1, j1, ref1, ref2, ref3, retString;
14565 accumulator = "";
14566 if (firstLevel) {
14567 accumulator += "\\begin{bmatrix} ";
14568 }
14569 if (j < p.tensor.ndim - 1) {
14570 for (i = i1 = 0, ref1 = p.tensor.dim[j]; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
14571 ref2 = print_tensor_inner_latex(0, p, j + 1, k), k = ref2[0], retString = ref2[1];
14572 accumulator += retString;
14573 if (i !== p.tensor.dim[j] - 1) {
14574 accumulator += print_str(" \\\\ ");
14575 }
14576 }
14577 } else {
14578 for (i = j1 = 0, ref3 = p.tensor.dim[j]; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
14579 accumulator += print_expr(p.tensor.elem[k]);
14580 if (i !== p.tensor.dim[j] - 1) {
14581 accumulator += print_str(" & ");
14582 }
14583 k++;
14584 }
14585 }
14586 if (firstLevel) {
14587 accumulator += " \\end{bmatrix}";
14588 }
14589 return [k, accumulator];
14590 };
14591
14592 print_SUM_latex = function(p) {
14593 var accumulator;
14594 accumulator = "\\sum_{";
14595 accumulator += print_expr(caddr(p));
14596 accumulator += "=";
14597 accumulator += print_expr(cadddr(p));
14598 accumulator += "}^{";
14599 accumulator += print_expr(caddddr(p));
14600 accumulator += "}{";
14601 accumulator += print_expr(cadr(p));
14602 accumulator += "}";
14603 return accumulator;
14604 };
14605
14606 print_SUM_codegen = function(p) {
14607 var accumulator, body, lowerlimit, upperlimit, variable;
14608 body = cadr(p);
14609 variable = caddr(p);
14610 lowerlimit = cadddr(p);
14611 upperlimit = caddddr(p);
14612 accumulator = "(function(){" + " var " + variable + "; " + " var holderSum = 0; " + " var lowerlimit = " + print_expr(lowerlimit) + "; " + " var upperlimit = " + print_expr(upperlimit) + "; " + " for (" + variable + " = lowerlimit; " + variable + " < upperlimit; " + variable + "++) { " + " holderSum += " + print_expr(body) + ";" + " } " + " return holderSum;" + "})()";
14613 return accumulator;
14614 };
14615
14616 print_TEST_latex = function(p) {
14617 var accumulator;
14618 accumulator = "\\left\\{ \\begin{array}{ll}";
14619 p = cdr(p);
14620 while (iscons(p)) {
14621 if (cdr(p) === symbol(NIL)) {
14622 accumulator += "{";
14623 accumulator += print_expr(car(p));
14624 accumulator += "} & otherwise ";
14625 accumulator += " \\\\\\\\";
14626 break;
14627 }
14628 accumulator += "{";
14629 accumulator += print_expr(cadr(p));
14630 accumulator += "} & if & ";
14631 accumulator += print_expr(car(p));
14632 accumulator += " \\\\\\\\";
14633 p = cddr(p);
14634 }
14635 accumulator = accumulator.substring(0, accumulator.length - 4);
14636 return accumulator += "\\end{array} \\right.";
14637 };
14638
14639 print_TEST_codegen = function(p) {
14640 var accumulator, howManyIfs;
14641 accumulator = "(function(){";
14642 p = cdr(p);
14643 howManyIfs = 0;
14644 while (iscons(p)) {
14645 if (cdr(p) === symbol(NIL)) {
14646 accumulator += "else {";
14647 accumulator += "return (" + print_expr(car(p)) + ");";
14648 accumulator += "}";
14649 break;
14650 }
14651 if (howManyIfs) {
14652 accumulator += " else ";
14653 }
14654 accumulator += "if (" + print_expr(car(p)) + "){";
14655 accumulator += "return (" + print_expr(cadr(p)) + ");";
14656 accumulator += "}";
14657 howManyIfs++;
14658 p = cddr(p);
14659 }
14660 accumulator += "})()";
14661 return accumulator;
14662 };
14663
14664 print_TESTLT_latex = function(p) {
14665 var accumulator;
14666 accumulator = "{";
14667 accumulator += print_expr(cadr(p));
14668 accumulator += "}";
14669 accumulator += " < ";
14670 accumulator += "{";
14671 accumulator += print_expr(caddr(p));
14672 return accumulator += "}";
14673 };
14674
14675 print_TESTLE_latex = function(p) {
14676 var accumulator;
14677 accumulator = "{";
14678 accumulator += print_expr(cadr(p));
14679 accumulator += "}";
14680 accumulator += " \\leq ";
14681 accumulator += "{";
14682 accumulator += print_expr(caddr(p));
14683 return accumulator += "}";
14684 };
14685
14686 print_TESTGT_latex = function(p) {
14687 var accumulator;
14688 accumulator = "{";
14689 accumulator += print_expr(cadr(p));
14690 accumulator += "}";
14691 accumulator += " > ";
14692 accumulator += "{";
14693 accumulator += print_expr(caddr(p));
14694 return accumulator += "}";
14695 };
14696
14697 print_TESTGE_latex = function(p) {
14698 var accumulator;
14699 accumulator = "{";
14700 accumulator += print_expr(cadr(p));
14701 accumulator += "}";
14702 accumulator += " \\geq ";
14703 accumulator += "{";
14704 accumulator += print_expr(caddr(p));
14705 return accumulator += "}";
14706 };
14707
14708 print_TESTEQ_latex = function(p) {
14709 var accumulator;
14710 accumulator = "{";
14711 accumulator += print_expr(cadr(p));
14712 accumulator += "}";
14713 accumulator += " = ";
14714 accumulator += "{";
14715 accumulator += print_expr(caddr(p));
14716 return accumulator += "}";
14717 };
14718
14719 print_FOR_codegen = function(p) {
14720 var accumulator, body, lowerlimit, upperlimit, variable;
14721 body = cadr(p);
14722 variable = caddr(p);
14723 lowerlimit = cadddr(p);
14724 upperlimit = caddddr(p);
14725 accumulator = "(function(){" + " var " + variable + "; " + " var lowerlimit = " + print_expr(lowerlimit) + "; " + " var upperlimit = " + print_expr(upperlimit) + "; " + " for (" + variable + " = lowerlimit; " + variable + " < upperlimit; " + variable + "++) { " + " " + print_expr(body) + " } " + "})()";
14726 return accumulator;
14727 };
14728
14729 print_DO_codegen = function(p) {
14730 var accumulator;
14731 accumulator = "";
14732 p = cdr(p);
14733 while (iscons(p)) {
14734 accumulator += print_expr(car(p));
14735 p = cdr(p);
14736 }
14737 return accumulator;
14738 };
14739
14740 print_SETQ_codegen = function(p) {
14741 var accumulator;
14742 accumulator = "";
14743 accumulator += print_expr(cadr(p));
14744 accumulator += " = ";
14745 accumulator += print_expr(caddr(p));
14746 accumulator += "; ";
14747 return accumulator;
14748 };
14749
14750 print_PRODUCT_latex = function(p) {
14751 var accumulator;
14752 accumulator = "\\prod_{";
14753 accumulator += print_expr(caddr(p));
14754 accumulator += "=";
14755 accumulator += print_expr(cadddr(p));
14756 accumulator += "}^{";
14757 accumulator += print_expr(caddddr(p));
14758 accumulator += "}{";
14759 accumulator += print_expr(cadr(p));
14760 accumulator += "}";
14761 return accumulator;
14762 };
14763
14764 print_PRODUCT_codegen = function(p) {
14765 var accumulator, body, lowerlimit, upperlimit, variable;
14766 body = cadr(p);
14767 variable = caddr(p);
14768 lowerlimit = cadddr(p);
14769 upperlimit = caddddr(p);
14770 accumulator = "(function(){" + " var " + variable + "; " + " var holderProduct = 1; " + " var lowerlimit = " + print_expr(lowerlimit) + "; " + " var upperlimit = " + print_expr(upperlimit) + "; " + " for (" + variable + " = lowerlimit; " + variable + " < upperlimit; " + variable + "++) { " + " holderProduct *= " + print_expr(body) + ";" + " } " + " return holderProduct;" + "})()";
14771 return accumulator;
14772 };
14773
14774 print_base = function(p) {
14775 var accumulator;
14776 accumulator = "";
14777 if (isadd(cadr(p)) || caadr(p) === symbol(MULTIPLY) || caadr(p) === symbol(POWER) || isnegativenumber(cadr(p))) {
14778 accumulator += print_str('(');
14779 accumulator += print_expr(cadr(p));
14780 accumulator += print_str(')');
14781 } else if (isnum(cadr(p)) && (lessp(cadr(p), zero) || isfraction(cadr(p)))) {
14782 accumulator += print_str('(');
14783 accumulator += print_factor(cadr(p));
14784 accumulator += print_str(')');
14785 } else {
14786 accumulator += print_factor(cadr(p));
14787 }
14788 return accumulator;
14789 };
14790
14791 print_exponent = function(p) {
14792 var accumulator;
14793 accumulator = "";
14794 if (iscons(caddr(p)) || isfraction(caddr(p)) || (isnum(caddr(p)) && lessp(caddr(p), zero))) {
14795 accumulator += print_str('(');
14796 accumulator += print_expr(caddr(p));
14797 accumulator += print_str(')');
14798 } else {
14799 accumulator += print_factor(caddr(p));
14800 }
14801 return accumulator;
14802 };
14803
14804 print_power = function(base, exponent) {
14805 var accumulator, denomExponent, newExponent, numExponent;
14806 accumulator = "";
14807 if (DEBUG) {
14808 console.log("power base: " + base + " " + " exponent: " + exponent);
14809 }
14810 if (isoneovertwo(exponent)) {
14811 if (equaln(base, 2)) {
14812 if (codeGen) {
14813 accumulator += print_str("Math.SQRT2");
14814 return accumulator;
14815 }
14816 } else {
14817 if (printMode === PRINTMODE_LATEX) {
14818 accumulator += print_str("\\sqrt{");
14819 accumulator += print_expr(base);
14820 accumulator += print_str("}");
14821 return accumulator;
14822 } else if (codeGen) {
14823 accumulator += print_str("Math.sqrt(");
14824 accumulator += print_expr(base);
14825 accumulator += print_str(')');
14826 return accumulator;
14827 }
14828 }
14829 }
14830 if ((equaln(get_binding(symbol(PRINT_LEAVE_E_ALONE)), 1)) && base === symbol(E)) {
14831 if (codeGen) {
14832 accumulator += print_str("Math.exp(");
14833 accumulator += print_expo_of_denom(exponent);
14834 accumulator += print_str(')');
14835 return accumulator;
14836 }
14837 if (printMode === PRINTMODE_LATEX) {
14838 accumulator += print_str("e^{");
14839 accumulator += print_expr(exponent);
14840 accumulator += print_str("}");
14841 } else {
14842 accumulator += print_str("exp(");
14843 accumulator += print_expr(exponent);
14844 accumulator += print_str(')');
14845 }
14846 return accumulator;
14847 }
14848 if (codeGen) {
14849 accumulator += print_str("Math.pow(");
14850 accumulator += print_base_of_denom(base);
14851 accumulator += print_str(", ");
14852 accumulator += print_expo_of_denom(exponent);
14853 accumulator += print_str(')');
14854 return accumulator;
14855 }
14856 if ((equaln(get_binding(symbol(PRINT_LEAVE_X_ALONE)), 0)) || base.printname !== "x") {
14857 if (base !== symbol(E)) {
14858 if (isminusone(exponent)) {
14859 if (printMode === PRINTMODE_LATEX) {
14860 accumulator += print_str("\\frac{1}{");
14861 } else if (printMode === PRINTMODE_PLAIN && !test_flag) {
14862 accumulator += print_str("1 / ");
14863 } else {
14864 accumulator += print_str("1/");
14865 }
14866 if (iscons(base) && printMode !== PRINTMODE_LATEX) {
14867 accumulator += print_str('(');
14868 accumulator += print_expr(base);
14869 accumulator += print_str(')');
14870 } else {
14871 accumulator += print_expr(base);
14872 }
14873 if (printMode === PRINTMODE_LATEX) {
14874 accumulator += print_str("}");
14875 }
14876 return accumulator;
14877 }
14878 if (isnegativeterm(exponent)) {
14879 if (printMode === PRINTMODE_LATEX) {
14880 accumulator += print_str("\\frac{1}{");
14881 } else if (printMode === PRINTMODE_PLAIN && !test_flag) {
14882 accumulator += print_str("1 / ");
14883 } else {
14884 accumulator += print_str("1/");
14885 }
14886 push(exponent);
14887 push_integer(-1);
14888 multiply();
14889 newExponent = pop();
14890 if (iscons(base) && printMode !== PRINTMODE_LATEX) {
14891 accumulator += print_str('(');
14892 accumulator += print_power(base, newExponent);
14893 accumulator += print_str(')');
14894 } else {
14895 accumulator += print_power(base, newExponent);
14896 }
14897 if (printMode === PRINTMODE_LATEX) {
14898 accumulator += print_str("}");
14899 }
14900 return accumulator;
14901 }
14902 }
14903 if (isfraction(exponent) && printMode === PRINTMODE_LATEX) {
14904 accumulator += print_str("\\sqrt");
14905 push(exponent);
14906 denominator();
14907 denomExponent = pop();
14908 if (!isplustwo(denomExponent)) {
14909 accumulator += print_str("[");
14910 accumulator += print_expr(denomExponent);
14911 accumulator += print_str("]");
14912 }
14913 accumulator += print_str("{");
14914 push(exponent);
14915 numerator();
14916 numExponent = pop();
14917 exponent = numExponent;
14918 accumulator += print_power(base, exponent);
14919 accumulator += print_str("}");
14920 return accumulator;
14921 }
14922 }
14923 if (printMode === PRINTMODE_LATEX && isplusone(exponent)) {
14924 accumulator += print_expr(base);
14925 } else {
14926 if (isadd(base) || isnegativenumber(base)) {
14927 accumulator += print_str('(');
14928 accumulator += print_expr(base);
14929 accumulator += print_str(')');
14930 } else if (car(base) === symbol(MULTIPLY) || car(base) === symbol(POWER)) {
14931 if (printMode !== PRINTMODE_LATEX) {
14932 accumulator += print_str('(');
14933 }
14934 accumulator += print_factor(base, true);
14935 if (printMode !== PRINTMODE_LATEX) {
14936 accumulator += print_str(')');
14937 }
14938 } else if (isnum(base) && (lessp(base, zero) || isfraction(base))) {
14939 accumulator += print_str('(');
14940 accumulator += print_factor(base);
14941 accumulator += print_str(')');
14942 } else {
14943 accumulator += print_factor(base);
14944 }
14945 if (printMode === PRINTMODE_PLAIN && !test_flag) {
14946 accumulator += print_str(power_str);
14947 } else {
14948 accumulator += print_str("^");
14949 }
14950 if (printMode === PRINTMODE_LATEX) {
14951 if (print_expr(exponent).length > 1) {
14952 accumulator += print_str("{");
14953 accumulator += print_expr(exponent);
14954 accumulator += print_str("}");
14955 } else {
14956 accumulator += print_expr(exponent);
14957 }
14958 } else if (iscons(exponent) || isfraction(exponent) || (isnum(exponent) && lessp(exponent, zero))) {
14959 accumulator += print_str('(');
14960 accumulator += print_expr(exponent);
14961 accumulator += print_str(')');
14962 } else {
14963 accumulator += print_factor(exponent);
14964 }
14965 }
14966 return accumulator;
14967 };
14968
14969 print_index_function = function(p) {
14970 var accumulator;
14971 accumulator = "";
14972 p = cdr(p);
14973 if (caar(p) === symbol(ADD) || caar(p) === symbol(MULTIPLY) || caar(p) === symbol(POWER) || caar(p) === symbol(FACTORIAL)) {
14974 accumulator += print_subexpr(car(p));
14975 } else {
14976 accumulator += print_expr(car(p));
14977 }
14978 accumulator += print_str('[');
14979 p = cdr(p);
14980 if (iscons(p)) {
14981 accumulator += print_expr(car(p));
14982 p = cdr(p);
14983 while (iscons(p)) {
14984 accumulator += print_str(',');
14985 accumulator += print_expr(car(p));
14986 p = cdr(p);
14987 }
14988 }
14989 accumulator += print_str(']');
14990 return accumulator;
14991 };
14992
14993 print_factor = function(p, omitParens) {
14994 var accumulator, base, exponent, fbody, parameters, returned;
14995 accumulator = "";
14996 if (isnum(p)) {
14997 accumulator += print_number(p, false);
14998 return accumulator;
14999 }
15000 if (isstr(p)) {
15001 accumulator += print_str("\"");
15002 accumulator += print_str(p.str);
15003 accumulator += print_str("\"");
15004 return accumulator;
15005 }
15006 if (istensor(p)) {
15007 if (printMode === PRINTMODE_LATEX) {
15008 accumulator += print_tensor_latex(p);
15009 } else {
15010 accumulator += print_tensor(p);
15011 }
15012 return accumulator;
15013 }
15014 if (car(p) === symbol(MULTIPLY)) {
15015 if (!omitParens) {
15016 if (sign_of_term(p) === '-' || printMode !== PRINTMODE_LATEX) {
15017 if (printMode === PRINTMODE_LATEX) {
15018 accumulator += print_str(" \\left (");
15019 } else {
15020 accumulator += print_str('(');
15021 }
15022 }
15023 }
15024 accumulator += print_expr(p);
15025 if (!omitParens) {
15026 if (sign_of_term(p) === '-' || printMode !== PRINTMODE_LATEX) {
15027 if (printMode === PRINTMODE_LATEX) {
15028 accumulator += print_str(" \\right ) ");
15029 } else {
15030 accumulator += print_str(')');
15031 }
15032 }
15033 }
15034 return accumulator;
15035 } else if (isadd(p)) {
15036 if (!omitParens) {
15037 accumulator += print_str('(');
15038 }
15039 accumulator += print_expr(p);
15040 if (!omitParens) {
15041 accumulator += print_str(')');
15042 }
15043 return accumulator;
15044 }
15045 if (car(p) === symbol(POWER)) {
15046 base = cadr(p);
15047 exponent = caddr(p);
15048 accumulator += print_power(base, exponent);
15049 return accumulator;
15050 }
15051 if (car(p) === symbol(FUNCTION)) {
15052 fbody = cadr(p);
15053 if (!codeGen) {
15054 parameters = caddr(p);
15055 accumulator += print_str("function ");
15056 if (DEBUG) {
15057 console.log("emittedString from print_factor " + stringsEmittedByUserPrintouts);
15058 }
15059 returned = print_list(parameters);
15060 accumulator += returned;
15061 accumulator += print_str(" -> ");
15062 }
15063 accumulator += print_expr(fbody);
15064 return accumulator;
15065 }
15066 if (car(p) === symbol(PATTERN)) {
15067 accumulator += print_expr(caadr(p));
15068 if (printMode === PRINTMODE_LATEX) {
15069 accumulator += print_str(" \\rightarrow ");
15070 } else {
15071 if (printMode === PRINTMODE_PLAIN && !test_flag) {
15072 accumulator += print_str(" -> ");
15073 } else {
15074 accumulator += print_str("->");
15075 }
15076 }
15077 accumulator += print_expr(car(cdr(cadr(p))));
15078 return accumulator;
15079 }
15080 if (car(p) === symbol(INDEX) && issymbol(cadr(p))) {
15081 accumulator += print_index_function(p);
15082 return accumulator;
15083 }
15084 if (car(p) === symbol(FACTORIAL)) {
15085 accumulator += print_factorial_function(p);
15086 return accumulator;
15087 } else if (car(p) === symbol(ABS) && printMode === PRINTMODE_LATEX) {
15088 accumulator += print_ABS_latex(p);
15089 return accumulator;
15090 } else if (car(p) === symbol(SQRT) && printMode === PRINTMODE_LATEX) {
15091 accumulator += print_SQRT_latex(p);
15092 return accumulator;
15093 } else if (car(p) === symbol(TRANSPOSE)) {
15094 if (printMode === PRINTMODE_LATEX) {
15095 accumulator += print_TRANSPOSE_latex(p);
15096 return accumulator;
15097 } else if (codeGen) {
15098 accumulator += print_TRANSPOSE_codegen(p);
15099 return accumulator;
15100 }
15101 } else if (car(p) === symbol(UNIT)) {
15102 if (codeGen) {
15103 accumulator += print_UNIT_codegen(p);
15104 return accumulator;
15105 }
15106 } else if (car(p) === symbol(INV)) {
15107 if (printMode === PRINTMODE_LATEX) {
15108 accumulator += print_INV_latex(p);
15109 return accumulator;
15110 } else if (codeGen) {
15111 accumulator += print_INV_codegen(p);
15112 return accumulator;
15113 }
15114 } else if (car(p) === symbol(BINOMIAL) && printMode === PRINTMODE_LATEX) {
15115 accumulator += print_BINOMIAL_latex(p);
15116 return accumulator;
15117 } else if (car(p) === symbol(DEFINT) && printMode === PRINTMODE_LATEX) {
15118 accumulator += print_DEFINT_latex(p);
15119 return accumulator;
15120 } else if (isinnerordot(p)) {
15121 if (printMode === PRINTMODE_LATEX) {
15122 accumulator += print_DOT_latex(p);
15123 return accumulator;
15124 } else if (codeGen) {
15125 accumulator += print_DOT_codegen(p);
15126 return accumulator;
15127 }
15128 } else if (car(p) === symbol(SIN)) {
15129 if (codeGen) {
15130 accumulator += print_SIN_codegen(p);
15131 return accumulator;
15132 }
15133 } else if (car(p) === symbol(COS)) {
15134 if (codeGen) {
15135 accumulator += print_COS_codegen(p);
15136 return accumulator;
15137 }
15138 } else if (car(p) === symbol(TAN)) {
15139 if (codeGen) {
15140 accumulator += print_TAN_codegen(p);
15141 return accumulator;
15142 }
15143 } else if (car(p) === symbol(ARCSIN)) {
15144 if (codeGen) {
15145 accumulator += print_ARCSIN_codegen(p);
15146 return accumulator;
15147 }
15148 } else if (car(p) === symbol(ARCCOS)) {
15149 if (codeGen) {
15150 accumulator += print_ARCCOS_codegen(p);
15151 return accumulator;
15152 }
15153 } else if (car(p) === symbol(ARCTAN)) {
15154 if (codeGen) {
15155 accumulator += print_ARCTAN_codegen(p);
15156 return accumulator;
15157 }
15158 } else if (car(p) === symbol(SUM)) {
15159 if (printMode === PRINTMODE_LATEX) {
15160 accumulator += print_SUM_latex(p);
15161 return accumulator;
15162 } else if (codeGen) {
15163 accumulator += print_SUM_codegen(p);
15164 return accumulator;
15165 }
15166 } else if (car(p) === symbol(PRODUCT)) {
15167 if (printMode === PRINTMODE_LATEX) {
15168 accumulator += print_PRODUCT_latex(p);
15169 return accumulator;
15170 } else if (codeGen) {
15171 accumulator += print_PRODUCT_codegen(p);
15172 return accumulator;
15173 }
15174 } else if (car(p) === symbol(FOR)) {
15175 if (codeGen) {
15176 accumulator += print_FOR_codegen(p);
15177 return accumulator;
15178 }
15179 } else if (car(p) === symbol(DO)) {
15180 if (codeGen) {
15181 accumulator += print_DO_codegen(p);
15182 return accumulator;
15183 }
15184 } else if (car(p) === symbol(TEST)) {
15185 if (codeGen) {
15186 accumulator += print_TEST_codegen(p);
15187 return accumulator;
15188 }
15189 if (printMode === PRINTMODE_LATEX) {
15190 accumulator += print_TEST_latex(p);
15191 return accumulator;
15192 }
15193 } else if (car(p) === symbol(TESTLT)) {
15194 if (codeGen) {
15195 accumulator += "((" + print_expr(cadr(p)) + ") < (" + print_expr(caddr(p)) + "))";
15196 return accumulator;
15197 }
15198 if (printMode === PRINTMODE_LATEX) {
15199 accumulator += print_TESTLT_latex(p);
15200 return accumulator;
15201 }
15202 } else if (car(p) === symbol(TESTLE)) {
15203 if (codeGen) {
15204 accumulator += "((" + print_expr(cadr(p)) + ") <= (" + print_expr(caddr(p)) + "))";
15205 return accumulator;
15206 }
15207 if (printMode === PRINTMODE_LATEX) {
15208 accumulator += print_TESTLE_latex(p);
15209 return accumulator;
15210 }
15211 } else if (car(p) === symbol(TESTGT)) {
15212 if (codeGen) {
15213 accumulator += "((" + print_expr(cadr(p)) + ") > (" + print_expr(caddr(p)) + "))";
15214 return accumulator;
15215 }
15216 if (printMode === PRINTMODE_LATEX) {
15217 accumulator += print_TESTGT_latex(p);
15218 return accumulator;
15219 }
15220 } else if (car(p) === symbol(TESTGE)) {
15221 if (codeGen) {
15222 accumulator += "((" + print_expr(cadr(p)) + ") >= (" + print_expr(caddr(p)) + "))";
15223 return accumulator;
15224 }
15225 if (printMode === PRINTMODE_LATEX) {
15226 accumulator += print_TESTGE_latex(p);
15227 return accumulator;
15228 }
15229 } else if (car(p) === symbol(TESTEQ)) {
15230 if (codeGen) {
15231 accumulator += "((" + print_expr(cadr(p)) + ") === (" + print_expr(caddr(p)) + "))";
15232 return accumulator;
15233 }
15234 if (printMode === PRINTMODE_LATEX) {
15235 accumulator += print_TESTEQ_latex(p);
15236 return accumulator;
15237 }
15238 } else if (car(p) === symbol(FLOOR)) {
15239 if (codeGen) {
15240 accumulator += "Math.floor(" + print_expr(cadr(p)) + ")";
15241 return accumulator;
15242 }
15243 if (printMode === PRINTMODE_LATEX) {
15244 accumulator += " \\lfloor {" + print_expr(cadr(p)) + "} \\rfloor ";
15245 return accumulator;
15246 }
15247 } else if (car(p) === symbol(CEILING)) {
15248 debugger;
15249 if (codeGen) {
15250 accumulator += "Math.ceiling(" + print_expr(cadr(p)) + ")";
15251 return accumulator;
15252 }
15253 if (printMode === PRINTMODE_LATEX) {
15254 accumulator += " \\lceil {" + print_expr(cadr(p)) + "} \\rceil ";
15255 return accumulator;
15256 }
15257 } else if (car(p) === symbol(ROUND)) {
15258 if (codeGen) {
15259 accumulator += "Math.round(" + print_expr(cadr(p)) + ")";
15260 return accumulator;
15261 }
15262 } else if (car(p) === symbol(SETQ)) {
15263 if (codeGen) {
15264 accumulator += print_SETQ_codegen(p);
15265 return accumulator;
15266 } else {
15267 accumulator += print_expr(cadr(p));
15268 accumulator += print_str("=");
15269 accumulator += print_expr(caddr(p));
15270 return accumulator;
15271 }
15272 }
15273 if (iscons(p)) {
15274 accumulator += print_factor(car(p));
15275 p = cdr(p);
15276 if (!omitParens) {
15277 accumulator += print_str('(');
15278 }
15279 if (iscons(p)) {
15280 accumulator += print_expr(car(p));
15281 p = cdr(p);
15282 while (iscons(p)) {
15283 accumulator += print_str(",");
15284 accumulator += print_expr(car(p));
15285 p = cdr(p);
15286 }
15287 }
15288 if (!omitParens) {
15289 accumulator += print_str(')');
15290 }
15291 return accumulator;
15292 }
15293 if (p === symbol(DERIVATIVE)) {
15294 accumulator += print_char('d');
15295 } else if (p === symbol(E)) {
15296 if (codeGen) {
15297 accumulator += print_str("Math.E");
15298 } else {
15299 accumulator += print_str("e");
15300 }
15301 } else if (p === symbol(PI)) {
15302 if (printMode === PRINTMODE_LATEX) {
15303 accumulator += print_str("\\pi");
15304 } else {
15305 accumulator += print_str("pi");
15306 }
15307 } else {
15308 accumulator += print_str(get_printname(p));
15309 }
15310 return accumulator;
15311 };
15312
15313 print_list = function(p) {
15314 var accumulator;
15315 accumulator = "";
15316 switch (p.k) {
15317 case CONS:
15318 accumulator += '(';
15319 accumulator += print_list(car(p));
15320 if (p === cdr(p) && p !== symbol(NIL)) {
15321 console.log("oh no recursive!");
15322 debugger;
15323 }
15324 p = cdr(p);
15325 while (iscons(p)) {
15326 accumulator += " ";
15327 accumulator += print_list(car(p));
15328 p = cdr(p);
15329 if (p === cdr(p) && p !== symbol(NIL)) {
15330 console.log("oh no recursive!");
15331 debugger;
15332 }
15333 }
15334 if (p !== symbol(NIL)) {
15335 accumulator += " . ";
15336 accumulator += print_list(p);
15337 }
15338 accumulator += ')';
15339 break;
15340 case STR:
15341 accumulator += p.str;
15342 break;
15343 case NUM:
15344 case DOUBLE:
15345 accumulator += print_number(p, true);
15346 break;
15347 case SYM:
15348 accumulator += get_printname(p);
15349 break;
15350 default:
15351 accumulator += "<tensor>";
15352 }
15353 return accumulator;
15354 };
15355
15356 print_multiply_sign = function() {
15357 var accumulator;
15358 accumulator = "";
15359 if (printMode === PRINTMODE_LATEX) {
15360 if (printMode === PRINTMODE_PLAIN && !test_flag) {
15361 accumulator += print_str(" ");
15362 } else {
15363 return accumulator;
15364 }
15365 }
15366 if (printMode === PRINTMODE_PLAIN && !test_flag && !codeGen) {
15367 accumulator += print_str(" ");
15368 } else {
15369 accumulator += print_str("*");
15370 }
15371 return accumulator;
15372 };
15373
15374 is_denominator = function(p) {
15375 if (car(p) === symbol(POWER) && cadr(p) !== symbol(E) && isnegativeterm(caddr(p))) {
15376 return 1;
15377 } else {
15378 return 0;
15379 }
15380 };
15381
15382 any_denominators = function(p) {
15383 var q;
15384 p = cdr(p);
15385 while (iscons(p)) {
15386 q = car(p);
15387 if (is_denominator(q)) {
15388 return 1;
15389 }
15390 p = cdr(p);
15391 }
15392 return 0;
15393 };
15394
15395
15396 /*
15397
15398 Prints in "2d", e.g. instead of 1/(x+1)^2 :
15399
15400 1
15401 ----------
15402 2
15403 (1 + x)
15404
15405 Note that although this looks more natural, a) it's not parsable and
15406 b) it can be occasionally be ambiguous, such as:
15407
15408 1
15409 ----
15410 2
15411 x
15412
15413 is 1/x^2 but it also looks a little like x^(1/2)
15414 */
15415
15416 YMAX = 10000;
15417
15418 glyph = (function() {
15419 function glyph() {}
15420
15421 glyph.prototype.c = 0;
15422
15423 glyph.prototype.x = 0;
15424
15425 glyph.prototype.y = 0;
15426
15427 return glyph;
15428
15429 })();
15430
15431 chartab = [];
15432
15433 for (charTabIndex = i1 = 0, ref1 = YMAX; 0 <= ref1 ? i1 < ref1 : i1 > ref1; charTabIndex = 0 <= ref1 ? ++i1 : --i1) {
15434 chartab[charTabIndex] = new glyph();
15435 }
15436
15437 yindex = 0;
15438
15439 level = 0;
15440
15441 emit_x = 0;
15442
15443 expr_level = 0;
15444
15445 display_flag = 0;
15446
15447 printchar_nowrap = function(character) {
15448 var accumulator;
15449 accumulator = "";
15450 accumulator += character;
15451 return accumulator;
15452 };
15453
15454 printchar = function(character) {
15455 return printchar_nowrap(character);
15456 };
15457
15458 print2dascii = function(p) {
15459 var beenPrinted, h, ref2, w, y;
15460 h = 0;
15461 w = 0;
15462 y = 0;
15463 save();
15464 yindex = 0;
15465 level = 0;
15466 emit_x = 0;
15467 emit_top_expr(p);
15468 ref2 = get_size(0, yindex), h = ref2[0], w = ref2[1], y = ref2[2];
15469 if (w > 100) {
15470 printline(p);
15471 restore();
15472 return;
15473 }
15474 beenPrinted = print_glyphs();
15475 restore();
15476 return beenPrinted;
15477 };
15478
15479 emit_top_expr = function(p) {
15480 if (car(p) === symbol(SETQ)) {
15481 emit_expr(cadr(p));
15482 __emit_str(" = ");
15483 emit_expr(caddr(p));
15484 return;
15485 }
15486 if (istensor(p)) {
15487 return emit_tensor(p);
15488 } else {
15489 return emit_expr(p);
15490 }
15491 };
15492
15493 will_be_displayed_as_fraction = function(p) {
15494 if (level > 0) {
15495 return 0;
15496 }
15497 if (isfraction(p)) {
15498 return 1;
15499 }
15500 if (car(p) !== symbol(MULTIPLY)) {
15501 return 0;
15502 }
15503 if (isfraction(cadr(p))) {
15504 return 1;
15505 }
15506 while (iscons(p)) {
15507 if (isdenominator(car(p))) {
15508 return 1;
15509 }
15510 p = cdr(p);
15511 }
15512 return 0;
15513 };
15514
15515 emit_expr = function(p) {
15516 expr_level++;
15517 if (car(p) === symbol(ADD)) {
15518 p = cdr(p);
15519 if (__is_negative(car(p))) {
15520 __emit_char('-');
15521 if (will_be_displayed_as_fraction(car(p))) {
15522 __emit_char(' ');
15523 }
15524 }
15525 emit_term(car(p));
15526 p = cdr(p);
15527 while (iscons(p)) {
15528 if (__is_negative(car(p))) {
15529 __emit_char(' ');
15530 __emit_char('-');
15531 __emit_char(' ');
15532 } else {
15533 __emit_char(' ');
15534 __emit_char('+');
15535 __emit_char(' ');
15536 }
15537 emit_term(car(p));
15538 p = cdr(p);
15539 }
15540 } else {
15541 if (__is_negative(p)) {
15542 __emit_char('-');
15543 if (will_be_displayed_as_fraction(p)) {
15544 __emit_char(' ');
15545 }
15546 }
15547 emit_term(p);
15548 }
15549 return expr_level--;
15550 };
15551
15552 emit_unsigned_expr = function(p) {
15553 var results;
15554 if (car(p) === symbol(ADD)) {
15555 p = cdr(p);
15556 emit_term(car(p));
15557 p = cdr(p);
15558 results = [];
15559 while (iscons(p)) {
15560 if (__is_negative(car(p))) {
15561 __emit_char(' ');
15562 __emit_char('-');
15563 __emit_char(' ');
15564 } else {
15565 __emit_char(' ');
15566 __emit_char('+');
15567 __emit_char(' ');
15568 }
15569 emit_term(car(p));
15570 results.push(p = cdr(p));
15571 }
15572 return results;
15573 } else {
15574 return emit_term(p);
15575 }
15576 };
15577
15578 __is_negative = function(p) {
15579 if (isnegativenumber(p)) {
15580 return 1;
15581 }
15582 if (car(p) === symbol(MULTIPLY) && isnegativenumber(cadr(p))) {
15583 return 1;
15584 }
15585 return 0;
15586 };
15587
15588 emit_term = function(p) {
15589 var n;
15590 if (car(p) === symbol(MULTIPLY)) {
15591 n = count_denominators(p);
15592 if (n && level === 0) {
15593 return emit_fraction(p, n);
15594 } else {
15595 return emit_multiply(p, n);
15596 }
15597 } else {
15598 return emit_factor(p);
15599 }
15600 };
15601
15602 isdenominator = function(p) {
15603 if (car(p) === symbol(POWER) && cadr(p) !== symbol(E) && __is_negative(caddr(p))) {
15604 return 1;
15605 } else {
15606 return 0;
15607 }
15608 };
15609
15610 count_denominators = function(p) {
15611 var count, q;
15612 count = 0;
15613 p = cdr(p);
15614 while (iscons(p)) {
15615 q = car(p);
15616 if (isdenominator(q)) {
15617 count++;
15618 }
15619 p = cdr(p);
15620 }
15621 return count;
15622 };
15623
15624 emit_multiply = function(p, n) {
15625 var results;
15626 if (n === 0) {
15627 p = cdr(p);
15628 if (isplusone(car(p)) || isminusone(car(p))) {
15629 p = cdr(p);
15630 }
15631 emit_factor(car(p));
15632 p = cdr(p);
15633 results = [];
15634 while (iscons(p)) {
15635 __emit_char(' ');
15636 emit_factor(car(p));
15637 results.push(p = cdr(p));
15638 }
15639 return results;
15640 } else {
15641 emit_numerators(p);
15642 __emit_char('/');
15643 if (n > 1 || isfraction(cadr(p))) {
15644 __emit_char('(');
15645 emit_denominators(p);
15646 return __emit_char(')');
15647 } else {
15648 return emit_denominators(p);
15649 }
15650 }
15651 };
15652
15653 emit_fraction = function(p, d) {
15654 var count, doNothing, k1, k2, n, x;
15655 count = 0;
15656 k1 = 0;
15657 k2 = 0;
15658 n = 0;
15659 x = 0;
15660 save();
15661 p3 = one;
15662 p4 = one;
15663 if (isrational(cadr(p))) {
15664 push(cadr(p));
15665 mp_numerator();
15666 absval();
15667 p3 = pop();
15668 push(cadr(p));
15669 mp_denominator();
15670 p4 = pop();
15671 }
15672 if (isdouble(cadr(p))) {
15673 push(cadr(p));
15674 absval();
15675 p3 = pop();
15676 }
15677 if (isplusone(p3)) {
15678 n = 0;
15679 } else {
15680 n = 1;
15681 }
15682 p1 = cdr(p);
15683 if (isnum(car(p1))) {
15684 p1 = cdr(p1);
15685 }
15686 while (iscons(p1)) {
15687 p2 = car(p1);
15688 if (isdenominator(p2)) {
15689 doNothing = 1;
15690 } else {
15691 n++;
15692 }
15693 p1 = cdr(p1);
15694 }
15695 x = emit_x;
15696 k1 = yindex;
15697 count = 0;
15698 if (!isplusone(p3)) {
15699 emit_number(p3, 0);
15700 count++;
15701 }
15702 p1 = cdr(p);
15703 if (isnum(car(p1))) {
15704 p1 = cdr(p1);
15705 }
15706 while (iscons(p1)) {
15707 p2 = car(p1);
15708 if (isdenominator(p2)) {
15709 doNothing = 1;
15710 } else {
15711 if (count > 0) {
15712 __emit_char(' ');
15713 }
15714 if (n === 1) {
15715 emit_expr(p2);
15716 } else {
15717 emit_factor(p2);
15718 }
15719 count++;
15720 }
15721 p1 = cdr(p1);
15722 }
15723 if (count === 0) {
15724 __emit_char('1');
15725 }
15726 k2 = yindex;
15727 count = 0;
15728 if (!isplusone(p4)) {
15729 emit_number(p4, 0);
15730 count++;
15731 d++;
15732 }
15733 p1 = cdr(p);
15734 if (isrational(car(p1))) {
15735 p1 = cdr(p1);
15736 }
15737 while (iscons(p1)) {
15738 p2 = car(p1);
15739 if (isdenominator(p2)) {
15740 if (count > 0) {
15741 __emit_char(' ');
15742 }
15743 emit_denominator(p2, d);
15744 count++;
15745 }
15746 p1 = cdr(p1);
15747 }
15748 fixup_fraction(x, k1, k2);
15749 return restore();
15750 };
15751
15752 emit_numerators = function(p) {
15753 var doNothing, n;
15754 save();
15755 n = 0;
15756 p1 = one;
15757 p = cdr(p);
15758 if (isrational(car(p))) {
15759 push(car(p));
15760 mp_numerator();
15761 absval();
15762 p1 = pop();
15763 p = cdr(p);
15764 } else if (isdouble(car(p))) {
15765 push(car(p));
15766 absval();
15767 p1 = pop();
15768 p = cdr(p);
15769 }
15770 n = 0;
15771 if (!isplusone(p1)) {
15772 emit_number(p1, 0);
15773 n++;
15774 }
15775 while (iscons(p)) {
15776 if (isdenominator(car(p))) {
15777 doNothing = 1;
15778 } else {
15779 if (n > 0) {
15780 __emit_char(' ');
15781 }
15782 emit_factor(car(p));
15783 n++;
15784 }
15785 p = cdr(p);
15786 }
15787 if (n === 0) {
15788 __emit_char('1');
15789 }
15790 return restore();
15791 };
15792
15793 emit_denominators = function(p) {
15794 var n;
15795 save();
15796 n = 0;
15797 p = cdr(p);
15798 if (isfraction(car(p))) {
15799 push(car(p));
15800 mp_denominator();
15801 p1 = pop();
15802 emit_number(p1, 0);
15803 n++;
15804 p = cdr(p);
15805 }
15806 while (iscons(p)) {
15807 if (isdenominator(car(p))) {
15808 if (n > 0) {
15809 __emit_char(' ');
15810 }
15811 emit_denominator(car(p), 0);
15812 n++;
15813 }
15814 p = cdr(p);
15815 }
15816 return restore();
15817 };
15818
15819 emit_factor = function(p) {
15820 if (istensor(p)) {
15821 if (level === 0) {
15822 emit_flat_tensor(p);
15823 } else {
15824 emit_flat_tensor(p);
15825 }
15826 return;
15827 }
15828 if (isdouble(p)) {
15829 emit_number(p, 0);
15830 return;
15831 }
15832 if (car(p) === symbol(ADD) || car(p) === symbol(MULTIPLY)) {
15833 emit_subexpr(p);
15834 return;
15835 }
15836 if (car(p) === symbol(POWER)) {
15837 emit_power(p);
15838 return;
15839 }
15840 if (iscons(p)) {
15841 emit_function(p);
15842 return;
15843 }
15844 if (isnum(p)) {
15845 if (level === 0) {
15846 emit_numerical_fraction(p);
15847 } else {
15848 emit_number(p, 0);
15849 }
15850 return;
15851 }
15852 if (issymbol(p)) {
15853 emit_symbol(p);
15854 return;
15855 }
15856 if (isstr(p)) {
15857 emit_string(p);
15858 }
15859 };
15860
15861 emit_numerical_fraction = function(p) {
15862 var k1, k2, x;
15863 k1 = 0;
15864 k2 = 0;
15865 x = 0;
15866 save();
15867 push(p);
15868 mp_numerator();
15869 absval();
15870 p3 = pop();
15871 push(p);
15872 mp_denominator();
15873 p4 = pop();
15874 if (isplusone(p4)) {
15875 emit_number(p3, 0);
15876 restore();
15877 return;
15878 }
15879 x = emit_x;
15880 k1 = yindex;
15881 emit_number(p3, 0);
15882 k2 = yindex;
15883 emit_number(p4, 0);
15884 fixup_fraction(x, k1, k2);
15885 return restore();
15886 };
15887
15888 isfactor = function(p) {
15889 if (iscons(p) && car(p) !== symbol(ADD) && car(p) !== symbol(MULTIPLY) && car(p) !== symbol(POWER)) {
15890 return 1;
15891 }
15892 if (issymbol(p)) {
15893 return 1;
15894 }
15895 if (isfraction(p)) {
15896 return 0;
15897 }
15898 if (isnegativenumber(p)) {
15899 return 0;
15900 }
15901 if (isnum(p)) {
15902 return 1;
15903 }
15904 return 0;
15905 };
15906
15907 emit_power = function(p) {
15908 var k1, k2, x;
15909 k1 = 0;
15910 k2 = 0;
15911 x = 0;
15912 if (cadr(p) === symbol(E)) {
15913 __emit_str("exp(");
15914 emit_expr(caddr(p));
15915 __emit_char(')');
15916 return;
15917 }
15918 if (level > 0) {
15919 if (isminusone(caddr(p))) {
15920 __emit_char('1');
15921 __emit_char('/');
15922 if (isfactor(cadr(p))) {
15923 emit_factor(cadr(p));
15924 } else {
15925 emit_subexpr(cadr(p));
15926 }
15927 } else {
15928 if (isfactor(cadr(p))) {
15929 emit_factor(cadr(p));
15930 } else {
15931 emit_subexpr(cadr(p));
15932 }
15933 __emit_char('^');
15934 if (isfactor(caddr(p))) {
15935 emit_factor(caddr(p));
15936 } else {
15937 emit_subexpr(caddr(p));
15938 }
15939 }
15940 return;
15941 }
15942 if (__is_negative(caddr(p))) {
15943 x = emit_x;
15944 k1 = yindex;
15945 __emit_char('1');
15946 k2 = yindex;
15947 emit_denominator(p, 1);
15948 fixup_fraction(x, k1, k2);
15949 return;
15950 }
15951 k1 = yindex;
15952 if (isfactor(cadr(p))) {
15953 emit_factor(cadr(p));
15954 } else {
15955 emit_subexpr(cadr(p));
15956 }
15957 k2 = yindex;
15958 level++;
15959 emit_expr(caddr(p));
15960 level--;
15961 return fixup_power(k1, k2);
15962 };
15963
15964 emit_denominator = function(p, n) {
15965 var k1, k2;
15966 k1 = 0;
15967 k2 = 0;
15968 if (isminusone(caddr(p))) {
15969 if (n === 1) {
15970 emit_expr(cadr(p));
15971 } else {
15972 emit_factor(cadr(p));
15973 }
15974 return;
15975 }
15976 k1 = yindex;
15977 if (isfactor(cadr(p))) {
15978 emit_factor(cadr(p));
15979 } else {
15980 emit_subexpr(cadr(p));
15981 }
15982 k2 = yindex;
15983 level++;
15984 emit_unsigned_expr(caddr(p));
15985 level--;
15986 return fixup_power(k1, k2);
15987 };
15988
15989 emit_function = function(p) {
15990 if (car(p) === symbol(INDEX) && issymbol(cadr(p))) {
15991 emit_index_function(p);
15992 return;
15993 }
15994 if (car(p) === symbol(FACTORIAL)) {
15995 emit_factorial_function(p);
15996 return;
15997 }
15998 if (car(p) === symbol(DERIVATIVE)) {
15999 __emit_char('d');
16000 } else {
16001 emit_symbol(car(p));
16002 }
16003 __emit_char('(');
16004 p = cdr(p);
16005 if (iscons(p)) {
16006 emit_expr(car(p));
16007 p = cdr(p);
16008 while (iscons(p)) {
16009 __emit_char(',');
16010 emit_expr(car(p));
16011 p = cdr(p);
16012 }
16013 }
16014 return __emit_char(')');
16015 };
16016
16017 emit_index_function = function(p) {
16018 p = cdr(p);
16019 if (caar(p) === symbol(ADD) || caar(p) === symbol(MULTIPLY) || caar(p) === symbol(POWER) || caar(p) === symbol(FACTORIAL)) {
16020 emit_subexpr(car(p));
16021 } else {
16022 emit_expr(car(p));
16023 }
16024 __emit_char('[');
16025 p = cdr(p);
16026 if (iscons(p)) {
16027 emit_expr(car(p));
16028 p = cdr(p);
16029 while (iscons(p)) {
16030 __emit_char(',');
16031 emit_expr(car(p));
16032 p = cdr(p);
16033 }
16034 }
16035 return __emit_char(']');
16036 };
16037
16038 emit_factorial_function = function(p) {
16039 p = cadr(p);
16040 if (car(p) === symbol(ADD) || car(p) === symbol(MULTIPLY) || car(p) === symbol(POWER) || car(p) === symbol(FACTORIAL)) {
16041 emit_subexpr(p);
16042 } else {
16043 emit_expr(p);
16044 }
16045 return __emit_char('!');
16046 };
16047
16048 emit_subexpr = function(p) {
16049 __emit_char('(');
16050 emit_expr(p);
16051 return __emit_char(')');
16052 };
16053
16054 emit_symbol = function(p) {
16055 var i, j1, pPrintName, ref2, results;
16056 i = 0;
16057 if (p === symbol(E)) {
16058 __emit_str("exp(1)");
16059 return;
16060 }
16061 pPrintName = get_printname(p);
16062 results = [];
16063 for (i = j1 = 0, ref2 = pPrintName.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16064 results.push(__emit_char(pPrintName[i]));
16065 }
16066 return results;
16067 };
16068
16069 emit_string = function(p) {
16070 var i, j1, pString, ref2;
16071 i = 0;
16072 pString = p.str;
16073 __emit_char('"');
16074 for (i = j1 = 0, ref2 = pString.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16075 __emit_char(pString[i]);
16076 }
16077 return __emit_char('"');
16078 };
16079
16080 fixup_fraction = function(x, k1, k2) {
16081 var dx, dy, h1, h2, i, j1, ref2, ref3, ref4, results, w, w1, w2, y, y1, y2;
16082 dx = 0;
16083 dy = 0;
16084 i = 0;
16085 w = 0;
16086 y = 0;
16087 h1 = 0;
16088 w1 = 0;
16089 y1 = 0;
16090 h2 = 0;
16091 w2 = 0;
16092 y2 = 0;
16093 ref2 = get_size(k1, k2), h1 = ref2[0], w1 = ref2[1], y1 = ref2[2];
16094 ref3 = get_size(k2, yindex), h2 = ref3[0], w2 = ref3[1], y2 = ref3[2];
16095 if (w2 > w1) {
16096 dx = (w2 - w1) / 2;
16097 } else {
16098 dx = 0;
16099 }
16100 dx++;
16101 y = y1 + h1 - 1;
16102 dy = -y - 1;
16103 move(k1, k2, dx, dy);
16104 if (w2 > w1) {
16105 dx = -w1;
16106 } else {
16107 dx = -w1 + (w1 - w2) / 2;
16108 }
16109 dx++;
16110 dy = -y2 + 1;
16111 move(k2, yindex, dx, dy);
16112 if (w2 > w1) {
16113 w = w2;
16114 } else {
16115 w = w1;
16116 }
16117 w += 2;
16118 emit_x = x;
16119 results = [];
16120 for (i = j1 = 0, ref4 = w; 0 <= ref4 ? j1 < ref4 : j1 > ref4; i = 0 <= ref4 ? ++j1 : --j1) {
16121 results.push(__emit_char('-'));
16122 }
16123 return results;
16124 };
16125
16126 fixup_power = function(k1, k2) {
16127 var dy, h1, h2, ref2, ref3, w1, w2, y1, y2;
16128 dy = 0;
16129 h1 = 0;
16130 w1 = 0;
16131 y1 = 0;
16132 h2 = 0;
16133 w2 = 0;
16134 y2 = 0;
16135 ref2 = get_size(k1, k2), h1 = ref2[0], w1 = ref2[1], y1 = ref2[2];
16136 ref3 = get_size(k2, yindex), h2 = ref3[0], w2 = ref3[1], y2 = ref3[2];
16137 dy = -y2 - h2 + 1;
16138 dy += y1 - 1;
16139 return move(k2, yindex, 0, dy);
16140 };
16141
16142 move = function(j, k, dx, dy) {
16143 var i, j1, ref2, ref3, results;
16144 i = 0;
16145 results = [];
16146 for (i = j1 = ref2 = j, ref3 = k; ref2 <= ref3 ? j1 < ref3 : j1 > ref3; i = ref2 <= ref3 ? ++j1 : --j1) {
16147 chartab[i].x += dx;
16148 results.push(chartab[i].y += dy);
16149 }
16150 return results;
16151 };
16152
16153 get_size = function(j, k) {
16154 var h, i, j1, max_x, max_y, min_x, min_y, ref2, ref3, w, y;
16155 i = 0;
16156 min_x = chartab[j].x;
16157 max_x = chartab[j].x;
16158 min_y = chartab[j].y;
16159 max_y = chartab[j].y;
16160 for (i = j1 = ref2 = j + 1, ref3 = k; ref2 <= ref3 ? j1 < ref3 : j1 > ref3; i = ref2 <= ref3 ? ++j1 : --j1) {
16161 if (chartab[i].x < min_x) {
16162 min_x = chartab[i].x;
16163 }
16164 if (chartab[i].x > max_x) {
16165 max_x = chartab[i].x;
16166 }
16167 if (chartab[i].y < min_y) {
16168 min_y = chartab[i].y;
16169 }
16170 if (chartab[i].y > max_y) {
16171 max_y = chartab[i].y;
16172 }
16173 }
16174 h = max_y - min_y + 1;
16175 w = max_x - min_x + 1;
16176 y = min_y;
16177 return [h, w, y];
16178 };
16179
16180 displaychar = function(c) {
16181 return __emit_char(c);
16182 };
16183
16184 __emit_char = function(c) {
16185 if (yindex === YMAX) {
16186 return;
16187 }
16188 if (chartab[yindex] == null) {
16189 debugger;
16190 }
16191 chartab[yindex].c = c;
16192 chartab[yindex].x = emit_x;
16193 chartab[yindex].y = 0;
16194 yindex++;
16195 return emit_x++;
16196 };
16197
16198 __emit_str = function(s) {
16199 var i, j1, ref2, results;
16200 i = 0;
16201 results = [];
16202 for (i = j1 = 0, ref2 = s.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16203 results.push(__emit_char(s[i]));
16204 }
16205 return results;
16206 };
16207
16208 emit_number = function(p, emit_sign) {
16209 var i, j1, l1, m1, ref2, ref3, ref4, results, results1, tmpString;
16210 tmpString = "";
16211 i = 0;
16212 switch (p.k) {
16213 case NUM:
16214 tmpString = p.q.a.toString();
16215 if (tmpString[0] === '-' && emit_sign === 0) {
16216 tmpString = tmpString.substring(1);
16217 }
16218 for (i = j1 = 0, ref2 = tmpString.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16219 __emit_char(tmpString[i]);
16220 }
16221 tmpString = p.q.b.toString();
16222 if (tmpString === "1") {
16223 break;
16224 }
16225 __emit_char('/');
16226 results = [];
16227 for (i = l1 = 0, ref3 = tmpString.length; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
16228 results.push(__emit_char(tmpString[i]));
16229 }
16230 return results;
16231 break;
16232 case DOUBLE:
16233 tmpString = doubleToReasonableString(p.d);
16234 if (tmpString[0] === '-' && emit_sign === 0) {
16235 tmpString = tmpString.substring(1);
16236 }
16237 results1 = [];
16238 for (i = m1 = 0, ref4 = tmpString.length; 0 <= ref4 ? m1 < ref4 : m1 > ref4; i = 0 <= ref4 ? ++m1 : --m1) {
16239 results1.push(__emit_char(tmpString[i]));
16240 }
16241 return results1;
16242 }
16243 };
16244
16245 cmpGlyphs = function(a, b) {
16246 if (a.y < b.y) {
16247 return -1;
16248 }
16249 if (a.y > b.y) {
16250 return 1;
16251 }
16252 if (a.x < b.x) {
16253 return -1;
16254 }
16255 if (a.x > b.x) {
16256 return 1;
16257 }
16258 return 0;
16259 };
16260
16261 print_glyphs = function() {
16262 var accumulator, i, j1, ref2, subsetOfStack, x, y;
16263 i = 0;
16264 accumulator = "";
16265 subsetOfStack = chartab.slice(0, yindex);
16266 subsetOfStack.sort(cmpGlyphs);
16267 chartab = [].concat(subsetOfStack).concat(chartab.slice(yindex));
16268 x = 0;
16269 y = chartab[0].y;
16270 for (i = j1 = 0, ref2 = yindex; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16271 while (chartab[i].y > y) {
16272 accumulator += printchar('\n');
16273 x = 0;
16274 y++;
16275 }
16276 while (chartab[i].x > x) {
16277 accumulator += printchar_nowrap(' ');
16278 x++;
16279 }
16280 accumulator += printchar_nowrap(chartab[i].c);
16281 x++;
16282 }
16283 return accumulator;
16284 };
16285
16286 buffer = "";
16287
16288 getdisplaystr = function() {
16289 yindex = 0;
16290 level = 0;
16291 emit_x = 0;
16292 emit_expr(pop());
16293 fill_buf();
16294 return buffer;
16295 };
16296
16297 fill_buf = function() {
16298 var i, j1, ref2, sIndex, subsetOfStack, tmpBuffer, x, y;
16299 tmpBuffer = buffer;
16300 sIndex = 0;
16301 i = 0;
16302 subsetOfStack = chartab.slice(0, yindex);
16303 subsetOfStack.sort(cmpGlyphs);
16304 chartab = [].concat(subsetOfStack).concat(chartab.slice(yindex));
16305 x = 0;
16306 y = chartab[0].y;
16307 for (i = j1 = 0, ref2 = yindex; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16308 while (chartab[i].y > y) {
16309 tmpBuffer[sIndex++] = '\n';
16310 x = 0;
16311 y++;
16312 }
16313 while (chartab[i].x > x) {
16314 tmpBuffer[sIndex++] = ' ';
16315 x++;
16316 }
16317 tmpBuffer[sIndex++] = chartab[i].c;
16318 x++;
16319 }
16320 return tmpBuffer[sIndex++] = '\n';
16321 };
16322
16323 N = 100;
16324
16325 oneElement = (function() {
16326 function oneElement() {}
16327
16328 oneElement.prototype.x = 0;
16329
16330 oneElement.prototype.y = 0;
16331
16332 oneElement.prototype.h = 0;
16333
16334 oneElement.prototype.w = 0;
16335
16336 oneElement.prototype.index = 0;
16337
16338 oneElement.prototype.count = 0;
16339
16340 return oneElement;
16341
16342 })();
16343
16344 elem = [];
16345
16346 for (elelmIndex = j1 = 0; j1 < 10000; elelmIndex = ++j1) {
16347 elem[elelmIndex] = new oneElement;
16348 }
16349
16350 SPACE_BETWEEN_COLUMNS = 3;
16351
16352 SPACE_BETWEEN_ROWS = 1;
16353
16354 emit_tensor = function(p) {
16355 var col, dx, dy, eh, ew, h, i, l1, m1, n, n1, ncol, nrow, o1, ref2, ref3, ref4, ref5, ref6, row, w, x, y;
16356 i = 0;
16357 n = 0;
16358 nrow = 0;
16359 ncol = 0;
16360 x = 0;
16361 y = 0;
16362 h = 0;
16363 w = 0;
16364 dx = 0;
16365 dy = 0;
16366 eh = 0;
16367 ew = 0;
16368 row = 0;
16369 col = 0;
16370 if (p.tensor.ndim > 2) {
16371 emit_flat_tensor(p);
16372 return;
16373 }
16374 nrow = p.tensor.dim[0];
16375 if (p.tensor.ndim === 2) {
16376 ncol = p.tensor.dim[1];
16377 } else {
16378 ncol = 1;
16379 }
16380 n = nrow * ncol;
16381 if (n > N) {
16382 emit_flat_tensor(p);
16383 return;
16384 }
16385 x = emit_x;
16386 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
16387 elem[i].index = yindex;
16388 elem[i].x = emit_x;
16389 emit_expr(p.tensor.elem[i]);
16390 elem[i].count = yindex - elem[i].index;
16391 ref3 = get_size(elem[i].index, yindex), elem[i].h = ref3[0], elem[i].w = ref3[1], elem[i].y = ref3[2];
16392 }
16393 eh = 0;
16394 ew = 0;
16395 for (i = m1 = 0, ref4 = n; 0 <= ref4 ? m1 < ref4 : m1 > ref4; i = 0 <= ref4 ? ++m1 : --m1) {
16396 if (elem[i].h > eh) {
16397 eh = elem[i].h;
16398 }
16399 if (elem[i].w > ew) {
16400 ew = elem[i].w;
16401 }
16402 }
16403 h = nrow * eh + (nrow - 1) * SPACE_BETWEEN_ROWS;
16404 w = ncol * ew + (ncol - 1) * SPACE_BETWEEN_COLUMNS;
16405 y = -(h / 2);
16406 for (row = n1 = 0, ref5 = nrow; 0 <= ref5 ? n1 < ref5 : n1 > ref5; row = 0 <= ref5 ? ++n1 : --n1) {
16407 for (col = o1 = 0, ref6 = ncol; 0 <= ref6 ? o1 < ref6 : o1 > ref6; col = 0 <= ref6 ? ++o1 : --o1) {
16408 i = row * ncol + col;
16409 dx = x - elem[i].x;
16410 dy = y - elem[i].y;
16411 move(elem[i].index, elem[i].index + elem[i].count, dx, dy);
16412 dx = 0;
16413 if (col > 0) {
16414 dx = col * (ew + SPACE_BETWEEN_COLUMNS);
16415 }
16416 dy = 0;
16417 if (row > 0) {
16418 dy = row * (eh + SPACE_BETWEEN_ROWS);
16419 }
16420 dx += (ew - elem[i].w) / 2;
16421 dy += (eh - elem[i].h) / 2;
16422 move(elem[i].index, elem[i].index + elem[i].count, dx, dy);
16423 }
16424 }
16425 return emit_x = x + w;
16426
16427 /*
16428 if 0
16429
16430 * left brace
16431
16432 for (i = 0; i < h; i++) {
16433 if (yindex == YMAX)
16434 break
16435 chartab[yindex].c = '|'
16436 chartab[yindex].x = x - 2
16437 chartab[yindex].y = y + i
16438 yindex++
16439 }
16440
16441 * right brace
16442
16443 emit_x++
16444
16445 for (i = 0; i < h; i++) {
16446 if (yindex == YMAX)
16447 break
16448 chartab[yindex].c = '|'
16449 chartab[yindex].x = emit_x
16450 chartab[yindex].y = y + i
16451 yindex++
16452 }
16453
16454 emit_x++
16455
16456 endif
16457 */
16458 };
16459
16460 emit_flat_tensor = function(p) {
16461 return emit_tensor_inner(p, 0, 0);
16462 };
16463
16464 emit_tensor_inner = function(p, j, k) {
16465 var i, l1, ref2;
16466 i = 0;
16467 __emit_char('(');
16468 for (i = l1 = 0, ref2 = p.tensor.dim[j]; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
16469 if (j + 1 === p.tensor.ndim) {
16470 emit_expr(p.tensor.elem[k]);
16471 k = k + 1;
16472 } else {
16473 k = emit_tensor_inner(p, j + 1, k);
16474 }
16475 if (i + 1 < p.tensor.dim[j]) {
16476 __emit_char(',');
16477 }
16478 }
16479 __emit_char(')');
16480 return k;
16481 };
16482
16483 Eval_product = function() {
16484 var body, i, indexVariable, j, k, l1, oldIndexVariableValue, ref2, ref3;
16485 i = 0;
16486 j = 0;
16487 k = 0;
16488 body = cadr(p1);
16489 indexVariable = caddr(p1);
16490 if (!issymbol(p6)) {
16491 stop("sum: 1st arg?");
16492 }
16493 push(cadddr(p1));
16494 Eval();
16495 j = pop_integer();
16496 if (isNaN(j)) {
16497 push(p1);
16498 return;
16499 }
16500 push(caddddr(p1));
16501 Eval();
16502 k = pop_integer();
16503 if (isNaN(k)) {
16504 push(p1);
16505 return;
16506 }
16507 oldIndexVariableValue = get_binding(indexVariable);
16508 push_integer(1);
16509 for (i = l1 = ref2 = j, ref3 = k; ref2 <= ref3 ? l1 <= ref3 : l1 >= ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
16510 push_integer(i);
16511 p5 = pop();
16512 set_binding(indexVariable, p5);
16513 push(body);
16514 Eval();
16515 if (DEBUG) {
16516 console.log("product - factor 1: " + stack[tos - 1].toString());
16517 console.log("product - factor 2: " + stack[tos - 2].toString());
16518 }
16519 multiply();
16520 if (DEBUG) {
16521 console.log("product - result: " + stack[tos - 1].toString());
16522 }
16523 }
16524 return set_binding(indexVariable, oldIndexVariableValue);
16525 };
16526
16527 qadd = function() {
16528 var a, ab, b, ba, c;
16529 save();
16530 p2 = pop();
16531 p1 = pop();
16532 ab = mmul(p1.q.a, p2.q.b);
16533 ba = mmul(p1.q.b, p2.q.a);
16534 a = madd(ab, ba);
16535 if (MZERO(a)) {
16536 push(zero);
16537 restore();
16538 return;
16539 }
16540 b = mmul(p1.q.b, p2.q.b);
16541 c = mgcd(a, b);
16542 c = makeSignSameAs(c, b);
16543 p1 = new U();
16544 p1.k = NUM;
16545 p1.q.a = mdiv(a, c);
16546 p1.q.b = mdiv(b, c);
16547 push(p1);
16548 return restore();
16549 };
16550
16551 qdiv = function() {
16552 var aa, bb, c;
16553 save();
16554 p2 = pop();
16555 p1 = pop();
16556 if (MZERO(p2.q.a)) {
16557 stop("divide by zero");
16558 }
16559 if (MZERO(p1.q.a)) {
16560 push(zero);
16561 restore();
16562 return;
16563 }
16564 aa = mmul(p1.q.a, p2.q.b);
16565 bb = mmul(p1.q.b, p2.q.a);
16566 c = mgcd(aa, bb);
16567 c = makeSignSameAs(c, bb);
16568 p1 = new U();
16569 p1.k = NUM;
16570 p1.q.a = mdiv(aa, c);
16571 p1.q.b = mdiv(bb, c);
16572 push(p1);
16573 return restore();
16574 };
16575
16576 qmul = function() {
16577 var aa, bb, c;
16578 save();
16579 p2 = pop();
16580 p1 = pop();
16581 if (MZERO(p1.q.a) || MZERO(p2.q.a)) {
16582 push(zero);
16583 restore();
16584 return;
16585 }
16586 aa = mmul(p1.q.a, p2.q.a);
16587 bb = mmul(p1.q.b, p2.q.b);
16588 c = mgcd(aa, bb);
16589 c = makeSignSameAs(c, bb);
16590 p1 = new U();
16591 p1.k = NUM;
16592 p1.q.a = mdiv(aa, c);
16593 p1.q.b = mdiv(bb, c);
16594 push(p1);
16595 return restore();
16596 };
16597
16598 qpow = function() {
16599 save();
16600 qpowf();
16601 return restore();
16602 };
16603
16604 qpowf = function() {
16605 var a, b, expo, t, x, y;
16606 expo = 0;
16607 p2 = pop();
16608 p1 = pop();
16609 if (isplusone(p1) || iszero(p2)) {
16610 push_integer(1);
16611 return;
16612 }
16613 if (isminusone(p1) && isoneovertwo(p2)) {
16614 push(imaginaryunit);
16615 return;
16616 }
16617 if (iszero(p1)) {
16618 if (isnegativenumber(p2)) {
16619 stop("divide by zero");
16620 }
16621 push(zero);
16622 return;
16623 }
16624 if (isplusone(p2)) {
16625 push(p1);
16626 return;
16627 }
16628 if (isinteger(p2)) {
16629 push(p2);
16630 expo = pop_integer();
16631 if (isNaN(expo)) {
16632 push_symbol(POWER);
16633 push(p1);
16634 push(p2);
16635 list(3);
16636 return;
16637 }
16638 x = mpow(p1.q.a, Math.abs(expo));
16639 y = mpow(p1.q.b, Math.abs(expo));
16640 if (expo < 0) {
16641 t = x;
16642 x = y;
16643 y = t;
16644 x = makeSignSameAs(x, y);
16645 y = makePositive(y);
16646 }
16647 p3 = new U();
16648 p3.k = NUM;
16649 p3.q.a = x;
16650 p3.q.b = y;
16651 push(p3);
16652 return;
16653 }
16654 if (isminusone(p1)) {
16655 push(p2);
16656 normalize_angle();
16657 return;
16658 }
16659 if (isnegativenumber(p1)) {
16660 push(p1);
16661 negate();
16662 push(p2);
16663 qpow();
16664 push_integer(-1);
16665 push(p2);
16666 qpow();
16667 multiply();
16668 return;
16669 }
16670 if (!isinteger(p1)) {
16671 push(p1);
16672 mp_numerator();
16673 push(p2);
16674 qpow();
16675 push(p1);
16676 mp_denominator();
16677 push(p2);
16678 negate();
16679 qpow();
16680 multiply();
16681 return;
16682 }
16683 if (is_small_integer(p1)) {
16684 push(p1);
16685 push(p2);
16686 quickfactor();
16687 return;
16688 }
16689 if (!p2.q.a.isSmall || !p2.q.b.isSmall) {
16690 push_symbol(POWER);
16691 push(p1);
16692 push(p2);
16693 list(3);
16694 return;
16695 }
16696 a = p2.q.a;
16697 b = p2.q.b;
16698 x = mroot(p1.q.a, b);
16699 if (x === 0) {
16700 push_symbol(POWER);
16701 push(p1);
16702 push(p2);
16703 list(3);
16704 return;
16705 }
16706 y = mpow(x, a);
16707 p3 = new U();
16708 p3.k = NUM;
16709 if (p2.q.a.isNegative()) {
16710 p3.q.a = bigInt(1);
16711 p3.q.b = y;
16712 } else {
16713 p3.q.a = y;
16714 p3.q.b = bigInt(1);
16715 }
16716 return push(p3);
16717 };
16718
16719 normalize_angle = function() {
16720 save();
16721 p1 = pop();
16722 if (isinteger(p1)) {
16723 if (p1.q.a.isOdd()) {
16724 push_integer(-1);
16725 } else {
16726 push_integer(1);
16727 }
16728 restore();
16729 return;
16730 }
16731 push(p1);
16732 bignum_truncate();
16733 p2 = pop();
16734 if (isnegativenumber(p1)) {
16735 push(p2);
16736 push_integer(-1);
16737 add();
16738 p2 = pop();
16739 }
16740 push(p1);
16741 push(p2);
16742 subtract();
16743 p3 = pop();
16744 push_symbol(POWER);
16745 push_integer(-1);
16746 push(p3);
16747 list(3);
16748 if (p2.q.a.isOdd()) {
16749 negate();
16750 }
16751 return restore();
16752 };
16753
16754 is_small_integer = function(p) {
16755 return p.q.a.isSmall;
16756 };
16757
16758 quickfactor = function() {
16759 var h, i, l1, n, ref2, stackIndex;
16760 i = 0;
16761 save();
16762 p2 = pop();
16763 p1 = pop();
16764 h = tos;
16765 push(p1);
16766 factor_small_number();
16767 n = tos - h;
16768 stackIndex = h;
16769 for (i = l1 = 0, ref2 = n; l1 < ref2; i = l1 += 2) {
16770 push(stack[stackIndex + i]);
16771 push(stack[stackIndex + i + 1]);
16772 push(p2);
16773 multiply();
16774 quickpower();
16775 }
16776 multiply_all(tos - h - n);
16777 p1 = pop();
16778 moveTos(h);
16779 push(p1);
16780 return restore();
16781 };
16782
16783 quickpower = function() {
16784 var expo;
16785 expo = 0;
16786 save();
16787 p2 = pop();
16788 p1 = pop();
16789 push(p2);
16790 bignum_truncate();
16791 p3 = pop();
16792 push(p2);
16793 push(p3);
16794 subtract();
16795 p4 = pop();
16796 if (!iszero(p4)) {
16797 push_symbol(POWER);
16798 push(p1);
16799 push(p4);
16800 list(3);
16801 }
16802 push(p3);
16803 expo = pop_integer();
16804 if (isNaN(expo)) {
16805 push_symbol(POWER);
16806 push(p1);
16807 push(p3);
16808 list(3);
16809 restore();
16810 return;
16811 }
16812 if (expo === 0) {
16813 restore();
16814 return;
16815 }
16816 push(p1);
16817 bignum_power_number(expo);
16818 return restore();
16819 };
16820
16821 Eval_quotient = function() {
16822 push(cadr(p1));
16823 Eval();
16824 push(caddr(p1));
16825 Eval();
16826 push(cadddr(p1));
16827 Eval();
16828 p1 = pop();
16829 if (p1 === symbol(NIL)) {
16830 p1 = symbol(SYMBOL_X);
16831 }
16832 push(p1);
16833 return divpoly();
16834 };
16835
16836 divpoly = function() {
16837 var dividend, divisor, h, i, l1, m, n, ref2, x;
16838 h = 0;
16839 i = 0;
16840 m = 0;
16841 n = 0;
16842 x = 0;
16843 save();
16844 p3 = pop();
16845 p2 = pop();
16846 p1 = pop();
16847 h = tos;
16848 dividend = tos;
16849 push(p1);
16850 push(p3);
16851 m = coeff() - 1;
16852 divisor = tos;
16853 push(p2);
16854 push(p3);
16855 n = coeff() - 1;
16856 x = m - n;
16857 push_integer(0);
16858 p5 = pop();
16859 while (x >= 0) {
16860 push(stack[dividend + m]);
16861 push(stack[divisor + n]);
16862 divide();
16863 p4 = pop();
16864 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 0 <= ref2 ? ++l1 : --l1) {
16865 push(stack[dividend + x + i]);
16866 push(stack[divisor + i]);
16867 push(p4);
16868 multiply();
16869 subtract();
16870 stack[dividend + x + i] = pop();
16871 }
16872 push(p5);
16873 push(p4);
16874 push(p3);
16875 push_integer(x);
16876 power();
16877 multiply();
16878 add();
16879 p5 = pop();
16880 m--;
16881 x--;
16882 }
16883 moveTos(h);
16884 push(p5);
16885 return restore();
16886 };
16887
16888 Eval_rationalize = function() {
16889 push(cadr(p1));
16890 Eval();
16891 return rationalize();
16892 };
16893
16894 rationalize = function() {
16895 var x;
16896 x = expanding;
16897 save();
16898 yyrationalize();
16899 restore();
16900 return expanding = x;
16901 };
16902
16903 yyrationalize = function() {
16904 p1 = pop();
16905 if (istensor(p1)) {
16906 __rationalize_tensor();
16907 return;
16908 }
16909 expanding = 0;
16910 if (car(p1) !== symbol(ADD)) {
16911 push(p1);
16912 return;
16913 }
16914 if (DEBUG) {
16915 printf("rationalize: this is the input expr:\n");
16916 printline(p1);
16917 }
16918 push(one);
16919 multiply_denominators(p1);
16920 p2 = pop();
16921 if (DEBUG) {
16922 printf("rationalize: this is the common denominator:\n");
16923 printline(p2);
16924 }
16925 push(zero);
16926 p3 = cdr(p1);
16927 while (iscons(p3)) {
16928 push(p2);
16929 push(car(p3));
16930 multiply();
16931 add();
16932 p3 = cdr(p3);
16933 }
16934 if (DEBUG) {
16935 printf("rationalize: original expr times common denominator:\n");
16936 printline(stack[tos - 1]);
16937 }
16938 Condense();
16939 if (DEBUG) {
16940 printf("rationalize: after factoring:\n");
16941 printline(stack[tos - 1]);
16942 }
16943 push(p2);
16944 divide();
16945 if (DEBUG) {
16946 printf("rationalize: after dividing by common denom. (and we're done):\n");
16947 return printline(stack[tos - 1]);
16948 }
16949 };
16950
16951 multiply_denominators = function(p) {
16952 var results;
16953 if (car(p) === symbol(ADD)) {
16954 p = cdr(p);
16955 results = [];
16956 while (iscons(p)) {
16957 multiply_denominators_term(car(p));
16958 results.push(p = cdr(p));
16959 }
16960 return results;
16961 } else {
16962 return multiply_denominators_term(p);
16963 }
16964 };
16965
16966 multiply_denominators_term = function(p) {
16967 var results;
16968 if (car(p) === symbol(MULTIPLY)) {
16969 p = cdr(p);
16970 results = [];
16971 while (iscons(p)) {
16972 multiply_denominators_factor(car(p));
16973 results.push(p = cdr(p));
16974 }
16975 return results;
16976 } else {
16977 return multiply_denominators_factor(p);
16978 }
16979 };
16980
16981 multiply_denominators_factor = function(p) {
16982 if (car(p) !== symbol(POWER)) {
16983 return;
16984 }
16985 push(p);
16986 p = caddr(p);
16987 if (isnegativenumber(p)) {
16988 inverse();
16989 __lcm();
16990 return;
16991 }
16992 if (car(p) === symbol(MULTIPLY) && isnegativenumber(cadr(p))) {
16993 inverse();
16994 __lcm();
16995 return;
16996 }
16997 return pop();
16998 };
16999
17000 __rationalize_tensor = function() {
17001 var i, l1, n, ref2;
17002 i = 0;
17003 push(p1);
17004 Eval();
17005 p1 = pop();
17006 if (!istensor(p1)) {
17007 push(p1);
17008 return;
17009 }
17010 n = p1.tensor.nelem;
17011 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
17012 push(p1.tensor.elem[i]);
17013 rationalize();
17014 p1.tensor.elem[i] = pop();
17015 }
17016 check_tensor_dimensions(p1);
17017 return push(p1);
17018 };
17019
17020 __lcm = function() {
17021 save();
17022 p1 = pop();
17023 p2 = pop();
17024 push(p1);
17025 push(p2);
17026 multiply();
17027 push(p1);
17028 push(p2);
17029 gcd();
17030 divide();
17031 return restore();
17032 };
17033
17034
17035 /*
17036 Returns the real part of complex z
17037
17038 z real(z)
17039 - -------
17040
17041 a + i b a
17042
17043 exp(i a) cos(a)
17044 */
17045
17046 Eval_real = function() {
17047 push(cadr(p1));
17048 Eval();
17049 return real();
17050 };
17051
17052 real = function() {
17053 save();
17054 rect();
17055 p1 = pop();
17056 push(p1);
17057 push(p1);
17058 conjugate();
17059 add();
17060 push_integer(2);
17061 divide();
17062 return restore();
17063 };
17064
17065
17066 /*
17067 Convert complex z to rectangular form
17068
17069 Input: push z
17070
17071 Output: Result on stack
17072 */
17073
17074 DEBUG_RECT = false;
17075
17076 Eval_rect = function() {
17077 push(cadr(p1));
17078 Eval();
17079 return rect();
17080 };
17081
17082 rect = function() {
17083 var input;
17084 save();
17085 p1 = pop();
17086 input = p1;
17087 if (DEBUG_RECT) {
17088 console.log("RECT of " + input);
17089 }
17090 if (DEBUG_RECT) {
17091 console.log("any clock forms in : " + input + " ? " + findPossibleClockForm(input));
17092 }
17093 if (issymbol(p1)) {
17094 if (DEBUG_RECT) {
17095 console.log(" rect: simple symbol: " + input);
17096 }
17097 if (!iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
17098 push(p1);
17099 } else {
17100 push_symbol(YYRECT);
17101 push(p1);
17102 list(2);
17103 }
17104 } else if (!iszero(get_binding(symbol(ASSUME_REAL_VARIABLES))) && !findPossibleExponentialForm(p1) && !findPossibleClockForm(p1) && !(Find(p1, symbol(SIN)) && Find(p1, symbol(COS)) && Find(p1, imaginaryunit))) {
17105 if (DEBUG_RECT) {
17106 console.log(" rect: simple symbol: " + input);
17107 }
17108 push(p1);
17109 } else if (car(p1) === symbol(MULTIPLY) && isimaginaryunit(cadr(p1)) && !iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
17110 push(p1);
17111 } else if (car(p1) === symbol(ADD)) {
17112 if (DEBUG_RECT) {
17113 console.log(" rect - " + input + " is a sum ");
17114 }
17115 push_integer(0);
17116 p1 = cdr(p1);
17117 while (iscons(p1)) {
17118 push(car(p1));
17119 rect();
17120 add();
17121 p1 = cdr(p1);
17122 }
17123 } else {
17124 if (DEBUG_RECT) {
17125 console.log(" rect - " + input + " is NOT a sum ");
17126 }
17127 push(p1);
17128 abs();
17129 if (DEBUG_RECT) {
17130 console.log(" rect - " + input + " abs: " + stack[tos - 1].toString());
17131 }
17132 push(p1);
17133 arg();
17134 if (DEBUG_RECT) {
17135 console.log(" rect - " + input + " arg of " + p1 + " : " + stack[tos - 1].toString());
17136 }
17137 p1 = pop();
17138 push(p1);
17139 cosine();
17140 if (DEBUG_RECT) {
17141 console.log(" rect - " + input + " cosine: " + stack[tos - 1].toString());
17142 }
17143 push(imaginaryunit);
17144 push(p1);
17145 sine();
17146 if (DEBUG_RECT) {
17147 console.log(" rect - " + input + " sine: " + stack[tos - 1].toString());
17148 }
17149 multiply();
17150 if (DEBUG_RECT) {
17151 console.log(" rect - " + input + " i * sine: " + stack[tos - 1].toString());
17152 }
17153 add();
17154 if (DEBUG_RECT) {
17155 console.log(" rect - " + input + " cos + i * sine: " + stack[tos - 1].toString());
17156 }
17157 multiply();
17158 }
17159 restore();
17160 if (DEBUG_RECT) {
17161 return console.log("rect of " + input + " : " + stack[tos - 1]);
17162 }
17163 };
17164
17165 show_power_debug = false;
17166
17167 performing_roots = false;
17168
17169 Eval_roots = function() {
17170 p2 = cadr(p1);
17171 if (car(p2) === symbol(SETQ) || car(p2) === symbol(TESTEQ)) {
17172 push(cadr(p2));
17173 Eval();
17174 push(caddr(p2));
17175 Eval();
17176 subtract();
17177 } else {
17178 push(p2);
17179 Eval();
17180 p2 = pop();
17181 if (car(p2) === symbol(SETQ) || car(p2) === symbol(TESTEQ)) {
17182 push(cadr(p2));
17183 Eval();
17184 push(caddr(p2));
17185 Eval();
17186 subtract();
17187 } else {
17188 push(p2);
17189 }
17190 }
17191 push(caddr(p1));
17192 Eval();
17193 p2 = pop();
17194 if (p2 === symbol(NIL)) {
17195 guess();
17196 } else {
17197 push(p2);
17198 }
17199 p2 = pop();
17200 p1 = pop();
17201 if (!ispoly(p1, p2)) {
17202 stop("roots: 1st argument is not a polynomial");
17203 }
17204 push(p1);
17205 push(p2);
17206 return roots();
17207 };
17208
17209 hasImaginaryCoeff = function(k) {
17210 var h, i, imaginaryCoefficients, l1, ref2;
17211 imaginaryCoefficients = false;
17212 h = tos;
17213 for (i = l1 = ref2 = k; l1 > 0; i = l1 += -1) {
17214 if (iscomplexnumber(stack[tos - i])) {
17215 imaginaryCoefficients = true;
17216 break;
17217 }
17218 }
17219 return imaginaryCoefficients;
17220 };
17221
17222 isSimpleRoot = function(k) {
17223 var h, i, isSimpleRootPolynomial, l1, ref2;
17224 if (k > 2) {
17225 isSimpleRootPolynomial = true;
17226 h = tos;
17227 if (iszero(stack[tos - k])) {
17228 isSimpleRootPolynomial = false;
17229 }
17230 for (i = l1 = ref2 = k - 1; l1 > 1; i = l1 += -1) {
17231 if (!iszero(stack[tos - i])) {
17232 isSimpleRootPolynomial = false;
17233 break;
17234 }
17235 }
17236 } else {
17237 isSimpleRootPolynomial = false;
17238 }
17239 return isSimpleRootPolynomial;
17240 };
17241
17242 normalisedCoeff = function() {
17243 var divideBy, i, k, l1, m1, miniStack, ref2, ref3;
17244 k = coeff();
17245 divideBy = stack[tos - 1];
17246 miniStack = [];
17247 for (i = l1 = 1, ref2 = k; 1 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 1 <= ref2 ? ++l1 : --l1) {
17248 miniStack.push(pop());
17249 }
17250 for (i = m1 = ref3 = k - 1; ref3 <= 0 ? m1 <= 0 : m1 >= 0; i = ref3 <= 0 ? ++m1 : --m1) {
17251 push(miniStack[i]);
17252 push(divideBy);
17253 divide();
17254 }
17255 return k;
17256 };
17257
17258 roots = function() {
17259 var h, i, k, l1, lastCoeff, leadingCoeff, n, ref2;
17260 h = 0;
17261 i = 0;
17262 n = 0;
17263 save();
17264 if (recursionLevelNestedRadicalsRemoval > 1) {
17265 pop();
17266 pop();
17267 push(symbol(NIL));
17268 restore();
17269 return;
17270 }
17271 performing_roots = true;
17272 h = tos - 2;
17273 if (DEBUG) {
17274 console.log("checking if " + stack[tos - 1].toString() + " is a case of simple roots");
17275 }
17276 p2 = pop();
17277 p1 = pop();
17278 push(p1);
17279 push(p2);
17280 push(p1);
17281 push(p2);
17282 k = normalisedCoeff();
17283 if (isSimpleRoot(k)) {
17284 if (DEBUG) {
17285 console.log("yes, " + stack[tos - 1].toString() + " is a case of simple roots");
17286 }
17287 lastCoeff = stack[tos - k];
17288 leadingCoeff = stack[tos - 1];
17289 moveTos(tos - k);
17290 pop();
17291 pop();
17292 getSimpleRoots(k, leadingCoeff, lastCoeff);
17293 } else {
17294 moveTos(tos - k);
17295 roots2();
17296 }
17297 n = tos - h;
17298 if (n === 0) {
17299 stop("roots: the polynomial is not factorable, try nroots");
17300 }
17301 if (n === 1) {
17302 performing_roots = false;
17303 restore();
17304 return;
17305 }
17306 sort_stack(n);
17307 p1 = alloc_tensor(n);
17308 p1.tensor.ndim = 1;
17309 p1.tensor.dim[0] = n;
17310 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
17311 p1.tensor.elem[i] = stack[h + i];
17312 }
17313 moveTos(h);
17314 push(p1);
17315 restore();
17316 return performing_roots = false;
17317 };
17318
17319 getSimpleRoots = function(n, leadingCoeff, lastCoeff) {
17320 var aSol, commonPart, l1, m1, ref2, ref3, rootsOfOne;
17321 if (DEBUG) {
17322 console.log("getSimpleRoots");
17323 }
17324 save();
17325 n = n - 1;
17326 push(lastCoeff);
17327 push_rational(1, n);
17328 power();
17329 push(leadingCoeff);
17330 push_rational(1, n);
17331 power();
17332 divide();
17333 commonPart = pop();
17334 if (n % 2 === 0) {
17335 for (rootsOfOne = l1 = 1, ref2 = n; l1 <= ref2; rootsOfOne = l1 += 2) {
17336 push(commonPart);
17337 push_integer(-1);
17338 push_rational(rootsOfOne, n);
17339 power();
17340 multiply();
17341 aSol = pop();
17342 push(aSol);
17343 push(aSol);
17344 negate();
17345 }
17346 } else {
17347 for (rootsOfOne = m1 = 1, ref3 = n; 1 <= ref3 ? m1 <= ref3 : m1 >= ref3; rootsOfOne = 1 <= ref3 ? ++m1 : --m1) {
17348 push(commonPart);
17349 push_integer(-1);
17350 push_rational(rootsOfOne, n);
17351 power();
17352 multiply();
17353 if (rootsOfOne % 2 === 0) {
17354 negate();
17355 }
17356 }
17357 }
17358 return restore();
17359 };
17360
17361 roots2 = function() {
17362 var k;
17363 save();
17364 p2 = pop();
17365 p1 = pop();
17366 push(p1);
17367 push(p2);
17368 push(p1);
17369 push(p2);
17370 k = normalisedCoeff();
17371 if (!hasImaginaryCoeff(k)) {
17372 moveTos(tos - k);
17373 factorpoly();
17374 p1 = pop();
17375 } else {
17376 moveTos(tos - k);
17377 pop();
17378 pop();
17379 }
17380 if (car(p1) === symbol(MULTIPLY)) {
17381 p1 = cdr(p1);
17382 while (iscons(p1)) {
17383 push(car(p1));
17384 push(p2);
17385 roots3();
17386 p1 = cdr(p1);
17387 }
17388 } else {
17389 push(p1);
17390 push(p2);
17391 roots3();
17392 }
17393 return restore();
17394 };
17395
17396 roots3 = function() {
17397 var n;
17398 save();
17399 p2 = pop();
17400 p1 = pop();
17401 if (car(p1) === symbol(POWER) && ispoly(cadr(p1), p2) && isposint(caddr(p1))) {
17402 push(cadr(p1));
17403 push(p2);
17404 n = normalisedCoeff();
17405 mini_solve(n);
17406 } else if (ispoly(p1, p2)) {
17407 push(p1);
17408 push(p2);
17409 n = normalisedCoeff();
17410 mini_solve(n);
17411 }
17412 return restore();
17413 };
17414
17415 mini_solve = function(n) {
17416 var C_CHECKED_AS_NOT_ZERO, Q_CHECKED_AS_NOT_ZERO, R_18_a_b_c_d, R_27_a2_d, R_2_b3, R_3_a, R_3_a_C, R_3_a_c, R_4_DELTA03, R_6_a, R_6_a_C, R_C, R_C_over_3a, R_C_simplified_toCheckIfZero, R_DELTA0, R_DELTA0_simplified_toCheckIfZero, R_DELTA0_toBeCheckedIfZero, R_DELTA1, R_Q, R_Q_simplified_toCheckIfZero, R_S, R_S_simplified_toCheckIfZero, R_a2, R_a2_d, R_a2_d2, R_a3, R_a_b_c, R_a_b_c_d, R_a_c, R_b2, R_b2_c2, R_b3, R_b3_d, R_c2, R_c3, R_d2, R_determinant, R_determinant_simplified_toCheckIfZero, R_e2, R_e3, R_m, R_m27_a2_d2, R_m4_a_c3, R_m4_b3_d, R_m9_a_b_c, R_m_b_over_3a, R_minus_4S2_minus_2p, R_minus_b_over_4a, R_p, R_principalCubicRoot, R_q, R_q_over_S, R_r, S_CHECKED_AS_NOT_ZERO, ThreePPlus2M, TwoQOversqrtPPlus2M, biquadraticSolutions, choiceOfRadicalInQSoSIsNotZero, coeff2, coeff3, coeff4, depressedSolutions, eachSolution, flipSignOFQSoCIsNotZero, flipSignOFRadicalSoQIsNotZero, i_sqrt3, l1, len, len1, len2, m1, n1, one_minus_i_sqrt3, one_plus_i_sqrt3, ref2, ref3, ref4, resolventCubicSolutions, root_solution, sqrtPPlus2M, toBeCheckedIFZero;
17417 save();
17418 if (n === 2) {
17419 p3 = pop();
17420 p4 = pop();
17421 push(p4);
17422 push(p3);
17423 divide();
17424 negate();
17425 restore();
17426 return;
17427 }
17428 if (n === 3) {
17429 p3 = pop();
17430 p4 = pop();
17431 p5 = pop();
17432 push(p4);
17433 push_integer(2);
17434 power();
17435 push_integer(4);
17436 push(p3);
17437 multiply();
17438 push(p5);
17439 multiply();
17440 subtract();
17441 push_rational(1, 2);
17442 power();
17443 p6 = pop();
17444 push(p6);
17445 push(p4);
17446 subtract();
17447 push(p3);
17448 push_integer(2);
17449 multiply();
17450 divide();
17451 push(p6);
17452 push(p4);
17453 add();
17454 negate();
17455 push(p3);
17456 divide();
17457 push_rational(1, 2);
17458 multiply();
17459 restore();
17460 return;
17461 }
17462 if (n === 4 || n === 5) {
17463 p3 = pop();
17464 p4 = pop();
17465 p5 = pop();
17466 p6 = pop();
17467 push(p5);
17468 push(p5);
17469 multiply();
17470 R_c2 = pop();
17471 push(R_c2);
17472 push(p5);
17473 multiply();
17474 R_c3 = pop();
17475 push(p4);
17476 push(p4);
17477 multiply();
17478 R_b2 = pop();
17479 push(R_b2);
17480 push(p4);
17481 multiply();
17482 R_b3 = pop();
17483 push(R_b3);
17484 push(p6);
17485 multiply();
17486 R_b3_d = pop();
17487 push(R_b3_d);
17488 push_integer(-4);
17489 multiply();
17490 R_m4_b3_d = pop();
17491 push(R_b3);
17492 push_integer(2);
17493 multiply();
17494 R_2_b3 = pop();
17495 push(p3);
17496 push(p3);
17497 multiply();
17498 R_a2 = pop();
17499 push(R_a2);
17500 push(p3);
17501 multiply();
17502 R_a3 = pop();
17503 push_integer(3);
17504 push(p3);
17505 multiply();
17506 R_3_a = pop();
17507 push(R_a2);
17508 push(p6);
17509 multiply();
17510 R_a2_d = pop();
17511 push(R_a2_d);
17512 push(p6);
17513 multiply();
17514 R_a2_d2 = pop();
17515 push(R_a2_d);
17516 push_integer(27);
17517 multiply();
17518 R_27_a2_d = pop();
17519 push(R_a2_d2);
17520 push_integer(-27);
17521 multiply();
17522 R_m27_a2_d2 = pop();
17523 push(R_3_a);
17524 push_integer(2);
17525 multiply();
17526 R_6_a = pop();
17527 push(p3);
17528 push(p5);
17529 multiply();
17530 R_a_c = pop();
17531 push(R_a_c);
17532 push(p4);
17533 multiply();
17534 R_a_b_c = pop();
17535 push(R_a_b_c);
17536 push(p6);
17537 multiply();
17538 R_a_b_c_d = pop();
17539 push(R_a_c);
17540 push_integer(3);
17541 multiply();
17542 R_3_a_c = pop();
17543 push_integer(-4);
17544 push(p3);
17545 push(R_c3);
17546 multiply();
17547 multiply();
17548 R_m4_a_c3 = pop();
17549 push(R_a_b_c);
17550 push_integer(9);
17551 multiply();
17552 negate();
17553 R_m9_a_b_c = pop();
17554 push(R_a_b_c_d);
17555 push_integer(18);
17556 multiply();
17557 R_18_a_b_c_d = pop();
17558 push(R_b2);
17559 push(R_3_a_c);
17560 subtract();
17561 R_DELTA0 = pop();
17562 push(R_b2);
17563 push(R_c2);
17564 multiply();
17565 R_b2_c2 = pop();
17566 push(p4);
17567 negate();
17568 push(R_3_a);
17569 divide();
17570 R_m_b_over_3a = pop();
17571 if (n === 4) {
17572 if (DEBUG) {
17573 console.log(">>>>>>>>>>>>>>>> actually using cubic formula <<<<<<<<<<<<<<< ");
17574 }
17575 if (DEBUG) {
17576 console.log("cubic: D0: " + R_DELTA0.toString());
17577 }
17578 push(R_DELTA0);
17579 push_integer(3);
17580 power();
17581 push_integer(4);
17582 multiply();
17583 R_4_DELTA03 = pop();
17584 push(R_DELTA0);
17585 simplify();
17586 absValFloat();
17587 R_DELTA0_toBeCheckedIfZero = pop();
17588 if (DEBUG) {
17589 console.log("cubic: D0 as float: " + R_DELTA0_toBeCheckedIfZero.toString());
17590 }
17591 push(R_18_a_b_c_d);
17592 push(R_m4_b3_d);
17593 push(R_b2_c2);
17594 push(R_m4_a_c3);
17595 push(R_m27_a2_d2);
17596 add();
17597 add();
17598 add();
17599 add();
17600 simplify();
17601 absValFloat();
17602 R_determinant = pop();
17603 if (DEBUG) {
17604 console.log("cubic: DETERMINANT: " + R_determinant.toString());
17605 }
17606 push(R_2_b3);
17607 push(R_m9_a_b_c);
17608 push(R_27_a2_d);
17609 add();
17610 add();
17611 R_DELTA1 = pop();
17612 if (DEBUG) {
17613 console.log("cubic: D1: " + R_DELTA1.toString());
17614 }
17615 push(R_DELTA1);
17616 push_integer(2);
17617 power();
17618 push(R_4_DELTA03);
17619 subtract();
17620 push_rational(1, 2);
17621 power();
17622 simplify();
17623 R_Q = pop();
17624 if (iszero(R_determinant)) {
17625 if (iszero(R_DELTA0_toBeCheckedIfZero)) {
17626 if (DEBUG) {
17627 console.log(" cubic: DETERMINANT IS ZERO and delta0 is zero");
17628 }
17629 push(R_m_b_over_3a);
17630 restore();
17631 return;
17632 } else {
17633 if (DEBUG) {
17634 console.log(" cubic: DETERMINANT IS ZERO and delta0 is not zero");
17635 }
17636 push(p3);
17637 push(p6);
17638 push_integer(9);
17639 multiply();
17640 multiply();
17641 push(p4);
17642 push(p5);
17643 multiply();
17644 subtract();
17645 push(R_DELTA0);
17646 push_integer(2);
17647 multiply();
17648 divide();
17649 root_solution = pop();
17650 push(root_solution);
17651 push(root_solution);
17652 push(R_a_b_c);
17653 push_integer(4);
17654 multiply();
17655 push(p3);
17656 push(p3);
17657 push(p6);
17658 push_integer(9);
17659 multiply();
17660 multiply();
17661 multiply();
17662 negate();
17663 push(R_b3);
17664 negate();
17665 add();
17666 add();
17667 push(p3);
17668 push(R_DELTA0);
17669 multiply();
17670 divide();
17671 restore();
17672 return;
17673 }
17674 }
17675 C_CHECKED_AS_NOT_ZERO = false;
17676 flipSignOFQSoCIsNotZero = false;
17677 while (!C_CHECKED_AS_NOT_ZERO) {
17678 push(R_Q);
17679 if (flipSignOFQSoCIsNotZero) {
17680 negate();
17681 }
17682 push(R_DELTA1);
17683 add();
17684 push_rational(1, 2);
17685 multiply();
17686 push_rational(1, 3);
17687 power();
17688 simplify();
17689 R_C = pop();
17690 if (DEBUG) {
17691 console.log("cubic: C: " + R_C.toString());
17692 }
17693 push(R_C);
17694 simplify();
17695 absValFloat();
17696 R_C_simplified_toCheckIfZero = pop();
17697 if (DEBUG) {
17698 console.log("cubic: C as absval and float: " + R_C_simplified_toCheckIfZero.toString());
17699 }
17700 if (iszero(R_C_simplified_toCheckIfZero)) {
17701 if (DEBUG) {
17702 console.log(" cubic: C IS ZERO flipping the sign");
17703 }
17704 flipSignOFQSoCIsNotZero = true;
17705 } else {
17706 C_CHECKED_AS_NOT_ZERO = true;
17707 }
17708 }
17709 push(R_C);
17710 push(R_3_a);
17711 multiply();
17712 R_3_a_C = pop();
17713 push(R_3_a_C);
17714 push_integer(2);
17715 multiply();
17716 R_6_a_C = pop();
17717 push(imaginaryunit);
17718 push_integer(3);
17719 push_rational(1, 2);
17720 power();
17721 multiply();
17722 i_sqrt3 = pop();
17723 push_integer(1);
17724 push(i_sqrt3);
17725 add();
17726 one_plus_i_sqrt3 = pop();
17727 push_integer(1);
17728 push(i_sqrt3);
17729 subtract();
17730 one_minus_i_sqrt3 = pop();
17731 push(R_C);
17732 push(R_3_a);
17733 divide();
17734 R_C_over_3a = pop();
17735 push(R_m_b_over_3a);
17736 push(R_C_over_3a);
17737 negate();
17738 push(R_DELTA0);
17739 push(R_3_a_C);
17740 divide();
17741 negate();
17742 add();
17743 add();
17744 simplify();
17745 push(R_m_b_over_3a);
17746 push(R_C_over_3a);
17747 push(one_plus_i_sqrt3);
17748 multiply();
17749 push_integer(2);
17750 divide();
17751 push(one_minus_i_sqrt3);
17752 push(R_DELTA0);
17753 multiply();
17754 push(R_6_a_C);
17755 divide();
17756 add();
17757 add();
17758 simplify();
17759 push(R_m_b_over_3a);
17760 push(R_C_over_3a);
17761 push(one_minus_i_sqrt3);
17762 multiply();
17763 push_integer(2);
17764 divide();
17765 push(one_plus_i_sqrt3);
17766 push(R_DELTA0);
17767 multiply();
17768 push(R_6_a_C);
17769 divide();
17770 add();
17771 add();
17772 simplify();
17773 restore();
17774 return;
17775 }
17776 if (n === 5) {
17777 if (DEBUG) {
17778 console.log(">>>>>>>>>>>>>>>> actually using quartic formula <<<<<<<<<<<<<<< ");
17779 }
17780 p7 = pop();
17781 if (iszero(p4) && iszero(p6) && !iszero(p5) && !iszero(p7)) {
17782 if (DEBUG) {
17783 console.log("biquadratic case");
17784 }
17785 push(p3);
17786 push(symbol(SECRETX));
17787 push_integer(2);
17788 power();
17789 multiply();
17790 push(p5);
17791 push(symbol(SECRETX));
17792 multiply();
17793 push(p7);
17794 add();
17795 add();
17796 push(symbol(SECRETX));
17797 roots();
17798 biquadraticSolutions = pop();
17799 ref2 = biquadraticSolutions.tensor.elem;
17800 for (l1 = 0, len = ref2.length; l1 < len; l1++) {
17801 eachSolution = ref2[l1];
17802 push(eachSolution);
17803 push_rational(1, 2);
17804 power();
17805 simplify();
17806 push(eachSolution);
17807 push_rational(1, 2);
17808 power();
17809 negate();
17810 simplify();
17811 }
17812 restore();
17813 return;
17814 }
17815 push(p6);
17816 push(p6);
17817 multiply();
17818 R_d2 = pop();
17819 push(p7);
17820 push(p7);
17821 multiply();
17822 R_e2 = pop();
17823 push(R_e2);
17824 push(p7);
17825 multiply();
17826 R_e3 = pop();
17827 push_integer(256);
17828 push(R_a3);
17829 push(R_e3);
17830 multiply();
17831 multiply();
17832 push_integer(-192);
17833 push(R_a2_d);
17834 push(R_e2);
17835 push(p4);
17836 multiply();
17837 multiply();
17838 multiply();
17839 push_integer(-128);
17840 push(R_a2);
17841 push(R_c2);
17842 push(R_e2);
17843 multiply();
17844 multiply();
17845 multiply();
17846 push_integer(144);
17847 push(R_a2_d2);
17848 push(p5);
17849 push(p7);
17850 multiply();
17851 multiply();
17852 multiply();
17853 push(R_m27_a2_d2);
17854 push(R_d2);
17855 multiply();
17856 push_integer(144);
17857 push(R_a_b_c);
17858 push(p4);
17859 push(R_e2);
17860 multiply();
17861 multiply();
17862 multiply();
17863 push_integer(-6);
17864 push(p3);
17865 push(R_b2);
17866 push(R_d2);
17867 push(p7);
17868 multiply();
17869 multiply();
17870 multiply();
17871 multiply();
17872 push_integer(-80);
17873 push(R_a_b_c_d);
17874 push(p5);
17875 push(p7);
17876 multiply();
17877 multiply();
17878 multiply();
17879 push_integer(18);
17880 push(R_a_b_c_d);
17881 push(R_d2);
17882 multiply();
17883 multiply();
17884 push_integer(16);
17885 push(R_a_c);
17886 push(R_c3);
17887 push(p7);
17888 multiply();
17889 multiply();
17890 multiply();
17891 push_integer(-4);
17892 push(R_a_c);
17893 push(R_c2);
17894 push(R_d2);
17895 multiply();
17896 multiply();
17897 multiply();
17898 push_integer(-27);
17899 push(R_b3);
17900 push(p4);
17901 push(R_e2);
17902 multiply();
17903 multiply();
17904 multiply();
17905 push_integer(18);
17906 push(R_b3_d);
17907 push(p5);
17908 push(p7);
17909 multiply();
17910 multiply();
17911 multiply();
17912 push(R_m4_b3_d);
17913 push(R_d2);
17914 multiply();
17915 push_integer(-4);
17916 push(R_b2_c2);
17917 push(p5);
17918 push(p7);
17919 multiply();
17920 multiply();
17921 multiply();
17922 push(R_b2_c2);
17923 push(R_d2);
17924 multiply();
17925 add();
17926 add();
17927 add();
17928 add();
17929 add();
17930 add();
17931 add();
17932 add();
17933 add();
17934 add();
17935 add();
17936 add();
17937 add();
17938 add();
17939 add();
17940 R_determinant = pop();
17941 if (DEBUG) {
17942 console.log("R_determinant: " + R_determinant.toString());
17943 }
17944 push(R_c2);
17945 push_integer(-3);
17946 push(p4);
17947 push(p6);
17948 multiply();
17949 multiply();
17950 push_integer(12);
17951 push(p3);
17952 push(p7);
17953 multiply();
17954 multiply();
17955 add();
17956 add();
17957 R_DELTA0 = pop();
17958 if (DEBUG) {
17959 console.log("R_DELTA0: " + R_DELTA0.toString());
17960 }
17961 push_integer(2);
17962 push(R_c3);
17963 multiply();
17964 push_integer(-9);
17965 push(p4);
17966 push(p5);
17967 push(p6);
17968 multiply();
17969 multiply();
17970 multiply();
17971 push_integer(27);
17972 push(R_b2);
17973 push(p7);
17974 multiply();
17975 multiply();
17976 push_integer(27);
17977 push(p3);
17978 push(R_d2);
17979 multiply();
17980 multiply();
17981 push_integer(-72);
17982 push(R_a_c);
17983 push(p7);
17984 multiply();
17985 multiply();
17986 add();
17987 add();
17988 add();
17989 add();
17990 R_DELTA1 = pop();
17991 if (DEBUG) {
17992 console.log("R_DELTA1: " + R_DELTA1.toString());
17993 }
17994 push_integer(8);
17995 push(R_a_c);
17996 multiply();
17997 push_integer(-3);
17998 push(R_b2);
17999 multiply();
18000 add();
18001 push_integer(8);
18002 push(R_a2);
18003 multiply();
18004 divide();
18005 R_p = pop();
18006 if (DEBUG) {
18007 console.log("p: " + R_p.toString());
18008 }
18009 push(R_b3);
18010 push_integer(-4);
18011 push(R_a_b_c);
18012 multiply();
18013 push_integer(8);
18014 push(R_a2_d);
18015 multiply();
18016 add();
18017 add();
18018 push_integer(8);
18019 push(R_a3);
18020 multiply();
18021 divide();
18022 R_q = pop();
18023 if (DEBUG) {
18024 console.log("q: " + R_q.toString());
18025 }
18026 if (DEBUG) {
18027 console.log("tos 1 " + tos);
18028 }
18029 if (!iszero(p4)) {
18030 if (DEBUG) {
18031 console.log("tos 2 " + tos);
18032 }
18033 push_integer(8);
18034 push(p5);
18035 push(p3);
18036 multiply();
18037 multiply();
18038 push_integer(-3);
18039 push(p4);
18040 push_integer(2);
18041 power();
18042 multiply();
18043 add();
18044 push_integer(8);
18045 push(p3);
18046 push_integer(2);
18047 power();
18048 multiply();
18049 divide();
18050 R_p = pop();
18051 if (DEBUG) {
18052 console.log("p for depressed quartic: " + R_p.toString());
18053 }
18054 push(p4);
18055 push_integer(3);
18056 power();
18057 push_integer(-4);
18058 push(p3);
18059 push(p4);
18060 push(p5);
18061 multiply();
18062 multiply();
18063 multiply();
18064 push_integer(8);
18065 push(p6);
18066 push(p3);
18067 push_integer(2);
18068 power();
18069 multiply();
18070 multiply();
18071 add();
18072 add();
18073 push_integer(8);
18074 push(p3);
18075 push_integer(3);
18076 power();
18077 multiply();
18078 divide();
18079 R_q = pop();
18080 if (DEBUG) {
18081 console.log("q for depressed quartic: " + R_q.toString());
18082 }
18083 push(p4);
18084 push_integer(4);
18085 power();
18086 push_integer(-3);
18087 multiply();
18088 push_integer(256);
18089 push(R_a3);
18090 push(p7);
18091 multiply();
18092 multiply();
18093 push_integer(-64);
18094 push(R_a2_d);
18095 push(p4);
18096 multiply();
18097 multiply();
18098 push_integer(16);
18099 push(R_b2);
18100 push(p3);
18101 push(p5);
18102 multiply();
18103 multiply();
18104 multiply();
18105 add();
18106 add();
18107 add();
18108 push_integer(256);
18109 push(p3);
18110 push_integer(4);
18111 power();
18112 multiply();
18113 divide();
18114 R_r = pop();
18115 if (DEBUG) {
18116 console.log("r for depressed quartic: " + R_r.toString());
18117 }
18118 if (DEBUG) {
18119 console.log("tos 4 " + tos);
18120 }
18121 push(symbol(SECRETX));
18122 push_integer(4);
18123 power();
18124 if (DEBUG) {
18125 console.log("4 * x^4: " + stack[tos - 1].toString());
18126 }
18127 push(R_p);
18128 push(symbol(SECRETX));
18129 push_integer(2);
18130 power();
18131 multiply();
18132 if (DEBUG) {
18133 console.log("R_p * x^2: " + stack[tos - 1].toString());
18134 }
18135 push(R_q);
18136 push(symbol(SECRETX));
18137 multiply();
18138 if (DEBUG) {
18139 console.log("R_q * x: " + stack[tos - 1].toString());
18140 }
18141 push(R_r);
18142 if (DEBUG) {
18143 console.log("R_r: " + stack[tos - 1].toString());
18144 }
18145 add();
18146 add();
18147 add();
18148 simplify();
18149 if (DEBUG) {
18150 console.log("solving depressed quartic: " + stack[tos - 1].toString());
18151 }
18152 push(symbol(SECRETX));
18153 roots();
18154 depressedSolutions = pop();
18155 if (DEBUG) {
18156 console.log("depressedSolutions: " + depressedSolutions);
18157 }
18158 ref3 = depressedSolutions.tensor.elem;
18159 for (m1 = 0, len1 = ref3.length; m1 < len1; m1++) {
18160 eachSolution = ref3[m1];
18161 push(eachSolution);
18162 push(p4);
18163 push_integer(4);
18164 push(p3);
18165 multiply();
18166 divide();
18167 subtract();
18168 simplify();
18169 if (DEBUG) {
18170 console.log("solution from depressed: " + stack[tos - 1].toString());
18171 }
18172 }
18173 restore();
18174 return;
18175 } else {
18176 R_p = p5;
18177 R_q = p6;
18178 R_r = p7;
18179
18180 /*
18181 * Descartes' solution
18182 * https://en.wikipedia.org/wiki/Quartic_function#Descartes.27_solution
18183 * finding the "u" in the depressed equation
18184
18185 push_integer(2)
18186 push(R_p)
18187 multiply()
18188 coeff2 = pop()
18189
18190 push_integer(-4)
18191 push(R_p)
18192 push_integer(2)
18193 power()
18194 multiply()
18195 push(R_r)
18196 multiply()
18197 coeff3 = pop()
18198
18199 push(R_q)
18200 push_integer(2)
18201 power()
18202 negate()
18203 coeff4 = pop()
18204
18205 * now build the polynomial
18206 push(symbol(SECRETX))
18207 push_integer(3)
18208 power()
18209
18210 push(coeff2)
18211 push(symbol(SECRETX))
18212 push_integer(2)
18213 power()
18214 multiply()
18215
18216 push(coeff3)
18217 push(symbol(SECRETX))
18218 multiply()
18219
18220 push(coeff4)
18221
18222 add()
18223 add()
18224 add()
18225
18226 console.log("Descarte's resolventCubic: " + stack[tos-1].toString())
18227 push(symbol(SECRETX))
18228
18229 roots()
18230
18231 resolventCubicSolutions = pop()
18232 console.log("Descarte's resolventCubic solutions: " + resolventCubicSolutions)
18233 console.log("tos: " + tos)
18234
18235 R_u = null
18236 #R_u = resolventCubicSolutions.tensor.elem[1]
18237 for eachSolution in resolventCubicSolutions.tensor.elem
18238 console.log("examining solution: " + eachSolution)
18239 push(eachSolution)
18240 push_integer(2)
18241 multiply()
18242 push(R_p)
18243 add()
18244
18245 absValFloat()
18246 toBeCheckedIFZero = pop()
18247 console.log("abs value is: " + eachSolution)
18248 if !iszero(toBeCheckedIFZero)
18249 R_u = eachSolution
18250 break
18251
18252 console.log("chosen solution: " + R_u)
18253
18254 push(R_u)
18255 negate()
18256 R_s = pop()
18257
18258 push(R_p)
18259 push(R_u)
18260 push_integer(2)
18261 power()
18262 push(R_q)
18263 push(R_u)
18264 divide()
18265 add()
18266 add()
18267 push_integer(2)
18268 divide()
18269 R_t = pop()
18270
18271 push(R_p)
18272 push(R_u)
18273 push_integer(2)
18274 power()
18275 push(R_q)
18276 push(R_u)
18277 divide()
18278 subtract()
18279 add()
18280 push_integer(2)
18281 divide()
18282 R_v = pop()
18283
18284 * factoring the quartic into two quadratics:
18285
18286 * now build the polynomial
18287 push(symbol(SECRETX))
18288 push_integer(2)
18289 power()
18290
18291 push(R_s)
18292 push(symbol(SECRETX))
18293 multiply()
18294
18295 push(R_t)
18296
18297 add()
18298 add()
18299
18300 console.log("factored quartic 1: " + stack[tos-1].toString())
18301
18302 push(symbol(SECRETX))
18303 push_integer(2)
18304 power()
18305
18306 push(R_u)
18307 push(symbol(SECRETX))
18308 multiply()
18309
18310 push(R_v)
18311
18312 add()
18313 add()
18314
18315 console.log("factored quartic 2: " + stack[tos-1].toString())
18316 pop()
18317
18318 restore()
18319 return
18320 */
18321 push_rational(5, 2);
18322 push(R_p);
18323 multiply();
18324 coeff2 = pop();
18325 push_integer(2);
18326 push(R_p);
18327 push_integer(2);
18328 power();
18329 multiply();
18330 push(R_r);
18331 subtract();
18332 coeff3 = pop();
18333 push(R_p);
18334 push_integer(3);
18335 power();
18336 push_integer(2);
18337 divide();
18338 push_rational(-1, 2);
18339 push(R_p);
18340 push(R_r);
18341 multiply();
18342 multiply();
18343 push_rational(-1, 8);
18344 push(R_q);
18345 push_integer(2);
18346 power();
18347 multiply();
18348 add();
18349 add();
18350 coeff4 = pop();
18351 push(symbol(SECRETX));
18352 push_integer(3);
18353 power();
18354 push(coeff2);
18355 push(symbol(SECRETX));
18356 push_integer(2);
18357 power();
18358 multiply();
18359 push(coeff3);
18360 push(symbol(SECRETX));
18361 multiply();
18362 push(coeff4);
18363 add();
18364 add();
18365 add();
18366 if (DEBUG) {
18367 console.log("resolventCubic: " + stack[tos - 1].toString());
18368 }
18369 push(symbol(SECRETX));
18370 roots();
18371 resolventCubicSolutions = pop();
18372 if (DEBUG) {
18373 console.log("resolventCubicSolutions: " + resolventCubicSolutions);
18374 }
18375 R_m = null;
18376 ref4 = resolventCubicSolutions.tensor.elem;
18377 for (n1 = 0, len2 = ref4.length; n1 < len2; n1++) {
18378 eachSolution = ref4[n1];
18379 if (DEBUG) {
18380 console.log("examining solution: " + eachSolution);
18381 }
18382 push(eachSolution);
18383 push_integer(2);
18384 multiply();
18385 push(R_p);
18386 add();
18387 absValFloat();
18388 toBeCheckedIFZero = pop();
18389 if (DEBUG) {
18390 console.log("abs value is: " + eachSolution);
18391 }
18392 if (!iszero(toBeCheckedIFZero)) {
18393 R_m = eachSolution;
18394 break;
18395 }
18396 }
18397 if (DEBUG) {
18398 console.log("chosen solution: " + R_m);
18399 }
18400 push(R_m);
18401 push_integer(2);
18402 multiply();
18403 push(R_p);
18404 add();
18405 push_rational(1, 2);
18406 power();
18407 simplify();
18408 sqrtPPlus2M = pop();
18409 push(R_q);
18410 push_integer(2);
18411 multiply();
18412 push(sqrtPPlus2M);
18413 divide();
18414 simplify();
18415 TwoQOversqrtPPlus2M = pop();
18416 push(R_p);
18417 push_integer(3);
18418 multiply();
18419 push(R_m);
18420 push_integer(2);
18421 multiply();
18422 add();
18423 ThreePPlus2M = pop();
18424 push(sqrtPPlus2M);
18425 push(ThreePPlus2M);
18426 push(TwoQOversqrtPPlus2M);
18427 add();
18428 negate();
18429 push_rational(1, 2);
18430 power();
18431 simplify();
18432 add();
18433 push_integer(2);
18434 divide();
18435 push(sqrtPPlus2M);
18436 push(ThreePPlus2M);
18437 push(TwoQOversqrtPPlus2M);
18438 add();
18439 negate();
18440 push_rational(1, 2);
18441 power();
18442 simplify();
18443 subtract();
18444 push_integer(2);
18445 divide();
18446 push(sqrtPPlus2M);
18447 negate();
18448 push(ThreePPlus2M);
18449 push(TwoQOversqrtPPlus2M);
18450 subtract();
18451 negate();
18452 push_rational(1, 2);
18453 power();
18454 simplify();
18455 add();
18456 push_integer(2);
18457 divide();
18458 push(sqrtPPlus2M);
18459 negate();
18460 push(ThreePPlus2M);
18461 push(TwoQOversqrtPPlus2M);
18462 subtract();
18463 negate();
18464 push_rational(1, 2);
18465 power();
18466 simplify();
18467 subtract();
18468 push_integer(2);
18469 divide();
18470 restore();
18471 return;
18472 }
18473 push(R_determinant);
18474 simplify();
18475 absValFloat();
18476 R_determinant_simplified_toCheckIfZero = pop();
18477 push(R_DELTA0);
18478 simplify();
18479 absValFloat();
18480 R_DELTA0_simplified_toCheckIfZero = pop();
18481 S_CHECKED_AS_NOT_ZERO = false;
18482 choiceOfRadicalInQSoSIsNotZero = 0;
18483 while (!S_CHECKED_AS_NOT_ZERO) {
18484 Q_CHECKED_AS_NOT_ZERO = false;
18485 flipSignOFRadicalSoQIsNotZero = false;
18486 while (!Q_CHECKED_AS_NOT_ZERO) {
18487 push(R_DELTA1);
18488 push(R_DELTA1);
18489 push_integer(2);
18490 power();
18491 push_integer(-4);
18492 push(R_DELTA0);
18493 push_integer(3);
18494 power();
18495 multiply();
18496 add();
18497 push_rational(1, 2);
18498 power();
18499 if (flipSignOFRadicalSoQIsNotZero) {
18500 negate();
18501 }
18502 add();
18503 push_integer(2);
18504 divide();
18505 if (DEBUG) {
18506 console.log("content of cubic root: " + stack[tos - 1].toString());
18507 }
18508 push_rational(1, 3);
18509 power();
18510 simplify();
18511 R_principalCubicRoot = pop();
18512 if (DEBUG) {
18513 console.log("principal cubic root: " + R_principalCubicRoot.toString());
18514 }
18515 if (DEBUG) {
18516 console.log("tos : " + tos);
18517 }
18518 if (choiceOfRadicalInQSoSIsNotZero === 0) {
18519 if (DEBUG) {
18520 console.log("chosing principal cubic root");
18521 }
18522 push(R_principalCubicRoot);
18523 } else if (choiceOfRadicalInQSoSIsNotZero === 1) {
18524 if (DEBUG) {
18525 console.log("chosing cubic root beyond principal");
18526 }
18527 push(R_principalCubicRoot);
18528 push_rational(-1, 2);
18529 multiply();
18530 push_integer(3);
18531 push_rational(1, 2);
18532 power();
18533 push(imaginaryunit);
18534 multiply();
18535 push_rational(-1, 2);
18536 multiply();
18537 push(R_principalCubicRoot);
18538 multiply();
18539 add();
18540 } else if (choiceOfRadicalInQSoSIsNotZero === 1) {
18541 if (DEBUG) {
18542 console.log("chosing cubic root beyond beyond principal");
18543 }
18544 push(R_principalCubicRoot);
18545 push_rational(-1, 2);
18546 multiply();
18547 push_integer(3);
18548 push_rational(1, 2);
18549 power();
18550 push(imaginaryunit);
18551 multiply();
18552 push_rational(1, 2);
18553 multiply();
18554 push(R_principalCubicRoot);
18555 multiply();
18556 add();
18557 }
18558 simplify();
18559 R_Q = pop();
18560 if (DEBUG) {
18561 console.log("Q " + R_Q.toString());
18562 }
18563 if (DEBUG) {
18564 console.log("tos: " + tos);
18565 }
18566 push(R_Q);
18567 simplify();
18568 absValFloat();
18569 R_Q_simplified_toCheckIfZero = pop();
18570 if (DEBUG) {
18571 console.log("Q simplified and abs" + R_Q_simplified_toCheckIfZero.toString());
18572 }
18573 if (iszero(R_Q_simplified_toCheckIfZero) && (!iszero(R_determinant_simplified_toCheckIfZero) && iszero(R_DELTA0_simplified_toCheckIfZero))) {
18574 if (DEBUG) {
18575 console.log(" *********************************** Q IS ZERO and it matters, flipping the sign");
18576 }
18577 flipSignOFRadicalSoQIsNotZero = true;
18578 } else {
18579 Q_CHECKED_AS_NOT_ZERO = true;
18580 }
18581 if (DEBUG) {
18582 console.log("tos: " + tos);
18583 }
18584 }
18585 push_rational(-2, 3);
18586 push(R_p);
18587 multiply();
18588 push(R_Q);
18589 push(R_DELTA0);
18590 push(R_Q);
18591 divide();
18592 add();
18593 push(R_3_a);
18594 divide();
18595 add();
18596 push_rational(1, 2);
18597 power();
18598 push_integer(2);
18599 divide();
18600 show_power_debug = true;
18601 simplify();
18602 R_S = pop();
18603 if (DEBUG) {
18604 console.log("S " + R_S.toString());
18605 }
18606 push(R_S);
18607 simplify();
18608 absValFloat();
18609 R_S_simplified_toCheckIfZero = pop();
18610 if (DEBUG) {
18611 console.log("S " + R_S_simplified_toCheckIfZero.toString());
18612 }
18613 if (iszero(R_S_simplified_toCheckIfZero)) {
18614 if (DEBUG) {
18615 console.log(" *********************************** S IS ZERO chosing another cubic root");
18616 }
18617 choiceOfRadicalInQSoSIsNotZero++;
18618 } else {
18619 S_CHECKED_AS_NOT_ZERO = true;
18620 }
18621 if (DEBUG) {
18622 console.log("tos: " + tos);
18623 }
18624 }
18625 if (DEBUG) {
18626 console.log("tos: " + tos);
18627 }
18628 push(p4);
18629 negate();
18630 push(p3);
18631 push_integer(4);
18632 multiply();
18633 divide();
18634 R_minus_b_over_4a = pop();
18635 push_integer(-4);
18636 push(R_S);
18637 push_integer(2);
18638 power();
18639 multiply();
18640 push_integer(2);
18641 push(R_p);
18642 multiply();
18643 subtract();
18644 R_minus_4S2_minus_2p = pop();
18645 push(R_q);
18646 push(R_S);
18647 divide();
18648 R_q_over_S = pop();
18649 if (DEBUG) {
18650 console.log("tos before putting together the 4 solutions: " + tos);
18651 }
18652 push(R_minus_b_over_4a);
18653 push(R_S);
18654 subtract();
18655 push(R_minus_4S2_minus_2p);
18656 push(R_q_over_S);
18657 add();
18658 push_rational(1, 2);
18659 power();
18660 push_integer(2);
18661 divide();
18662 add();
18663 simplify();
18664 push(R_minus_b_over_4a);
18665 push(R_S);
18666 subtract();
18667 push(R_minus_4S2_minus_2p);
18668 push(R_q_over_S);
18669 add();
18670 push_rational(1, 2);
18671 power();
18672 push_integer(2);
18673 divide();
18674 subtract();
18675 simplify();
18676 push(R_minus_b_over_4a);
18677 push(R_S);
18678 add();
18679 push(R_minus_4S2_minus_2p);
18680 push(R_q_over_S);
18681 subtract();
18682 push_rational(1, 2);
18683 power();
18684 push_integer(2);
18685 divide();
18686 add();
18687 simplify();
18688 push(R_minus_b_over_4a);
18689 push(R_S);
18690 add();
18691 push(R_minus_4S2_minus_2p);
18692 push(R_q_over_S);
18693 subtract();
18694 push_rational(1, 2);
18695 power();
18696 push_integer(2);
18697 divide();
18698 subtract();
18699 simplify();
18700 restore();
18701 return;
18702 }
18703 }
18704 moveTos(tos - n);
18705 return restore();
18706 };
18707
18708 Eval_round = function() {
18709 push(cadr(p1));
18710 Eval();
18711 return yround();
18712 };
18713
18714 yround = function() {
18715 save();
18716 yyround();
18717 return restore();
18718 };
18719
18720 yyround = function() {
18721 var d;
18722 d = 0.0;
18723 p1 = pop();
18724 if (!isnum(p1)) {
18725 push_symbol(ROUND);
18726 push(p1);
18727 list(2);
18728 return;
18729 }
18730 if (isdouble(p1)) {
18731 d = Math.round(p1.d);
18732 push_double(d);
18733 return;
18734 }
18735 if (isinteger(p1)) {
18736 push(p1);
18737 return;
18738 }
18739 push(p1);
18740 yyfloat();
18741 p1 = pop();
18742 return push_integer(Math.round(p1.d));
18743 };
18744
18745 T_INTEGER = 1001;
18746
18747 T_DOUBLE = 1002;
18748
18749 T_SYMBOL = 1003;
18750
18751 T_FUNCTION = 1004;
18752
18753 T_NEWLINE = 1006;
18754
18755 T_STRING = 1007;
18756
18757 T_GTEQ = 1008;
18758
18759 T_LTEQ = 1009;
18760
18761 T_EQ = 1010;
18762
18763 T_NEQ = 1011;
18764
18765 T_QUOTASSIGN = 1012;
18766
18767 token = "";
18768
18769 newline_flag = 0;
18770
18771 meta_mode = 0;
18772
18773 input_str = 0;
18774
18775 scan_str = 0;
18776
18777 token_str = 0;
18778
18779 token_buf = 0;
18780
18781 lastFoundSymbol = null;
18782
18783 symbolsRightOfAssignment = null;
18784
18785 symbolsLeftOfAssignment = null;
18786
18787 isSymbolLeftOfAssignment = null;
18788
18789 scanningParameters = null;
18790
18791 functionInvokationsScanningStack = null;
18792
18793 skipRootVariableToBeSolved = false;
18794
18795 assignmentFound = null;
18796
18797 scanned = "";
18798
18799 scan = function(s) {
18800 if (DEBUG) {
18801 console.log("#### scanning " + s);
18802 }
18803 lastFoundSymbol = null;
18804 symbolsRightOfAssignment = [];
18805 symbolsLeftOfAssignment = [];
18806 isSymbolLeftOfAssignment = true;
18807 scanningParameters = [];
18808 functionInvokationsScanningStack = [""];
18809 assignmentFound = false;
18810 scanned = s;
18811 meta_mode = 0;
18812 expanding++;
18813 input_str = 0;
18814 scan_str = 0;
18815 get_next_token();
18816 if (token === "") {
18817 push(symbol(NIL));
18818 expanding--;
18819 return 0;
18820 }
18821 scan_stmt();
18822 expanding--;
18823 if (!assignmentFound) {
18824 symbolsInExpressionsWithoutAssignments = symbolsInExpressionsWithoutAssignments.concat(symbolsLeftOfAssignment);
18825 }
18826 return token_str - input_str;
18827 };
18828
18829 scan_meta = function(s) {
18830 scanned = s;
18831 meta_mode = 1;
18832 expanding++;
18833 input_str = 0;
18834 scan_str = 0;
18835 get_next_token();
18836 if (token === "") {
18837 push(symbol(NIL));
18838 expanding--;
18839 return 0;
18840 }
18841 scan_stmt();
18842 expanding--;
18843 return token_str - input_str;
18844 };
18845
18846 scan_stmt = function() {
18847 var assignmentIsOfQuotedType, existingDependencies, i, indexOfSymbolLeftOfAssignment, l1, len, len1, m1, symbolLeftOfAssignment;
18848 scan_relation();
18849 assignmentIsOfQuotedType = false;
18850 if (token === T_QUOTASSIGN) {
18851 assignmentIsOfQuotedType = true;
18852 }
18853 if (token === T_QUOTASSIGN || token === '=') {
18854 symbolLeftOfAssignment = lastFoundSymbol;
18855 if (DEBUG) {
18856 console.log("assignment!");
18857 }
18858 assignmentFound = true;
18859 isSymbolLeftOfAssignment = false;
18860 get_next_token();
18861 push_symbol(SETQ);
18862 swap();
18863 if (assignmentIsOfQuotedType) {
18864 push_symbol(QUOTE);
18865 }
18866 scan_relation();
18867 if (assignmentIsOfQuotedType) {
18868 list(2);
18869 }
18870 list(3);
18871 isSymbolLeftOfAssignment = true;
18872 if (codeGen) {
18873 indexOfSymbolLeftOfAssignment = symbolsRightOfAssignment.indexOf(symbolLeftOfAssignment);
18874 if (indexOfSymbolLeftOfAssignment !== -1) {
18875 symbolsRightOfAssignment.splice(indexOfSymbolLeftOfAssignment, 1);
18876 symbolsHavingReassignments.push(symbolLeftOfAssignment);
18877 }
18878 if (DEBUG) {
18879 console.log("locally, " + symbolLeftOfAssignment + " depends on: ");
18880 for (l1 = 0, len = symbolsRightOfAssignment.length; l1 < len; l1++) {
18881 i = symbolsRightOfAssignment[l1];
18882 console.log(" " + i);
18883 }
18884 }
18885 if (symbolsDependencies[symbolLeftOfAssignment] == null) {
18886 symbolsDependencies[symbolLeftOfAssignment] = [];
18887 }
18888 existingDependencies = symbolsDependencies[symbolLeftOfAssignment];
18889 for (m1 = 0, len1 = symbolsRightOfAssignment.length; m1 < len1; m1++) {
18890 i = symbolsRightOfAssignment[m1];
18891 if (existingDependencies.indexOf(i) === -1) {
18892 existingDependencies.push(i);
18893 }
18894 }
18895 return symbolsRightOfAssignment = [];
18896 }
18897 }
18898 };
18899
18900 scan_relation = function() {
18901 scan_expression();
18902 switch (token) {
18903 case T_EQ:
18904 push_symbol(TESTEQ);
18905 swap();
18906 get_next_token();
18907 scan_expression();
18908 return list(3);
18909 case T_NEQ:
18910 push_symbol(NOT);
18911 swap();
18912 push_symbol(TESTEQ);
18913 swap();
18914 get_next_token();
18915 scan_expression();
18916 list(3);
18917 return list(2);
18918 case T_LTEQ:
18919 push_symbol(TESTLE);
18920 swap();
18921 get_next_token();
18922 scan_expression();
18923 return list(3);
18924 case T_GTEQ:
18925 push_symbol(TESTGE);
18926 swap();
18927 get_next_token();
18928 scan_expression();
18929 return list(3);
18930 case '<':
18931 push_symbol(TESTLT);
18932 swap();
18933 get_next_token();
18934 scan_expression();
18935 return list(3);
18936 case '>':
18937 push_symbol(TESTGT);
18938 swap();
18939 get_next_token();
18940 scan_expression();
18941 return list(3);
18942 }
18943 };
18944
18945 scan_expression = function() {
18946 var h;
18947 h = tos;
18948 switch (token) {
18949 case '+':
18950 get_next_token();
18951 scan_term();
18952 break;
18953 case '-':
18954 get_next_token();
18955 scan_term();
18956 negate();
18957 break;
18958 default:
18959 scan_term();
18960 }
18961 while (newline_flag === 0 && (token === '+' || token === '-')) {
18962 if (token === '+') {
18963 get_next_token();
18964 scan_term();
18965 } else {
18966 get_next_token();
18967 scan_term();
18968 negate();
18969 }
18970 }
18971 if (tos - h > 1) {
18972 list(tos - h);
18973 push_symbol(ADD);
18974 swap();
18975 return cons();
18976 }
18977 };
18978
18979 is_factor = function() {
18980 if ((typeof token.charCodeAt === "function" ? token.charCodeAt(0) : void 0) === dotprod_unicode) {
18981 return 1;
18982 }
18983 switch (token) {
18984 case '*':
18985 case '/':
18986 return 1;
18987 case '(':
18988 case T_SYMBOL:
18989 case T_FUNCTION:
18990 case T_INTEGER:
18991 case T_DOUBLE:
18992 case T_STRING:
18993 if (newline_flag) {
18994 scan_str = token_str;
18995 return 0;
18996 } else {
18997 return 1;
18998 }
18999 }
19000 return 0;
19001 };
19002
19003 simplify_1_in_products = function(tos, h) {
19004 if (tos > h && isrational(stack[tos - 1]) && equaln(stack[tos - 1], 1)) {
19005 return pop();
19006 }
19007 };
19008
19009 multiply_consecutive_constants = function(tos, h) {
19010 if (tos > h + 1 && isnum(stack[tos - 2]) && isnum(stack[tos - 1])) {
19011 return multiply();
19012 }
19013 };
19014
19015 scan_term = function() {
19016 var h;
19017 h = tos;
19018 scan_factor();
19019 if (parse_time_simplifications) {
19020 simplify_1_in_products(tos, h);
19021 }
19022 while (is_factor()) {
19023 if (token === '*') {
19024 get_next_token();
19025 scan_factor();
19026 } else if (token === '/') {
19027 simplify_1_in_products(tos, h);
19028 get_next_token();
19029 scan_factor();
19030 inverse();
19031 } else if ((typeof token.charCodeAt === "function" ? token.charCodeAt(0) : void 0) === dotprod_unicode) {
19032 get_next_token();
19033 push_symbol(INNER);
19034 swap();
19035 scan_factor();
19036 list(3);
19037 } else {
19038 scan_factor();
19039 }
19040 if (parse_time_simplifications) {
19041 multiply_consecutive_constants(tos, h);
19042 simplify_1_in_products(tos, h);
19043 }
19044 }
19045 if (h === tos) {
19046 return push_integer(1);
19047 } else if (tos - h > 1) {
19048 list(tos - h);
19049 push_symbol(MULTIPLY);
19050 swap();
19051 return cons();
19052 }
19053 };
19054
19055 scan_power = function() {
19056 if (token === '^') {
19057 get_next_token();
19058 push_symbol(POWER);
19059 swap();
19060 scan_factor();
19061 return list(3);
19062 }
19063 };
19064
19065 scan_index = function(h) {
19066 get_next_token();
19067 push_symbol(INDEX);
19068 swap();
19069 scan_expression();
19070 while (token === ',') {
19071 get_next_token();
19072 scan_expression();
19073 }
19074 if (token !== ']') {
19075 scan_error("] expected");
19076 }
19077 get_next_token();
19078 return list(tos - h);
19079 };
19080
19081 scan_factor = function() {
19082 var h;
19083 h = tos;
19084 if (token === '(') {
19085 scan_subexpr();
19086 } else if (token === T_SYMBOL) {
19087 scan_symbol();
19088 } else if (token === T_FUNCTION) {
19089 scan_function_call_with_function_name();
19090 } else if (token === '[') {
19091 scan_tensor();
19092 } else if (token === T_INTEGER) {
19093 bignum_scan_integer(token_buf);
19094 get_next_token();
19095 } else if (token === T_DOUBLE) {
19096 bignum_scan_float(token_buf);
19097 get_next_token();
19098 } else if (token === T_STRING) {
19099 scan_string();
19100 } else {
19101 scan_error("syntax error");
19102 }
19103 while (token === '[' || token === '(' && newline_flag === 0) {
19104 if (token === '[') {
19105 scan_index(h);
19106 } else if (token === '(') {
19107 scan_function_call_without_function_name();
19108 }
19109 }
19110 while (token === '!') {
19111 get_next_token();
19112 push_symbol(FACTORIAL);
19113 swap();
19114 list(2);
19115 }
19116 while ((typeof token.charCodeAt === "function" ? token.charCodeAt(0) : void 0) === transpose_unicode) {
19117 get_next_token();
19118 push_symbol(TRANSPOSE);
19119 swap();
19120 list(2);
19121 }
19122 return scan_power();
19123 };
19124
19125 addSymbolRightOfAssignment = function(theSymbol) {
19126 var i, l1, prefixVar, ref2;
19127 if (predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(theSymbol) === -1 && symbolsRightOfAssignment.indexOf(theSymbol) === -1 && symbolsRightOfAssignment.indexOf("'" + theSymbol) === -1 && !skipRootVariableToBeSolved) {
19128 if (DEBUG) {
19129 console.log("... adding symbol: " + theSymbol + " to the set of the symbols right of assignment");
19130 }
19131 prefixVar = "";
19132 for (i = l1 = 1, ref2 = functionInvokationsScanningStack.length; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
19133 if (functionInvokationsScanningStack[i] !== "") {
19134 prefixVar += functionInvokationsScanningStack[i] + "_" + i + "_";
19135 }
19136 }
19137 theSymbol = prefixVar + theSymbol;
19138 return symbolsRightOfAssignment.push(theSymbol);
19139 }
19140 };
19141
19142 addSymbolLeftOfAssignment = function(theSymbol) {
19143 var i, l1, prefixVar, ref2;
19144 if (predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(theSymbol) === -1 && symbolsLeftOfAssignment.indexOf(theSymbol) === -1 && symbolsLeftOfAssignment.indexOf("'" + theSymbol) === -1 && !skipRootVariableToBeSolved) {
19145 if (DEBUG) {
19146 console.log("... adding symbol: " + theSymbol + " to the set of the symbols left of assignment");
19147 }
19148 prefixVar = "";
19149 for (i = l1 = 1, ref2 = functionInvokationsScanningStack.length; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
19150 if (functionInvokationsScanningStack[i] !== "") {
19151 prefixVar += functionInvokationsScanningStack[i] + "_" + i + "_";
19152 }
19153 }
19154 theSymbol = prefixVar + theSymbol;
19155 return symbolsLeftOfAssignment.push(theSymbol);
19156 }
19157 };
19158
19159 scan_symbol = function() {
19160 if (token !== T_SYMBOL) {
19161 scan_error("symbol expected");
19162 }
19163 if (meta_mode && token_buf.length === 1) {
19164 switch (token_buf[0]) {
19165 case 'a':
19166 push(symbol(METAA));
19167 break;
19168 case 'b':
19169 push(symbol(METAB));
19170 break;
19171 case 'x':
19172 push(symbol(METAX));
19173 break;
19174 default:
19175 push(usr_symbol(token_buf));
19176 }
19177 } else {
19178 push(usr_symbol(token_buf));
19179 }
19180 if (scanningParameters.length === 0) {
19181 if (DEBUG) {
19182 console.log("out of scanning parameters, processing " + token_buf);
19183 }
19184 lastFoundSymbol = token_buf;
19185 if (isSymbolLeftOfAssignment) {
19186 addSymbolLeftOfAssignment(token_buf);
19187 }
19188 } else {
19189 if (DEBUG) {
19190 console.log("still scanning parameters, skipping " + token_buf);
19191 }
19192 if (isSymbolLeftOfAssignment) {
19193 addSymbolRightOfAssignment("'" + token_buf);
19194 }
19195 }
19196 if (DEBUG) {
19197 console.log("found symbol: " + token_buf + " left of assignment: " + isSymbolLeftOfAssignment);
19198 }
19199 if (!isSymbolLeftOfAssignment) {
19200 addSymbolRightOfAssignment(token_buf);
19201 }
19202 return get_next_token();
19203 };
19204
19205 scan_string = function() {
19206 new_string(token_buf);
19207 return get_next_token();
19208 };
19209
19210 scan_function_call_with_function_name = function() {
19211 var functionName, i, l1, n, p, ref2;
19212 if (DEBUG) {
19213 console.log("-- scan_function_call_with_function_name start");
19214 }
19215 n = 1;
19216 p = new U();
19217 p = usr_symbol(token_buf);
19218 push(p);
19219 get_next_token();
19220 functionName = token_buf;
19221 if (functionName === "roots" || functionName === "defint" || functionName === "sum" || functionName === "product" || functionName === "for") {
19222 functionInvokationsScanningStack.push(token_buf);
19223 }
19224 lastFoundSymbol = token_buf;
19225 if (!isSymbolLeftOfAssignment) {
19226 addSymbolRightOfAssignment(token_buf);
19227 }
19228 get_next_token();
19229 scanningParameters.push(true);
19230 if (token !== ')') {
19231 scan_stmt();
19232 n++;
19233 while (token === ',') {
19234 get_next_token();
19235 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("roots") !== -1) {
19236 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19237 return !(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19238 });
19239 skipRootVariableToBeSolved = true;
19240 }
19241 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("sum") !== -1) {
19242 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19243 return !(new RegExp("sum_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19244 });
19245 skipRootVariableToBeSolved = true;
19246 }
19247 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("product") !== -1) {
19248 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19249 return !(new RegExp("product_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19250 });
19251 skipRootVariableToBeSolved = true;
19252 }
19253 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("for") !== -1) {
19254 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19255 return !(new RegExp("for_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19256 });
19257 skipRootVariableToBeSolved = true;
19258 }
19259 if (functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("defint") !== -1 && (n === 2 || (n > 2 && ((n - 2) % 3 === 0)))) {
19260 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19261 return !(new RegExp("defint_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19262 });
19263 skipRootVariableToBeSolved = true;
19264 }
19265 scan_stmt();
19266 skipRootVariableToBeSolved = false;
19267 n++;
19268 }
19269 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("roots") !== -1) {
19270 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19271 return !(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_" + "x")).test(x);
19272 });
19273 }
19274 }
19275 scanningParameters.pop();
19276 for (i = l1 = 0, ref2 = symbolsRightOfAssignment.length; 0 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19277 if (symbolsRightOfAssignment[i] != null) {
19278 if (functionName === "roots") {
19279 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19280 }
19281 if (functionName === "defint") {
19282 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("defint_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19283 }
19284 if (functionName === "sum") {
19285 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("sum_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19286 }
19287 if (functionName === "product") {
19288 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("product_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19289 }
19290 if (functionName === "for") {
19291 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("for_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19292 }
19293 }
19294 }
19295 if (token !== ')') {
19296 scan_error(") expected");
19297 }
19298 get_next_token();
19299 list(n);
19300 if (functionName === "roots" || functionName === "defint" || functionName === "sum" || functionName === "product" || functionName === "for") {
19301 functionInvokationsScanningStack.pop();
19302 }
19303 if (functionName === symbol(PATTERN).printname) {
19304 patternHasBeenFound = true;
19305 }
19306 if (DEBUG) {
19307 return console.log("-- scan_function_call_with_function_name end");
19308 }
19309 };
19310
19311 scan_function_call_without_function_name = function() {
19312 var n;
19313 if (DEBUG) {
19314 console.log("-- scan_function_call_without_function_name start");
19315 }
19316 push_symbol(EVAL);
19317 swap();
19318 list(2);
19319 n = 1;
19320 get_next_token();
19321 scanningParameters.push(true);
19322 if (token !== ')') {
19323 scan_stmt();
19324 n++;
19325 while (token === ',') {
19326 get_next_token();
19327 scan_stmt();
19328 n++;
19329 }
19330 }
19331 scanningParameters.pop();
19332 if (token !== ')') {
19333 scan_error(") expected");
19334 }
19335 get_next_token();
19336 list(n);
19337 if (DEBUG) {
19338 return console.log("-- scan_function_call_without_function_name end: " + stack[tos - 1]);
19339 }
19340 };
19341
19342 scan_subexpr = function() {
19343 var n;
19344 n = 0;
19345 if (token !== '(') {
19346 scan_error("( expected");
19347 }
19348 get_next_token();
19349 scan_stmt();
19350 if (token !== ')') {
19351 scan_error(") expected");
19352 }
19353 return get_next_token();
19354 };
19355
19356 scan_tensor = function() {
19357 var n;
19358 n = 0;
19359 if (token !== '[') {
19360 scan_error("[ expected");
19361 }
19362 get_next_token();
19363 scan_stmt();
19364 n = 1;
19365 while (token === ',') {
19366 get_next_token();
19367 scan_stmt();
19368 n++;
19369 }
19370 build_tensor(n);
19371 if (token !== ']') {
19372 scan_error("] expected");
19373 }
19374 return get_next_token();
19375 };
19376
19377 scan_error = function(errmsg) {
19378 errorMessage = "";
19379 while (input_str !== scan_str) {
19380 if ((scanned[input_str] === '\n' || scanned[input_str] === '\r') && input_str + 1 === scan_str) {
19381 break;
19382 }
19383 errorMessage += scanned[input_str++];
19384 }
19385 errorMessage += " ? ";
19386 while (scanned[input_str] && (scanned[input_str] !== '\n' && scanned[input_str] !== '\r')) {
19387 errorMessage += scanned[input_str++];
19388 }
19389 errorMessage += '\n';
19390 return stop(errmsg);
19391 };
19392
19393 build_tensor = function(n) {
19394 var i, l1, ref2;
19395 i = 0;
19396 save();
19397 p2 = alloc_tensor(n);
19398 p2.tensor.ndim = 1;
19399 p2.tensor.dim[0] = n;
19400 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19401 p2.tensor.elem[i] = stack[tos - n + i];
19402 }
19403 check_tensor_dimensions(p2);
19404 moveTos(tos - n);
19405 push(p2);
19406 return restore();
19407 };
19408
19409 get_next_token = function() {
19410 newline_flag = 0;
19411 while (1) {
19412 get_token();
19413 if (token !== T_NEWLINE) {
19414 break;
19415 }
19416 newline_flag = 1;
19417 }
19418 if (DEBUG) {
19419 return console.log("get_next_token token: " + token);
19420 }
19421 };
19422
19423 get_token = function() {
19424 while (isspace(scanned[scan_str])) {
19425 if (scanned[scan_str] === '\n' || scanned[scan_str] === '\r') {
19426 token = T_NEWLINE;
19427 scan_str++;
19428 return;
19429 }
19430 scan_str++;
19431 }
19432 token_str = scan_str;
19433 if (scan_str === scanned.length) {
19434 token = "";
19435 return;
19436 }
19437 if (isdigit(scanned[scan_str]) || scanned[scan_str] === '.') {
19438 while (isdigit(scanned[scan_str])) {
19439 scan_str++;
19440 }
19441 if (scanned[scan_str] === '.') {
19442 scan_str++;
19443 while (isdigit(scanned[scan_str])) {
19444 scan_str++;
19445 }
19446 if (scanned[scan_str] === 'e' && (scanned[scan_str + 1] === '+' || scanned[scan_str + 1] === '-' || isdigit(scanned[scan_str + 1]))) {
19447 scan_str += 2;
19448 while (isdigit(scanned[scan_str])) {
19449 scan_str++;
19450 }
19451 }
19452 token = T_DOUBLE;
19453 } else {
19454 token = T_INTEGER;
19455 }
19456 update_token_buf(token_str, scan_str);
19457 return;
19458 }
19459 if (isalpha(scanned[scan_str])) {
19460 while (isalnumorunderscore(scanned[scan_str])) {
19461 scan_str++;
19462 }
19463 if (scanned[scan_str] === '(') {
19464 token = T_FUNCTION;
19465 } else {
19466 token = T_SYMBOL;
19467 }
19468 update_token_buf(token_str, scan_str);
19469 return;
19470 }
19471 if (scanned[scan_str] === '"') {
19472 scan_str++;
19473 while (scanned[scan_str] !== '"') {
19474 if (scan_str === scanned.length - 1) {
19475 scan_str++;
19476 scan_error("runaway string");
19477 scan_str--;
19478 }
19479 scan_str++;
19480 }
19481 scan_str++;
19482 token = T_STRING;
19483 update_token_buf(token_str + 1, scan_str - 1);
19484 return;
19485 }
19486 if (scanned[scan_str] === '#' || scanned[scan_str] === '-' && scanned[scan_str + 1] === '-') {
19487 while (scanned[scan_str] && scanned[scan_str] !== '\n' && scanned[scan_str] !== '\r') {
19488 scan_str++;
19489 }
19490 if (scanned[scan_str]) {
19491 scan_str++;
19492 }
19493 token = T_NEWLINE;
19494 return;
19495 }
19496 if (scanned[scan_str] === ':' && scanned[scan_str + 1] === '=') {
19497 scan_str += 2;
19498 token = T_QUOTASSIGN;
19499 return;
19500 }
19501 if (scanned[scan_str] === '=' && scanned[scan_str + 1] === '=') {
19502 scan_str += 2;
19503 token = T_EQ;
19504 return;
19505 }
19506 if (scanned[scan_str] === '!' && scanned[scan_str + 1] === '=') {
19507 scan_str += 2;
19508 token = T_NEQ;
19509 return;
19510 }
19511 if (scanned[scan_str] === '<' && scanned[scan_str + 1] === '=') {
19512 scan_str += 2;
19513 token = T_LTEQ;
19514 return;
19515 }
19516 if (scanned[scan_str] === '>' && scanned[scan_str + 1] === '=') {
19517 scan_str += 2;
19518 token = T_GTEQ;
19519 return;
19520 }
19521 return token = scanned[scan_str++];
19522 };
19523
19524 update_token_buf = function(a, b) {
19525 return token_buf = scanned.substring(a, b);
19526 };
19527
19528 $.scan = scan;
19529
19530 Eval_sgn = function() {
19531 push(cadr(p1));
19532 Eval();
19533 return sgn();
19534 };
19535
19536 sgn = function() {
19537 save();
19538 yysgn();
19539 return restore();
19540 };
19541
19542 yysgn = function() {
19543 p1 = pop();
19544 if (isdouble(p1)) {
19545 if (p1.d > 0) {
19546 push_integer(1);
19547 return;
19548 } else {
19549 if (p1.d === 0) {
19550 push_integer(1);
19551 return;
19552 } else {
19553 push_integer(-1);
19554 return;
19555 }
19556 }
19557 }
19558 if (isrational(p1)) {
19559 if (MSIGN(mmul(p1.q.a, p1.q.b)) === -1) {
19560 push_integer(-1);
19561 return;
19562 } else {
19563 if (MZERO(mmul(p1.q.a, p1.q.b))) {
19564 push_integer(0);
19565 return;
19566 } else {
19567 push_integer(1);
19568 return;
19569 }
19570 }
19571 }
19572 if (iscomplexnumber(p1)) {
19573 push_integer(-1);
19574 push(p1);
19575 absval();
19576 power();
19577 push(p1);
19578 multiply();
19579 return;
19580 }
19581 if (isnegativeterm(p1)) {
19582 push_symbol(SGN);
19583 push(p1);
19584 negate();
19585 list(2);
19586 push_integer(-1);
19587 multiply();
19588 return;
19589 }
19590
19591 /*
19592 push_integer(2)
19593 push(p1)
19594 heaviside()
19595 multiply()
19596 push_integer(-1)
19597 add()
19598 */
19599 push_symbol(SGN);
19600 push(p1);
19601 return list(2);
19602 };
19603
19604 Eval_shape = function() {
19605 push(cadr(p1));
19606 Eval();
19607 return shape();
19608 };
19609
19610 shape = function() {
19611 var ai, an, i, l1, m1, ndim, ref2, ref3, t;
19612 i = 0;
19613 ndim = 0;
19614 t = 0;
19615 ai = [];
19616 an = [];
19617 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19618 ai[i] = 0;
19619 an[i] = 0;
19620 }
19621 save();
19622 p1 = pop();
19623 if (!istensor(p1)) {
19624 if (!iszero(p1)) {
19625 stop("transpose: tensor expected, 1st arg is not a tensor");
19626 }
19627 push(zero);
19628 restore();
19629 return;
19630 }
19631 ndim = p1.tensor.ndim;
19632 p2 = alloc_tensor(ndim);
19633 p2.tensor.ndim = 1;
19634 p2.tensor.dim[0] = ndim;
19635 for (i = m1 = 0, ref3 = ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
19636 push_integer(p1.tensor.dim[i]);
19637 p2.tensor.elem[i] = pop();
19638 }
19639 push(p2);
19640 return restore();
19641 };
19642
19643
19644 /*
19645 Simplify factorials
19646
19647 The following script
19648
19649 F(n,k) = k binomial(n,k)
19650 (F(n,k) + F(n,k-1)) / F(n+1,k)
19651
19652 generates
19653
19654 k! n! n! (1 - k + n)! k! n!
19655 -------------------- + -------------------- - ----------------------
19656 (-1 + k)! (1 + n)! (1 + n)! (-k + n)! k (-1 + k)! (1 + n)!
19657
19658 Simplify each term to get
19659
19660 k 1 - k + n 1
19661 ------- + ----------- - -------
19662 1 + n 1 + n 1 + n
19663
19664 Then simplify the sum to get
19665
19666 n
19667 -------
19668 1 + n
19669 */
19670
19671 Eval_simfac = function() {
19672 push(cadr(p1));
19673 Eval();
19674 return simfac();
19675 };
19676
19677 simfac = function() {
19678 var h;
19679 h = 0;
19680 save();
19681 p1 = pop();
19682 if (car(p1) === symbol(ADD)) {
19683 h = tos;
19684 p1 = cdr(p1);
19685 while (p1 !== symbol(NIL)) {
19686 push(car(p1));
19687 simfac_term();
19688 p1 = cdr(p1);
19689 }
19690 add_all(tos - h);
19691 } else {
19692 push(p1);
19693 simfac_term();
19694 }
19695 return restore();
19696 };
19697
19698
19699 /*
19700 void
19701 simfac(void)
19702 {
19703 int h
19704 save()
19705 p1 = pop()
19706 if (car(p1) == symbol(ADD)) {
19707 h = tos
19708 p1 = cdr(p1)
19709 while (p1 != symbol(NIL)) {
19710 push(car(p1))
19711 simfac_term()
19712 p1 = cdr(p1)
19713 }
19714 addk(tos - h)
19715 p1 = pop()
19716 if (find(p1, symbol(FACTORIAL))) {
19717 push(p1)
19718 if (car(p1) == symbol(ADD)) {
19719 Condense()
19720 simfac_term()
19721 }
19722 }
19723 } else {
19724 push(p1)
19725 simfac_term()
19726 }
19727 restore()
19728 }
19729
19730 #endif
19731 */
19732
19733 simfac_term = function() {
19734 var doNothing, h;
19735 h = 0;
19736 save();
19737 p1 = pop();
19738 if (car(p1) !== symbol(MULTIPLY)) {
19739 push(p1);
19740 restore();
19741 return;
19742 }
19743 h = tos;
19744 p1 = cdr(p1);
19745 while (p1 !== symbol(NIL)) {
19746 push(car(p1));
19747 p1 = cdr(p1);
19748 }
19749 while (yysimfac(h)) {
19750 doNothing = 1;
19751 }
19752 multiply_all_noexpand(tos - h);
19753 return restore();
19754 };
19755
19756 yysimfac = function(h) {
19757 var i, j, l1, m1, ref2, ref3, ref4, ref5;
19758 i = 0;
19759 j = 0;
19760 for (i = l1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
19761 p1 = stack[i];
19762 for (j = m1 = ref4 = h, ref5 = tos; ref4 <= ref5 ? m1 < ref5 : m1 > ref5; j = ref4 <= ref5 ? ++m1 : --m1) {
19763 if (i === j) {
19764 continue;
19765 }
19766 p2 = stack[j];
19767 if (car(p1) === symbol(FACTORIAL) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && equal(cadr(p1), cadr(p2))) {
19768 push(cadr(p1));
19769 push(one);
19770 subtract();
19771 factorial();
19772 stack[i] = pop();
19773 stack[j] = one;
19774 return 1;
19775 }
19776 if (car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL) && equal(p1, cadadr(p2))) {
19777 push(p1);
19778 push_integer(-1);
19779 add();
19780 factorial();
19781 reciprocate();
19782 stack[i] = pop();
19783 stack[j] = one;
19784 return 1;
19785 }
19786 if (car(p2) === symbol(FACTORIAL)) {
19787 push(p1);
19788 push(cadr(p2));
19789 subtract();
19790 p3 = pop();
19791 if (isplusone(p3)) {
19792 push(p1);
19793 factorial();
19794 stack[i] = pop();
19795 stack[j] = one;
19796 return 1;
19797 }
19798 }
19799 if (car(p1) === symbol(POWER) && isminusone(caddr(p1)) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL)) {
19800 push(cadr(p1));
19801 push(cadr(cadr(p2)));
19802 subtract();
19803 p3 = pop();
19804 if (isplusone(p3)) {
19805 push(cadr(p1));
19806 factorial();
19807 reciprocate();
19808 stack[i] = pop();
19809 stack[j] = one;
19810 return 1;
19811 }
19812 }
19813 if (car(p1) === symbol(FACTORIAL) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL)) {
19814 push(cadr(p1));
19815 push(cadr(cadr(p2)));
19816 subtract();
19817 p3 = pop();
19818 if (isplusone(p3)) {
19819 stack[i] = cadr(p1);
19820 stack[j] = one;
19821 return 1;
19822 }
19823 if (isminusone(p3)) {
19824 push(cadr(cadr(p2)));
19825 reciprocate();
19826 stack[i] = pop();
19827 stack[j] = one;
19828 return 1;
19829 }
19830 if (equaln(p3, 2)) {
19831 stack[i] = cadr(p1);
19832 push(cadr(p1));
19833 push_integer(-1);
19834 add();
19835 stack[j] = pop();
19836 return 1;
19837 }
19838 if (equaln(p3, -2)) {
19839 push(cadr(cadr(p2)));
19840 reciprocate();
19841 stack[i] = pop();
19842 push(cadr(cadr(p2)));
19843 push_integer(-1);
19844 add();
19845 reciprocate();
19846 stack[j] = pop();
19847 return 1;
19848 }
19849 }
19850 }
19851 }
19852 return 0;
19853 };
19854
19855 Eval_simplify = function() {
19856 push(cadr(p1));
19857 runUserDefinedSimplifications();
19858 Eval();
19859 return simplify();
19860 };
19861
19862 runUserDefinedSimplifications = function() {
19863 var atLeastOneSuccessInRouldOfRulesApplications, eachConsecutiveRuleApplication, eachSimplification, l1, len, len1, m1, numberOfRulesApplications, originalexpanding, success;
19864 if (userSimplificationsInListForm.length !== 0 && !Find(cadr(p1), symbol(INTEGRAL))) {
19865 originalexpanding = expanding;
19866 expanding = false;
19867 if (DEBUG) {
19868 console.log("runUserDefinedSimplifications passed: " + stack[tos - 1].toString());
19869 }
19870 Eval();
19871 if (DEBUG) {
19872 console.log("runUserDefinedSimplifications after eval no expanding: " + stack[tos - 1].toString());
19873 }
19874 expanding = originalexpanding;
19875 p1 = stack[tos - 1];
19876 if (DEBUG) {
19877 console.log("patterns to be checked: ");
19878 }
19879 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
19880 eachSimplification = userSimplificationsInListForm[l1];
19881 if (DEBUG) {
19882 console.log("..." + eachSimplification);
19883 }
19884 }
19885 atLeastOneSuccessInRouldOfRulesApplications = true;
19886 numberOfRulesApplications = 0;
19887 while (atLeastOneSuccessInRouldOfRulesApplications && numberOfRulesApplications < MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES) {
19888 atLeastOneSuccessInRouldOfRulesApplications = false;
19889 numberOfRulesApplications++;
19890 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
19891 eachSimplification = userSimplificationsInListForm[m1];
19892 success = true;
19893 eachConsecutiveRuleApplication = 0;
19894 while (success && eachConsecutiveRuleApplication < MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE) {
19895 eachConsecutiveRuleApplication++;
19896 if (DEBUG) {
19897 console.log("simplify - tos: " + tos + " checking pattern: " + eachSimplification + " on: " + p1);
19898 }
19899 push_symbol(NIL);
19900 success = transform(eachSimplification, true);
19901 if (success) {
19902 atLeastOneSuccessInRouldOfRulesApplications = true;
19903 }
19904 p1 = stack[tos - 1];
19905 if (DEBUG) {
19906 console.log("p1 at this stage of simplification: " + p1);
19907 }
19908 }
19909 if (eachConsecutiveRuleApplication === MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE) {
19910 stop("maximum application of single transformation rule exceeded: " + eachSimplification);
19911 }
19912 }
19913 }
19914 if (numberOfRulesApplications === MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES) {
19915 stop("maximum application of all transformation rules exceeded ");
19916 }
19917 if (DEBUG) {
19918 console.log("METAX = " + get_binding(symbol(METAX)));
19919 console.log("METAA = " + get_binding(symbol(METAA)));
19920 return console.log("METAB = " + get_binding(symbol(METAB)));
19921 }
19922 }
19923 };
19924
19925 simplifyForCodeGeneration = function() {
19926 save();
19927 runUserDefinedSimplifications();
19928 codeGen = true;
19929 simplify_main();
19930 codeGen = false;
19931 return restore();
19932 };
19933
19934 simplify = function() {
19935 save();
19936 simplify_main();
19937 return restore();
19938 };
19939
19940 simplify_main = function() {
19941 var args, fbody;
19942 p1 = pop();
19943 if (codeGen && car(p1) === symbol(FUNCTION)) {
19944 fbody = cadr(p1);
19945 push(fbody);
19946 eval();
19947 simplify();
19948 p3 = pop();
19949 args = caddr(p1);
19950 push_symbol(FUNCTION);
19951 push(p3);
19952 push(args);
19953 list(3);
19954 p1 = pop();
19955 }
19956 if (istensor(p1)) {
19957 simplify_tensor();
19958 return;
19959 }
19960 if (Find(p1, symbol(FACTORIAL))) {
19961 push(p1);
19962 simfac();
19963 p2 = pop();
19964 push(p1);
19965 rationalize();
19966 simfac();
19967 p3 = pop();
19968 if (count(p2) < count(p3)) {
19969 p1 = p2;
19970 } else {
19971 p1 = p3;
19972 }
19973 }
19974 f10();
19975 f1();
19976 f2();
19977 f3();
19978 f4();
19979 f5();
19980 f9();
19981 simplify_polarRect();
19982 if (do_simplify_nested_radicals) {
19983 if (simplify_nested_radicals()) {
19984 if (DEBUG) {
19985 console.log("de-nesting successful into: " + p1.toString());
19986 }
19987 push(p1);
19988 simplify();
19989 return;
19990 }
19991 }
19992 simplify_rectToClock();
19993 return push(p1);
19994 };
19995
19996 simplify_tensor = function() {
19997 var i, l1, m1, ref2, ref3;
19998 i = 0;
19999 p2 = alloc_tensor(p1.tensor.nelem);
20000 p2.tensor.ndim = p1.tensor.ndim;
20001 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
20002 p2.tensor.dim[i] = p1.tensor.dim[i];
20003 }
20004 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
20005 push(p1.tensor.elem[i]);
20006 simplify();
20007 p2.tensor.elem[i] = pop();
20008 }
20009 check_tensor_dimensions(p2);
20010 if (iszero(p2)) {
20011 p2 = zero;
20012 }
20013 return push(p2);
20014 };
20015
20016 f1 = function() {
20017 if (car(p1) !== symbol(ADD)) {
20018 return;
20019 }
20020 push(p1);
20021 rationalize();
20022 p2 = pop();
20023 if (count(p2) < count(p1)) {
20024 return p1 = p2;
20025 }
20026 };
20027
20028 f2 = function() {
20029 if (car(p1) !== symbol(ADD)) {
20030 return;
20031 }
20032 push(p1);
20033 Condense();
20034 p2 = pop();
20035 if (count(p2) <= count(p1)) {
20036 return p1 = p2;
20037 }
20038 };
20039
20040 f3 = function() {
20041 push(p1);
20042 rationalize();
20043 negate();
20044 rationalize();
20045 negate();
20046 rationalize();
20047 p2 = pop();
20048 if (count(p2) < count(p1)) {
20049 return p1 = p2;
20050 }
20051 };
20052
20053 f10 = function() {
20054 var a, b, carp1, miao, originalexpanding;
20055 carp1 = car(p1);
20056 miao = cdr(p1);
20057 if (carp1 === symbol(MULTIPLY) || isinnerordot(p1)) {
20058 if ((car(car(cdr(p1))) === symbol(TRANSPOSE)) && (car(car(cdr(cdr(p1)))) === symbol(TRANSPOSE))) {
20059 if (DEBUG) {
20060 console.log("maybe collecting a transpose " + p1);
20061 }
20062 a = cadr(car(cdr(p1)));
20063 b = cadr(car(cdr(cdr(p1))));
20064 if (carp1 === symbol(MULTIPLY)) {
20065 push(a);
20066 push(b);
20067 multiply();
20068 } else if (isinnerordot(p1)) {
20069 push(b);
20070 push(a);
20071 inner();
20072 }
20073 push_integer(1);
20074 push_integer(2);
20075 originalexpanding = expanding;
20076 expanding = false;
20077 transpose();
20078 expanding = originalexpanding;
20079 p2 = pop();
20080 if (count(p2) < count(p1)) {
20081 p1 = p2;
20082 }
20083 if (DEBUG) {
20084 return console.log("collecting a transpose " + p2);
20085 }
20086 }
20087 }
20088 };
20089
20090 f4 = function() {
20091 if (iszero(p1)) {
20092 return;
20093 }
20094 push(p1);
20095 rationalize();
20096 inverse();
20097 rationalize();
20098 inverse();
20099 rationalize();
20100 p2 = pop();
20101 if (count(p2) < count(p1)) {
20102 return p1 = p2;
20103 }
20104 };
20105
20106 simplify_trig = function() {
20107 save();
20108 p1 = pop();
20109 f5();
20110 push(p1);
20111 return restore();
20112 };
20113
20114 f5 = function() {
20115 if (Find(p1, symbol(SIN)) === 0 && Find(p1, symbol(COS)) === 0) {
20116 return;
20117 }
20118 p2 = p1;
20119 trigmode = 1;
20120 push(p2);
20121 Eval();
20122 p3 = pop();
20123 trigmode = 2;
20124 push(p2);
20125 Eval();
20126 p4 = pop();
20127 trigmode = 0;
20128 if (count(p4) < count(p3) || nterms(p4) < nterms(p3)) {
20129 p3 = p4;
20130 }
20131 if (count(p3) < count(p1) || nterms(p3) < nterms(p1)) {
20132 return p1 = p3;
20133 }
20134 };
20135
20136 f9 = function() {
20137 if (car(p1) !== symbol(ADD)) {
20138 return;
20139 }
20140 push_integer(0);
20141 p2 = cdr(p1);
20142 while (iscons(p2)) {
20143 push(car(p2));
20144 simplify();
20145 add();
20146 p2 = cdr(p2);
20147 }
20148 p2 = pop();
20149 if (count(p2) < count(p1)) {
20150 return p1 = p2;
20151 }
20152 };
20153
20154 simplify_rectToClock = function() {
20155 if (Find(p1, symbol(SIN)) === 0 && Find(p1, symbol(COS)) === 0) {
20156 return;
20157 }
20158 push(p1);
20159 Eval();
20160 clockform();
20161 p2 = pop();
20162 if (DEBUG) {
20163 console.log("before simplification clockform: " + p1 + " after: " + p2);
20164 }
20165 if (count(p2) < count(p1)) {
20166 return p1 = p2;
20167 }
20168 };
20169
20170 simplify_polarRect = function() {
20171 push(p1);
20172 polarRectAMinusOneBase();
20173 Eval();
20174 p2 = pop();
20175 if (count(p2) < count(p1)) {
20176 return p1 = p2;
20177 }
20178 };
20179
20180 polarRectAMinusOneBase = function() {
20181 var h;
20182 save();
20183 p1 = pop();
20184 if (isimaginaryunit(p1)) {
20185 push(p1);
20186 restore();
20187 return;
20188 }
20189 if (equal(car(p1), symbol(POWER)) && isminusone(cadr(p1))) {
20190 push(one);
20191 negate();
20192 push(caddr(p1));
20193 polarRectAMinusOneBase();
20194 power();
20195 polar();
20196 rect();
20197 } else if (iscons(p1)) {
20198 h = tos;
20199 while (iscons(p1)) {
20200 push(car(p1));
20201 polarRectAMinusOneBase();
20202 p1 = cdr(p1);
20203 }
20204 list(tos - h);
20205 } else {
20206 push(p1);
20207 }
20208 restore();
20209 };
20210
20211 nterms = function(p) {
20212 if (car(p) !== symbol(ADD)) {
20213 return 1;
20214 } else {
20215 return length(p) - 1;
20216 }
20217 };
20218
20219 simplify_nested_radicals = function() {
20220 var prev_expanding, simplificationWithCondense, simplificationWithoutCondense, somethingSimplified;
20221 if (recursionLevelNestedRadicalsRemoval > 0) {
20222 if (DEBUG) {
20223 console.log("denesting bailing out because of too much recursion");
20224 }
20225 return false;
20226 }
20227 push(p1);
20228 somethingSimplified = take_care_of_nested_radicals();
20229 simplificationWithoutCondense = stack[tos - 1];
20230 prev_expanding = expanding;
20231 expanding = 0;
20232 yycondense();
20233 expanding = prev_expanding;
20234 simplificationWithCondense = pop();
20235 if (countOccurrencesOfSymbol(symbol(POWER), simplificationWithoutCondense) < countOccurrencesOfSymbol(symbol(POWER), simplificationWithCondense)) {
20236 push(simplificationWithoutCondense);
20237 } else {
20238 push(simplificationWithCondense);
20239 }
20240 p1 = pop();
20241 return somethingSimplified;
20242 };
20243
20244 take_care_of_nested_radicals = function() {
20245 var A, B, C, SOLUTION, anyRadicalSimplificationWorked, base, checkSize, commonBases, commonInnerExponent, countingTerms, eachSolution, exponent, firstTerm, h, i, innerbase, innerexponent, l1, len, len1, len2, len3, lowercase_a, lowercase_b, m1, n1, numberOfTerms, o1, possibleNewExpression, possibleNewExpressionValue, possibleRationalSolutions, possibleSolutions, potentialPower, realOfpossibleRationalSolutions, ref2, secondTerm, secondTermFactor, termsThatAreNotPowers, whichRationalSolution;
20246 if (recursionLevelNestedRadicalsRemoval > 0) {
20247 if (DEBUG) {
20248 console.log("denesting bailing out because of too much recursion");
20249 }
20250 return false;
20251 }
20252 save();
20253 p1 = pop();
20254 if (equal(car(p1), symbol(POWER))) {
20255 base = cadr(p1);
20256 exponent = caddr(p1);
20257 if (!isminusone(exponent) && equal(car(base), symbol(ADD)) && isfraction(exponent) && (equalq(exponent, 1, 3) || equalq(exponent, 1, 2))) {
20258 firstTerm = cadr(base);
20259 push(firstTerm);
20260 take_care_of_nested_radicals();
20261 pop();
20262 secondTerm = caddr(base);
20263 push(secondTerm);
20264 take_care_of_nested_radicals();
20265 pop();
20266 numberOfTerms = 0;
20267 countingTerms = base;
20268 while (cdr(countingTerms) !== symbol(NIL)) {
20269 numberOfTerms++;
20270 countingTerms = cdr(countingTerms);
20271 }
20272 if (numberOfTerms > 2) {
20273 push(p1);
20274 restore();
20275 return false;
20276 }
20277 commonInnerExponent = null;
20278 commonBases = [];
20279 termsThatAreNotPowers = [];
20280 if (car(secondTerm) === symbol(MULTIPLY)) {
20281 secondTermFactor = cdr(secondTerm);
20282 if (iscons(secondTermFactor)) {
20283 while (iscons(secondTermFactor)) {
20284 potentialPower = car(secondTermFactor);
20285 if (car(potentialPower) === symbol(POWER)) {
20286 innerbase = cadr(potentialPower);
20287 innerexponent = caddr(potentialPower);
20288 if (equalq(innerexponent, 1, 2)) {
20289 if (commonInnerExponent == null) {
20290 commonInnerExponent = innerexponent;
20291 commonBases.push(innerbase);
20292 } else {
20293 if (equal(innerexponent, commonInnerExponent)) {
20294 commonBases.push(innerbase);
20295 } else {
20296
20297 }
20298 }
20299 }
20300 } else {
20301 termsThatAreNotPowers.push(potentialPower);
20302 }
20303 secondTermFactor = cdr(secondTermFactor);
20304 }
20305 }
20306 } else if (car(secondTerm) === symbol(POWER)) {
20307 innerbase = cadr(secondTerm);
20308 innerexponent = caddr(secondTerm);
20309 if ((commonInnerExponent == null) && equalq(innerexponent, 1, 2)) {
20310 commonInnerExponent = innerexponent;
20311 commonBases.push(innerbase);
20312 }
20313 }
20314 if (commonBases.length === 0) {
20315 push(p1);
20316 restore();
20317 return false;
20318 }
20319 A = firstTerm;
20320 push_integer(1);
20321 for (l1 = 0, len = commonBases.length; l1 < len; l1++) {
20322 i = commonBases[l1];
20323 push(i);
20324 multiply();
20325 }
20326 C = pop();
20327 push_integer(1);
20328 for (m1 = 0, len1 = termsThatAreNotPowers.length; m1 < len1; m1++) {
20329 i = termsThatAreNotPowers[m1];
20330 push(i);
20331 multiply();
20332 }
20333 B = pop();
20334 if (equalq(exponent, 1, 3)) {
20335 push(A);
20336 negate();
20337 push(C);
20338 multiply();
20339 push(B);
20340 divide();
20341 checkSize = pop();
20342 push(checkSize);
20343 real();
20344 yyfloat();
20345 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20346 push(p1);
20347 restore();
20348 return false;
20349 }
20350 push(checkSize);
20351 push_integer(3);
20352 push(C);
20353 multiply();
20354 checkSize = pop();
20355 push(checkSize);
20356 real();
20357 yyfloat();
20358 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20359 pop();
20360 push(p1);
20361 restore();
20362 return false;
20363 }
20364 push(checkSize);
20365 push(symbol(SECRETX));
20366 multiply();
20367 push_integer(-3);
20368 push(A);
20369 multiply();
20370 push(B);
20371 divide();
20372 checkSize = pop();
20373 push(checkSize);
20374 real();
20375 yyfloat();
20376 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20377 pop();
20378 pop();
20379 push(p1);
20380 restore();
20381 return false;
20382 }
20383 push(checkSize);
20384 push(symbol(SECRETX));
20385 push_integer(2);
20386 power();
20387 multiply();
20388 push_integer(1);
20389 push(symbol(SECRETX));
20390 push_integer(3);
20391 power();
20392 multiply();
20393 add();
20394 add();
20395 add();
20396 } else if (equalq(exponent, 1, 2)) {
20397 push(C);
20398 checkSize = pop();
20399 push(checkSize);
20400 real();
20401 yyfloat();
20402 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20403 push(p1);
20404 restore();
20405 return false;
20406 }
20407 push(checkSize);
20408 push_integer(-2);
20409 push(A);
20410 multiply();
20411 push(B);
20412 divide();
20413 checkSize = pop();
20414 push(checkSize);
20415 real();
20416 yyfloat();
20417 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20418 pop();
20419 push(p1);
20420 restore();
20421 return false;
20422 }
20423 push(checkSize);
20424 push(symbol(SECRETX));
20425 multiply();
20426 push_integer(1);
20427 push(symbol(SECRETX));
20428 push_integer(2);
20429 power();
20430 multiply();
20431 add();
20432 add();
20433 }
20434 push(symbol(SECRETX));
20435 recursionLevelNestedRadicalsRemoval++;
20436 roots();
20437 recursionLevelNestedRadicalsRemoval--;
20438 if (equal(stack[tos - 1], symbol(NIL))) {
20439 if (DEBUG) {
20440 console.log("roots bailed out because of too much recursion");
20441 }
20442 pop();
20443 push(p1);
20444 restore();
20445 return false;
20446 }
20447 possibleSolutions = [];
20448 ref2 = stack[tos - 1].tensor.elem;
20449 for (n1 = 0, len2 = ref2.length; n1 < len2; n1++) {
20450 eachSolution = ref2[n1];
20451 if (!Find(eachSolution, symbol(POWER))) {
20452 possibleSolutions.push(eachSolution);
20453 }
20454 }
20455 pop();
20456 if (possibleSolutions.length === 0) {
20457 push(p1);
20458 restore();
20459 return false;
20460 }
20461 possibleRationalSolutions = [];
20462 realOfpossibleRationalSolutions = [];
20463 for (o1 = 0, len3 = possibleSolutions.length; o1 < len3; o1++) {
20464 i = possibleSolutions[o1];
20465 push(i);
20466 real();
20467 yyfloat();
20468 possibleRationalSolutions.push(i);
20469 realOfpossibleRationalSolutions.push(pop().d);
20470 }
20471 whichRationalSolution = realOfpossibleRationalSolutions.indexOf(Math.max.apply(Math, realOfpossibleRationalSolutions));
20472 SOLUTION = possibleRationalSolutions[whichRationalSolution];
20473
20474 /*
20475 #possibleNewExpressions = []
20476 #realOfPossibleNewExpressions = []
20477 * pick the solution which cubic root has no radicals
20478 lowercase_b = null
20479 for SOLUTION in possibleSolutions
20480 console.log("testing solution: " + SOLUTION.toString())
20481
20482 debugger
20483 if equalq(exponent,1,3)
20484 push(A)
20485 push(SOLUTION)
20486 push_integer(3)
20487 power()
20488 push_integer(3)
20489 push(C)
20490 multiply()
20491 push(SOLUTION)
20492 multiply()
20493 add()
20494 divide()
20495 console.log("argument of cubic root: " + stack[tos-1].toString())
20496 push_rational(1,3)
20497 power()
20498 else if equalq(exponent,1,2)
20499 push(A)
20500 push(SOLUTION)
20501 push_integer(2)
20502 power()
20503 push(C)
20504 add()
20505 divide()
20506 console.log("argument of cubic root: " + stack[tos-1].toString())
20507 push_rational(1,2)
20508 power()
20509 console.log("b is: " + stack[tos-1].toString())
20510
20511 lowercase_b = pop()
20512
20513 if !Find(lowercase_b, symbol(POWER))
20514 break
20515 */
20516 if (equalq(exponent, 1, 3)) {
20517 push(A);
20518 push(SOLUTION);
20519 push_integer(3);
20520 power();
20521 push_integer(3);
20522 push(C);
20523 multiply();
20524 push(SOLUTION);
20525 multiply();
20526 add();
20527 divide();
20528 push_rational(1, 3);
20529 power();
20530 } else if (equalq(exponent, 1, 2)) {
20531 push(A);
20532 push(SOLUTION);
20533 push_integer(2);
20534 power();
20535 push(C);
20536 add();
20537 divide();
20538 push_rational(1, 2);
20539 power();
20540 }
20541 lowercase_b = pop();
20542 if (lowercase_b == null) {
20543 push(p1);
20544 restore();
20545 return false;
20546 }
20547 push(lowercase_b);
20548 push(SOLUTION);
20549 multiply();
20550 if (equalq(exponent, 1, 3)) {
20551 lowercase_a = pop();
20552 push(lowercase_b);
20553 push(C);
20554 push_rational(1, 2);
20555 power();
20556 multiply();
20557 push(lowercase_a);
20558 add();
20559 simplify();
20560 } else if (equalq(exponent, 1, 2)) {
20561 lowercase_a = pop();
20562 push(lowercase_b);
20563 push(C);
20564 push_rational(1, 2);
20565 power();
20566 multiply();
20567 push(lowercase_a);
20568 add();
20569 simplify();
20570 possibleNewExpression = pop();
20571 push(possibleNewExpression);
20572 real();
20573 yyfloat();
20574 possibleNewExpressionValue = pop();
20575 if (!isnegativenumber(possibleNewExpressionValue)) {
20576 push(possibleNewExpression);
20577 } else {
20578 push(lowercase_b);
20579 negate();
20580 lowercase_b = pop();
20581 push(lowercase_a);
20582 negate();
20583 lowercase_a = pop();
20584 push(lowercase_b);
20585 push(C);
20586 push_rational(1, 2);
20587 power();
20588 multiply();
20589 push(lowercase_a);
20590 add();
20591 simplify();
20592 }
20593 }
20594 p1 = pop();
20595 push(p1);
20596 restore();
20597 return true;
20598 } else {
20599 push(p1);
20600 restore();
20601 return false;
20602 }
20603 } else if (iscons(p1)) {
20604 h = tos;
20605 anyRadicalSimplificationWorked = false;
20606 while (iscons(p1)) {
20607 push(car(p1));
20608 anyRadicalSimplificationWorked = anyRadicalSimplificationWorked || take_care_of_nested_radicals();
20609 p1 = cdr(p1);
20610 }
20611 list(tos - h);
20612 restore();
20613 return anyRadicalSimplificationWorked;
20614 } else {
20615 push(p1);
20616 restore();
20617 return false;
20618 }
20619 throw new Error("control flow should never reach here");
20620 };
20621
20622 Eval_sin = function() {
20623 push(cadr(p1));
20624 Eval();
20625 return sine();
20626 };
20627
20628 sine = function() {
20629 save();
20630 p1 = pop();
20631 if (car(p1) === symbol(ADD)) {
20632 sine_of_angle_sum();
20633 } else {
20634 sine_of_angle();
20635 }
20636 return restore();
20637 };
20638
20639 sine_of_angle_sum = function() {
20640 p2 = cdr(p1);
20641 while (iscons(p2)) {
20642 p4 = car(p2);
20643 if (isnpi(p4)) {
20644 push(p1);
20645 push(p4);
20646 subtract();
20647 p3 = pop();
20648 push(p3);
20649 sine();
20650 push(p4);
20651 cosine();
20652 multiply();
20653 push(p3);
20654 cosine();
20655 push(p4);
20656 sine();
20657 multiply();
20658 add();
20659 return;
20660 }
20661 p2 = cdr(p2);
20662 }
20663 return sine_of_angle();
20664 };
20665
20666 sine_of_angle = function() {
20667 var d, n;
20668 if (car(p1) === symbol(ARCSIN)) {
20669 push(cadr(p1));
20670 return;
20671 }
20672 if (isdouble(p1)) {
20673 d = Math.sin(p1.d);
20674 if (Math.abs(d) < 1e-10) {
20675 d = 0.0;
20676 }
20677 push_double(d);
20678 return;
20679 }
20680 if (isnegative(p1)) {
20681 push(p1);
20682 negate();
20683 sine();
20684 negate();
20685 return;
20686 }
20687 if (car(p1) === symbol(ARCTAN)) {
20688 push(cadr(p1));
20689 push_integer(1);
20690 push(cadr(p1));
20691 push_integer(2);
20692 power();
20693 add();
20694 push_rational(-1, 2);
20695 power();
20696 multiply();
20697 return;
20698 }
20699 push(p1);
20700 push_integer(180);
20701 multiply();
20702 if (evaluatingAsFloats) {
20703 push_double(Math.PI);
20704 } else {
20705 push_symbol(PI);
20706 }
20707 divide();
20708 n = pop_integer();
20709 if (n < 0 || isNaN(n)) {
20710 push(symbol(SIN));
20711 push(p1);
20712 list(2);
20713 return;
20714 }
20715 switch (n % 360) {
20716 case 0:
20717 case 180:
20718 return push_integer(0);
20719 case 30:
20720 case 150:
20721 return push_rational(1, 2);
20722 case 210:
20723 case 330:
20724 return push_rational(-1, 2);
20725 case 45:
20726 case 135:
20727 push_rational(1, 2);
20728 push_integer(2);
20729 push_rational(1, 2);
20730 power();
20731 return multiply();
20732 case 225:
20733 case 315:
20734 push_rational(-1, 2);
20735 push_integer(2);
20736 push_rational(1, 2);
20737 power();
20738 return multiply();
20739 case 60:
20740 case 120:
20741 push_rational(1, 2);
20742 push_integer(3);
20743 push_rational(1, 2);
20744 power();
20745 return multiply();
20746 case 240:
20747 case 300:
20748 push_rational(-1, 2);
20749 push_integer(3);
20750 push_rational(1, 2);
20751 power();
20752 return multiply();
20753 case 90:
20754 return push_integer(1);
20755 case 270:
20756 return push_integer(-1);
20757 default:
20758 push(symbol(SIN));
20759 push(p1);
20760 return list(2);
20761 }
20762 };
20763
20764 Eval_sinh = function() {
20765 push(cadr(p1));
20766 Eval();
20767 return ysinh();
20768 };
20769
20770 ysinh = function() {
20771 save();
20772 yysinh();
20773 return restore();
20774 };
20775
20776 yysinh = function() {
20777 var d;
20778 d = 0.0;
20779 p1 = pop();
20780 if (car(p1) === symbol(ARCSINH)) {
20781 push(cadr(p1));
20782 return;
20783 }
20784 if (isdouble(p1)) {
20785 d = Math.sinh(p1.d);
20786 if (Math.abs(d) < 1e-10) {
20787 d = 0.0;
20788 }
20789 push_double(d);
20790 return;
20791 }
20792 if (iszero(p1)) {
20793 push(zero);
20794 return;
20795 }
20796 push_symbol(SINH);
20797 push(p1);
20798 return list(2);
20799 };
20800
20801
20802 /*
20803 Substitute new expr for old expr in expr.
20804
20805 Input: push expr
20806
20807 push old expr
20808
20809 push new expr
20810
20811 Output: Result on stack
20812 */
20813
20814 subst = function() {
20815 var i, l1, m1, ref2, ref3;
20816 i = 0;
20817 save();
20818 p3 = pop();
20819 p2 = pop();
20820 if (p2 === symbol(NIL) || p3 === symbol(NIL)) {
20821 restore();
20822 return;
20823 }
20824 p1 = pop();
20825 if (istensor(p1)) {
20826 p4 = alloc_tensor(p1.tensor.nelem);
20827 p4.tensor.ndim = p1.tensor.ndim;
20828 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
20829 p4.tensor.dim[i] = p1.tensor.dim[i];
20830 }
20831 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
20832 push(p1.tensor.elem[i]);
20833 push(p2);
20834 push(p3);
20835 subst();
20836 p4.tensor.elem[i] = pop();
20837 check_tensor_dimensions(p4);
20838 }
20839 push(p4);
20840 } else if (equal(p1, p2)) {
20841 push(p3);
20842 } else if (iscons(p1)) {
20843 push(car(p1));
20844 push(p2);
20845 push(p3);
20846 subst();
20847 push(cdr(p1));
20848 push(p2);
20849 push(p3);
20850 subst();
20851 cons();
20852 } else {
20853 push(p1);
20854 }
20855 return restore();
20856 };
20857
20858 Eval_sum = function() {
20859 var body, i, indexVariable, j, k, l1, ref2, ref3;
20860 i = 0;
20861 j = 0;
20862 k = 0;
20863 body = cadr(p1);
20864 indexVariable = caddr(p1);
20865 if (!issymbol(p6)) {
20866 stop("sum: 1st arg?");
20867 }
20868 push(cadddr(p1));
20869 Eval();
20870 j = pop_integer();
20871 if (isNaN(j)) {
20872 push(p1);
20873 return;
20874 }
20875 push(caddddr(p1));
20876 Eval();
20877 k = pop_integer();
20878 if (isNaN(k)) {
20879 push(p1);
20880 return;
20881 }
20882 p4 = get_binding(indexVariable);
20883 push_integer(0);
20884 for (i = l1 = ref2 = j, ref3 = k; ref2 <= ref3 ? l1 <= ref3 : l1 >= ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
20885 push_integer(i);
20886 p5 = pop();
20887 set_binding(indexVariable, p5);
20888 push(body);
20889 Eval();
20890 add();
20891 }
20892 return set_binding(indexVariable, p4);
20893 };
20894
20895 Eval_tan = function() {
20896 push(cadr(p1));
20897 Eval();
20898 return tangent();
20899 };
20900
20901 tangent = function() {
20902 save();
20903 yytangent();
20904 return restore();
20905 };
20906
20907 yytangent = function() {
20908 var d, n;
20909 n = 0;
20910 d = 0.0;
20911 p1 = pop();
20912 if (car(p1) === symbol(ARCTAN)) {
20913 push(cadr(p1));
20914 return;
20915 }
20916 if (isdouble(p1)) {
20917 d = Math.tan(p1.d);
20918 if (Math.abs(d) < 1e-10) {
20919 d = 0.0;
20920 }
20921 push_double(d);
20922 return;
20923 }
20924 if (isnegative(p1)) {
20925 push(p1);
20926 negate();
20927 tangent();
20928 negate();
20929 return;
20930 }
20931 push(p1);
20932 push_integer(180);
20933 multiply();
20934 if (evaluatingAsFloats) {
20935 push_double(Math.PI);
20936 } else {
20937 push_symbol(PI);
20938 }
20939 divide();
20940 n = pop_integer();
20941 if (n < 0 || isNaN(n)) {
20942 push(symbol(TAN));
20943 push(p1);
20944 list(2);
20945 return;
20946 }
20947 switch (n % 360) {
20948 case 0:
20949 case 180:
20950 return push_integer(0);
20951 case 30:
20952 case 210:
20953 push_rational(1, 3);
20954 push_integer(3);
20955 push_rational(1, 2);
20956 power();
20957 return multiply();
20958 case 150:
20959 case 330:
20960 push_rational(-1, 3);
20961 push_integer(3);
20962 push_rational(1, 2);
20963 power();
20964 return multiply();
20965 case 45:
20966 case 225:
20967 return push_integer(1);
20968 case 135:
20969 case 315:
20970 return push_integer(-1);
20971 case 60:
20972 case 240:
20973 push_integer(3);
20974 push_rational(1, 2);
20975 return power();
20976 case 120:
20977 case 300:
20978 push_integer(3);
20979 push_rational(1, 2);
20980 power();
20981 return negate();
20982 default:
20983 push(symbol(TAN));
20984 push(p1);
20985 return list(2);
20986 }
20987 };
20988
20989 Eval_tanh = function() {
20990 var d;
20991 d = 0.0;
20992 push(cadr(p1));
20993 Eval();
20994 p1 = pop();
20995 if (car(p1) === symbol(ARCTANH)) {
20996 push(cadr(p1));
20997 return;
20998 }
20999 if (isdouble(p1)) {
21000 d = Math.tanh(p1.d);
21001 if (Math.abs(d) < 1e-10) {
21002 d = 0.0;
21003 }
21004 push_double(d);
21005 return;
21006 }
21007 if (iszero(p1)) {
21008 push(zero);
21009 return;
21010 }
21011 push_symbol(TANH);
21012 push(p1);
21013 return list(2);
21014 };
21015
21016
21017 /*
21018 Taylor expansion of a function
21019
21020 push(F)
21021 push(X)
21022 push(N)
21023 push(A)
21024 taylor()
21025 */
21026
21027 Eval_taylor = function() {
21028 p1 = cdr(p1);
21029 push(car(p1));
21030 Eval();
21031 p1 = cdr(p1);
21032 push(car(p1));
21033 Eval();
21034 p2 = pop();
21035 if (p2 === symbol(NIL)) {
21036 guess();
21037 } else {
21038 push(p2);
21039 }
21040 p1 = cdr(p1);
21041 push(car(p1));
21042 Eval();
21043 p2 = pop();
21044 if (p2 === symbol(NIL)) {
21045 push_integer(24);
21046 } else {
21047 push(p2);
21048 }
21049 p1 = cdr(p1);
21050 push(car(p1));
21051 Eval();
21052 p2 = pop();
21053 if (p2 === symbol(NIL)) {
21054 push_integer(0);
21055 } else {
21056 push(p2);
21057 }
21058 return taylor();
21059 };
21060
21061 taylor = function() {
21062 var i, k, l1, ref2;
21063 i = 0;
21064 k = 0;
21065 save();
21066 p4 = pop();
21067 p3 = pop();
21068 p2 = pop();
21069 p1 = pop();
21070 push(p3);
21071 k = pop_integer();
21072 if (isNaN(k)) {
21073 push_symbol(TAYLOR);
21074 push(p1);
21075 push(p2);
21076 push(p3);
21077 push(p4);
21078 list(5);
21079 restore();
21080 return;
21081 }
21082 push(p1);
21083 push(p2);
21084 push(p4);
21085 subst();
21086 Eval();
21087 push_integer(1);
21088 p5 = pop();
21089 for (i = l1 = 1, ref2 = k; 1 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 1 <= ref2 ? ++l1 : --l1) {
21090 push(p1);
21091 push(p2);
21092 derivative();
21093 p1 = pop();
21094 if (iszero(p1)) {
21095 break;
21096 }
21097 push(p5);
21098 push(p2);
21099 push(p4);
21100 subtract();
21101 multiply();
21102 p5 = pop();
21103 push(p1);
21104 push(p2);
21105 push(p4);
21106 subst();
21107 Eval();
21108 push(p5);
21109 multiply();
21110 push_integer(i);
21111 factorial();
21112 divide();
21113 add();
21114 }
21115 return restore();
21116 };
21117
21118
21119 /* tensor =====================================================================
21120
21121 Tags
21122 ----
21123 scripting, JS, internal, treenode, general concept
21124
21125 General description
21126 -------------------
21127 Tensors are a strange in-between of matrices and "computer"
21128 rectangular data structures.
21129
21130 Tensors, unlike matrices, and like rectangular data structures,
21131 can have an arbitrary number of dimensions (rank), although a tensor with
21132 rank zero is just a scalar.
21133
21134 Tensors, like matrices and unlike many computer rectangular data structures,
21135 must be "contiguous" i.e. have no empty spaces within its size, and "uniform",
21136 i.e. each element must have the same shape and hence the same rank.
21137
21138 Also tensors have necessarily to make a distinction between row vectors,
21139 column vectors (which have a rank of 2) and uni-dimensional vectors (rank 1).
21140 They look very similar but they are fundamentally different.
21141
21142 Tensors with elements that are also tensors get promoted to a higher rank
21143 , this is so we can represent and get the rank of a matrix correctly.
21144 Example:
21145 Start with a tensor of rank 1 with 2 elements (i.e. shape: 2)
21146 if you put in both its elements another 2 tensors
21147 of rank 1 with 2 elements (i.e. shape: 2)
21148 then the result is a tensor of rank 2 with shape 2,2
21149 i.e. the dimension of a tensor at all times must be
21150 the number of nested tensors in it.
21151 Also, all tensors must be "uniform" i.e. they must be accessed
21152 uniformly, which means that all existing elements of a tensor
21153 must be contiguous and have the same shape.
21154 Implication of it all is that you can't put arbitrary
21155 tensors inside tensors (like you would do to represent block matrices)
21156 Rather, all tensors inside tensors must have same shape (and hence, rank)
21157
21158 Limitations
21159 -----------
21160 n.a.
21161
21162 Implementation info
21163 -------------------
21164 Tensors are implemented...
21165 */
21166
21167 Eval_tensor = function() {
21168 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21169 i = 0;
21170 ndim = 0;
21171 nelem = 0;
21172 check_tensor_dimensions(p1);
21173 nelem = p1.tensor.nelem;
21174 ndim = p1.tensor.ndim;
21175 p2 = alloc_tensor(nelem);
21176 p2.tensor.ndim = ndim;
21177 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21178 p2.tensor.dim[i] = p1.tensor.dim[i];
21179 }
21180 a = p1.tensor.elem;
21181 b = p2.tensor.elem;
21182 check_tensor_dimensions(p2);
21183 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21184 push(a[i]);
21185 Eval();
21186 b[i] = pop();
21187 }
21188 check_tensor_dimensions(p1);
21189 check_tensor_dimensions(p2);
21190 push(p2);
21191 return promote_tensor();
21192 };
21193
21194 tensor_plus_tensor = function() {
21195 var a, b, c, i, l1, m1, n1, ndim, nelem, ref2, ref3, ref4;
21196 i = 0;
21197 ndim = 0;
21198 nelem = 0;
21199 save();
21200 p2 = pop();
21201 p1 = pop();
21202 ndim = p1.tensor.ndim;
21203 if (ndim !== p2.tensor.ndim) {
21204 push(symbol(NIL));
21205 restore();
21206 return;
21207 }
21208 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21209 if (p1.tensor.dim[i] !== p2.tensor.dim[i]) {
21210 push(symbol(NIL));
21211 restore();
21212 return;
21213 }
21214 }
21215 nelem = p1.tensor.nelem;
21216 p3 = alloc_tensor(nelem);
21217 p3.tensor.ndim = ndim;
21218 for (i = m1 = 0, ref3 = ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21219 p3.tensor.dim[i] = p1.tensor.dim[i];
21220 }
21221 a = p1.tensor.elem;
21222 b = p2.tensor.elem;
21223 c = p3.tensor.elem;
21224 for (i = n1 = 0, ref4 = nelem; 0 <= ref4 ? n1 < ref4 : n1 > ref4; i = 0 <= ref4 ? ++n1 : --n1) {
21225 push(a[i]);
21226 push(b[i]);
21227 add();
21228 c[i] = pop();
21229 }
21230 push(p3);
21231 return restore();
21232 };
21233
21234 tensor_times_scalar = function() {
21235 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21236 i = 0;
21237 ndim = 0;
21238 nelem = 0;
21239 save();
21240 p2 = pop();
21241 p1 = pop();
21242 ndim = p1.tensor.ndim;
21243 nelem = p1.tensor.nelem;
21244 p3 = alloc_tensor(nelem);
21245 p3.tensor.ndim = ndim;
21246 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21247 p3.tensor.dim[i] = p1.tensor.dim[i];
21248 }
21249 a = p1.tensor.elem;
21250 b = p3.tensor.elem;
21251 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21252 push(a[i]);
21253 push(p2);
21254 multiply();
21255 b[i] = pop();
21256 }
21257 push(p3);
21258 return restore();
21259 };
21260
21261 scalar_times_tensor = function() {
21262 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21263 i = 0;
21264 ndim = 0;
21265 nelem = 0;
21266 save();
21267 p2 = pop();
21268 p1 = pop();
21269 ndim = p2.tensor.ndim;
21270 nelem = p2.tensor.nelem;
21271 p3 = alloc_tensor(nelem);
21272 p3.tensor.ndim = ndim;
21273 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21274 p3.tensor.dim[i] = p2.tensor.dim[i];
21275 }
21276 a = p2.tensor.elem;
21277 b = p3.tensor.elem;
21278 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21279 push(p1);
21280 push(a[i]);
21281 multiply();
21282 b[i] = pop();
21283 }
21284 push(p3);
21285 return restore();
21286 };
21287
21288 check_tensor_dimensions = function(p) {
21289 if (p.tensor.nelem !== p.tensor.elem.length) {
21290 console.log("something wrong in tensor dimensions");
21291 debugger;
21292 }
21293 };
21294
21295 is_square_matrix = function(p) {
21296 if (istensor(p) && p.tensor.ndim === 2 && p.tensor.dim[0] === p.tensor.dim[1]) {
21297 return 1;
21298 } else {
21299 return 0;
21300 }
21301 };
21302
21303 d_tensor_tensor = function() {
21304 var a, b, c, i, j, l1, m1, n1, ndim, nelem, ref2, ref3, ref4;
21305 i = 0;
21306 j = 0;
21307 ndim = 0;
21308 nelem = 0;
21309 ndim = p1.tensor.ndim;
21310 nelem = p1.tensor.nelem;
21311 if (ndim + 1 >= MAXDIM) {
21312 push_symbol(DERIVATIVE);
21313 push(p1);
21314 push(p2);
21315 list(3);
21316 return;
21317 }
21318 p3 = alloc_tensor(nelem * p2.tensor.nelem);
21319 p3.tensor.ndim = ndim + 1;
21320 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21321 p3.tensor.dim[i] = p1.tensor.dim[i];
21322 }
21323 p3.tensor.dim[ndim] = p2.tensor.dim[0];
21324 a = p1.tensor.elem;
21325 b = p2.tensor.elem;
21326 c = p3.tensor.elem;
21327 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21328 for (j = n1 = 0, ref4 = p2.tensor.nelem; 0 <= ref4 ? n1 < ref4 : n1 > ref4; j = 0 <= ref4 ? ++n1 : --n1) {
21329 push(a[i]);
21330 push(b[j]);
21331 derivative();
21332 c[i * p2.tensor.nelem + j] = pop();
21333 }
21334 }
21335 return push(p3);
21336 };
21337
21338 d_scalar_tensor = function() {
21339 var a, b, i, l1, ref2;
21340 p3 = alloc_tensor(p2.tensor.nelem);
21341 p3.tensor.ndim = 1;
21342 p3.tensor.dim[0] = p2.tensor.dim[0];
21343 a = p2.tensor.elem;
21344 b = p3.tensor.elem;
21345 for (i = l1 = 0, ref2 = p2.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21346 push(p1);
21347 push(a[i]);
21348 derivative();
21349 b[i] = pop();
21350 }
21351 return push(p3);
21352 };
21353
21354 d_tensor_scalar = function() {
21355 var a, b, i, l1, m1, ref2, ref3;
21356 i = 0;
21357 p3 = alloc_tensor(p1.tensor.nelem);
21358 p3.tensor.ndim = p1.tensor.ndim;
21359 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21360 p3.tensor.dim[i] = p1.tensor.dim[i];
21361 }
21362 a = p1.tensor.elem;
21363 b = p3.tensor.elem;
21364 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21365 push(a[i]);
21366 push(p2);
21367 derivative();
21368 b[i] = pop();
21369 }
21370 return push(p3);
21371 };
21372
21373 compare_tensors = function(p1, p2) {
21374 var i, l1, m1, ref2, ref3;
21375 i = 0;
21376 if (p1.tensor.ndim < p2.tensor.ndim) {
21377 return -1;
21378 }
21379 if (p1.tensor.ndim > p2.tensor.ndim) {
21380 return 1;
21381 }
21382 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21383 if (p1.tensor.dim[i] < p2.tensor.dim[i]) {
21384 return -1;
21385 }
21386 if (p1.tensor.dim[i] > p2.tensor.dim[i]) {
21387 return 1;
21388 }
21389 }
21390 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21391 if (equal(p1.tensor.elem[i], p2.tensor.elem[i])) {
21392 continue;
21393 }
21394 if (lessp(p1.tensor.elem[i], p2.tensor.elem[i])) {
21395 return -1;
21396 } else {
21397 return 1;
21398 }
21399 }
21400 return 0;
21401 };
21402
21403 power_tensor = function() {
21404 var i, k, l1, m1, n, ref2, ref3, results;
21405 i = 0;
21406 k = 0;
21407 n = 0;
21408 k = p1.tensor.ndim - 1;
21409 if (p1.tensor.dim[0] !== p1.tensor.dim[k]) {
21410 push_symbol(POWER);
21411 push(p1);
21412 push(p2);
21413 list(3);
21414 return;
21415 }
21416 push(p2);
21417 n = pop_integer();
21418 if (isNaN(n)) {
21419 push_symbol(POWER);
21420 push(p1);
21421 push(p2);
21422 list(3);
21423 return;
21424 }
21425 if (n === 0) {
21426 if (p1.tensor.ndim !== 2) {
21427 stop("power(tensor,0) with tensor rank not equal to 2");
21428 }
21429 n = p1.tensor.dim[0];
21430 p1 = alloc_tensor(n * n);
21431 p1.tensor.ndim = 2;
21432 p1.tensor.dim[0] = n;
21433 p1.tensor.dim[1] = n;
21434 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21435 p1.tensor.elem[n * i + i] = one;
21436 }
21437 check_tensor_dimensions(p1);
21438 push(p1);
21439 return;
21440 }
21441 if (n < 0) {
21442 n = -n;
21443 push(p1);
21444 inv();
21445 p1 = pop();
21446 }
21447 push(p1);
21448 results = [];
21449 for (i = m1 = 1, ref3 = n; 1 <= ref3 ? m1 < ref3 : m1 > ref3; i = 1 <= ref3 ? ++m1 : --m1) {
21450 push(p1);
21451 inner();
21452 if (iszero(stack[tos - 1])) {
21453 break;
21454 } else {
21455 results.push(void 0);
21456 }
21457 }
21458 return results;
21459 };
21460
21461 copy_tensor = function() {
21462 var i, l1, m1, ref2, ref3;
21463 i = 0;
21464 save();
21465 p1 = pop();
21466 p2 = alloc_tensor(p1.tensor.nelem);
21467 p2.tensor.ndim = p1.tensor.ndim;
21468 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21469 p2.tensor.dim[i] = p1.tensor.dim[i];
21470 }
21471 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21472 p2.tensor.elem[i] = p1.tensor.elem[i];
21473 }
21474 check_tensor_dimensions(p1);
21475 check_tensor_dimensions(p2);
21476 push(p2);
21477 return restore();
21478 };
21479
21480 promote_tensor = function() {
21481 var i, j, k, l1, m1, n1, ndim, nelem, o1, q1, ref2, ref3, ref4, ref5, ref6;
21482 i = 0;
21483 j = 0;
21484 k = 0;
21485 nelem = 0;
21486 ndim = 0;
21487 save();
21488 p1 = pop();
21489 if (!istensor(p1)) {
21490 push(p1);
21491 restore();
21492 return;
21493 }
21494 p2 = p1.tensor.elem[0];
21495 for (i = l1 = 1, ref2 = p1.tensor.nelem; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
21496 if (!compatible(p2, p1.tensor.elem[i])) {
21497 stop("Cannot promote tensor due to inconsistent tensor components.");
21498 }
21499 }
21500 if (!istensor(p2)) {
21501 push(p1);
21502 restore();
21503 return;
21504 }
21505 ndim = p1.tensor.ndim + p2.tensor.ndim;
21506 if (ndim > MAXDIM) {
21507 stop("tensor rank > " + MAXDIM);
21508 }
21509 nelem = p1.tensor.nelem * p2.tensor.nelem;
21510 p3 = alloc_tensor(nelem);
21511 p3.tensor.ndim = ndim;
21512 for (i = m1 = 0, ref3 = p1.tensor.ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21513 p3.tensor.dim[i] = p1.tensor.dim[i];
21514 }
21515 for (j = n1 = 0, ref4 = p2.tensor.ndim; 0 <= ref4 ? n1 < ref4 : n1 > ref4; j = 0 <= ref4 ? ++n1 : --n1) {
21516 p3.tensor.dim[i + j] = p2.tensor.dim[j];
21517 }
21518 k = 0;
21519 for (i = o1 = 0, ref5 = p1.tensor.nelem; 0 <= ref5 ? o1 < ref5 : o1 > ref5; i = 0 <= ref5 ? ++o1 : --o1) {
21520 p2 = p1.tensor.elem[i];
21521 for (j = q1 = 0, ref6 = p2.tensor.nelem; 0 <= ref6 ? q1 < ref6 : q1 > ref6; j = 0 <= ref6 ? ++q1 : --q1) {
21522 p3.tensor.elem[k++] = p2.tensor.elem[j];
21523 }
21524 }
21525 check_tensor_dimensions(p2);
21526 check_tensor_dimensions(p3);
21527 push(p3);
21528 return restore();
21529 };
21530
21531 compatible = function(p, q) {
21532 var i, l1, ref2;
21533 if (!istensor(p) && !istensor(q)) {
21534 return 1;
21535 }
21536 if (!istensor(p) || !istensor(q)) {
21537 return 0;
21538 }
21539 if (p.tensor.ndim !== q.tensor.ndim) {
21540 return 0;
21541 }
21542 for (i = l1 = 0, ref2 = p.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21543 if (p.tensor.dim[i] !== q.tensor.dim[i]) {
21544 return 0;
21545 }
21546 }
21547 return 1;
21548 };
21549
21550 Eval_test = function() {
21551 var orig;
21552 orig = p1;
21553 p1 = cdr(p1);
21554 while (iscons(p1)) {
21555 if (cdr(p1) === symbol(NIL)) {
21556 push(car(p1));
21557 Eval();
21558 return;
21559 }
21560 push(car(p1));
21561 Eval_predicate();
21562 p2 = pop();
21563 if (isone(p2)) {
21564 push(cadr(p1));
21565 Eval();
21566 return;
21567 } else if (!iszero(p2)) {
21568 push(orig);
21569 return;
21570 }
21571 p1 = cddr(p1);
21572 }
21573 return push_integer(0);
21574 };
21575
21576 Eval_testeq = function() {
21577 var orig, subtractionResult;
21578 orig = p1;
21579 push(cadr(p1));
21580 Eval();
21581 push(caddr(p1));
21582 Eval();
21583 subtract();
21584 subtractionResult = pop();
21585 if (iszero(subtractionResult)) {
21586 p1 = subtractionResult;
21587 return push_integer(1);
21588 } else {
21589 push(cadr(p1));
21590 Eval();
21591 simplify();
21592 push(caddr(p1));
21593 Eval();
21594 simplify();
21595 subtract();
21596 p1 = pop();
21597 if (iszero(p1)) {
21598 return push_integer(1);
21599 } else {
21600 push(p1);
21601 yyfloat();
21602 p1 = pop();
21603 if (iszero(p1)) {
21604 return push_integer(1);
21605 } else if (isnum(p1)) {
21606 return push_integer(0);
21607 } else {
21608 return push(orig);
21609 }
21610 }
21611 }
21612 };
21613
21614 Eval_testge = function() {
21615 var comparison, orig;
21616 orig = p1;
21617 comparison = cmp_args();
21618 if (comparison == null) {
21619 push(orig);
21620 return;
21621 }
21622 if (comparison >= 0) {
21623 return push_integer(1);
21624 } else {
21625 return push_integer(0);
21626 }
21627 };
21628
21629 Eval_testgt = function() {
21630 var comparison, orig;
21631 orig = p1;
21632 comparison = cmp_args();
21633 if (comparison == null) {
21634 push(orig);
21635 return;
21636 }
21637 if (comparison > 0) {
21638 return push_integer(1);
21639 } else {
21640 return push_integer(0);
21641 }
21642 };
21643
21644 Eval_testle = function() {
21645 var comparison, orig;
21646 orig = p1;
21647 comparison = cmp_args();
21648 if (comparison == null) {
21649 push(orig);
21650 return;
21651 }
21652 if (comparison <= 0) {
21653 return push_integer(1);
21654 } else {
21655 return push_integer(0);
21656 }
21657 };
21658
21659 Eval_testlt = function() {
21660 var comparison, orig;
21661 orig = p1;
21662 comparison = cmp_args();
21663 if (comparison == null) {
21664 push(orig);
21665 return;
21666 }
21667 if (comparison < 0) {
21668 return push_integer(1);
21669 } else {
21670 return push_integer(0);
21671 }
21672 };
21673
21674 Eval_not = function() {
21675 push(cadr(p1));
21676 Eval_predicate();
21677 p1 = pop();
21678 if (iszero(p1)) {
21679 return push_integer(1);
21680 } else {
21681 return push_integer(0);
21682 }
21683 };
21684
21685
21686 /* and =====================================================================
21687
21688 Tags
21689 ----
21690 scripting, JS, internal, treenode, general concept
21691
21692 Parameters
21693 ----------
21694 a,b,...
21695
21696 General description
21697 -------------------
21698 Logical-and of predicate expressions.
21699 */
21700
21701 Eval_and = function() {
21702 p1 = cdr(p1);
21703 while (iscons(p1)) {
21704 push(car(p1));
21705 Eval_predicate();
21706 p2 = pop();
21707 if (iszero(p2)) {
21708 push_integer(0);
21709 return;
21710 }
21711 p1 = cdr(p1);
21712 }
21713 return push_integer(1);
21714 };
21715
21716 Eval_or = function() {
21717 p1 = cdr(p1);
21718 while (iscons(p1)) {
21719 push(car(p1));
21720 Eval_predicate();
21721 p2 = pop();
21722 if (!iszero(p2)) {
21723 push_integer(1);
21724 return;
21725 }
21726 p1 = cdr(p1);
21727 }
21728 return push_integer(0);
21729 };
21730
21731 cmp_args = function() {
21732 var t;
21733 t = 0;
21734 push(cadr(p1));
21735 Eval();
21736 simplify();
21737 push(caddr(p1));
21738 Eval();
21739 simplify();
21740 subtract();
21741 p1 = pop();
21742 if (p1.k !== NUM && p1.k !== DOUBLE) {
21743 push(p1);
21744 yyfloat();
21745 Eval();
21746 p1 = pop();
21747 }
21748 if (iszero(p1)) {
21749 return 0;
21750 }
21751 switch (p1.k) {
21752 case NUM:
21753 if (MSIGN(p1.q.a) === -1) {
21754 t = -1;
21755 } else {
21756 t = 1;
21757 }
21758 break;
21759 case DOUBLE:
21760 if (p1.d < 0.0) {
21761 t = -1;
21762 } else {
21763 t = 1;
21764 }
21765 break;
21766 default:
21767 t = null;
21768 }
21769 return t;
21770 };
21771
21772
21773 /*
21774 Transform an expression using a pattern. The
21775 pattern can come from the integrals table or
21776 the user-defined patterns.
21777
21778 The expression and free variable are on the stack.
21779
21780 The argument s is a null terminated list of transform rules.
21781
21782 For example, see the itab (integrals table)
21783
21784 Internally, the following symbols are used:
21785
21786 F input expression
21787
21788 X free variable, i.e. F of X
21789
21790 A template expression
21791
21792 B result expression
21793
21794 C list of conditional expressions
21795
21796 Puts the final expression on top of stack
21797 (whether it's transformed or not) and returns
21798 true is successful, false if not.
21799 */
21800
21801 transform = function(s, generalTransform) {
21802 var bookmarkTosToPrintDecomps, eachTransformEntry, i, l1, len, len1, m1, n1, numberOfDecomps, ref2, restTerm, secondTerm, success, theTransform, transform_h, transformationSuccessful, transformedTerms;
21803 transform_h = 0;
21804 save();
21805 p1 = null;
21806 p4 = pop();
21807 p3 = pop();
21808 if (DEBUG) {
21809 console.log(" !!!!!!!!! transform on: " + p3);
21810 }
21811 saveMetaBindings();
21812 set_binding(symbol(METAX), p4);
21813 transform_h = tos;
21814 push_integer(1);
21815 push(p3);
21816 push(p4);
21817 polyform();
21818 push(p4);
21819 bookmarkTosToPrintDecomps = tos - 2;
21820 decomp(generalTransform);
21821 numberOfDecomps = tos - bookmarkTosToPrintDecomps;
21822 if (DEBUG) {
21823 console.log(" " + numberOfDecomps + " decomposed elements ====== ");
21824 for (i = l1 = 0, ref2 = numberOfDecomps; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21825 console.log(" decomposition element " + i + ": " + stack[tos - 1 - i]);
21826 }
21827 }
21828 transformationSuccessful = false;
21829 if (generalTransform) {
21830 if (!isnum(p3)) {
21831 theTransform = s;
21832 if (DEBUG) {
21833 console.log("applying transform: " + theTransform);
21834 }
21835 if (DEBUG) {
21836 console.log("scanning table entry " + theTransform);
21837 }
21838 push(theTransform);
21839 push(symbol(SYMBOL_A_UNDERSCORE));
21840 push(symbol(METAA));
21841 subst();
21842 push(symbol(SYMBOL_B_UNDERSCORE));
21843 push(symbol(METAB));
21844 subst();
21845 push(symbol(SYMBOL_X_UNDERSCORE));
21846 push(symbol(METAX));
21847 subst();
21848 p1 = pop();
21849 p5 = car(p1);
21850 if (DEBUG) {
21851 console.log("template expression: " + p5);
21852 }
21853 p6 = cadr(p1);
21854 p7 = cddr(p1);
21855
21856 /*
21857 p5 = p1.tensor.elem[0]
21858 p6 = p1.tensor.elem[1]
21859 for i in [2..(p1.tensor.elem.length-1)]
21860 push p1.tensor.elem[i]
21861 list(p1.tensor.elem.length - 2)
21862 p7 = pop()
21863 */
21864 if (f_equals_a(transform_h, generalTransform)) {
21865 transformationSuccessful = true;
21866 } else {
21867 if (DEBUG) {
21868 console.log("p3 at this point: " + p3);
21869 }
21870 transformedTerms = [];
21871 if (DEBUG) {
21872 console.log("car(p3): " + car(p3));
21873 }
21874 restTerm = p3;
21875 if (iscons(restTerm)) {
21876 transformedTerms.push(car(p3));
21877 restTerm = cdr(p3);
21878 }
21879 while (iscons(restTerm)) {
21880 secondTerm = car(restTerm);
21881 restTerm = cdr(restTerm);
21882 if (DEBUG) {
21883 console.log("tos before recursive transform: " + tos);
21884 }
21885 push(secondTerm);
21886 push_symbol(NIL);
21887 if (DEBUG) {
21888 console.log("testing: " + secondTerm);
21889 }
21890 if (DEBUG) {
21891 console.log("about to try to simplify other term: " + secondTerm);
21892 }
21893 success = transform(s, generalTransform);
21894 transformationSuccessful = transformationSuccessful || success;
21895 transformedTerms.push(pop());
21896 if (DEBUG) {
21897 console.log("tried to simplify other term: " + secondTerm + " ...successful?: " + success + " ...transformed: " + transformedTerms[transformedTerms.length - 1]);
21898 }
21899 }
21900 if (transformedTerms.length !== 0) {
21901 for (m1 = 0, len = transformedTerms.length; m1 < len; m1++) {
21902 i = transformedTerms[m1];
21903 push(i);
21904 }
21905 list(transformedTerms.length);
21906 p6 = pop();
21907 }
21908 }
21909 }
21910 } else {
21911 for (n1 = 0, len1 = s.length; n1 < len1; n1++) {
21912 eachTransformEntry = s[n1];
21913 if (DEBUG) {
21914 console.log("scanning table entry " + eachTransformEntry);
21915 if ((eachTransformEntry + "").indexOf("f(sqrt(a+b*x),2/3*1/b*sqrt((a+b*x)^3))") !== -1) {
21916 debugger;
21917 }
21918 }
21919 if (eachTransformEntry) {
21920 scan_meta(eachTransformEntry);
21921 p1 = pop();
21922 p5 = cadr(p1);
21923 p6 = caddr(p1);
21924 p7 = cdddr(p1);
21925
21926 /*
21927 p5 = p1.tensor.elem[0]
21928 p6 = p1.tensor.elem[1]
21929 for i in [2..(p1.tensor.elem.length-1)]
21930 push p1.tensor.elem[i]
21931 list(p1.tensor.elem.length - 2)
21932 p7 = pop()
21933 */
21934 if (f_equals_a(transform_h, generalTransform)) {
21935 transformationSuccessful = true;
21936 break;
21937 }
21938 }
21939 }
21940 }
21941 moveTos(transform_h);
21942 if (transformationSuccessful) {
21943 push(p6);
21944 Eval();
21945 p1 = pop();
21946 transformationSuccessful = true;
21947 } else {
21948 if (generalTransform) {
21949 p1 = p3;
21950 } else {
21951 p1 = symbol(NIL);
21952 }
21953 }
21954 restoreMetaBindings();
21955 push(p1);
21956 restore();
21957 return transformationSuccessful;
21958 };
21959
21960 saveMetaBindings = function() {
21961 push(get_binding(symbol(METAA)));
21962 push(get_binding(symbol(METAB)));
21963 return push(get_binding(symbol(METAX)));
21964 };
21965
21966 restoreMetaBindings = function() {
21967 set_binding(symbol(METAX), pop());
21968 set_binding(symbol(METAB), pop());
21969 return set_binding(symbol(METAA), pop());
21970 };
21971
21972 f_equals_a = function(h, generalTransform) {
21973 var fea_i, fea_j, l1, m1, originalexpanding, ref2, ref3, ref4, ref5;
21974 fea_i = 0;
21975 fea_j = 0;
21976 for (fea_i = l1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; fea_i = ref2 <= ref3 ? ++l1 : --l1) {
21977 set_binding(symbol(METAA), stack[fea_i]);
21978 if (DEBUG) {
21979 console.log(" binding METAA to " + get_binding(symbol(METAA)));
21980 }
21981 for (fea_j = m1 = ref4 = h, ref5 = tos; ref4 <= ref5 ? m1 < ref5 : m1 > ref5; fea_j = ref4 <= ref5 ? ++m1 : --m1) {
21982 set_binding(symbol(METAB), stack[fea_j]);
21983 if (DEBUG) {
21984 console.log(" binding METAB to " + get_binding(symbol(METAB)));
21985 }
21986 p1 = p7;
21987 while (iscons(p1)) {
21988 push(car(p1));
21989 Eval();
21990 p2 = pop();
21991 if (iszero(p2)) {
21992 break;
21993 }
21994 p1 = cdr(p1);
21995 }
21996 if (iscons(p1)) {
21997 continue;
21998 }
21999 push(p3);
22000 if (DEBUG) {
22001 console.log("about to evaluate template expression: " + p5 + " binding METAA to " + get_binding(symbol(METAA)) + " and binding METAB to " + get_binding(symbol(METAB)) + " and binding METAX to " + get_binding(symbol(METAX)));
22002 }
22003 push(p5);
22004 if (generalTransform) {
22005 originalexpanding = expanding;
22006 expanding = false;
22007 }
22008 Eval();
22009 if (generalTransform) {
22010 expanding = originalexpanding;
22011 }
22012 if (DEBUG) {
22013 console.log(" comparing " + stack[tos - 1] + " to: " + stack[tos - 2]);
22014 }
22015 subtract();
22016 p1 = pop();
22017 if (iszero(p1)) {
22018 if (DEBUG) {
22019 console.log("binding METAA to " + get_binding(symbol(METAA)));
22020 console.log("binding METAB to " + get_binding(symbol(METAB)));
22021 console.log("binding METAX to " + get_binding(symbol(METAX)));
22022 console.log("comparing " + p3 + " to: " + p5);
22023 }
22024 return 1;
22025 }
22026 }
22027 }
22028 return 0;
22029 };
22030
22031 Eval_transpose = function() {
22032 push(cadr(p1));
22033 Eval();
22034 if (cddr(p1) === symbol(NIL)) {
22035 push_integer(1);
22036 push_integer(2);
22037 } else {
22038 push(caddr(p1));
22039 Eval();
22040 push(cadddr(p1));
22041 Eval();
22042 }
22043 return transpose();
22044 };
22045
22046 transpose = function() {
22047 var a, accumulator, ai, an, b, eachEntry, i, innerTranspSwitch1, innerTranspSwitch2, j, k, l, l1, m, m1, n1, ndim, nelem, o1, q1, r1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, s1, t;
22048 i = 0;
22049 j = 0;
22050 k = 0;
22051 l = 0;
22052 m = 0;
22053 ndim = 0;
22054 nelem = 0;
22055 t = 0;
22056 ai = [];
22057 an = [];
22058 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22059 ai[i] = 0;
22060 an[i] = 0;
22061 }
22062 save();
22063 p3 = pop();
22064 p2 = pop();
22065 p1 = pop();
22066 if (isnum(p1)) {
22067 push(p1);
22068 restore();
22069 return;
22070 }
22071 if ((isplusone(p2) && isplustwo(p3)) || (isplusone(p3) && isplustwo(p2))) {
22072 if (isidentitymatrix(p1)) {
22073 push(p1);
22074 restore();
22075 return;
22076 }
22077 }
22078 if (istranspose(p1)) {
22079 innerTranspSwitch1 = car(cdr(cdr(p1)));
22080 innerTranspSwitch2 = car(cdr(cdr(cdr(p1))));
22081 if ((equal(innerTranspSwitch1, p3) && equal(innerTranspSwitch2, p2)) || (equal(innerTranspSwitch2, p3) && equal(innerTranspSwitch1, p2)) || ((equal(innerTranspSwitch1, symbol(NIL)) && equal(innerTranspSwitch2, symbol(NIL))) && ((isplusone(p3) && isplustwo(p2)) || (isplusone(p2) && isplustwo(p3))))) {
22082 push(car(cdr(p1)));
22083 restore();
22084 return;
22085 }
22086 }
22087 if (expanding && isadd(p1)) {
22088 p1 = cdr(p1);
22089 push(zero);
22090 while (iscons(p1)) {
22091 push(car(p1));
22092 push(p2);
22093 push(p3);
22094 transpose();
22095 add();
22096 p1 = cdr(p1);
22097 }
22098 restore();
22099 return;
22100 }
22101 if (expanding && ismultiply(p1)) {
22102 p1 = cdr(p1);
22103 push(one);
22104 while (iscons(p1)) {
22105 push(car(p1));
22106 push(p2);
22107 push(p3);
22108 transpose();
22109 multiply();
22110 p1 = cdr(p1);
22111 }
22112 restore();
22113 return;
22114 }
22115 if (expanding && isinnerordot(p1)) {
22116 p1 = cdr(p1);
22117 accumulator = [];
22118 while (iscons(p1)) {
22119 accumulator.push([car(p1), p2, p3]);
22120 p1 = cdr(p1);
22121 }
22122 for (eachEntry = m1 = ref3 = accumulator.length - 1; ref3 <= 0 ? m1 <= 0 : m1 >= 0; eachEntry = ref3 <= 0 ? ++m1 : --m1) {
22123 push(accumulator[eachEntry][0]);
22124 push(accumulator[eachEntry][1]);
22125 push(accumulator[eachEntry][2]);
22126 transpose();
22127 if (eachEntry !== accumulator.length - 1) {
22128 inner();
22129 }
22130 }
22131 restore();
22132 return;
22133 }
22134 if (!istensor(p1)) {
22135 if (!iszero(p1)) {
22136 push_symbol(TRANSPOSE);
22137 push(p1);
22138 if ((!isplusone(p2) || !isplustwo(p3)) && (!isplusone(p3) || !isplustwo(p2))) {
22139 push(p2);
22140 push(p3);
22141 list(4);
22142 } else {
22143 list(2);
22144 }
22145 restore();
22146 return;
22147 }
22148 push(zero);
22149 restore();
22150 return;
22151 }
22152 ndim = p1.tensor.ndim;
22153 nelem = p1.tensor.nelem;
22154 if (ndim === 1) {
22155 push(p1);
22156 restore();
22157 return;
22158 }
22159 push(p2);
22160 l = pop_integer();
22161 push(p3);
22162 m = pop_integer();
22163 if (l < 1 || l > ndim || m < 1 || m > ndim) {
22164 stop("transpose: index out of range");
22165 }
22166 l--;
22167 m--;
22168 p2 = alloc_tensor(nelem);
22169 p2.tensor.ndim = ndim;
22170 for (i = n1 = 0, ref4 = ndim; 0 <= ref4 ? n1 < ref4 : n1 > ref4; i = 0 <= ref4 ? ++n1 : --n1) {
22171 p2.tensor.dim[i] = p1.tensor.dim[i];
22172 }
22173 p2.tensor.dim[l] = p1.tensor.dim[m];
22174 p2.tensor.dim[m] = p1.tensor.dim[l];
22175 a = p1.tensor.elem;
22176 b = p2.tensor.elem;
22177 for (i = o1 = 0, ref5 = ndim; 0 <= ref5 ? o1 < ref5 : o1 > ref5; i = 0 <= ref5 ? ++o1 : --o1) {
22178 ai[i] = 0;
22179 an[i] = p1.tensor.dim[i];
22180 }
22181 for (i = q1 = 0, ref6 = nelem; 0 <= ref6 ? q1 < ref6 : q1 > ref6; i = 0 <= ref6 ? ++q1 : --q1) {
22182 t = ai[l];
22183 ai[l] = ai[m];
22184 ai[m] = t;
22185 t = an[l];
22186 an[l] = an[m];
22187 an[m] = t;
22188 k = 0;
22189 for (j = r1 = 0, ref7 = ndim; 0 <= ref7 ? r1 < ref7 : r1 > ref7; j = 0 <= ref7 ? ++r1 : --r1) {
22190 k = (k * an[j]) + ai[j];
22191 }
22192 t = ai[l];
22193 ai[l] = ai[m];
22194 ai[m] = t;
22195 t = an[l];
22196 an[l] = an[m];
22197 an[m] = t;
22198 b[k] = a[i];
22199 for (j = s1 = ref8 = ndim - 1; ref8 <= 0 ? s1 <= 0 : s1 >= 0; j = ref8 <= 0 ? ++s1 : --s1) {
22200 if (++ai[j] < an[j]) {
22201 break;
22202 }
22203 ai[j] = 0;
22204 }
22205 }
22206 push(p2);
22207 return restore();
22208 };
22209
22210
22211 /* d =====================================================================
22212
22213 Tags
22214 ----
22215 scripting, JS, internal, treenode, general concept
22216
22217 Parameters
22218 ----------
22219 f,x
22220
22221 General description
22222 -------------------
22223 Returns the partial derivative of f with respect to x. x can be a vector e.g. [x,y].
22224 */
22225
22226 Eval_user_function = function() {
22227 var bodyAndFormalArguments, h;
22228 if (DEBUG) {
22229 console.log("Eval_user_function evaluating: " + car(p1));
22230 }
22231 if (car(p1) === symbol(SYMBOL_D) && get_binding(symbol(SYMBOL_D)) === symbol(SYMBOL_D)) {
22232 Eval_derivative();
22233 return;
22234 }
22235 push(car(p1));
22236 Eval();
22237 bodyAndFormalArguments = pop();
22238 p3 = car(cdr(bodyAndFormalArguments));
22239 p4 = car(cdr(cdr(bodyAndFormalArguments)));
22240 p5 = cdr(p1);
22241 if (bodyAndFormalArguments === car(p1)) {
22242 h = tos;
22243 push(bodyAndFormalArguments);
22244 p1 = p5;
22245 while (iscons(p1)) {
22246 push(car(p1));
22247 Eval();
22248 p1 = cdr(p1);
22249 }
22250 list(tos - h);
22251 return;
22252 }
22253 p1 = p4;
22254 p2 = p5;
22255 h = tos;
22256 while (iscons(p1) && iscons(p2)) {
22257 push(car(p1));
22258 push(car(p2));
22259 p1 = cdr(p1);
22260 p2 = cdr(p2);
22261 }
22262 list(tos - h);
22263 p6 = pop();
22264 push(p3);
22265 if (iscons(p6)) {
22266 push(p6);
22267 rewrite_args();
22268 }
22269 return Eval();
22270 };
22271
22272 rewrite_args = function() {
22273 var h, n;
22274 n = 0;
22275 save();
22276 p2 = pop();
22277 p1 = pop();
22278 if (istensor(p1)) {
22279 n = rewrite_args_tensor();
22280 restore();
22281 return n;
22282 }
22283 if (iscons(p1)) {
22284 h = tos;
22285 if (car(p1) === car(p2)) {
22286 push_symbol(EVAL);
22287 push(car(cdr(p2)));
22288 list(2);
22289 } else {
22290 push(car(p1));
22291 }
22292 p1 = cdr(p1);
22293 while (iscons(p1)) {
22294 push(car(p1));
22295 push(p2);
22296 n += rewrite_args();
22297 p1 = cdr(p1);
22298 }
22299 list(tos - h);
22300 restore();
22301 return n;
22302 }
22303 if (!issymbol(p1)) {
22304 push(p1);
22305 restore();
22306 return 0;
22307 }
22308 p3 = p2;
22309 while (iscons(p3)) {
22310 if (p1 === car(p3)) {
22311 push(cadr(p3));
22312 restore();
22313 return 1;
22314 }
22315 p3 = cddr(p3);
22316 }
22317 p3 = get_binding(p1);
22318 push(p3);
22319 if (p1 !== p3) {
22320 push(p2);
22321 n = rewrite_args();
22322 if (n === 0) {
22323 pop();
22324 push(p1);
22325 }
22326 }
22327 restore();
22328 return n;
22329 };
22330
22331 rewrite_args_tensor = function() {
22332 var i, l1, n, ref2;
22333 n = 0;
22334 i = 0;
22335 push(p1);
22336 copy_tensor();
22337 p1 = pop();
22338 for (i = l1 = 0, ref2 = p1.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22339 push(p1.tensor.elem[i]);
22340 push(p2);
22341 n += rewrite_args();
22342 p1.tensor.elem[i] = pop();
22343 }
22344 check_tensor_dimensions(p1);
22345 push(p1);
22346 return n;
22347 };
22348
22349 Eval_zero = function() {
22350 var i, k, l1, m, m1, n, ref2, ref3;
22351 i = 0;
22352 k = [];
22353 m = 0;
22354 n = 0;
22355 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22356 k[i] = 0;
22357 }
22358 m = 1;
22359 n = 0;
22360 p2 = cdr(p1);
22361 while (iscons(p2)) {
22362 push(car(p2));
22363 Eval();
22364 i = pop_integer();
22365 if (i < 1 || isNaN(i)) {
22366 push(zero);
22367 return;
22368 }
22369 m *= i;
22370 k[n++] = i;
22371 p2 = cdr(p2);
22372 }
22373 if (n === 0) {
22374 push(zero);
22375 return;
22376 }
22377 p1 = alloc_tensor(m);
22378 p1.tensor.ndim = n;
22379 for (i = m1 = 0, ref3 = n; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
22380 p1.tensor.dim[i] = k[i];
22381 }
22382 return push(p1);
22383 };
22384
22385
22386 /*
22387 // up to 100 blocks of 100,000 atoms
22388
22389 #define M 100
22390 #define N 100000
22391
22392 U *mem[M]
22393 int mcount
22394
22395 U *free_list
22396 int free_count
22397
22398 U *
22399 alloc(void)
22400 {
22401 U *p
22402 if (free_count == 0) {
22403 if (mcount == 0)
22404 alloc_mem()
22405 else {
22406 gc()
22407 if (free_count < N * mcount / 2)
22408 alloc_mem()
22409 }
22410 if (free_count == 0)
22411 stop("atom space exhausted")
22412 }
22413 p = free_list
22414 free_list = free_list->u.cons.cdr
22415 free_count--
22416 return p
22417 }
22418 */
22419
22420 allocatedId = 0;
22421
22422 alloc_tensor = function(nelem) {
22423 var i, l1, p, ref2;
22424 i = 0;
22425 p = new U();
22426 p.k = TENSOR;
22427 p.tensor = new tensor();
22428 p.tensor.nelem = nelem;
22429 for (i = l1 = 0, ref2 = nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22430 p.tensor.elem[i] = zero;
22431 }
22432 p.tensor.allocatedId = allocatedId;
22433 allocatedId++;
22434 check_tensor_dimensions(p);
22435 return p;
22436 };
22437
22438
22439 /*
22440 // garbage collector
22441
22442 void
22443 gc(void)
22444 {
22445 int i, j
22446 U *p
22447
22448 // tag everything
22449
22450 for (i = 0; i < mcount; i++) {
22451 p = mem[i]
22452 for (j = 0; j < N; j++)
22453 p[j].tag = 1
22454 }
22455
22456 // untag what's used
22457
22458 untag(p0)
22459 untag(p1)
22460 untag(p2)
22461 untag(p3)
22462 untag(p4)
22463 untag(p5)
22464 untag(p6)
22465 untag(p7)
22466 untag(p8)
22467 untag(p9)
22468
22469 untag(one)
22470 untag(zero)
22471 untag(imaginaryunit)
22472
22473 for (i = 0; i < NSYM; i++) {
22474 untag(binding[i])
22475 untag(arglist[i])
22476 }
22477
22478 for (i = 0; i < tos; i++)
22479 untag(stack[i])
22480
22481 for (i = (int) (frame - stack); i < TOS; i++)
22482 untag(stack[i])
22483
22484 // collect everything that's still tagged
22485
22486 free_count = 0
22487
22488 for (i = 0; i < mcount; i++) {
22489 p = mem[i]
22490 for (j = 0; j < N; j++) {
22491 if (p[j].tag == 0)
22492 continue
22493 // still tagged so it's unused, put on free list
22494 switch (p[j].k) {
22495 case TENSOR:
22496 free(p[j].u.tensor)
22497 break
22498 case STR:
22499 free(p[j].u.str)
22500 break
22501 case NUM:
22502 mfree(p[j].u.q.a)
22503 mfree(p[j].u.q.b)
22504 break
22505 }
22506 p[j].k = CONS; // so no double free occurs above
22507 p[j].u.cons.cdr = free_list
22508 free_list = p + j
22509 free_count++
22510 }
22511 }
22512 }
22513
22514 void
22515 untag(U *p)
22516 {
22517 int i
22518
22519 if (iscons(p)) {
22520 do {
22521 if (p->tag == 0)
22522 return
22523 p->tag = 0
22524 untag(p->u.cons.car)
22525 p = p->u.cons.cdr
22526 } while (iscons(p))
22527 untag(p)
22528 return
22529 }
22530
22531 if (p->tag) {
22532 p->tag = 0
22533 if (istensor(p)) {
22534 for (i = 0; i < p->u.tensor->nelem; i++)
22535 untag(p->u.tensor->elem[i])
22536 }
22537 }
22538 }
22539
22540 // get memory for 100,000 atoms
22541
22542 void
22543 alloc_mem(void)
22544 {
22545 int i
22546 U *p
22547 if (mcount == M)
22548 return
22549 p = (U *) malloc(N * sizeof (struct U))
22550 if (p == NULL)
22551 return
22552 mem[mcount++] = p
22553 for (i = 0; i < N; i++) {
22554 p[i].k = CONS; // so no free in gc
22555 p[i].u.cons.cdr = p + i + 1
22556 }
22557 p[N - 1].u.cons.cdr = free_list
22558 free_list = p
22559 free_count += N
22560 }
22561
22562 void
22563 print_mem_info(void)
22564 {
22565 char buf[100]
22566
22567 sprintf(buf, "%d blocks (%d bytes/block)\n", N * mcount, (int) sizeof (U))
22568 printstr(buf)
22569
22570 sprintf(buf, "%d free\n", free_count)
22571 printstr(buf)
22572
22573 sprintf(buf, "%d used\n", N * mcount - free_count)
22574 printstr(buf)
22575 }
22576 */
22577
22578 Find = function(p, q) {
22579 var i, l1, ref2;
22580 i = 0;
22581 if (equal(p, q)) {
22582 return 1;
22583 }
22584 if (istensor(p)) {
22585 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22586 if (Find(p.tensor.elem[i], q)) {
22587 return 1;
22588 }
22589 }
22590 return 0;
22591 }
22592 while (iscons(p)) {
22593 if (Find(car(p), q)) {
22594 return 1;
22595 }
22596 p = cdr(p);
22597 }
22598 return 0;
22599 };
22600
22601 findPossibleClockForm = function(p) {
22602 var i, l1, ref2;
22603 i = 0;
22604 if (isimaginaryunit(p)) {
22605 return 0;
22606 }
22607 if (car(p) === symbol(POWER) && !isinteger(caddr(p1))) {
22608 if (Find(cadr(p), imaginaryunit)) {
22609 return 1;
22610 }
22611 }
22612 if (car(p) === symbol(POWER) && equaln(cadr(p), -1) && !isinteger(caddr(p1))) {
22613 return 1;
22614 }
22615 if (istensor(p)) {
22616 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22617 if (findPossibleClockForm(p.tensor.elem[i])) {
22618 return 1;
22619 }
22620 }
22621 return 0;
22622 }
22623 while (iscons(p)) {
22624 if (findPossibleClockForm(car(p))) {
22625 return 1;
22626 }
22627 p = cdr(p);
22628 }
22629 return 0;
22630 };
22631
22632 findPossibleExponentialForm = function(p) {
22633 var i, l1, ref2;
22634 i = 0;
22635 if (car(p) === symbol(POWER) && cadr(p) === symbol(E)) {
22636 return Find(caddr(p), imaginaryunit);
22637 }
22638 if (istensor(p)) {
22639 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22640 if (findPossibleExponentialForm(p.tensor.elem[i])) {
22641 return 1;
22642 }
22643 }
22644 return 0;
22645 }
22646 while (iscons(p)) {
22647 if (findPossibleExponentialForm(car(p))) {
22648 return 1;
22649 }
22650 p = cdr(p);
22651 }
22652 return 0;
22653 };
22654
22655 $.Find = Find;
22656
22657 init = function() {
22658 var i, l1, ref2;
22659 i = 0;
22660 flag = 0;
22661 reset_after_error();
22662 chainOfUserSymbolsNotFunctionsBeingEvaluated = [];
22663 if (flag) {
22664 return;
22665 }
22666 flag = 1;
22667 for (i = l1 = 0, ref2 = NSYM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22668 symtab[i] = new U();
22669 symtab[i].k = SYM;
22670 binding[i] = symtab[i];
22671 isSymbolReclaimable[i] = false;
22672 }
22673 return defn();
22674 };
22675
22676
22677 /* cross =====================================================================
22678
22679 Tags
22680 ----
22681 scripting, JS, internal, treenode, general concept, script_defined
22682
22683 Parameters
22684 ----------
22685 u,v
22686
22687 General description
22688 -------------------
22689 Returns the cross product of vectors u and v.
22690 */
22691
22692
22693 /* curl =====================================================================
22694
22695 Tags
22696 ----
22697 scripting, JS, internal, treenode, general concept, script_defined
22698
22699 Parameters
22700 ----------
22701 u
22702
22703 General description
22704 -------------------
22705 Returns the curl of vector u.
22706 */
22707
22708 defn_str = ["version=\"" + version + "\"", "e=exp(1)", "i=sqrt(-1)", "autoexpand=1", "assumeRealVariables=1", "trange=[-pi,pi]", "xrange=[-10,10]", "yrange=[-10,10]", "last=0", "trace=0", "printLeaveEAlone=1", "printLeaveXAlone=0", "cross(u,v)=[u[2]*v[3]-u[3]*v[2],u[3]*v[1]-u[1]*v[3],u[1]*v[2]-u[2]*v[1]]", "curl(v)=[d(v[3],y)-d(v[2],z),d(v[1],z)-d(v[3],x),d(v[2],x)-d(v[1],y)]", "div(v)=d(v[1],x)+d(v[2],y)+d(v[3],z)", "ln(x)=log(x)"];
22709
22710 defn = function() {
22711 var definitionOfInterest, defn_i, l1, originalCodeGen, ref2;
22712 p0 = symbol(NIL);
22713 p1 = symbol(NIL);
22714 p2 = symbol(NIL);
22715 p3 = symbol(NIL);
22716 p4 = symbol(NIL);
22717 p5 = symbol(NIL);
22718 p6 = symbol(NIL);
22719 p7 = symbol(NIL);
22720 p8 = symbol(NIL);
22721 p9 = symbol(NIL);
22722 std_symbol("abs", ABS);
22723 std_symbol("add", ADD);
22724 std_symbol("adj", ADJ);
22725 std_symbol("and", AND);
22726 std_symbol("approxratio", APPROXRATIO);
22727 std_symbol("arccos", ARCCOS);
22728 std_symbol("arccosh", ARCCOSH);
22729 std_symbol("arcsin", ARCSIN);
22730 std_symbol("arcsinh", ARCSINH);
22731 std_symbol("arctan", ARCTAN);
22732 std_symbol("arctanh", ARCTANH);
22733 std_symbol("arg", ARG);
22734 std_symbol("atomize", ATOMIZE);
22735 std_symbol("besselj", BESSELJ);
22736 std_symbol("bessely", BESSELY);
22737 std_symbol("binding", BINDING);
22738 std_symbol("binomial", BINOMIAL);
22739 std_symbol("ceiling", CEILING);
22740 std_symbol("check", CHECK);
22741 std_symbol("choose", CHOOSE);
22742 std_symbol("circexp", CIRCEXP);
22743 std_symbol("clear", CLEAR);
22744 std_symbol("clearall", CLEARALL);
22745 std_symbol("clearpatterns", CLEARPATTERNS);
22746 std_symbol("clock", CLOCK);
22747 std_symbol("coeff", COEFF);
22748 std_symbol("cofactor", COFACTOR);
22749 std_symbol("condense", CONDENSE);
22750 std_symbol("conj", CONJ);
22751 std_symbol("contract", CONTRACT);
22752 std_symbol("cos", COS);
22753 std_symbol("cosh", COSH);
22754 std_symbol("decomp", DECOMP);
22755 std_symbol("defint", DEFINT);
22756 std_symbol("deg", DEGREE);
22757 std_symbol("denominator", DENOMINATOR);
22758 std_symbol("det", DET);
22759 std_symbol("derivative", DERIVATIVE);
22760 std_symbol("dim", DIM);
22761 std_symbol("dirac", DIRAC);
22762 std_symbol("divisors", DIVISORS);
22763 std_symbol("do", DO);
22764 std_symbol("dot", DOT);
22765 std_symbol("draw", DRAW);
22766 std_symbol("dsolve", DSOLVE);
22767 std_symbol("erf", ERF);
22768 std_symbol("erfc", ERFC);
22769 std_symbol("eigen", EIGEN);
22770 std_symbol("eigenval", EIGENVAL);
22771 std_symbol("eigenvec", EIGENVEC);
22772 std_symbol("eval", EVAL);
22773 std_symbol("exp", EXP);
22774 std_symbol("expand", EXPAND);
22775 std_symbol("expcos", EXPCOS);
22776 std_symbol("expsin", EXPSIN);
22777 std_symbol("factor", FACTOR);
22778 std_symbol("factorial", FACTORIAL);
22779 std_symbol("factorpoly", FACTORPOLY);
22780 std_symbol("filter", FILTER);
22781 std_symbol("float", FLOATF);
22782 std_symbol("floor", FLOOR);
22783 std_symbol("for", FOR);
22784 std_symbol("function", FUNCTION);
22785 std_symbol("Gamma", GAMMA);
22786 std_symbol("gcd", GCD);
22787 std_symbol("hermite", HERMITE);
22788 std_symbol("hilbert", HILBERT);
22789 std_symbol("imag", IMAG);
22790 std_symbol("component", INDEX);
22791 std_symbol("inner", INNER);
22792 std_symbol("integral", INTEGRAL);
22793 std_symbol("inv", INV);
22794 std_symbol("invg", INVG);
22795 std_symbol("isinteger", ISINTEGER);
22796 std_symbol("isprime", ISPRIME);
22797 std_symbol("laguerre", LAGUERRE);
22798 std_symbol("lcm", LCM);
22799 std_symbol("leading", LEADING);
22800 std_symbol("legendre", LEGENDRE);
22801 std_symbol("log", LOG);
22802 std_symbol("lookup", LOOKUP);
22803 std_symbol("mod", MOD);
22804 std_symbol("multiply", MULTIPLY);
22805 std_symbol("not", NOT);
22806 std_symbol("nroots", NROOTS);
22807 std_symbol("number", NUMBER);
22808 std_symbol("numerator", NUMERATOR);
22809 std_symbol("operator", OPERATOR);
22810 std_symbol("or", OR);
22811 std_symbol("outer", OUTER);
22812 std_symbol("pattern", PATTERN);
22813 std_symbol("patternsinfo", PATTERNSINFO);
22814 std_symbol("polar", POLAR);
22815 std_symbol("power", POWER);
22816 std_symbol("prime", PRIME);
22817 std_symbol("print", PRINT);
22818 std_symbol("print2dascii", PRINT2DASCII);
22819 std_symbol("printfull", PRINTFULL);
22820 std_symbol("printlatex", PRINTLATEX);
22821 std_symbol("printlist", PRINTLIST);
22822 std_symbol("printplain", PRINTPLAIN);
22823 std_symbol("printLeaveEAlone", PRINT_LEAVE_E_ALONE);
22824 std_symbol("printLeaveXAlone", PRINT_LEAVE_X_ALONE);
22825 std_symbol("product", PRODUCT);
22826 std_symbol("quote", QUOTE);
22827 std_symbol("quotient", QUOTIENT);
22828 std_symbol("rank", RANK);
22829 std_symbol("rationalize", RATIONALIZE);
22830 std_symbol("real", REAL);
22831 std_symbol("rect", YYRECT);
22832 std_symbol("roots", ROOTS);
22833 std_symbol("round", ROUND);
22834 std_symbol("equals", SETQ);
22835 std_symbol("sgn", SGN);
22836 std_symbol("silentpattern", SILENTPATTERN);
22837 std_symbol("simplify", SIMPLIFY);
22838 std_symbol("sin", SIN);
22839 std_symbol("sinh", SINH);
22840 std_symbol("shape", SHAPE);
22841 std_symbol("sqrt", SQRT);
22842 std_symbol("stop", STOP);
22843 std_symbol("subst", SUBST);
22844 std_symbol("sum", SUM);
22845 std_symbol("symbolsinfo", SYMBOLSINFO);
22846 std_symbol("tan", TAN);
22847 std_symbol("tanh", TANH);
22848 std_symbol("taylor", TAYLOR);
22849 std_symbol("test", TEST);
22850 std_symbol("testeq", TESTEQ);
22851 std_symbol("testge", TESTGE);
22852 std_symbol("testgt", TESTGT);
22853 std_symbol("testle", TESTLE);
22854 std_symbol("testlt", TESTLT);
22855 std_symbol("transpose", TRANSPOSE);
22856 std_symbol("unit", UNIT);
22857 std_symbol("zero", ZERO);
22858 std_symbol("nil", NIL);
22859 std_symbol("autoexpand", AUTOEXPAND);
22860 std_symbol("bake", BAKE);
22861 std_symbol("assumeRealVariables", ASSUME_REAL_VARIABLES);
22862 std_symbol("last", LAST);
22863 std_symbol("lastprint", LAST_PRINT);
22864 std_symbol("last2dasciiprint", LAST_2DASCII_PRINT);
22865 std_symbol("lastfullprint", LAST_FULL_PRINT);
22866 std_symbol("lastlatexprint", LAST_LATEX_PRINT);
22867 std_symbol("lastlistprint", LAST_LIST_PRINT);
22868 std_symbol("lastplainprint", LAST_PLAIN_PRINT);
22869 std_symbol("trace", TRACE);
22870 std_symbol("~", YYE);
22871 std_symbol("$DRAWX", DRAWX);
22872 std_symbol("$METAA", METAA);
22873 std_symbol("$METAB", METAB);
22874 std_symbol("$METAX", METAX);
22875 std_symbol("$SECRETX", SECRETX);
22876 std_symbol("version", VERSION);
22877 std_symbol("pi", PI);
22878 std_symbol("a", SYMBOL_A);
22879 std_symbol("b", SYMBOL_B);
22880 std_symbol("c", SYMBOL_C);
22881 std_symbol("d", SYMBOL_D);
22882 std_symbol("i", SYMBOL_I);
22883 std_symbol("j", SYMBOL_J);
22884 std_symbol("n", SYMBOL_N);
22885 std_symbol("r", SYMBOL_R);
22886 std_symbol("s", SYMBOL_S);
22887 std_symbol("t", SYMBOL_T);
22888 std_symbol("x", SYMBOL_X);
22889 std_symbol("y", SYMBOL_Y);
22890 std_symbol("z", SYMBOL_Z);
22891 std_symbol("I", SYMBOL_IDENTITY_MATRIX);
22892 std_symbol("a_", SYMBOL_A_UNDERSCORE);
22893 std_symbol("b_", SYMBOL_B_UNDERSCORE);
22894 std_symbol("x_", SYMBOL_X_UNDERSCORE);
22895 std_symbol("$C1", C1);
22896 std_symbol("$C2", C2);
22897 std_symbol("$C3", C3);
22898 std_symbol("$C4", C4);
22899 std_symbol("$C5", C5);
22900 std_symbol("$C6", C6);
22901 defineSomeHandyConstants();
22902 originalCodeGen = codeGen;
22903 codeGen = false;
22904 for (defn_i = l1 = 0, ref2 = defn_str.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; defn_i = 0 <= ref2 ? ++l1 : --l1) {
22905 definitionOfInterest = defn_str[defn_i];
22906 scan(definitionOfInterest);
22907 if (DEBUG) {
22908 console.log("... evaling " + definitionOfInterest);
22909 console.log("top of stack:");
22910 console.log(print_list(stack[tos - 1]));
22911 }
22912 Eval();
22913 pop();
22914 }
22915 return codeGen = originalCodeGen;
22916 };
22917
22918 defineSomeHandyConstants = function() {
22919 push_integer(0);
22920 zero = pop();
22921 push_integer(1);
22922 one = pop();
22923 push_double(1.0);
22924 one_as_double = pop();
22925 push_symbol(POWER);
22926 if (DEBUG) {
22927 console.log(print_list(stack[tos - 1]));
22928 }
22929 push_integer(-1);
22930 if (DEBUG) {
22931 console.log(print_list(stack[tos - 1]));
22932 }
22933 push_rational(1, 2);
22934 if (DEBUG) {
22935 console.log(print_list(stack[tos - 1]));
22936 }
22937 list(3);
22938 if (DEBUG) {
22939 console.log(print_list(stack[tos - 1]));
22940 }
22941 return imaginaryunit = pop();
22942 };
22943
22944 mcmp = function(a, b) {
22945 return a.compare(b);
22946 };
22947
22948 mcmpint = function(a, n) {
22949 var b, t;
22950 b = bigInt(n);
22951 t = mcmp(a, b);
22952 return t;
22953 };
22954
22955
22956 /*
22957 #if SELFTEST
22958
22959 void
22960 test_mcmp(void)
22961 {
22962 int i, j, k
22963 unsigned int *x, *y
22964 logout("testing mcmp\n")
22965 for (i = -1000; i < 1000; i++) {
22966 x = mint(i)
22967 for (j = -1000; j < 1000; j++) {
22968 y = mint(j)
22969 k = mcmp(x, y)
22970 if (i == j && k != 0) {
22971 logout("failed\n")
22972 errout()
22973 }
22974 if (i < j && k != -1) {
22975 logout("failed\n")
22976 errout()
22977 }
22978 if (i > j && k != 1) {
22979 logout("failed\n")
22980 errout()
22981 }
22982 mfree(y)
22983 }
22984 mfree(x)
22985 }
22986 logout("ok\n")
22987 }
22988
22989 #endif
22990 */
22991
22992 strcmp = function(str1, str2) {
22993 if (str1 === str2) {
22994 return 0;
22995 } else if (str1 > str2) {
22996 return 1;
22997 } else {
22998 return -1;
22999 }
23000 };
23001
23002 doubleToReasonableString = function(d) {
23003 var stringRepresentation;
23004 if (codeGen) {
23005 return d + "";
23006 }
23007 stringRepresentation = "" + parseFloat(d.toPrecision(6));
23008 if (stringRepresentation.indexOf(".") === -1) {
23009 stringRepresentation += ".0";
23010 }
23011 return stringRepresentation;
23012 };
23013
23014 clear_term = function() {};
23015
23016 isspace = function(s) {
23017 if (s == null) {
23018 return false;
23019 }
23020 return s === ' ' || s === '\t' || s === '\n' || s === '\v' || s === '\f' || s === '\r';
23021 };
23022
23023 isdigit = function(str) {
23024 if (str == null) {
23025 return false;
23026 }
23027 return /^\d+$/.test(str);
23028 };
23029
23030 isalpha = function(str) {
23031 if (str == null) {
23032 return false;
23033 }
23034 return str.search(/[^A-Za-z]/) === -1;
23035 };
23036
23037 isalphaOrUnderscore = function(str) {
23038 if (str == null) {
23039 return false;
23040 }
23041 return str.search(/[^A-Za-z_]/) === -1;
23042 };
23043
23044 isunderscore = function(str) {
23045 if (str == null) {
23046 return false;
23047 }
23048 return str.search(/_/) === -1;
23049 };
23050
23051 isalnumorunderscore = function(str) {
23052 if (str == null) {
23053 return false;
23054 }
23055 return isalphaOrUnderscore(str) || isdigit(str);
23056 };
23057
23058 count = function(p) {
23059 var n;
23060 if (iscons(p)) {
23061 n = 0;
23062 while (iscons(p)) {
23063 n += count(car(p)) + 1;
23064 p = cdr(p);
23065 }
23066 } else {
23067 n = 1;
23068 }
23069 return n;
23070 };
23071
23072 countOccurrencesOfSymbol = function(needle, p) {
23073 var n;
23074 n = 0;
23075 if (iscons(p)) {
23076 while (iscons(p)) {
23077 n += countOccurrencesOfSymbol(needle, car(p));
23078 p = cdr(p);
23079 }
23080 } else {
23081 if (equal(needle, p)) {
23082 n = 1;
23083 }
23084 }
23085 return n;
23086 };
23087
23088 countsize = function(p) {
23089 var i, l1, n, ref2;
23090 n = 0;
23091 if (istensor(p)) {
23092 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
23093 n += p.tensor.elem[i];
23094 }
23095 } else if (iscons(p)) {
23096 while (iscons(p)) {
23097 n += count(car(p)) + 1;
23098 p = cdr(p);
23099 }
23100 } else {
23101 n = 1;
23102 }
23103 return n;
23104 };
23105
23106 stop = function(s) {
23107 var message;
23108 errorMessage += "Stop: ";
23109 errorMessage += s;
23110 message = errorMessage;
23111 errorMessage = '';
23112 moveTos(0);
23113 throw new Error(message);
23114 };
23115
23116 findDependenciesInScript = function(stringToBeParsed, dontGenerateCode) {
23117 var allReturnedLatexStrings, allReturnedPlainStrings, bodyForReadableSummaryOfGeneratedCode, cacheKey, cacheMissPenalty, currentStateHash, cyclesDescriptions, deQuotedDep, dependencyInfo, eachDependency, error, frozen, generatedBody, generatedCode, i, indexOfEachReplacement, indexOfPartRemainingToBeParsed, inited, key, l1, len, len1, len2, len3, len4, len5, len6, len7, m1, n, n1, newUserSymbol, o1, origPrintMode, originalUserSymbol, parameters, possiblyCached, q1, r1, readableSummaryOfGeneratedCode, recursedDependencies, ref2, replacementsFrom, replacementsTo, s1, scriptEvaluation, stringToBeRun, t1, testableString, timeStartFromAlgebra, toBeFrozen, toBePrinted, totalTime, u1, userVariablesMentioned, value, variablesWithCycles;
23118 if (DEBUG) {
23119 console.log("stringToBeParsed: " + stringToBeParsed);
23120 }
23121 timeStartFromAlgebra = new Date().getTime();
23122 if (CACHE_DEBUGS || CACHE_HITSMISS_DEBUGS || TIMING_DEBUGS) {
23123 console.log(" --------- findDependenciesInScript input: " + stringToBeParsed + " at: " + (new Date()));
23124 currentStateHash = getStateHash();
23125 console.log("state hash: " + currentStateHash);
23126 }
23127 inited = true;
23128 codeGen = true;
23129 symbolsDependencies = {};
23130 symbolsHavingReassignments = [];
23131 symbolsInExpressionsWithoutAssignments = [];
23132 patternHasBeenFound = false;
23133 indexOfPartRemainingToBeParsed = 0;
23134 allReturnedPlainStrings = "";
23135 allReturnedLatexStrings = "";
23136 n = 0;
23137 dependencyInfo = {
23138 affectsVariables: [],
23139 affectedBy: []
23140 };
23141 stringToBeRun = stringToBeParsed;
23142 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23143 currentStateHash = getStateHash();
23144 cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun + " - " + dontGenerateCode;
23145 if (CACHE_DEBUGS) {
23146 console.log("cached_findDependenciesInScript key: " + cacheKey);
23147 }
23148 possiblyCached = cached_findDependenciesInScript.get(cacheKey);
23149 if (possiblyCached != null) {
23150 if (CACHE_HITSMISS_DEBUGS) {
23151 console.log("cached_findDependenciesInScript hit on " + stringToBeRun);
23152 }
23153 unfreeze(possiblyCached);
23154 if (TIMING_DEBUGS) {
23155 totalTime = new Date().getTime() - timeStartFromAlgebra;
23156 console.log("findDependenciesInScript input: " + stringToBeRun + " time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length - 5] - totalTime) + "ms due to cache hit");
23157 }
23158 return [possiblyCached[possiblyCached.length - 7], possiblyCached[possiblyCached.length - 6], possiblyCached[possiblyCached.length - 5], possiblyCached[possiblyCached.length - 4], possiblyCached[possiblyCached.length - 3], possiblyCached[possiblyCached.length - 2], possiblyCached[possiblyCached.length - 1]];
23159 } else {
23160 if (CACHE_HITSMISS_DEBUGS) {
23161 console.log("cached_findDependenciesInScript miss on: " + stringToBeRun);
23162 }
23163 if (TIMING_DEBUGS) {
23164 cacheMissPenalty = new Date().getTime() - timeStartFromAlgebra;
23165 }
23166 }
23167 }
23168 while (1) {
23169 try {
23170 errorMessage = "";
23171 check_stack();
23172 if (DEBUG) {
23173 console.log("findDependenciesInScript: scanning");
23174 }
23175 n = scan(stringToBeParsed.substring(indexOfPartRemainingToBeParsed));
23176 if (DEBUG) {
23177 console.log("scanned");
23178 }
23179 pop();
23180 check_stack();
23181 } catch (error1) {
23182 error = error1;
23183 if (PRINTOUTRESULT) {
23184 console.log(error);
23185 }
23186 errorMessage = error + "";
23187 reset_after_error();
23188 break;
23189 }
23190 if (n === 0) {
23191 break;
23192 }
23193 indexOfPartRemainingToBeParsed += n;
23194 }
23195 testableString = "";
23196 if (DEBUG) {
23197 console.log("all local dependencies ----------------");
23198 }
23199 testableString += "All local dependencies: ";
23200 for (key in symbolsDependencies) {
23201 value = symbolsDependencies[key];
23202 if (DEBUG) {
23203 console.log("variable " + key + " depends on: ");
23204 }
23205 dependencyInfo.affectsVariables.push(key);
23206 testableString += " variable " + key + " depends on: ";
23207 for (l1 = 0, len = value.length; l1 < len; l1++) {
23208 i = value[l1];
23209 if (DEBUG) {
23210 console.log(" " + i);
23211 }
23212 if (i[0] !== "'") {
23213 dependencyInfo.affectedBy.push(i);
23214 }
23215 testableString += i + ", ";
23216 }
23217 testableString += "; ";
23218 }
23219 testableString += ". ";
23220 if (DEBUG) {
23221 console.log("Symbols with reassignments ----------------");
23222 }
23223 testableString += "Symbols with reassignments: ";
23224 for (m1 = 0, len1 = symbolsHavingReassignments.length; m1 < len1; m1++) {
23225 key = symbolsHavingReassignments[m1];
23226 if (dependencyInfo.affectedBy.indexOf(key) === -1) {
23227 dependencyInfo.affectedBy.push(key);
23228 testableString += key + ", ";
23229 }
23230 }
23231 testableString += ". ";
23232 if (DEBUG) {
23233 console.log("Symbols in expressions without assignments ----------------");
23234 }
23235 testableString += "Symbols in expressions without assignments: ";
23236 for (n1 = 0, len2 = symbolsInExpressionsWithoutAssignments.length; n1 < len2; n1++) {
23237 key = symbolsInExpressionsWithoutAssignments[n1];
23238 if (dependencyInfo.affectedBy.indexOf(key) === -1) {
23239 dependencyInfo.affectedBy.push(key);
23240 testableString += key + ", ";
23241 }
23242 }
23243 testableString += ". ";
23244 dependencyInfo.affectedBy.push("PATTERN_DEPENDENCY");
23245 if (patternHasBeenFound) {
23246 dependencyInfo.affectsVariables.push("PATTERN_DEPENDENCY");
23247 testableString += " - PATTERN_DEPENDENCY inserted - ";
23248 }
23249 if (DEBUG) {
23250 console.log("All dependencies recursively ----------------");
23251 }
23252 testableString += "All dependencies recursively: ";
23253 scriptEvaluation = ["", ""];
23254 generatedCode = "";
23255 readableSummaryOfGeneratedCode = "";
23256 if (errorMessage === "" && !dontGenerateCode) {
23257 try {
23258 allReturnedPlainStrings = "";
23259 allReturnedLatexStrings = "";
23260 scriptEvaluation = run(stringToBeParsed, true);
23261 allReturnedPlainStrings = "";
23262 allReturnedLatexStrings = "";
23263 } catch (error1) {
23264 error = error1;
23265 if (PRINTOUTRESULT) {
23266 console.log(error);
23267 }
23268 errorMessage = error + "";
23269 init();
23270 }
23271 if (errorMessage === "") {
23272 for (key in symbolsDependencies) {
23273 codeGen = true;
23274 if (DEBUG) {
23275 console.log(" variable " + key + " is: " + get_binding(usr_symbol(key)).toString());
23276 }
23277 codeGen = false;
23278 if (DEBUG) {
23279 console.log(" variable " + key + " depends on: ");
23280 }
23281 testableString += " variable " + key + " depends on: ";
23282 recursedDependencies = [];
23283 variablesWithCycles = [];
23284 cyclesDescriptions = [];
23285 recursiveDependencies(key, recursedDependencies, [], variablesWithCycles, [], cyclesDescriptions);
23286 for (o1 = 0, len3 = variablesWithCycles.length; o1 < len3; o1++) {
23287 i = variablesWithCycles[o1];
23288 if (DEBUG) {
23289 console.log(" --> cycle through " + i);
23290 }
23291 }
23292 for (q1 = 0, len4 = recursedDependencies.length; q1 < len4; q1++) {
23293 i = recursedDependencies[q1];
23294 if (DEBUG) {
23295 console.log(" " + i);
23296 }
23297 testableString += i + ", ";
23298 }
23299 testableString += "; ";
23300 for (r1 = 0, len5 = cyclesDescriptions.length; r1 < len5; r1++) {
23301 i = cyclesDescriptions[r1];
23302 testableString += " " + i + ", ";
23303 }
23304 if (DEBUG) {
23305 console.log(" code generation:" + key + " is: " + get_binding(usr_symbol(key)).toString());
23306 }
23307 push(get_binding(usr_symbol(key)));
23308 replacementsFrom = [];
23309 replacementsTo = [];
23310 for (s1 = 0, len6 = recursedDependencies.length; s1 < len6; s1++) {
23311 eachDependency = recursedDependencies[s1];
23312 if (eachDependency[0] === "'") {
23313 deQuotedDep = eachDependency.substring(1);
23314 originalUserSymbol = usr_symbol(deQuotedDep);
23315 newUserSymbol = usr_symbol("AVOID_BINDING_TO_EXTERNAL_SCOPE_VALUE" + deQuotedDep);
23316 replacementsFrom.push(originalUserSymbol);
23317 replacementsTo.push(newUserSymbol);
23318 push(originalUserSymbol);
23319 push(newUserSymbol);
23320 subst();
23321 if (DEBUG) {
23322 console.log("after substitution: " + stack[tos - 1]);
23323 }
23324 }
23325 }
23326 try {
23327 simplifyForCodeGeneration();
23328 } catch (error1) {
23329 error = error1;
23330 if (PRINTOUTRESULT) {
23331 console.log(error);
23332 }
23333 errorMessage = error + "";
23334 init();
23335 }
23336 for (indexOfEachReplacement = t1 = 0, ref2 = replacementsFrom.length; 0 <= ref2 ? t1 < ref2 : t1 > ref2; indexOfEachReplacement = 0 <= ref2 ? ++t1 : --t1) {
23337 push(replacementsTo[indexOfEachReplacement]);
23338 push(replacementsFrom[indexOfEachReplacement]);
23339 subst();
23340 }
23341 clearRenamedVariablesToAvoidBindingToExternalScope();
23342 if (errorMessage === "") {
23343 toBePrinted = pop();
23344 userVariablesMentioned = [];
23345 collectUserSymbols(toBePrinted, userVariablesMentioned);
23346 allReturnedPlainStrings = "";
23347 allReturnedLatexStrings = "";
23348 codeGen = true;
23349 generatedBody = toBePrinted.toString();
23350 codeGen = false;
23351 origPrintMode = printMode;
23352 printMode = PRINTMODE_LATEX;
23353 bodyForReadableSummaryOfGeneratedCode = toBePrinted.toString();
23354 printMode = origPrintMode;
23355 if (variablesWithCycles.indexOf(key) !== -1) {
23356 generatedCode += "// " + key + " is part of a cyclic dependency, no code generated.";
23357 readableSummaryOfGeneratedCode += "#" + key + " is part of a cyclic dependency, no code generated.";
23358 } else {
23359
23360 /*
23361 * using this paragraph instead of the following one
23362 * creates methods signatures that
23363 * are slightly less efficient
23364 * i.e. variables compare even if they are
23365 * simplified away.
23366 * In theory these signatures are more stable, but
23367 * in practice signatures vary quite a bit anyways
23368 * depending on previous assignments for example,
23369 * so it's unclear whether going for stability
23370 * is sensible at all..
23371 if recursedDependencies.length != 0
23372 parameters = "("
23373 for i in recursedDependencies
23374 if i.indexOf("'") != 0
23375 parameters += i + ", "
23376 else
23377 if recursedDependencies.indexOf(i.substring(1)) == -1
23378 parameters += i.substring(1) + ", "
23379 */
23380 userVariablesMentioned = userVariablesMentioned.filter(function(x) {
23381 return predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(x + "") === -1;
23382 });
23383 userVariablesMentioned = userVariablesMentioned.filter(function(x) {
23384 return recursedDependencies.indexOf(x + "") !== -1 || recursedDependencies.indexOf("\'" + x + "") !== -1;
23385 });
23386 if (userVariablesMentioned.length !== 0) {
23387 parameters = "(";
23388 for (u1 = 0, len7 = userVariablesMentioned.length; u1 < len7; u1++) {
23389 i = userVariablesMentioned[u1];
23390 if (i.printname !== key) {
23391 parameters += i.printname + ", ";
23392 }
23393 }
23394 parameters = parameters.replace(/, $/gm, "");
23395 parameters += ")";
23396 generatedCode += key + " = function " + parameters + " { return ( " + generatedBody + " ); }";
23397 readableSummaryOfGeneratedCode += key + parameters + " = " + bodyForReadableSummaryOfGeneratedCode;
23398 } else {
23399 generatedCode += key + " = " + generatedBody + ";";
23400 readableSummaryOfGeneratedCode += key + " = " + bodyForReadableSummaryOfGeneratedCode;
23401 }
23402 }
23403 generatedCode += "\n";
23404 readableSummaryOfGeneratedCode += "\n";
23405 if (DEBUG) {
23406 console.log(" " + generatedCode);
23407 }
23408 }
23409 }
23410 }
23411 }
23412 generatedCode = generatedCode.replace(/\n$/gm, "");
23413 readableSummaryOfGeneratedCode = readableSummaryOfGeneratedCode.replace(/\n$/gm, "");
23414 symbolsDependencies = {};
23415 symbolsHavingReassignments = [];
23416 patternHasBeenFound = false;
23417 symbolsInExpressionsWithoutAssignments = [];
23418 if (DEBUG) {
23419 console.log("testable string: " + testableString);
23420 }
23421 if (TIMING_DEBUGS) {
23422 console.log("findDependenciesInScript time for: " + stringToBeRun + " : " + ((new Date().getTime()) - timeStartFromAlgebra) + "ms");
23423 }
23424 if (ENABLE_CACHING && stringToBeRun !== "clearall" && errorMessage === "") {
23425 frozen = freeze();
23426 toBeFrozen = [frozen[0], frozen[1], frozen[2], frozen[3], frozen[4], frozen[5], new Date().getTime() - timeStartFromAlgebra, testableString, scriptEvaluation[0], generatedCode, readableSummaryOfGeneratedCode, scriptEvaluation[1], errorMessage, dependencyInfo];
23427 if (CACHE_DEBUGS) {
23428 console.log("setting cached_findDependenciesInScript on key: " + cacheKey);
23429 }
23430 cached_findDependenciesInScript.set(cacheKey, toBeFrozen);
23431 }
23432 return [testableString, scriptEvaluation[0], generatedCode, readableSummaryOfGeneratedCode, scriptEvaluation[1], errorMessage, dependencyInfo];
23433 };
23434
23435 recursiveDependencies = function(variableToBeChecked, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions) {
23436 var cyclesDescription, i, k, l1, len, len1, m1, ref2;
23437 variablesAlreadyFleshedOut.push(variableToBeChecked);
23438 if (symbolsDependencies[chainBeingChecked[chainBeingChecked.length - 1]] != null) {
23439 if (symbolsDependencies[chainBeingChecked[chainBeingChecked.length - 1]].indexOf("'" + variableToBeChecked) !== -1) {
23440 if (DEBUG) {
23441 console.log("can't keep following the chain of " + variableToBeChecked + " because it's actually a variable bound to a parameter");
23442 }
23443 if (arrayWhereDependenciesWillBeAdded.indexOf("'" + variableToBeChecked) === -1 && arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) === -1) {
23444 arrayWhereDependenciesWillBeAdded.push(variableToBeChecked);
23445 }
23446 return arrayWhereDependenciesWillBeAdded;
23447 }
23448 }
23449 chainBeingChecked.push(variableToBeChecked);
23450 if (symbolsDependencies[variableToBeChecked] == null) {
23451 if (arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) === -1) {
23452 arrayWhereDependenciesWillBeAdded.push(variableToBeChecked);
23453 }
23454 return arrayWhereDependenciesWillBeAdded;
23455 } else {
23456 ref2 = symbolsDependencies[variableToBeChecked];
23457 for (l1 = 0, len = ref2.length; l1 < len; l1++) {
23458 i = ref2[l1];
23459 if (chainBeingChecked.indexOf(i) !== -1) {
23460 if (DEBUG) {
23461 console.log(" found cycle:");
23462 }
23463 cyclesDescription = "";
23464 for (m1 = 0, len1 = chainBeingChecked.length; m1 < len1; m1++) {
23465 k = chainBeingChecked[m1];
23466 if (variablesWithCycles.indexOf(k) === -1) {
23467 variablesWithCycles.push(k);
23468 }
23469 if (DEBUG) {
23470 console.log(k + " --> ");
23471 }
23472 cyclesDescription += k + " --> ";
23473 }
23474 if (DEBUG) {
23475 console.log(" ... then " + i + " again");
23476 }
23477 cyclesDescription += " ... then " + i + " again";
23478 cyclesDescriptions.push(cyclesDescription);
23479 if (variablesWithCycles.indexOf(i) === -1) {
23480 variablesWithCycles.push(i);
23481 }
23482 } else {
23483 recursiveDependencies(i, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions);
23484 chainBeingChecked.pop();
23485 }
23486 }
23487 return arrayWhereDependenciesWillBeAdded;
23488 }
23489 };
23490
23491 inited = false;
23492
23493 latexErrorSign = "\\rlap{\\large\\color{red}\\bigtriangleup}{\\ \\ \\tiny\\color{red}!}";
23494
23495 turnErrorMessageToLatex = function(theErrorMessage) {
23496 theErrorMessage = theErrorMessage.replace(/\n/g, "");
23497 theErrorMessage = theErrorMessage.replace(/_/g, "} \\_ \\text{");
23498 theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(transpose_unicode), 'g'), "}{}^{T}\\text{");
23499 theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(dotprod_unicode), 'g'), "}\\cdot \\text{");
23500 theErrorMessage = theErrorMessage.replace("Stop:", "} \\quad \\text{Stop:");
23501 theErrorMessage = theErrorMessage.replace("->", "} \\rightarrow \\text{");
23502 theErrorMessage = theErrorMessage.replace("?", "}\\enspace " + latexErrorSign + " \\enspace \\text{");
23503 theErrorMessage = "$$\\text{" + theErrorMessage.replace(/\n/g, "") + "}$$";
23504 return theErrorMessage;
23505 };
23506
23507 normaliseDots = function(stringToNormalise) {
23508 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8901), 'g'), String.fromCharCode(dotprod_unicode));
23509 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8226), 'g'), String.fromCharCode(dotprod_unicode));
23510 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(12539), 'g'), String.fromCharCode(dotprod_unicode));
23511 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(55296), 'g'), String.fromCharCode(dotprod_unicode));
23512 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(65381), 'g'), String.fromCharCode(dotprod_unicode));
23513 return stringToNormalise;
23514 };
23515
23516 CACHE_DEBUGS = false;
23517
23518 CACHE_HITSMISS_DEBUGS = false;
23519
23520 TIMING_DEBUGS = false;
23521
23522 cacheMissPenalty = 0;
23523
23524 run = function(stringToBeRun, generateLatex) {
23525 var allReturnedLatexStrings, allReturnedPlainStrings, cacheKey, collectedLatexResult, collectedPlainResult, currentStateHash, error, errorWhileExecution, frozen, i, indexOfPartRemainingToBeParsed, n, possiblyCached, stringToBeReturned, theErrorMessage, timeStart, timingDebugWrite, toBeFrozen, totalTime;
23526 if (generateLatex == null) {
23527 generateLatex = false;
23528 }
23529 timeStart = new Date().getTime();
23530 stringToBeRun = normaliseDots(stringToBeRun);
23531 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23532 currentStateHash = getStateHash();
23533 cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun;
23534 if (CACHE_DEBUGS) {
23535 console.log("cached_runs key: " + cacheKey);
23536 }
23537 possiblyCached = cached_runs.get(cacheKey);
23538 if (possiblyCached != null) {
23539 if (CACHE_HITSMISS_DEBUGS) {
23540 console.log("cached_runs hit on: " + stringToBeRun);
23541 }
23542 unfreeze(possiblyCached);
23543 if (TIMING_DEBUGS) {
23544 totalTime = new Date().getTime() - timeStart;
23545 console.log("run time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length - 2] - totalTime) + "ms due to cache hit");
23546 }
23547 return possiblyCached[possiblyCached.length - 1];
23548 } else {
23549 if (CACHE_HITSMISS_DEBUGS) {
23550 console.log("cached_runs miss on: " + stringToBeRun);
23551 }
23552 if (TIMING_DEBUGS) {
23553 cacheMissPenalty = new Date().getTime() - timeStart;
23554 }
23555 }
23556 }
23557 if (stringToBeRun === "selftest") {
23558 selftest();
23559 return;
23560 }
23561 if (!inited) {
23562 inited = true;
23563 init();
23564 }
23565 i = 0;
23566 n = 0;
23567 indexOfPartRemainingToBeParsed = 0;
23568 allReturnedPlainStrings = "";
23569 allReturnedLatexStrings = "";
23570 while (1) {
23571 try {
23572 errorMessage = "";
23573 check_stack();
23574 n = scan(stringToBeRun.substring(indexOfPartRemainingToBeParsed));
23575 p1 = pop();
23576 check_stack();
23577 } catch (error1) {
23578 error = error1;
23579 if (PRINTOUTRESULT) {
23580 console.log(error);
23581 }
23582 allReturnedPlainStrings += error.message;
23583 if (generateLatex) {
23584 theErrorMessage = turnErrorMessageToLatex(error.message);
23585 allReturnedLatexStrings += theErrorMessage;
23586 }
23587 reset_after_error();
23588 break;
23589 }
23590 if (n === 0) {
23591 break;
23592 }
23593 indexOfPartRemainingToBeParsed += n;
23594 push(p1);
23595 errorWhileExecution = false;
23596 try {
23597 stringsEmittedByUserPrintouts = "";
23598 top_level_eval();
23599 p2 = pop();
23600 check_stack();
23601 if (isstr(p2)) {
23602 if (DEBUG) {
23603 console.log(p2.str);
23604 }
23605 if (DEBUG) {
23606 console.log("\n");
23607 }
23608 }
23609 if (p2 === symbol(NIL)) {
23610 collectedPlainResult = stringsEmittedByUserPrintouts;
23611 if (generateLatex) {
23612 collectedLatexResult = "$$" + stringsEmittedByUserPrintouts + "$$";
23613 }
23614 } else {
23615 collectedPlainResult = print_expr(p2);
23616 collectedPlainResult += "\n";
23617 if (generateLatex) {
23618 collectedLatexResult = "$$" + collectLatexStringFromReturnValue(p2) + "$$";
23619 if (DEBUG) {
23620 console.log("collectedLatexResult: " + collectedLatexResult);
23621 }
23622 }
23623 }
23624 allReturnedPlainStrings += collectedPlainResult;
23625 if (generateLatex) {
23626 allReturnedLatexStrings += collectedLatexResult;
23627 }
23628 if (PRINTOUTRESULT) {
23629 if (DEBUG) {
23630 console.log("printline");
23631 }
23632 if (DEBUG) {
23633 console.log(collectedPlainResult);
23634 }
23635 }
23636 if (PRINTOUTRESULT) {
23637 if (DEBUG) {
23638 console.log("display:");
23639 }
23640 print2dascii(p2);
23641 }
23642 if (generateLatex) {
23643 allReturnedLatexStrings += "\n";
23644 }
23645 } catch (error1) {
23646 error = error1;
23647 errorWhileExecution = true;
23648 collectedPlainResult = error.message;
23649 if (generateLatex) {
23650 collectedLatexResult = turnErrorMessageToLatex(error.message);
23651 }
23652 if (PRINTOUTRESULT) {
23653 console.log(collectedPlainResult);
23654 }
23655 allReturnedPlainStrings += collectedPlainResult;
23656 if (collectedPlainResult !== "") {
23657 allReturnedPlainStrings += "\n";
23658 }
23659 if (generateLatex) {
23660 allReturnedLatexStrings += collectedLatexResult;
23661 allReturnedLatexStrings += "\n";
23662 }
23663 resetCache();
23664 init();
23665 }
23666 }
23667 if (allReturnedPlainStrings[allReturnedPlainStrings.length - 1] === "\n") {
23668 allReturnedPlainStrings = allReturnedPlainStrings.substring(0, allReturnedPlainStrings.length - 1);
23669 }
23670 if (generateLatex) {
23671 if (allReturnedLatexStrings[allReturnedLatexStrings.length - 1] === "\n") {
23672 allReturnedLatexStrings = allReturnedLatexStrings.substring(0, allReturnedLatexStrings.length - 1);
23673 }
23674 }
23675 if (generateLatex) {
23676 if (DEBUG) {
23677 console.log("allReturnedLatexStrings: " + allReturnedLatexStrings);
23678 }
23679 stringToBeReturned = [allReturnedPlainStrings, allReturnedLatexStrings];
23680 } else {
23681 stringToBeReturned = allReturnedPlainStrings;
23682 }
23683 if (ENABLE_CACHING && stringToBeRun !== "clearall" && !errorWhileExecution) {
23684 frozen = freeze();
23685 toBeFrozen = [frozen[0], frozen[1], frozen[2], frozen[3], frozen[4], frozen[5], new Date().getTime() - timeStart, stringToBeReturned];
23686 if (CACHE_DEBUGS) {
23687 console.log("setting cached_runs on key: " + cacheKey);
23688 }
23689 cached_runs.set(cacheKey, toBeFrozen);
23690 }
23691 if (TIMING_DEBUGS) {
23692 timingDebugWrite = "run time on: " + stringToBeRun + " : " + (new Date().getTime() - timeStart) + "ms";
23693 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23694 timingDebugWrite += ", of which cache miss penalty: " + cacheMissPenalty + "ms";
23695 }
23696 console.log(timingDebugWrite);
23697 }
23698 allReturnedPlainStrings = "";
23699 allReturnedLatexStrings = "";
23700 return stringToBeReturned;
23701 };
23702
23703 check_stack = function() {
23704 if (tos !== 0) {
23705 debugger;
23706 stop("stack error");
23707 }
23708 if (frame !== TOS) {
23709 debugger;
23710 stop("frame error");
23711 }
23712 if (chainOfUserSymbolsNotFunctionsBeingEvaluated.length !== 0) {
23713 debugger;
23714 stop("symbols evaluation still ongoing?");
23715 }
23716 if (evaluatingAsFloats !== 0) {
23717 debugger;
23718 stop("numeric evaluation still ongoing?");
23719 }
23720 if (evaluatingPolar !== 0) {
23721 debugger;
23722 return stop("evaluation of polar still ongoing?");
23723 }
23724 };
23725
23726 top_level_eval = function() {
23727 var doNothing;
23728 if (DEBUG) {
23729 console.log("#### top level eval");
23730 }
23731 save();
23732 trigmode = 0;
23733 p1 = symbol(AUTOEXPAND);
23734 if (iszero(get_binding(p1))) {
23735 expanding = 0;
23736 } else {
23737 expanding = 1;
23738 }
23739 p1 = pop();
23740 push(p1);
23741 Eval();
23742 p2 = pop();
23743 if (p2 === symbol(NIL)) {
23744 push(p2);
23745 restore();
23746 return;
23747 }
23748 set_binding(symbol(LAST), p2);
23749 if (!iszero(get_binding(symbol(BAKE)))) {
23750 push(p2);
23751 bake();
23752 p2 = pop();
23753 }
23754 if ((p1 === symbol(SYMBOL_I) || p1 === symbol(SYMBOL_J)) && isimaginaryunit(p2)) {
23755 doNothing = 0;
23756 } else if (isimaginaryunit(get_binding(symbol(SYMBOL_J)))) {
23757 push(p2);
23758 push(imaginaryunit);
23759 push_symbol(SYMBOL_J);
23760 subst();
23761 p2 = pop();
23762 } else if (isimaginaryunit(get_binding(symbol(SYMBOL_I)))) {
23763 push(p2);
23764 push(imaginaryunit);
23765 push_symbol(SYMBOL_I);
23766 subst();
23767 p2 = pop();
23768 }
23769 push(p2);
23770 return restore();
23771 };
23772
23773 check_esc_flag = function() {
23774 if (esc_flag) {
23775 return stop("esc key");
23776 }
23777 };
23778
23779 clearAlgebraEnvironment = function() {
23780 return do_clearall();
23781 };
23782
23783 computeDependenciesFromAlgebra = function(codeFromAlgebraBlock) {
23784 var i, keepState, l1, len, len1, m1, originalcodeFromAlgebraBlock, userSimplificationsInProgramForm;
23785 if (DEBUG) {
23786 console.log("computeDependenciesFromAlgebra!!!");
23787 }
23788 originalcodeFromAlgebraBlock = codeFromAlgebraBlock;
23789 keepState = true;
23790 called_from_Algebra_block = true;
23791 codeFromAlgebraBlock = normaliseDots(codeFromAlgebraBlock);
23792 if (!keepState) {
23793 userSimplificationsInListForm = [];
23794 userSimplificationsInProgramForm = "";
23795 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
23796 i = userSimplificationsInListForm[l1];
23797 userSimplificationsInProgramForm += "silentpattern(" + car(i) + "," + car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n";
23798 }
23799 do_clearall();
23800 codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock;
23801 if (DEBUG) {
23802 console.log("codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock);
23803 }
23804 }
23805 if (DEBUG) {
23806 console.log("computeDependenciesFromAlgebra: patterns in the list --------------- ");
23807 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
23808 i = userSimplificationsInListForm[m1];
23809 console.log(car(i) + "," + cdr(i) + ")");
23810 }
23811 console.log("...end of list --------------- ");
23812 }
23813 called_from_Algebra_block = false;
23814 return findDependenciesInScript(codeFromAlgebraBlock, true)[6];
23815 };
23816
23817 computeResultsAndJavaScriptFromAlgebra = function(codeFromAlgebraBlock) {
23818 var code, dependencyInfo, i, keepState, l1, latexResult, len, len1, m1, originalcodeFromAlgebraBlock, readableSummaryOfCode, ref2, result, stringToBeRun, testableStringIsIgnoredHere, timeStartFromAlgebra, userSimplificationsInProgramForm;
23819 originalcodeFromAlgebraBlock = codeFromAlgebraBlock;
23820 keepState = true;
23821 called_from_Algebra_block = true;
23822 timeStartFromAlgebra = new Date().getTime();
23823 if (TIMING_DEBUGS) {
23824 console.log(" --------- computeResultsAndJavaScriptFromAlgebra input: " + codeFromAlgebraBlock + " at: " + (new Date()));
23825 }
23826 codeFromAlgebraBlock = normaliseDots(codeFromAlgebraBlock);
23827 stringToBeRun = codeFromAlgebraBlock;
23828 if (DEBUG) {
23829 console.log("computeResultsAndJavaScriptFromAlgebra: patterns in the list --------------- ");
23830 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
23831 i = userSimplificationsInListForm[l1];
23832 console.log(car(i) + "," + cdr(i) + ")");
23833 }
23834 console.log("...end of list --------------- ");
23835 }
23836 if (!keepState) {
23837 userSimplificationsInListForm = [];
23838 userSimplificationsInProgramForm = "";
23839 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
23840 i = userSimplificationsInListForm[m1];
23841 userSimplificationsInProgramForm += "silentpattern(" + car(i) + "," + car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n";
23842 }
23843 do_clearall();
23844 codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock;
23845 if (DEBUG) {
23846 console.log("codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock);
23847 }
23848 }
23849 ref2 = findDependenciesInScript(codeFromAlgebraBlock), testableStringIsIgnoredHere = ref2[0], result = ref2[1], code = ref2[2], readableSummaryOfCode = ref2[3], latexResult = ref2[4], errorMessage = ref2[5], dependencyInfo = ref2[6];
23850 called_from_Algebra_block = false;
23851 if (readableSummaryOfCode !== "" || errorMessage !== "") {
23852 result += "\n" + readableSummaryOfCode;
23853 if (errorMessage !== "") {
23854 result += "\n" + errorMessage;
23855 }
23856 result = result.replace(/\n/g, "\n\n");
23857 latexResult += "\n" + "$$" + readableSummaryOfCode + "$$";
23858 if (errorMessage !== "") {
23859 latexResult += turnErrorMessageToLatex(errorMessage);
23860 }
23861 latexResult = latexResult.replace(/\n/g, "\n\n");
23862 }
23863 latexResult = latexResult.replace(/\n*/, "");
23864 latexResult = latexResult.replace(/\$\$\$\$\n*/g, "");
23865 code = code.replace(/Math\./g, "");
23866 code = code.replace(/\n/g, "\n\n");
23867 if (TIMING_DEBUGS) {
23868 console.log("computeResultsAndJavaScriptFromAlgebra time (total time from notebook and back) for: " + stringToBeRun + " : " + ((new Date().getTime()) - timeStartFromAlgebra) + "ms");
23869 }
23870 return {
23871 code: code,
23872 result: latexResult,
23873 latexResult: latexResult,
23874 dependencyInfo: dependencyInfo
23875 };
23876 };
23877
23878 enableCaching = function() {
23879 return ENABLE_CACHING = true;
23880 };
23881
23882 disableCaching = function() {
23883 return ENABLE_CACHING = false;
23884 };
23885
23886 (typeof exports !== "undefined" && exports !== null ? exports : this).run = run;
23887
23888 (typeof exports !== "undefined" && exports !== null ? exports : this).findDependenciesInScript = findDependenciesInScript;
23889
23890 (typeof exports !== "undefined" && exports !== null ? exports : this).computeDependenciesFromAlgebra = computeDependenciesFromAlgebra;
23891
23892 (typeof exports !== "undefined" && exports !== null ? exports : this).computeResultsAndJavaScriptFromAlgebra = computeResultsAndJavaScriptFromAlgebra;
23893
23894 (typeof exports !== "undefined" && exports !== null ? exports : this).clearAlgebraEnvironment = clearAlgebraEnvironment;
23895
23896 (typeof exports !== "undefined" && exports !== null ? exports : this).enableCaching = enableCaching;
23897
23898 (typeof exports !== "undefined" && exports !== null ? exports : this).disableCaching = disableCaching;
23899
23900 tos = 0;
23901
23902 nil_symbols = 0;
23903
23904 push = function(p) {
23905 if (p == null) {
23906 debugger;
23907 }
23908 if (p.isZero != null) {
23909 debugger;
23910 }
23911 if (p === symbol(NIL)) {
23912 nil_symbols++;
23913 if (DEBUG) {
23914 console.log("pushing symbol(NIL) #" + nil_symbols);
23915 }
23916 }
23917 if (tos >= frame) {
23918 stop("stack overflow");
23919 }
23920 return stack[tos++] = p;
23921 };
23922
23923 moveTos = function(stackPos) {
23924 if (tos <= stackPos) {
23925 tos = stackPos;
23926 return;
23927 }
23928 while (tos > stackPos) {
23929 stack[tos] = null;
23930 tos--;
23931 }
23932 };
23933
23934 top = function() {
23935 return stack[tos - 1];
23936 };
23937
23938 pop = function() {
23939 var elementToBeReturned;
23940 if (tos === 0) {
23941 debugger;
23942 stop("stack underflow");
23943 }
23944 if (stack[tos - 1] == null) {
23945 debugger;
23946 }
23947 elementToBeReturned = stack[--tos];
23948 stack[tos] = null;
23949 return elementToBeReturned;
23950 };
23951
23952 push_frame = function(n) {
23953 var i, l1, ref2, results;
23954 i = 0;
23955 frame -= n;
23956 if (frame < tos) {
23957 debugger;
23958 stop("frame overflow, circular reference?");
23959 }
23960 results = [];
23961 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
23962 results.push(stack[frame + i] = symbol(NIL));
23963 }
23964 return results;
23965 };
23966
23967 pop_frame = function(n) {
23968 frame += n;
23969 if (frame > TOS) {
23970 return stop("frame underflow");
23971 }
23972 };
23973
23974 save = function() {
23975 frame -= 10;
23976 if (frame < tos) {
23977 debugger;
23978 stop("frame overflow, circular reference?");
23979 }
23980 stack[frame + 0] = p0;
23981 stack[frame + 1] = p1;
23982 stack[frame + 2] = p2;
23983 stack[frame + 3] = p3;
23984 stack[frame + 4] = p4;
23985 stack[frame + 5] = p5;
23986 stack[frame + 6] = p6;
23987 stack[frame + 7] = p7;
23988 stack[frame + 8] = p8;
23989 return stack[frame + 9] = p9;
23990 };
23991
23992 restore = function() {
23993 if (frame > TOS - 10) {
23994 stop("frame underflow");
23995 }
23996 p0 = stack[frame + 0];
23997 p1 = stack[frame + 1];
23998 p2 = stack[frame + 2];
23999 p3 = stack[frame + 3];
24000 p4 = stack[frame + 4];
24001 p5 = stack[frame + 5];
24002 p6 = stack[frame + 6];
24003 p7 = stack[frame + 7];
24004 p8 = stack[frame + 8];
24005 p9 = stack[frame + 9];
24006 return frame += 10;
24007 };
24008
24009 swap = function() {
24010 var p, q;
24011 p = pop();
24012 q = pop();
24013 push(p);
24014 return push(q);
24015 };
24016
24017 dupl = function() {
24018 var p;
24019 p = pop();
24020 push(p);
24021 return push(p);
24022 };
24023
24024 $.dupl = dupl;
24025
24026 $.swap = swap;
24027
24028 $.restore = restore;
24029
24030 $.save = save;
24031
24032 $.push = push;
24033
24034 $.pop = pop;
24035
24036 Eval_symbolsinfo = function() {
24037 var symbolsinfoToBePrinted;
24038 symbolsinfoToBePrinted = symbolsinfo();
24039 if (symbolsinfoToBePrinted !== "") {
24040 return new_string(symbolsinfoToBePrinted);
24041 } else {
24042 return push_symbol(NIL);
24043 }
24044 };
24045
24046 symbolsinfo = function() {
24047 var bindingi, i, l1, ref2, ref3, symbolsinfoToBePrinted, symtabi;
24048 symbolsinfoToBePrinted = "";
24049 for (i = l1 = ref2 = NIL + 1, ref3 = symtab.length; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24050 if (symtab[i].printname === "") {
24051 if (isSymbolReclaimable[i] === false) {
24052 break;
24053 } else {
24054 continue;
24055 }
24056 }
24057 symtabi = symtab[i] + "";
24058 bindingi = (binding[i] + "").substring(0, 4);
24059 symbolsinfoToBePrinted += "symbol: " + symtabi + " size: " + countsize(binding[i]) + " value: " + bindingi + "...\n";
24060 }
24061 return symbolsinfoToBePrinted;
24062 };
24063
24064 std_symbol = function(s, n, latexPrint) {
24065 var p;
24066 p = symtab[n];
24067 if (p == null) {
24068 debugger;
24069 }
24070 p.printname = s;
24071 if (latexPrint != null) {
24072 return p.latexPrint = latexPrint;
24073 } else {
24074 return p.latexPrint = s;
24075 }
24076 };
24077
24078 usr_symbol = function(s) {
24079 var i, l1, ref2;
24080 i = 0;
24081 for (i = l1 = 0, ref2 = NSYM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24082 if (symtab[i].printname === "") {
24083 break;
24084 }
24085 if (s === symtab[i].printname) {
24086 return symtab[i];
24087 }
24088 }
24089 if (i === NSYM) {
24090 stop("symbol table overflow");
24091 }
24092 symtab[i] = new U();
24093 symtab[i].k = SYM;
24094 symtab[i].printname = s;
24095 binding[i] = symtab[i];
24096 isSymbolReclaimable[i] = false;
24097 return symtab[i];
24098 };
24099
24100 get_printname = function(p) {
24101 if (p.k !== SYM) {
24102 stop("symbol error");
24103 }
24104 return p.printname;
24105 };
24106
24107 set_binding = function(p, q) {
24108 var indexFound;
24109 if (p.k !== SYM) {
24110 stop("symbol error");
24111 }
24112 indexFound = symtab.indexOf(p);
24113
24114 /*
24115 if indexFound == -1
24116 debugger
24117 for i in [0...symtab.length]
24118 if p.printname == symtab[i].printname
24119 indexFound = i
24120 console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
24121 break
24122 */
24123 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24124 console.log("ops, more than one element!");
24125 debugger;
24126 }
24127 if (DEBUG) {
24128 console.log("lookup >> set_binding lookup " + indexFound);
24129 }
24130 isSymbolReclaimable[indexFound] = false;
24131 return binding[indexFound] = q;
24132 };
24133
24134 get_binding = function(p) {
24135 var indexFound;
24136 if (p.k !== SYM) {
24137 stop("symbol error");
24138 }
24139 indexFound = symtab.indexOf(p);
24140
24141 /*
24142 if indexFound == -1
24143 debugger
24144 for i in [0...symtab.length]
24145 if p.printname == symtab[i].printname
24146 indexFound = i
24147 console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
24148 break
24149 */
24150 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24151 console.log("ops, more than one element!");
24152 debugger;
24153 }
24154 if (DEBUG) {
24155 console.log("lookup >> get_binding lookup " + indexFound);
24156 }
24157 return binding[indexFound];
24158 };
24159
24160 is_usr_symbol = function(p) {
24161 var theSymnum;
24162 if (p.k !== SYM) {
24163 return false;
24164 }
24165 theSymnum = symnum(p);
24166 if (theSymnum > PI && theSymnum !== SYMBOL_I && theSymnum !== SYMBOL_IDENTITY_MATRIX) {
24167 return true;
24168 }
24169 return false;
24170 };
24171
24172 lookupsTotal = 0;
24173
24174 symnum = function(p) {
24175 var indexFound;
24176 lookupsTotal++;
24177 if (p.k !== SYM) {
24178 stop("symbol error");
24179 }
24180 indexFound = symtab.indexOf(p);
24181 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24182 console.log("ops, more than one element!");
24183 debugger;
24184 }
24185 if (DEBUG) {
24186 console.log("lookup >> symnum lookup " + indexFound + " lookup # " + lookupsTotal);
24187 }
24188 return indexFound;
24189 };
24190
24191 push_symbol = function(k) {
24192 return push(symtab[k]);
24193 };
24194
24195 clear_symbols = function() {
24196 var i, l1, ref2, ref3, results;
24197 results = [];
24198 for (i = l1 = ref2 = NIL + 1, ref3 = NSYM; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24199 if (symtab[i].printname === "") {
24200 if (isSymbolReclaimable[i] === false) {
24201 break;
24202 } else {
24203 continue;
24204 }
24205 }
24206 symtab[i] = new U();
24207 symtab[i].k = SYM;
24208 binding[i] = symtab[i];
24209 results.push(isSymbolReclaimable[i] = false);
24210 }
24211 return results;
24212 };
24213
24214 collectUserSymbols = function(p, accumulator) {
24215 var i, l1, ref2;
24216 if (accumulator == null) {
24217 accumulator = [];
24218 }
24219 if (is_usr_symbol(p)) {
24220 if (accumulator.indexOf(p) === -1) {
24221 accumulator.push(p);
24222 return;
24223 }
24224 }
24225 if (istensor(p)) {
24226 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24227 collectUserSymbols(p.tensor.elem[i], accumulator);
24228 }
24229 return;
24230 }
24231 while (iscons(p)) {
24232 collectUserSymbols(car(p), accumulator);
24233 p = cdr(p);
24234 }
24235 };
24236
24237 $.get_binding = get_binding;
24238
24239 $.set_binding = set_binding;
24240
24241 $.usr_symbol = usr_symbol;
24242
24243 $.symbolsinfo = symbolsinfo;
24244
24245 $.collectUserSymbols = collectUserSymbols;
24246
24247 if (!inited) {
24248 inited = true;
24249 init();
24250 }
24251
24252 $.init = init;
24253
24254 parse_internal = function(argu) {
24255 if (typeof argu === 'string') {
24256 return scan(argu);
24257 } else if (typeof argu === 'number') {
24258 if (argu % 1 === 0) {
24259 return push_integer(argu);
24260 } else {
24261 return push_double(argu);
24262 }
24263 } else if (argu instanceof U) {
24264 return push(argu);
24265 } else {
24266 console.warn('unknown argument type', argu);
24267 return push(symbol(NIL));
24268 }
24269 };
24270
24271 parse = function(argu) {
24272 var data, error;
24273 try {
24274 parse_internal(argu);
24275 data = pop();
24276 check_stack();
24277 } catch (error1) {
24278 error = error1;
24279 reset_after_error();
24280 throw error;
24281 }
24282 return data;
24283 };
24284
24285 exec = function() {
24286 var argu, argus, error, fn, l1, len, name, result;
24287 name = arguments[0], argus = 2 <= arguments.length ? slice.call(arguments, 1) : [];
24288 fn = get_binding(usr_symbol(name));
24289 check_stack();
24290 push(fn);
24291 for (l1 = 0, len = argus.length; l1 < len; l1++) {
24292 argu = argus[l1];
24293 parse_internal(argu);
24294 }
24295 list(1 + argus.length);
24296 p1 = pop();
24297 push(p1);
24298 try {
24299 fixed_top_level_eval();
24300 result = pop();
24301 check_stack();
24302 } catch (error1) {
24303 error = error1;
24304 reset_after_error();
24305 throw error;
24306 }
24307 return result;
24308 };
24309
24310 fixed_top_level_eval = function() {
24311 save();
24312 trigmode = 0;
24313 p1 = symbol(AUTOEXPAND);
24314 if (iszero(get_binding(p1))) {
24315 expanding = 0;
24316 } else {
24317 expanding = 1;
24318 }
24319 p1 = pop();
24320 push(p1);
24321 Eval();
24322 p2 = pop();
24323 if (p2 === symbol(NIL)) {
24324 push(p2);
24325 restore();
24326 return;
24327 }
24328 if (!iszero(get_binding(symbol(BAKE)))) {
24329 push(p2);
24330 bake();
24331 p2 = pop();
24332 }
24333 push(p2);
24334 return restore();
24335 };
24336
24337 $.exec = exec;
24338
24339 $.parse = parse;
24340
24341 (function() {
24342 var builtin_fns, fn, l1, len, results;
24343 builtin_fns = ["abs", "add", "adj", "and", "approxratio", "arccos", "arccosh", "arcsin", "arcsinh", "arctan", "arctanh", "arg", "atomize", "besselj", "bessely", "binding", "binomial", "ceiling", "check", "choose", "circexp", "clear", "clearall", "clearpatterns", "clock", "coeff", "cofactor", "condense", "conj", "contract", "cos", "cosh", "decomp", "defint", "deg", "denominator", "det", "derivative", "dim", "dirac", "divisors", "do", "dot", "draw", "dsolve", "eigen", "eigenval", "eigenvec", "erf", "erfc", "eval", "exp", "expand", "expcos", "expsin", "factor", "factorial", "factorpoly", "filter", "float", "floor", "for", "Gamma", "gcd", "hermite", "hilbert", "imag", "component", "inner", "integral", "inv", "invg", "isinteger", "isprime", "laguerre", "lcm", "leading", "legendre", "log", "mod", "multiply", "not", "nroots", "number", "numerator", "operator", "or", "outer", "pattern", "patternsinfo", "polar", "power", "prime", "print", "print2dascii", "printfull", "printlatex", "printlist", "printplain", "product", "quote", "quotient", "rank", "rationalize", "real", "rect", "roots", "round", "equals", "shape", "sgn", "silentpattern", "simplify", "sin", "sinh", "sqrt", "stop", "subst", "sum", "symbolsinfo", "tan", "tanh", "taylor", "test", "testeq", "testge", "testgt", "testle", "testlt", "transpose", "unit", "zero"];
24344 results = [];
24345 for (l1 = 0, len = builtin_fns.length; l1 < len; l1++) {
24346 fn = builtin_fns[l1];
24347 results.push($[fn] = exec.bind(this, fn));
24348 }
24349 return results;
24350 })();
24351
24352 DoubleLinkedList = (function() {
24353 function DoubleLinkedList() {
24354 this.headNode = this.tailNode = null;
24355 }
24356
24357 DoubleLinkedList.prototype.remove = function(node) {
24358 if (node.pre) {
24359 node.pre.next = node.next;
24360 } else {
24361 this.headNode = node.next;
24362 }
24363 if (node.next) {
24364 return node.next.pre = node.pre;
24365 } else {
24366 return this.tailNode = node.pre;
24367 }
24368 };
24369
24370 DoubleLinkedList.prototype.insertBeginning = function(node) {
24371 if (this.headNode) {
24372 node.next = this.headNode;
24373 this.headNode.pre = node;
24374 return this.headNode = node;
24375 } else {
24376 return this.headNode = this.tailNode = node;
24377 }
24378 };
24379
24380 DoubleLinkedList.prototype.moveToHead = function(node) {
24381 this.remove(node);
24382 return this.insertBeginning(node);
24383 };
24384
24385 DoubleLinkedList.prototype.clear = function() {
24386 return this.headNode = this.tailNode = null;
24387 };
24388
24389 return DoubleLinkedList;
24390
24391 })();
24392
24393 LRUCache = (function() {
24394 function LRUCache(capacity, maxAge) {
24395 this.capacity = capacity != null ? capacity : 10;
24396 this.maxAge = maxAge != null ? maxAge : 60000;
24397 this._linkList = new DoubleLinkedList();
24398 this.reset();
24399 this.hitCount = this.missCount = 0;
24400 }
24401
24402 LRUCache.prototype.resetHitMissCount = function() {
24403 return this.hitCount = this.missCount = 0;
24404 };
24405
24406 LRUCache.prototype.keys = function() {
24407 return Object.keys(this._hash);
24408 };
24409
24410 LRUCache.prototype.values = function() {
24411 var values;
24412 values = this.keys().map((function(_this) {
24413 return function(key) {
24414 return _this.get(key);
24415 };
24416 })(this));
24417 return values.filter(function(v) {
24418 return v !== void 0;
24419 });
24420 };
24421
24422 LRUCache.prototype.remove = function(key) {
24423 var node;
24424 if (this._hash[key] != null) {
24425 node = this._hash[key];
24426 this._linkList.remove(node);
24427 delete this._hash[key];
24428 if (node.data.onDispose) {
24429 node.data.onDispose.call(this, node.data.key, node.data.value);
24430 }
24431 return this.size--;
24432 }
24433 };
24434
24435 LRUCache.prototype.reset = function() {
24436 this._hash = {};
24437 this.size = 0;
24438 this.resetHitMissCount();
24439 return this._linkList.clear();
24440 };
24441
24442 LRUCache.prototype.set = function(key, value, onDispose) {
24443 var createNode, node;
24444 node = this._hash[key];
24445 if (node) {
24446 node.data.value = value;
24447 node.data.onDispose = onDispose;
24448 return this._refreshNode(node);
24449 } else {
24450 if (this.size === this.capacity) {
24451 this.remove(this._linkList.tailNode.data.key);
24452 }
24453 createNode = function(data, pre, next) {
24454 return {
24455 data: data,
24456 pre: pre,
24457 next: next
24458 };
24459 };
24460 node = createNode({
24461 key: key,
24462 value: value,
24463 onDispose: onDispose
24464 });
24465 node.data.lastVisitTime = Date.now();
24466 this._linkList.insertBeginning(node);
24467 this._hash[key] = node;
24468 this.size++;
24469 }
24470 };
24471
24472 LRUCache.prototype.get = function(key) {
24473 var node;
24474 node = this._hash[key];
24475 if (!node) {
24476 this.missCount++;
24477 return void 0;
24478 }
24479 if (this._isExpiredNode(node)) {
24480 this.remove(key);
24481 this.missCount++;
24482 return void 0;
24483 }
24484 this._refreshNode(node);
24485 this.hitCount++;
24486 return node.data.value;
24487 };
24488
24489 LRUCache.prototype._refreshNode = function(node) {
24490 node.data.lastVisitTime = Date.now();
24491 return this._linkList.moveToHead(node);
24492 };
24493
24494 LRUCache.prototype._isExpiredNode = function(node) {
24495 return Date.now() - node.data.lastVisitTime > this.maxAge;
24496 };
24497
24498 LRUCache.prototype.has = function(key) {
24499 return this._hash[key] != null;
24500 };
24501
24502 return LRUCache;
24503
24504 })();
24505
24506 cached_runs = new LRUCache(100, 60000 * 60 * 24 * 265);
24507
24508 cached_findDependenciesInScript = new LRUCache(100, 60000 * 60 * 24 * 265);
24509
24510 freeze = function() {
24511 var frozenContents, frozenHash, frozenPatterns, frozenSymbols, i, l1, ref2;
24512 frozenSymbols = [];
24513 frozenContents = [];
24514 frozenPatterns = [];
24515 frozenHash = "";
24516 for (i = l1 = 0, ref2 = symtab.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24517 if (isSymbolReclaimable[i] === false) {
24518 frozenSymbols.push(symtab[i]);
24519 frozenContents.push(binding[i]);
24520 }
24521 }
24522 frozenPatterns = userSimplificationsInListForm.slice(0);
24523 return [frozenSymbols, frozenContents, frozenPatterns, zero, one, imaginaryunit, getStateHash()];
24524 };
24525
24526 unfreeze = function(frozen) {
24527 var frozenContents, frozenPatterns, frozenSymbols, i, l1, ref2;
24528 frozenSymbols = frozen[0], frozenContents = frozen[1], frozenPatterns = frozen[2], zero = frozen[3], one = frozen[4], imaginaryunit = frozen[5];
24529 for (i = l1 = 0, ref2 = frozenSymbols.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24530 symtab[i] = frozenSymbols[i];
24531 binding[i] = frozenContents[i];
24532 }
24533 return userSimplificationsInListForm = frozenPatterns.slice(0);
24534 };
24535
24536 compareState = function(previousHash) {
24537 var frozenHash;
24538 frozenHash = getStateHash();
24539 if (frozenHash === previousHash) {
24540 return true;
24541 } else {
24542 return false;
24543 }
24544 };
24545
24546 resetCache = function() {
24547 if (cached_runs != null) {
24548 cached_runs.reset();
24549 if (DEBUG) {
24550 console.log("resetting cached_runs");
24551 }
24552 }
24553 if (cached_findDependenciesInScript != null) {
24554 cached_findDependenciesInScript.reset();
24555 if (DEBUG) {
24556 return console.log("resetting cached_findDependenciesInScript");
24557 }
24558 }
24559 };
24560
24561 resetCacheHitMissCounts = function() {
24562 if (cached_runs != null) {
24563 cached_runs.resetHitMissCount();
24564 }
24565 if (cached_findDependenciesInScript != null) {
24566 return cached_findDependenciesInScript.resetHitMissCount();
24567 }
24568 };
24569
24570 totalAllCachesHits = function() {
24571 return cached_runs.hitCount + cached_findDependenciesInScript.hitCount;
24572 };
24573
24574 totalAllCachesMisses = function() {
24575 return cached_runs.missCount + cached_findDependenciesInScript.missCount;
24576 };
24577
24578 getStateHash = function() {
24579 var bindingi, frozenHash, i, l1, len, m1, ref2, ref3, symtabi;
24580 frozenHash = "";
24581 for (i = l1 = ref2 = NIL + 1, ref3 = symtab.length; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24582 if (symtab[i].printname === "") {
24583 if (isSymbolReclaimable[i] === false) {
24584 break;
24585 } else {
24586 continue;
24587 }
24588 }
24589 symtabi = print_list(symtab[i]);
24590 bindingi = print_list(binding[i]);
24591 frozenHash += " //" + symtabi + " : " + bindingi;
24592 }
24593 for (m1 = 0, len = userSimplificationsInListForm.length; m1 < len; m1++) {
24594 i = userSimplificationsInListForm[m1];
24595 frozenHash += " pattern: " + i;
24596 }
24597 if (DEBUG) {
24598 console.log("frozenHash: " + frozenHash);
24599 }
24600 return frozenHash;
24601 };
24602
24603}).call(this);
24604
24605},{"big-integer":2}],2:[function(require,module,exports){
24606var bigInt = (function (undefined) {
24607 "use strict";
24608
24609 var BASE = 1e7,
24610 LOG_BASE = 7,
24611 MAX_INT = 9007199254740992,
24612 MAX_INT_ARR = smallToArray(MAX_INT),
24613 LOG_MAX_INT = Math.log(MAX_INT);
24614
24615 function Integer(v, radix) {
24616 if (typeof v === "undefined") return Integer[0];
24617 if (typeof radix !== "undefined") return +radix === 10 ? parseValue(v) : parseBase(v, radix);
24618 return parseValue(v);
24619 }
24620
24621 function BigInteger(value, sign) {
24622 this.value = value;
24623 this.sign = sign;
24624 this.isSmall = false;
24625 }
24626 BigInteger.prototype = Object.create(Integer.prototype);
24627
24628 function SmallInteger(value) {
24629 this.value = value;
24630 this.sign = value < 0;
24631 this.isSmall = true;
24632 }
24633 SmallInteger.prototype = Object.create(Integer.prototype);
24634
24635 function isPrecise(n) {
24636 return -MAX_INT < n && n < MAX_INT;
24637 }
24638
24639 function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
24640 if (n < 1e7)
24641 return [n];
24642 if (n < 1e14)
24643 return [n % 1e7, Math.floor(n / 1e7)];
24644 return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
24645 }
24646
24647 function arrayToSmall(arr) { // If BASE changes this function may need to change
24648 trim(arr);
24649 var length = arr.length;
24650 if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
24651 switch (length) {
24652 case 0: return 0;
24653 case 1: return arr[0];
24654 case 2: return arr[0] + arr[1] * BASE;
24655 default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
24656 }
24657 }
24658 return arr;
24659 }
24660
24661 function trim(v) {
24662 var i = v.length;
24663 while (v[--i] === 0);
24664 v.length = i + 1;
24665 }
24666
24667 function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
24668 var x = new Array(length);
24669 var i = -1;
24670 while (++i < length) {
24671 x[i] = 0;
24672 }
24673 return x;
24674 }
24675
24676 function truncate(n) {
24677 if (n > 0) return Math.floor(n);
24678 return Math.ceil(n);
24679 }
24680
24681 function add(a, b) { // assumes a and b are arrays with a.length >= b.length
24682 var l_a = a.length,
24683 l_b = b.length,
24684 r = new Array(l_a),
24685 carry = 0,
24686 base = BASE,
24687 sum, i;
24688 for (i = 0; i < l_b; i++) {
24689 sum = a[i] + b[i] + carry;
24690 carry = sum >= base ? 1 : 0;
24691 r[i] = sum - carry * base;
24692 }
24693 while (i < l_a) {
24694 sum = a[i] + carry;
24695 carry = sum === base ? 1 : 0;
24696 r[i++] = sum - carry * base;
24697 }
24698 if (carry > 0) r.push(carry);
24699 return r;
24700 }
24701
24702 function addAny(a, b) {
24703 if (a.length >= b.length) return add(a, b);
24704 return add(b, a);
24705 }
24706
24707 function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
24708 var l = a.length,
24709 r = new Array(l),
24710 base = BASE,
24711 sum, i;
24712 for (i = 0; i < l; i++) {
24713 sum = a[i] - base + carry;
24714 carry = Math.floor(sum / base);
24715 r[i] = sum - carry * base;
24716 carry += 1;
24717 }
24718 while (carry > 0) {
24719 r[i++] = carry % base;
24720 carry = Math.floor(carry / base);
24721 }
24722 return r;
24723 }
24724
24725 BigInteger.prototype.add = function (v) {
24726 var value, n = parseValue(v);
24727 if (this.sign !== n.sign) {
24728 return this.subtract(n.negate());
24729 }
24730 var a = this.value, b = n.value;
24731 if (n.isSmall) {
24732 return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
24733 }
24734 return new BigInteger(addAny(a, b), this.sign);
24735 };
24736 BigInteger.prototype.plus = BigInteger.prototype.add;
24737
24738 SmallInteger.prototype.add = function (v) {
24739 var n = parseValue(v);
24740 var a = this.value;
24741 if (a < 0 !== n.sign) {
24742 return this.subtract(n.negate());
24743 }
24744 var b = n.value;
24745 if (n.isSmall) {
24746 if (isPrecise(a + b)) return new SmallInteger(a + b);
24747 b = smallToArray(Math.abs(b));
24748 }
24749 return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
24750 };
24751 SmallInteger.prototype.plus = SmallInteger.prototype.add;
24752
24753 function subtract(a, b) { // assumes a and b are arrays with a >= b
24754 var a_l = a.length,
24755 b_l = b.length,
24756 r = new Array(a_l),
24757 borrow = 0,
24758 base = BASE,
24759 i, difference;
24760 for (i = 0; i < b_l; i++) {
24761 difference = a[i] - borrow - b[i];
24762 if (difference < 0) {
24763 difference += base;
24764 borrow = 1;
24765 } else borrow = 0;
24766 r[i] = difference;
24767 }
24768 for (i = b_l; i < a_l; i++) {
24769 difference = a[i] - borrow;
24770 if (difference < 0) difference += base;
24771 else {
24772 r[i++] = difference;
24773 break;
24774 }
24775 r[i] = difference;
24776 }
24777 for (; i < a_l; i++) {
24778 r[i] = a[i];
24779 }
24780 trim(r);
24781 return r;
24782 }
24783
24784 function subtractAny(a, b, sign) {
24785 var value, isSmall;
24786 if (compareAbs(a, b) >= 0) {
24787 value = subtract(a,b);
24788 } else {
24789 value = subtract(b, a);
24790 sign = !sign;
24791 }
24792 value = arrayToSmall(value);
24793 if (typeof value === "number") {
24794 if (sign) value = -value;
24795 return new SmallInteger(value);
24796 }
24797 return new BigInteger(value, sign);
24798 }
24799
24800 function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
24801 var l = a.length,
24802 r = new Array(l),
24803 carry = -b,
24804 base = BASE,
24805 i, difference;
24806 for (i = 0; i < l; i++) {
24807 difference = a[i] + carry;
24808 carry = Math.floor(difference / base);
24809 difference %= base;
24810 r[i] = difference < 0 ? difference + base : difference;
24811 }
24812 r = arrayToSmall(r);
24813 if (typeof r === "number") {
24814 if (sign) r = -r;
24815 return new SmallInteger(r);
24816 } return new BigInteger(r, sign);
24817 }
24818
24819 BigInteger.prototype.subtract = function (v) {
24820 var n = parseValue(v);
24821 if (this.sign !== n.sign) {
24822 return this.add(n.negate());
24823 }
24824 var a = this.value, b = n.value;
24825 if (n.isSmall)
24826 return subtractSmall(a, Math.abs(b), this.sign);
24827 return subtractAny(a, b, this.sign);
24828 };
24829 BigInteger.prototype.minus = BigInteger.prototype.subtract;
24830
24831 SmallInteger.prototype.subtract = function (v) {
24832 var n = parseValue(v);
24833 var a = this.value;
24834 if (a < 0 !== n.sign) {
24835 return this.add(n.negate());
24836 }
24837 var b = n.value;
24838 if (n.isSmall) {
24839 return new SmallInteger(a - b);
24840 }
24841 return subtractSmall(b, Math.abs(a), a >= 0);
24842 };
24843 SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
24844
24845 BigInteger.prototype.negate = function () {
24846 return new BigInteger(this.value, !this.sign);
24847 };
24848 SmallInteger.prototype.negate = function () {
24849 var sign = this.sign;
24850 var small = new SmallInteger(-this.value);
24851 small.sign = !sign;
24852 return small;
24853 };
24854
24855 BigInteger.prototype.abs = function () {
24856 return new BigInteger(this.value, false);
24857 };
24858 SmallInteger.prototype.abs = function () {
24859 return new SmallInteger(Math.abs(this.value));
24860 };
24861
24862 function multiplyLong(a, b) {
24863 var a_l = a.length,
24864 b_l = b.length,
24865 l = a_l + b_l,
24866 r = createArray(l),
24867 base = BASE,
24868 product, carry, i, a_i, b_j;
24869 for (i = 0; i < a_l; ++i) {
24870 a_i = a[i];
24871 for (var j = 0; j < b_l; ++j) {
24872 b_j = b[j];
24873 product = a_i * b_j + r[i + j];
24874 carry = Math.floor(product / base);
24875 r[i + j] = product - carry * base;
24876 r[i + j + 1] += carry;
24877 }
24878 }
24879 trim(r);
24880 return r;
24881 }
24882
24883 function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
24884 var l = a.length,
24885 r = new Array(l),
24886 base = BASE,
24887 carry = 0,
24888 product, i;
24889 for (i = 0; i < l; i++) {
24890 product = a[i] * b + carry;
24891 carry = Math.floor(product / base);
24892 r[i] = product - carry * base;
24893 }
24894 while (carry > 0) {
24895 r[i++] = carry % base;
24896 carry = Math.floor(carry / base);
24897 }
24898 return r;
24899 }
24900
24901 function shiftLeft(x, n) {
24902 var r = [];
24903 while (n-- > 0) r.push(0);
24904 return r.concat(x);
24905 }
24906
24907 function multiplyKaratsuba(x, y) {
24908 var n = Math.max(x.length, y.length);
24909
24910 if (n <= 30) return multiplyLong(x, y);
24911 n = Math.ceil(n / 2);
24912
24913 var b = x.slice(n),
24914 a = x.slice(0, n),
24915 d = y.slice(n),
24916 c = y.slice(0, n);
24917
24918 var ac = multiplyKaratsuba(a, c),
24919 bd = multiplyKaratsuba(b, d),
24920 abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
24921
24922 var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
24923 trim(product);
24924 return product;
24925 }
24926
24927 // The following function is derived from a surface fit of a graph plotting the performance difference
24928 // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
24929 function useKaratsuba(l1, l2) {
24930 return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
24931 }
24932
24933 BigInteger.prototype.multiply = function (v) {
24934 var value, n = parseValue(v),
24935 a = this.value, b = n.value,
24936 sign = this.sign !== n.sign,
24937 abs;
24938 if (n.isSmall) {
24939 if (b === 0) return Integer[0];
24940 if (b === 1) return this;
24941 if (b === -1) return this.negate();
24942 abs = Math.abs(b);
24943 if (abs < BASE) {
24944 return new BigInteger(multiplySmall(a, abs), sign);
24945 }
24946 b = smallToArray(abs);
24947 }
24948 if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
24949 return new BigInteger(multiplyKaratsuba(a, b), sign);
24950 return new BigInteger(multiplyLong(a, b), sign);
24951 };
24952
24953 BigInteger.prototype.times = BigInteger.prototype.multiply;
24954
24955 function multiplySmallAndArray(a, b, sign) { // a >= 0
24956 if (a < BASE) {
24957 return new BigInteger(multiplySmall(b, a), sign);
24958 }
24959 return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
24960 }
24961 SmallInteger.prototype._multiplyBySmall = function (a) {
24962 if (isPrecise(a.value * this.value)) {
24963 return new SmallInteger(a.value * this.value);
24964 }
24965 return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
24966 };
24967 BigInteger.prototype._multiplyBySmall = function (a) {
24968 if (a.value === 0) return Integer[0];
24969 if (a.value === 1) return this;
24970 if (a.value === -1) return this.negate();
24971 return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
24972 };
24973 SmallInteger.prototype.multiply = function (v) {
24974 return parseValue(v)._multiplyBySmall(this);
24975 };
24976 SmallInteger.prototype.times = SmallInteger.prototype.multiply;
24977
24978 function square(a) {
24979 var l = a.length,
24980 r = createArray(l + l),
24981 base = BASE,
24982 product, carry, i, a_i, a_j;
24983 for (i = 0; i < l; i++) {
24984 a_i = a[i];
24985 for (var j = 0; j < l; j++) {
24986 a_j = a[j];
24987 product = a_i * a_j + r[i + j];
24988 carry = Math.floor(product / base);
24989 r[i + j] = product - carry * base;
24990 r[i + j + 1] += carry;
24991 }
24992 }
24993 trim(r);
24994 return r;
24995 }
24996
24997 BigInteger.prototype.square = function () {
24998 return new BigInteger(square(this.value), false);
24999 };
25000
25001 SmallInteger.prototype.square = function () {
25002 var value = this.value * this.value;
25003 if (isPrecise(value)) return new SmallInteger(value);
25004 return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
25005 };
25006
25007 function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
25008 var a_l = a.length,
25009 b_l = b.length,
25010 base = BASE,
25011 result = createArray(b.length),
25012 divisorMostSignificantDigit = b[b_l - 1],
25013 // normalization
25014 lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
25015 remainder = multiplySmall(a, lambda),
25016 divisor = multiplySmall(b, lambda),
25017 quotientDigit, shift, carry, borrow, i, l, q;
25018 if (remainder.length <= a_l) remainder.push(0);
25019 divisor.push(0);
25020 divisorMostSignificantDigit = divisor[b_l - 1];
25021 for (shift = a_l - b_l; shift >= 0; shift--) {
25022 quotientDigit = base - 1;
25023 if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
25024 quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
25025 }
25026 // quotientDigit <= base - 1
25027 carry = 0;
25028 borrow = 0;
25029 l = divisor.length;
25030 for (i = 0; i < l; i++) {
25031 carry += quotientDigit * divisor[i];
25032 q = Math.floor(carry / base);
25033 borrow += remainder[shift + i] - (carry - q * base);
25034 carry = q;
25035 if (borrow < 0) {
25036 remainder[shift + i] = borrow + base;
25037 borrow = -1;
25038 } else {
25039 remainder[shift + i] = borrow;
25040 borrow = 0;
25041 }
25042 }
25043 while (borrow !== 0) {
25044 quotientDigit -= 1;
25045 carry = 0;
25046 for (i = 0; i < l; i++) {
25047 carry += remainder[shift + i] - base + divisor[i];
25048 if (carry < 0) {
25049 remainder[shift + i] = carry + base;
25050 carry = 0;
25051 } else {
25052 remainder[shift + i] = carry;
25053 carry = 1;
25054 }
25055 }
25056 borrow += carry;
25057 }
25058 result[shift] = quotientDigit;
25059 }
25060 // denormalization
25061 remainder = divModSmall(remainder, lambda)[0];
25062 return [arrayToSmall(result), arrayToSmall(remainder)];
25063 }
25064
25065 function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
25066 // Performs faster than divMod1 on larger input sizes.
25067 var a_l = a.length,
25068 b_l = b.length,
25069 result = [],
25070 part = [],
25071 base = BASE,
25072 guess, xlen, highx, highy, check;
25073 while (a_l) {
25074 part.unshift(a[--a_l]);
25075 if (compareAbs(part, b) < 0) {
25076 result.push(0);
25077 continue;
25078 }
25079 xlen = part.length;
25080 highx = part[xlen - 1] * base + part[xlen - 2];
25081 highy = b[b_l - 1] * base + b[b_l - 2];
25082 if (xlen > b_l) {
25083 highx = (highx + 1) * base;
25084 }
25085 guess = Math.ceil(highx / highy);
25086 do {
25087 check = multiplySmall(b, guess);
25088 if (compareAbs(check, part) <= 0) break;
25089 guess--;
25090 } while (guess);
25091 result.push(guess);
25092 part = subtract(part, check);
25093 }
25094 result.reverse();
25095 return [arrayToSmall(result), arrayToSmall(part)];
25096 }
25097
25098 function divModSmall(value, lambda) {
25099 var length = value.length,
25100 quotient = createArray(length),
25101 base = BASE,
25102 i, q, remainder, divisor;
25103 remainder = 0;
25104 for (i = length - 1; i >= 0; --i) {
25105 divisor = remainder * base + value[i];
25106 q = truncate(divisor / lambda);
25107 remainder = divisor - q * lambda;
25108 quotient[i] = q | 0;
25109 }
25110 return [quotient, remainder | 0];
25111 }
25112
25113 function divModAny(self, v) {
25114 var value, n = parseValue(v);
25115 var a = self.value, b = n.value;
25116 var quotient;
25117 if (b === 0) throw new Error("Cannot divide by zero");
25118 if (self.isSmall) {
25119 if (n.isSmall) {
25120 return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
25121 }
25122 return [Integer[0], self];
25123 }
25124 if (n.isSmall) {
25125 if (b === 1) return [self, Integer[0]];
25126 if (b == -1) return [self.negate(), Integer[0]];
25127 var abs = Math.abs(b);
25128 if (abs < BASE) {
25129 value = divModSmall(a, abs);
25130 quotient = arrayToSmall(value[0]);
25131 var remainder = value[1];
25132 if (self.sign) remainder = -remainder;
25133 if (typeof quotient === "number") {
25134 if (self.sign !== n.sign) quotient = -quotient;
25135 return [new SmallInteger(quotient), new SmallInteger(remainder)];
25136 }
25137 return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
25138 }
25139 b = smallToArray(abs);
25140 }
25141 var comparison = compareAbs(a, b);
25142 if (comparison === -1) return [Integer[0], self];
25143 if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
25144
25145 // divMod1 is faster on smaller input sizes
25146 if (a.length + b.length <= 200)
25147 value = divMod1(a, b);
25148 else value = divMod2(a, b);
25149
25150 quotient = value[0];
25151 var qSign = self.sign !== n.sign,
25152 mod = value[1],
25153 mSign = self.sign;
25154 if (typeof quotient === "number") {
25155 if (qSign) quotient = -quotient;
25156 quotient = new SmallInteger(quotient);
25157 } else quotient = new BigInteger(quotient, qSign);
25158 if (typeof mod === "number") {
25159 if (mSign) mod = -mod;
25160 mod = new SmallInteger(mod);
25161 } else mod = new BigInteger(mod, mSign);
25162 return [quotient, mod];
25163 }
25164
25165 BigInteger.prototype.divmod = function (v) {
25166 var result = divModAny(this, v);
25167 return {
25168 quotient: result[0],
25169 remainder: result[1]
25170 };
25171 };
25172 SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
25173
25174 BigInteger.prototype.divide = function (v) {
25175 return divModAny(this, v)[0];
25176 };
25177 SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
25178
25179 BigInteger.prototype.mod = function (v) {
25180 return divModAny(this, v)[1];
25181 };
25182 SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
25183
25184 BigInteger.prototype.pow = function (v) {
25185 var n = parseValue(v),
25186 a = this.value,
25187 b = n.value,
25188 value, x, y;
25189 if (b === 0) return Integer[1];
25190 if (a === 0) return Integer[0];
25191 if (a === 1) return Integer[1];
25192 if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
25193 if (n.sign) {
25194 return Integer[0];
25195 }
25196 if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
25197 if (this.isSmall) {
25198 if (isPrecise(value = Math.pow(a, b)))
25199 return new SmallInteger(truncate(value));
25200 }
25201 x = this;
25202 y = Integer[1];
25203 while (true) {
25204 if (b & 1 === 1) {
25205 y = y.times(x);
25206 --b;
25207 }
25208 if (b === 0) break;
25209 b /= 2;
25210 x = x.square();
25211 }
25212 return y;
25213 };
25214 SmallInteger.prototype.pow = BigInteger.prototype.pow;
25215
25216 BigInteger.prototype.modPow = function (exp, mod) {
25217 exp = parseValue(exp);
25218 mod = parseValue(mod);
25219 if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
25220 var r = Integer[1],
25221 base = this.mod(mod);
25222 while (exp.isPositive()) {
25223 if (base.isZero()) return Integer[0];
25224 if (exp.isOdd()) r = r.multiply(base).mod(mod);
25225 exp = exp.divide(2);
25226 base = base.square().mod(mod);
25227 }
25228 return r;
25229 };
25230 SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
25231
25232 function compareAbs(a, b) {
25233 if (a.length !== b.length) {
25234 return a.length > b.length ? 1 : -1;
25235 }
25236 for (var i = a.length - 1; i >= 0; i--) {
25237 if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
25238 }
25239 return 0;
25240 }
25241
25242 BigInteger.prototype.compareAbs = function (v) {
25243 var n = parseValue(v),
25244 a = this.value,
25245 b = n.value;
25246 if (n.isSmall) return 1;
25247 return compareAbs(a, b);
25248 };
25249 SmallInteger.prototype.compareAbs = function (v) {
25250 var n = parseValue(v),
25251 a = Math.abs(this.value),
25252 b = n.value;
25253 if (n.isSmall) {
25254 b = Math.abs(b);
25255 return a === b ? 0 : a > b ? 1 : -1;
25256 }
25257 return -1;
25258 };
25259
25260 BigInteger.prototype.compare = function (v) {
25261 // See discussion about comparison with Infinity:
25262 // https://github.com/peterolson/BigInteger.js/issues/61
25263 if (v === Infinity) {
25264 return -1;
25265 }
25266 if (v === -Infinity) {
25267 return 1;
25268 }
25269
25270 var n = parseValue(v),
25271 a = this.value,
25272 b = n.value;
25273 if (this.sign !== n.sign) {
25274 return n.sign ? 1 : -1;
25275 }
25276 if (n.isSmall) {
25277 return this.sign ? -1 : 1;
25278 }
25279 return compareAbs(a, b) * (this.sign ? -1 : 1);
25280 };
25281 BigInteger.prototype.compareTo = BigInteger.prototype.compare;
25282
25283 SmallInteger.prototype.compare = function (v) {
25284 if (v === Infinity) {
25285 return -1;
25286 }
25287 if (v === -Infinity) {
25288 return 1;
25289 }
25290
25291 var n = parseValue(v),
25292 a = this.value,
25293 b = n.value;
25294 if (n.isSmall) {
25295 return a == b ? 0 : a > b ? 1 : -1;
25296 }
25297 if (a < 0 !== n.sign) {
25298 return a < 0 ? -1 : 1;
25299 }
25300 return a < 0 ? 1 : -1;
25301 };
25302 SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
25303
25304 BigInteger.prototype.equals = function (v) {
25305 return this.compare(v) === 0;
25306 };
25307 SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
25308
25309 BigInteger.prototype.notEquals = function (v) {
25310 return this.compare(v) !== 0;
25311 };
25312 SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
25313
25314 BigInteger.prototype.greater = function (v) {
25315 return this.compare(v) > 0;
25316 };
25317 SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
25318
25319 BigInteger.prototype.lesser = function (v) {
25320 return this.compare(v) < 0;
25321 };
25322 SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
25323
25324 BigInteger.prototype.greaterOrEquals = function (v) {
25325 return this.compare(v) >= 0;
25326 };
25327 SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
25328
25329 BigInteger.prototype.lesserOrEquals = function (v) {
25330 return this.compare(v) <= 0;
25331 };
25332 SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
25333
25334 BigInteger.prototype.isEven = function () {
25335 return (this.value[0] & 1) === 0;
25336 };
25337 SmallInteger.prototype.isEven = function () {
25338 return (this.value & 1) === 0;
25339 };
25340
25341 BigInteger.prototype.isOdd = function () {
25342 return (this.value[0] & 1) === 1;
25343 };
25344 SmallInteger.prototype.isOdd = function () {
25345 return (this.value & 1) === 1;
25346 };
25347
25348 BigInteger.prototype.isPositive = function () {
25349 return !this.sign;
25350 };
25351 SmallInteger.prototype.isPositive = function () {
25352 return this.value > 0;
25353 };
25354
25355 BigInteger.prototype.isNegative = function () {
25356 return this.sign;
25357 };
25358 SmallInteger.prototype.isNegative = function () {
25359 return this.value < 0;
25360 };
25361
25362 BigInteger.prototype.isUnit = function () {
25363 return false;
25364 };
25365 SmallInteger.prototype.isUnit = function () {
25366 return Math.abs(this.value) === 1;
25367 };
25368
25369 BigInteger.prototype.isZero = function () {
25370 return false;
25371 };
25372 SmallInteger.prototype.isZero = function () {
25373 return this.value === 0;
25374 };
25375 BigInteger.prototype.isDivisibleBy = function (v) {
25376 var n = parseValue(v);
25377 var value = n.value;
25378 if (value === 0) return false;
25379 if (value === 1) return true;
25380 if (value === 2) return this.isEven();
25381 return this.mod(n).equals(Integer[0]);
25382 };
25383 SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
25384
25385 function isBasicPrime(v) {
25386 var n = v.abs();
25387 if (n.isUnit()) return false;
25388 if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
25389 if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
25390 if (n.lesser(25)) return true;
25391 // we don't know if it's prime: let the other functions figure it out
25392 }
25393
25394 BigInteger.prototype.isPrime = function () {
25395 var isPrime = isBasicPrime(this);
25396 if (isPrime !== undefined) return isPrime;
25397 var n = this.abs(),
25398 nPrev = n.prev();
25399 var a = [2, 3, 5, 7, 11, 13, 17, 19],
25400 b = nPrev,
25401 d, t, i, x;
25402 while (b.isEven()) b = b.divide(2);
25403 for (i = 0; i < a.length; i++) {
25404 x = bigInt(a[i]).modPow(b, n);
25405 if (x.equals(Integer[1]) || x.equals(nPrev)) continue;
25406 for (t = true, d = b; t && d.lesser(nPrev) ; d = d.multiply(2)) {
25407 x = x.square().mod(n);
25408 if (x.equals(nPrev)) t = false;
25409 }
25410 if (t) return false;
25411 }
25412 return true;
25413 };
25414 SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
25415
25416 BigInteger.prototype.isProbablePrime = function (iterations) {
25417 var isPrime = isBasicPrime(this);
25418 if (isPrime !== undefined) return isPrime;
25419 var n = this.abs();
25420 var t = iterations === undefined ? 5 : iterations;
25421 // use the Fermat primality test
25422 for (var i = 0; i < t; i++) {
25423 var a = bigInt.randBetween(2, n.minus(2));
25424 if (!a.modPow(n.prev(), n).isUnit()) return false; // definitely composite
25425 }
25426 return true; // large chance of being prime
25427 };
25428 SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
25429
25430 BigInteger.prototype.next = function () {
25431 var value = this.value;
25432 if (this.sign) {
25433 return subtractSmall(value, 1, this.sign);
25434 }
25435 return new BigInteger(addSmall(value, 1), this.sign);
25436 };
25437 SmallInteger.prototype.next = function () {
25438 var value = this.value;
25439 if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
25440 return new BigInteger(MAX_INT_ARR, false);
25441 };
25442
25443 BigInteger.prototype.prev = function () {
25444 var value = this.value;
25445 if (this.sign) {
25446 return new BigInteger(addSmall(value, 1), true);
25447 }
25448 return subtractSmall(value, 1, this.sign);
25449 };
25450 SmallInteger.prototype.prev = function () {
25451 var value = this.value;
25452 if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
25453 return new BigInteger(MAX_INT_ARR, true);
25454 };
25455
25456 var powersOfTwo = [1];
25457 while (powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
25458 var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
25459
25460 function shift_isSmall(n) {
25461 return ((typeof n === "number" || typeof n === "string") && +Math.abs(n) <= BASE) ||
25462 (n instanceof BigInteger && n.value.length <= 1);
25463 }
25464
25465 BigInteger.prototype.shiftLeft = function (n) {
25466 if (!shift_isSmall(n)) {
25467 throw new Error(String(n) + " is too large for shifting.");
25468 }
25469 n = +n;
25470 if (n < 0) return this.shiftRight(-n);
25471 var result = this;
25472 while (n >= powers2Length) {
25473 result = result.multiply(highestPower2);
25474 n -= powers2Length - 1;
25475 }
25476 return result.multiply(powersOfTwo[n]);
25477 };
25478 SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
25479
25480 BigInteger.prototype.shiftRight = function (n) {
25481 var remQuo;
25482 if (!shift_isSmall(n)) {
25483 throw new Error(String(n) + " is too large for shifting.");
25484 }
25485 n = +n;
25486 if (n < 0) return this.shiftLeft(-n);
25487 var result = this;
25488 while (n >= powers2Length) {
25489 if (result.isZero()) return result;
25490 remQuo = divModAny(result, highestPower2);
25491 result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
25492 n -= powers2Length - 1;
25493 }
25494 remQuo = divModAny(result, powersOfTwo[n]);
25495 return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
25496 };
25497 SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
25498
25499 function bitwise(x, y, fn) {
25500 y = parseValue(y);
25501 var xSign = x.isNegative(), ySign = y.isNegative();
25502 var xRem = xSign ? x.not() : x,
25503 yRem = ySign ? y.not() : y;
25504 var xBits = [], yBits = [];
25505 var xStop = false, yStop = false;
25506 while (!xStop || !yStop) {
25507 if (xRem.isZero()) { // virtual sign extension for simulating two's complement
25508 xStop = true;
25509 xBits.push(xSign ? 1 : 0);
25510 }
25511 else if (xSign) xBits.push(xRem.isEven() ? 1 : 0); // two's complement for negative numbers
25512 else xBits.push(xRem.isEven() ? 0 : 1);
25513
25514 if (yRem.isZero()) {
25515 yStop = true;
25516 yBits.push(ySign ? 1 : 0);
25517 }
25518 else if (ySign) yBits.push(yRem.isEven() ? 1 : 0);
25519 else yBits.push(yRem.isEven() ? 0 : 1);
25520
25521 xRem = xRem.over(2);
25522 yRem = yRem.over(2);
25523 }
25524 var result = [];
25525 for (var i = 0; i < xBits.length; i++) result.push(fn(xBits[i], yBits[i]));
25526 var sum = bigInt(result.pop()).negate().times(bigInt(2).pow(result.length));
25527 while (result.length) {
25528 sum = sum.add(bigInt(result.pop()).times(bigInt(2).pow(result.length)));
25529 }
25530 return sum;
25531 }
25532
25533 BigInteger.prototype.not = function () {
25534 return this.negate().prev();
25535 };
25536 SmallInteger.prototype.not = BigInteger.prototype.not;
25537
25538 BigInteger.prototype.and = function (n) {
25539 return bitwise(this, n, function (a, b) { return a & b; });
25540 };
25541 SmallInteger.prototype.and = BigInteger.prototype.and;
25542
25543 BigInteger.prototype.or = function (n) {
25544 return bitwise(this, n, function (a, b) { return a | b; });
25545 };
25546 SmallInteger.prototype.or = BigInteger.prototype.or;
25547
25548 BigInteger.prototype.xor = function (n) {
25549 return bitwise(this, n, function (a, b) { return a ^ b; });
25550 };
25551 SmallInteger.prototype.xor = BigInteger.prototype.xor;
25552
25553 var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
25554 function roughLOB(n) { // get lowestOneBit (rough)
25555 // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
25556 // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
25557 var v = n.value, x = typeof v === "number" ? v | LOBMASK_I : v[0] + v[1] * BASE | LOBMASK_BI;
25558 return x & -x;
25559 }
25560
25561 function max(a, b) {
25562 a = parseValue(a);
25563 b = parseValue(b);
25564 return a.greater(b) ? a : b;
25565 }
25566 function min(a,b) {
25567 a = parseValue(a);
25568 b = parseValue(b);
25569 return a.lesser(b) ? a : b;
25570 }
25571 function gcd(a, b) {
25572 a = parseValue(a).abs();
25573 b = parseValue(b).abs();
25574 if (a.equals(b)) return a;
25575 if (a.isZero()) return b;
25576 if (b.isZero()) return a;
25577 var c = Integer[1], d, t;
25578 while (a.isEven() && b.isEven()) {
25579 d = Math.min(roughLOB(a), roughLOB(b));
25580 a = a.divide(d);
25581 b = b.divide(d);
25582 c = c.multiply(d);
25583 }
25584 while (a.isEven()) {
25585 a = a.divide(roughLOB(a));
25586 }
25587 do {
25588 while (b.isEven()) {
25589 b = b.divide(roughLOB(b));
25590 }
25591 if (a.greater(b)) {
25592 t = b; b = a; a = t;
25593 }
25594 b = b.subtract(a);
25595 } while (!b.isZero());
25596 return c.isUnit() ? a : a.multiply(c);
25597 }
25598 function lcm(a, b) {
25599 a = parseValue(a).abs();
25600 b = parseValue(b).abs();
25601 return a.divide(gcd(a, b)).multiply(b);
25602 }
25603 function randBetween(a, b) {
25604 a = parseValue(a);
25605 b = parseValue(b);
25606 var low = min(a, b), high = max(a, b);
25607 var range = high.subtract(low);
25608 if (range.isSmall) return low.add(Math.round(Math.random() * range));
25609 var length = range.value.length - 1;
25610 var result = [], restricted = true;
25611 for (var i = length; i >= 0; i--) {
25612 var top = restricted ? range.value[i] : BASE;
25613 var digit = truncate(Math.random() * top);
25614 result.unshift(digit);
25615 if (digit < top) restricted = false;
25616 }
25617 result = arrayToSmall(result);
25618 return low.add(typeof result === "number" ? new SmallInteger(result) : new BigInteger(result, false));
25619 }
25620 var parseBase = function (text, base) {
25621 var val = Integer[0], pow = Integer[1],
25622 length = text.length;
25623 if (2 <= base && base <= 36) {
25624 if (length <= LOG_MAX_INT / Math.log(base)) {
25625 return new SmallInteger(parseInt(text, base));
25626 }
25627 }
25628 base = parseValue(base);
25629 var digits = [];
25630 var i;
25631 var isNegative = text[0] === "-";
25632 for (i = isNegative ? 1 : 0; i < text.length; i++) {
25633 var c = text[i].toLowerCase(),
25634 charCode = c.charCodeAt(0);
25635 if (48 <= charCode && charCode <= 57) digits.push(parseValue(c));
25636 else if (97 <= charCode && charCode <= 122) digits.push(parseValue(c.charCodeAt(0) - 87));
25637 else if (c === "<") {
25638 var start = i;
25639 do { i++; } while (text[i] !== ">");
25640 digits.push(parseValue(text.slice(start + 1, i)));
25641 }
25642 else throw new Error(c + " is not a valid character");
25643 }
25644 digits.reverse();
25645 for (i = 0; i < digits.length; i++) {
25646 val = val.add(digits[i].times(pow));
25647 pow = pow.times(base);
25648 }
25649 return isNegative ? val.negate() : val;
25650 };
25651
25652 function stringify(digit) {
25653 var v = digit.value;
25654 if (typeof v === "number") v = [v];
25655 if (v.length === 1 && v[0] <= 35) {
25656 return "0123456789abcdefghijklmnopqrstuvwxyz".charAt(v[0]);
25657 }
25658 return "<" + v + ">";
25659 }
25660 function toBase(n, base) {
25661 base = bigInt(base);
25662 if (base.isZero()) {
25663 if (n.isZero()) return "0";
25664 throw new Error("Cannot convert nonzero numbers to base 0.");
25665 }
25666 if (base.equals(-1)) {
25667 if (n.isZero()) return "0";
25668 if (n.isNegative()) return new Array(1 - n).join("10");
25669 return "1" + new Array(+n).join("01");
25670 }
25671 var minusSign = "";
25672 if (n.isNegative() && base.isPositive()) {
25673 minusSign = "-";
25674 n = n.abs();
25675 }
25676 if (base.equals(1)) {
25677 if (n.isZero()) return "0";
25678 return minusSign + new Array(+n + 1).join(1);
25679 }
25680 var out = [];
25681 var left = n, divmod;
25682 while (left.isNegative() || left.compareAbs(base) >= 0) {
25683 divmod = left.divmod(base);
25684 left = divmod.quotient;
25685 var digit = divmod.remainder;
25686 if (digit.isNegative()) {
25687 digit = base.minus(digit).abs();
25688 left = left.next();
25689 }
25690 out.push(stringify(digit));
25691 }
25692 out.push(stringify(left));
25693 return minusSign + out.reverse().join("");
25694 }
25695
25696 BigInteger.prototype.toString = function (radix) {
25697 if (radix === undefined) radix = 10;
25698 if (radix !== 10) return toBase(this, radix);
25699 var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
25700 while (--l >= 0) {
25701 digit = String(v[l]);
25702 str += zeros.slice(digit.length) + digit;
25703 }
25704 var sign = this.sign ? "-" : "";
25705 return sign + str;
25706 };
25707 SmallInteger.prototype.toString = function (radix) {
25708 if (radix === undefined) radix = 10;
25709 if (radix != 10) return toBase(this, radix);
25710 return String(this.value);
25711 };
25712
25713 BigInteger.prototype.valueOf = function () {
25714 return +this.toString();
25715 };
25716 BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
25717
25718 SmallInteger.prototype.valueOf = function () {
25719 return this.value;
25720 };
25721 SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
25722
25723 function parseStringValue(v) {
25724 if (isPrecise(+v)) {
25725 var x = +v;
25726 if (x === truncate(x))
25727 return new SmallInteger(x);
25728 throw "Invalid integer: " + v;
25729 }
25730 var sign = v[0] === "-";
25731 if (sign) v = v.slice(1);
25732 var split = v.split(/e/i);
25733 if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
25734 if (split.length === 2) {
25735 var exp = split[1];
25736 if (exp[0] === "+") exp = exp.slice(1);
25737 exp = +exp;
25738 if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
25739 var text = split[0];
25740 var decimalPlace = text.indexOf(".");
25741 if (decimalPlace >= 0) {
25742 exp -= text.length - decimalPlace - 1;
25743 text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
25744 }
25745 if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
25746 text += (new Array(exp + 1)).join("0");
25747 v = text;
25748 }
25749 var isValid = /^([0-9][0-9]*)$/.test(v);
25750 if (!isValid) throw new Error("Invalid integer: " + v);
25751 var r = [], max = v.length, l = LOG_BASE, min = max - l;
25752 while (max > 0) {
25753 r.push(+v.slice(min, max));
25754 min -= l;
25755 if (min < 0) min = 0;
25756 max -= l;
25757 }
25758 trim(r);
25759 return new BigInteger(r, sign);
25760 }
25761
25762 function parseNumberValue(v) {
25763 if (isPrecise(v)) {
25764 if (v !== truncate(v)) throw new Error(v + " is not an integer.");
25765 return new SmallInteger(v);
25766 }
25767 return parseStringValue(v.toString());
25768 }
25769
25770 function parseValue(v) {
25771 if (typeof v === "number") {
25772 return parseNumberValue(v);
25773 }
25774 if (typeof v === "string") {
25775 return parseStringValue(v);
25776 }
25777 return v;
25778 }
25779 // Pre-define numbers in range [-999,999]
25780 for (var i = 0; i < 1000; i++) {
25781 Integer[i] = new SmallInteger(i);
25782 if (i > 0) Integer[-i] = new SmallInteger(-i);
25783 }
25784 // Backwards compatibility
25785 Integer.one = Integer[1];
25786 Integer.zero = Integer[0];
25787 Integer.minusOne = Integer[-1];
25788 Integer.max = max;
25789 Integer.min = min;
25790 Integer.gcd = gcd;
25791 Integer.lcm = lcm;
25792 Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger; };
25793 Integer.randBetween = randBetween;
25794 return Integer;
25795})();
25796
25797// Node.js check
25798if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
25799 module.exports = bigInt;
25800}
25801
25802},{}],3:[function(require,module,exports){
25803window.Algebrite = require('../dist/algebrite')
25804},{"../dist/algebrite":1}]},{},[3]);