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.2";
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 firstFactorIsNumber, h;
19083 h = tos;
19084 firstFactorIsNumber = false;
19085 if (token === '(') {
19086 scan_subexpr();
19087 } else if (token === T_SYMBOL) {
19088 scan_symbol();
19089 } else if (token === T_FUNCTION) {
19090 scan_function_call_with_function_name();
19091 } else if (token === '[') {
19092 scan_tensor();
19093 } else if (token === T_INTEGER) {
19094 firstFactorIsNumber = true;
19095 bignum_scan_integer(token_buf);
19096 get_next_token();
19097 } else if (token === T_DOUBLE) {
19098 firstFactorIsNumber = true;
19099 bignum_scan_float(token_buf);
19100 get_next_token();
19101 } else if (token === T_STRING) {
19102 scan_string();
19103 } else {
19104 scan_error("syntax error");
19105 }
19106 while (token === '[' || token === '(' && newline_flag === 0 && !firstFactorIsNumber) {
19107 if (token === '[') {
19108 scan_index(h);
19109 } else if (token === '(') {
19110 scan_function_call_without_function_name();
19111 }
19112 }
19113 while (token === '!') {
19114 get_next_token();
19115 push_symbol(FACTORIAL);
19116 swap();
19117 list(2);
19118 }
19119 while ((typeof token.charCodeAt === "function" ? token.charCodeAt(0) : void 0) === transpose_unicode) {
19120 get_next_token();
19121 push_symbol(TRANSPOSE);
19122 swap();
19123 list(2);
19124 }
19125 return scan_power();
19126 };
19127
19128 addSymbolRightOfAssignment = function(theSymbol) {
19129 var i, l1, prefixVar, ref2;
19130 if (predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(theSymbol) === -1 && symbolsRightOfAssignment.indexOf(theSymbol) === -1 && symbolsRightOfAssignment.indexOf("'" + theSymbol) === -1 && !skipRootVariableToBeSolved) {
19131 if (DEBUG) {
19132 console.log("... adding symbol: " + theSymbol + " to the set of the symbols right of assignment");
19133 }
19134 prefixVar = "";
19135 for (i = l1 = 1, ref2 = functionInvokationsScanningStack.length; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
19136 if (functionInvokationsScanningStack[i] !== "") {
19137 prefixVar += functionInvokationsScanningStack[i] + "_" + i + "_";
19138 }
19139 }
19140 theSymbol = prefixVar + theSymbol;
19141 return symbolsRightOfAssignment.push(theSymbol);
19142 }
19143 };
19144
19145 addSymbolLeftOfAssignment = function(theSymbol) {
19146 var i, l1, prefixVar, ref2;
19147 if (predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(theSymbol) === -1 && symbolsLeftOfAssignment.indexOf(theSymbol) === -1 && symbolsLeftOfAssignment.indexOf("'" + theSymbol) === -1 && !skipRootVariableToBeSolved) {
19148 if (DEBUG) {
19149 console.log("... adding symbol: " + theSymbol + " to the set of the symbols left of assignment");
19150 }
19151 prefixVar = "";
19152 for (i = l1 = 1, ref2 = functionInvokationsScanningStack.length; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
19153 if (functionInvokationsScanningStack[i] !== "") {
19154 prefixVar += functionInvokationsScanningStack[i] + "_" + i + "_";
19155 }
19156 }
19157 theSymbol = prefixVar + theSymbol;
19158 return symbolsLeftOfAssignment.push(theSymbol);
19159 }
19160 };
19161
19162 scan_symbol = function() {
19163 if (token !== T_SYMBOL) {
19164 scan_error("symbol expected");
19165 }
19166 if (meta_mode && token_buf.length === 1) {
19167 switch (token_buf[0]) {
19168 case 'a':
19169 push(symbol(METAA));
19170 break;
19171 case 'b':
19172 push(symbol(METAB));
19173 break;
19174 case 'x':
19175 push(symbol(METAX));
19176 break;
19177 default:
19178 push(usr_symbol(token_buf));
19179 }
19180 } else {
19181 push(usr_symbol(token_buf));
19182 }
19183 if (scanningParameters.length === 0) {
19184 if (DEBUG) {
19185 console.log("out of scanning parameters, processing " + token_buf);
19186 }
19187 lastFoundSymbol = token_buf;
19188 if (isSymbolLeftOfAssignment) {
19189 addSymbolLeftOfAssignment(token_buf);
19190 }
19191 } else {
19192 if (DEBUG) {
19193 console.log("still scanning parameters, skipping " + token_buf);
19194 }
19195 if (isSymbolLeftOfAssignment) {
19196 addSymbolRightOfAssignment("'" + token_buf);
19197 }
19198 }
19199 if (DEBUG) {
19200 console.log("found symbol: " + token_buf + " left of assignment: " + isSymbolLeftOfAssignment);
19201 }
19202 if (!isSymbolLeftOfAssignment) {
19203 addSymbolRightOfAssignment(token_buf);
19204 }
19205 return get_next_token();
19206 };
19207
19208 scan_string = function() {
19209 new_string(token_buf);
19210 return get_next_token();
19211 };
19212
19213 scan_function_call_with_function_name = function() {
19214 var functionName, i, l1, n, p, ref2;
19215 if (DEBUG) {
19216 console.log("-- scan_function_call_with_function_name start");
19217 }
19218 n = 1;
19219 p = new U();
19220 p = usr_symbol(token_buf);
19221 push(p);
19222 get_next_token();
19223 functionName = token_buf;
19224 if (functionName === "roots" || functionName === "defint" || functionName === "sum" || functionName === "product" || functionName === "for") {
19225 functionInvokationsScanningStack.push(token_buf);
19226 }
19227 lastFoundSymbol = token_buf;
19228 if (!isSymbolLeftOfAssignment) {
19229 addSymbolRightOfAssignment(token_buf);
19230 }
19231 get_next_token();
19232 scanningParameters.push(true);
19233 if (token !== ')') {
19234 scan_stmt();
19235 n++;
19236 while (token === ',') {
19237 get_next_token();
19238 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("roots") !== -1) {
19239 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19240 return !(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19241 });
19242 skipRootVariableToBeSolved = true;
19243 }
19244 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("sum") !== -1) {
19245 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19246 return !(new RegExp("sum_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19247 });
19248 skipRootVariableToBeSolved = true;
19249 }
19250 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("product") !== -1) {
19251 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19252 return !(new RegExp("product_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19253 });
19254 skipRootVariableToBeSolved = true;
19255 }
19256 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("for") !== -1) {
19257 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19258 return !(new RegExp("for_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19259 });
19260 skipRootVariableToBeSolved = true;
19261 }
19262 if (functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("defint") !== -1 && (n === 2 || (n > 2 && ((n - 2) % 3 === 0)))) {
19263 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19264 return !(new RegExp("defint_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19265 });
19266 skipRootVariableToBeSolved = true;
19267 }
19268 scan_stmt();
19269 skipRootVariableToBeSolved = false;
19270 n++;
19271 }
19272 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("roots") !== -1) {
19273 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19274 return !(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_" + "x")).test(x);
19275 });
19276 }
19277 }
19278 scanningParameters.pop();
19279 for (i = l1 = 0, ref2 = symbolsRightOfAssignment.length; 0 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19280 if (symbolsRightOfAssignment[i] != null) {
19281 if (functionName === "roots") {
19282 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19283 }
19284 if (functionName === "defint") {
19285 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("defint_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19286 }
19287 if (functionName === "sum") {
19288 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("sum_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19289 }
19290 if (functionName === "product") {
19291 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("product_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19292 }
19293 if (functionName === "for") {
19294 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("for_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19295 }
19296 }
19297 }
19298 if (token !== ')') {
19299 scan_error(") expected");
19300 }
19301 get_next_token();
19302 list(n);
19303 if (functionName === "roots" || functionName === "defint" || functionName === "sum" || functionName === "product" || functionName === "for") {
19304 functionInvokationsScanningStack.pop();
19305 }
19306 if (functionName === symbol(PATTERN).printname) {
19307 patternHasBeenFound = true;
19308 }
19309 if (DEBUG) {
19310 return console.log("-- scan_function_call_with_function_name end");
19311 }
19312 };
19313
19314 scan_function_call_without_function_name = function() {
19315 var n;
19316 if (DEBUG) {
19317 console.log("-- scan_function_call_without_function_name start");
19318 }
19319 push_symbol(EVAL);
19320 swap();
19321 list(2);
19322 n = 1;
19323 get_next_token();
19324 scanningParameters.push(true);
19325 if (token !== ')') {
19326 scan_stmt();
19327 n++;
19328 while (token === ',') {
19329 get_next_token();
19330 scan_stmt();
19331 n++;
19332 }
19333 }
19334 scanningParameters.pop();
19335 if (token !== ')') {
19336 scan_error(") expected");
19337 }
19338 get_next_token();
19339 list(n);
19340 if (DEBUG) {
19341 return console.log("-- scan_function_call_without_function_name end: " + stack[tos - 1]);
19342 }
19343 };
19344
19345 scan_subexpr = function() {
19346 var n;
19347 n = 0;
19348 if (token !== '(') {
19349 scan_error("( expected");
19350 }
19351 get_next_token();
19352 scan_stmt();
19353 if (token !== ')') {
19354 scan_error(") expected");
19355 }
19356 return get_next_token();
19357 };
19358
19359 scan_tensor = function() {
19360 var n;
19361 n = 0;
19362 if (token !== '[') {
19363 scan_error("[ expected");
19364 }
19365 get_next_token();
19366 scan_stmt();
19367 n = 1;
19368 while (token === ',') {
19369 get_next_token();
19370 scan_stmt();
19371 n++;
19372 }
19373 build_tensor(n);
19374 if (token !== ']') {
19375 scan_error("] expected");
19376 }
19377 return get_next_token();
19378 };
19379
19380 scan_error = function(errmsg) {
19381 errorMessage = "";
19382 while (input_str !== scan_str) {
19383 if ((scanned[input_str] === '\n' || scanned[input_str] === '\r') && input_str + 1 === scan_str) {
19384 break;
19385 }
19386 errorMessage += scanned[input_str++];
19387 }
19388 errorMessage += " ? ";
19389 while (scanned[input_str] && (scanned[input_str] !== '\n' && scanned[input_str] !== '\r')) {
19390 errorMessage += scanned[input_str++];
19391 }
19392 errorMessage += '\n';
19393 return stop(errmsg);
19394 };
19395
19396 build_tensor = function(n) {
19397 var i, l1, ref2;
19398 i = 0;
19399 save();
19400 p2 = alloc_tensor(n);
19401 p2.tensor.ndim = 1;
19402 p2.tensor.dim[0] = n;
19403 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19404 p2.tensor.elem[i] = stack[tos - n + i];
19405 }
19406 check_tensor_dimensions(p2);
19407 moveTos(tos - n);
19408 push(p2);
19409 return restore();
19410 };
19411
19412 get_next_token = function() {
19413 newline_flag = 0;
19414 while (1) {
19415 get_token();
19416 if (token !== T_NEWLINE) {
19417 break;
19418 }
19419 newline_flag = 1;
19420 }
19421 if (DEBUG) {
19422 return console.log("get_next_token token: " + token);
19423 }
19424 };
19425
19426 get_token = function() {
19427 while (isspace(scanned[scan_str])) {
19428 if (scanned[scan_str] === '\n' || scanned[scan_str] === '\r') {
19429 token = T_NEWLINE;
19430 scan_str++;
19431 return;
19432 }
19433 scan_str++;
19434 }
19435 token_str = scan_str;
19436 if (scan_str === scanned.length) {
19437 token = "";
19438 return;
19439 }
19440 if (isdigit(scanned[scan_str]) || scanned[scan_str] === '.') {
19441 while (isdigit(scanned[scan_str])) {
19442 scan_str++;
19443 }
19444 if (scanned[scan_str] === '.') {
19445 scan_str++;
19446 while (isdigit(scanned[scan_str])) {
19447 scan_str++;
19448 }
19449 if (scanned[scan_str] === 'e' && (scanned[scan_str + 1] === '+' || scanned[scan_str + 1] === '-' || isdigit(scanned[scan_str + 1]))) {
19450 scan_str += 2;
19451 while (isdigit(scanned[scan_str])) {
19452 scan_str++;
19453 }
19454 }
19455 token = T_DOUBLE;
19456 } else {
19457 token = T_INTEGER;
19458 }
19459 update_token_buf(token_str, scan_str);
19460 return;
19461 }
19462 if (isalpha(scanned[scan_str])) {
19463 while (isalnumorunderscore(scanned[scan_str])) {
19464 scan_str++;
19465 }
19466 if (scanned[scan_str] === '(') {
19467 token = T_FUNCTION;
19468 } else {
19469 token = T_SYMBOL;
19470 }
19471 update_token_buf(token_str, scan_str);
19472 return;
19473 }
19474 if (scanned[scan_str] === '"') {
19475 scan_str++;
19476 while (scanned[scan_str] !== '"') {
19477 if (scan_str === scanned.length - 1) {
19478 scan_str++;
19479 scan_error("runaway string");
19480 scan_str--;
19481 }
19482 scan_str++;
19483 }
19484 scan_str++;
19485 token = T_STRING;
19486 update_token_buf(token_str + 1, scan_str - 1);
19487 return;
19488 }
19489 if (scanned[scan_str] === '#' || scanned[scan_str] === '-' && scanned[scan_str + 1] === '-') {
19490 while (scanned[scan_str] && scanned[scan_str] !== '\n' && scanned[scan_str] !== '\r') {
19491 scan_str++;
19492 }
19493 if (scanned[scan_str]) {
19494 scan_str++;
19495 }
19496 token = T_NEWLINE;
19497 return;
19498 }
19499 if (scanned[scan_str] === ':' && scanned[scan_str + 1] === '=') {
19500 scan_str += 2;
19501 token = T_QUOTASSIGN;
19502 return;
19503 }
19504 if (scanned[scan_str] === '=' && scanned[scan_str + 1] === '=') {
19505 scan_str += 2;
19506 token = T_EQ;
19507 return;
19508 }
19509 if (scanned[scan_str] === '!' && scanned[scan_str + 1] === '=') {
19510 scan_str += 2;
19511 token = T_NEQ;
19512 return;
19513 }
19514 if (scanned[scan_str] === '<' && scanned[scan_str + 1] === '=') {
19515 scan_str += 2;
19516 token = T_LTEQ;
19517 return;
19518 }
19519 if (scanned[scan_str] === '>' && scanned[scan_str + 1] === '=') {
19520 scan_str += 2;
19521 token = T_GTEQ;
19522 return;
19523 }
19524 return token = scanned[scan_str++];
19525 };
19526
19527 update_token_buf = function(a, b) {
19528 return token_buf = scanned.substring(a, b);
19529 };
19530
19531 $.scan = scan;
19532
19533 Eval_sgn = function() {
19534 push(cadr(p1));
19535 Eval();
19536 return sgn();
19537 };
19538
19539 sgn = function() {
19540 save();
19541 yysgn();
19542 return restore();
19543 };
19544
19545 yysgn = function() {
19546 p1 = pop();
19547 if (isdouble(p1)) {
19548 if (p1.d > 0) {
19549 push_integer(1);
19550 return;
19551 } else {
19552 if (p1.d === 0) {
19553 push_integer(1);
19554 return;
19555 } else {
19556 push_integer(-1);
19557 return;
19558 }
19559 }
19560 }
19561 if (isrational(p1)) {
19562 if (MSIGN(mmul(p1.q.a, p1.q.b)) === -1) {
19563 push_integer(-1);
19564 return;
19565 } else {
19566 if (MZERO(mmul(p1.q.a, p1.q.b))) {
19567 push_integer(0);
19568 return;
19569 } else {
19570 push_integer(1);
19571 return;
19572 }
19573 }
19574 }
19575 if (iscomplexnumber(p1)) {
19576 push_integer(-1);
19577 push(p1);
19578 absval();
19579 power();
19580 push(p1);
19581 multiply();
19582 return;
19583 }
19584 if (isnegativeterm(p1)) {
19585 push_symbol(SGN);
19586 push(p1);
19587 negate();
19588 list(2);
19589 push_integer(-1);
19590 multiply();
19591 return;
19592 }
19593
19594 /*
19595 push_integer(2)
19596 push(p1)
19597 heaviside()
19598 multiply()
19599 push_integer(-1)
19600 add()
19601 */
19602 push_symbol(SGN);
19603 push(p1);
19604 return list(2);
19605 };
19606
19607 Eval_shape = function() {
19608 push(cadr(p1));
19609 Eval();
19610 return shape();
19611 };
19612
19613 shape = function() {
19614 var ai, an, i, l1, m1, ndim, ref2, ref3, t;
19615 i = 0;
19616 ndim = 0;
19617 t = 0;
19618 ai = [];
19619 an = [];
19620 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19621 ai[i] = 0;
19622 an[i] = 0;
19623 }
19624 save();
19625 p1 = pop();
19626 if (!istensor(p1)) {
19627 if (!iszero(p1)) {
19628 stop("transpose: tensor expected, 1st arg is not a tensor");
19629 }
19630 push(zero);
19631 restore();
19632 return;
19633 }
19634 ndim = p1.tensor.ndim;
19635 p2 = alloc_tensor(ndim);
19636 p2.tensor.ndim = 1;
19637 p2.tensor.dim[0] = ndim;
19638 for (i = m1 = 0, ref3 = ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
19639 push_integer(p1.tensor.dim[i]);
19640 p2.tensor.elem[i] = pop();
19641 }
19642 push(p2);
19643 return restore();
19644 };
19645
19646
19647 /*
19648 Simplify factorials
19649
19650 The following script
19651
19652 F(n,k) = k binomial(n,k)
19653 (F(n,k) + F(n,k-1)) / F(n+1,k)
19654
19655 generates
19656
19657 k! n! n! (1 - k + n)! k! n!
19658 -------------------- + -------------------- - ----------------------
19659 (-1 + k)! (1 + n)! (1 + n)! (-k + n)! k (-1 + k)! (1 + n)!
19660
19661 Simplify each term to get
19662
19663 k 1 - k + n 1
19664 ------- + ----------- - -------
19665 1 + n 1 + n 1 + n
19666
19667 Then simplify the sum to get
19668
19669 n
19670 -------
19671 1 + n
19672 */
19673
19674 Eval_simfac = function() {
19675 push(cadr(p1));
19676 Eval();
19677 return simfac();
19678 };
19679
19680 simfac = function() {
19681 var h;
19682 h = 0;
19683 save();
19684 p1 = pop();
19685 if (car(p1) === symbol(ADD)) {
19686 h = tos;
19687 p1 = cdr(p1);
19688 while (p1 !== symbol(NIL)) {
19689 push(car(p1));
19690 simfac_term();
19691 p1 = cdr(p1);
19692 }
19693 add_all(tos - h);
19694 } else {
19695 push(p1);
19696 simfac_term();
19697 }
19698 return restore();
19699 };
19700
19701
19702 /*
19703 void
19704 simfac(void)
19705 {
19706 int h
19707 save()
19708 p1 = pop()
19709 if (car(p1) == symbol(ADD)) {
19710 h = tos
19711 p1 = cdr(p1)
19712 while (p1 != symbol(NIL)) {
19713 push(car(p1))
19714 simfac_term()
19715 p1 = cdr(p1)
19716 }
19717 addk(tos - h)
19718 p1 = pop()
19719 if (find(p1, symbol(FACTORIAL))) {
19720 push(p1)
19721 if (car(p1) == symbol(ADD)) {
19722 Condense()
19723 simfac_term()
19724 }
19725 }
19726 } else {
19727 push(p1)
19728 simfac_term()
19729 }
19730 restore()
19731 }
19732
19733 #endif
19734 */
19735
19736 simfac_term = function() {
19737 var doNothing, h;
19738 h = 0;
19739 save();
19740 p1 = pop();
19741 if (car(p1) !== symbol(MULTIPLY)) {
19742 push(p1);
19743 restore();
19744 return;
19745 }
19746 h = tos;
19747 p1 = cdr(p1);
19748 while (p1 !== symbol(NIL)) {
19749 push(car(p1));
19750 p1 = cdr(p1);
19751 }
19752 while (yysimfac(h)) {
19753 doNothing = 1;
19754 }
19755 multiply_all_noexpand(tos - h);
19756 return restore();
19757 };
19758
19759 yysimfac = function(h) {
19760 var i, j, l1, m1, ref2, ref3, ref4, ref5;
19761 i = 0;
19762 j = 0;
19763 for (i = l1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
19764 p1 = stack[i];
19765 for (j = m1 = ref4 = h, ref5 = tos; ref4 <= ref5 ? m1 < ref5 : m1 > ref5; j = ref4 <= ref5 ? ++m1 : --m1) {
19766 if (i === j) {
19767 continue;
19768 }
19769 p2 = stack[j];
19770 if (car(p1) === symbol(FACTORIAL) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && equal(cadr(p1), cadr(p2))) {
19771 push(cadr(p1));
19772 push(one);
19773 subtract();
19774 factorial();
19775 stack[i] = pop();
19776 stack[j] = one;
19777 return 1;
19778 }
19779 if (car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL) && equal(p1, cadadr(p2))) {
19780 push(p1);
19781 push_integer(-1);
19782 add();
19783 factorial();
19784 reciprocate();
19785 stack[i] = pop();
19786 stack[j] = one;
19787 return 1;
19788 }
19789 if (car(p2) === symbol(FACTORIAL)) {
19790 push(p1);
19791 push(cadr(p2));
19792 subtract();
19793 p3 = pop();
19794 if (isplusone(p3)) {
19795 push(p1);
19796 factorial();
19797 stack[i] = pop();
19798 stack[j] = one;
19799 return 1;
19800 }
19801 }
19802 if (car(p1) === symbol(POWER) && isminusone(caddr(p1)) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL)) {
19803 push(cadr(p1));
19804 push(cadr(cadr(p2)));
19805 subtract();
19806 p3 = pop();
19807 if (isplusone(p3)) {
19808 push(cadr(p1));
19809 factorial();
19810 reciprocate();
19811 stack[i] = pop();
19812 stack[j] = one;
19813 return 1;
19814 }
19815 }
19816 if (car(p1) === symbol(FACTORIAL) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL)) {
19817 push(cadr(p1));
19818 push(cadr(cadr(p2)));
19819 subtract();
19820 p3 = pop();
19821 if (isplusone(p3)) {
19822 stack[i] = cadr(p1);
19823 stack[j] = one;
19824 return 1;
19825 }
19826 if (isminusone(p3)) {
19827 push(cadr(cadr(p2)));
19828 reciprocate();
19829 stack[i] = pop();
19830 stack[j] = one;
19831 return 1;
19832 }
19833 if (equaln(p3, 2)) {
19834 stack[i] = cadr(p1);
19835 push(cadr(p1));
19836 push_integer(-1);
19837 add();
19838 stack[j] = pop();
19839 return 1;
19840 }
19841 if (equaln(p3, -2)) {
19842 push(cadr(cadr(p2)));
19843 reciprocate();
19844 stack[i] = pop();
19845 push(cadr(cadr(p2)));
19846 push_integer(-1);
19847 add();
19848 reciprocate();
19849 stack[j] = pop();
19850 return 1;
19851 }
19852 }
19853 }
19854 }
19855 return 0;
19856 };
19857
19858 Eval_simplify = function() {
19859 push(cadr(p1));
19860 runUserDefinedSimplifications();
19861 Eval();
19862 return simplify();
19863 };
19864
19865 runUserDefinedSimplifications = function() {
19866 var atLeastOneSuccessInRouldOfRulesApplications, eachConsecutiveRuleApplication, eachSimplification, l1, len, len1, m1, numberOfRulesApplications, originalexpanding, success;
19867 if (userSimplificationsInListForm.length !== 0 && !Find(cadr(p1), symbol(INTEGRAL))) {
19868 originalexpanding = expanding;
19869 expanding = false;
19870 if (DEBUG) {
19871 console.log("runUserDefinedSimplifications passed: " + stack[tos - 1].toString());
19872 }
19873 Eval();
19874 if (DEBUG) {
19875 console.log("runUserDefinedSimplifications after eval no expanding: " + stack[tos - 1].toString());
19876 }
19877 expanding = originalexpanding;
19878 p1 = stack[tos - 1];
19879 if (DEBUG) {
19880 console.log("patterns to be checked: ");
19881 }
19882 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
19883 eachSimplification = userSimplificationsInListForm[l1];
19884 if (DEBUG) {
19885 console.log("..." + eachSimplification);
19886 }
19887 }
19888 atLeastOneSuccessInRouldOfRulesApplications = true;
19889 numberOfRulesApplications = 0;
19890 while (atLeastOneSuccessInRouldOfRulesApplications && numberOfRulesApplications < MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES) {
19891 atLeastOneSuccessInRouldOfRulesApplications = false;
19892 numberOfRulesApplications++;
19893 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
19894 eachSimplification = userSimplificationsInListForm[m1];
19895 success = true;
19896 eachConsecutiveRuleApplication = 0;
19897 while (success && eachConsecutiveRuleApplication < MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE) {
19898 eachConsecutiveRuleApplication++;
19899 if (DEBUG) {
19900 console.log("simplify - tos: " + tos + " checking pattern: " + eachSimplification + " on: " + p1);
19901 }
19902 push_symbol(NIL);
19903 success = transform(eachSimplification, true);
19904 if (success) {
19905 atLeastOneSuccessInRouldOfRulesApplications = true;
19906 }
19907 p1 = stack[tos - 1];
19908 if (DEBUG) {
19909 console.log("p1 at this stage of simplification: " + p1);
19910 }
19911 }
19912 if (eachConsecutiveRuleApplication === MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE) {
19913 stop("maximum application of single transformation rule exceeded: " + eachSimplification);
19914 }
19915 }
19916 }
19917 if (numberOfRulesApplications === MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES) {
19918 stop("maximum application of all transformation rules exceeded ");
19919 }
19920 if (DEBUG) {
19921 console.log("METAX = " + get_binding(symbol(METAX)));
19922 console.log("METAA = " + get_binding(symbol(METAA)));
19923 return console.log("METAB = " + get_binding(symbol(METAB)));
19924 }
19925 }
19926 };
19927
19928 simplifyForCodeGeneration = function() {
19929 save();
19930 runUserDefinedSimplifications();
19931 codeGen = true;
19932 simplify_main();
19933 codeGen = false;
19934 return restore();
19935 };
19936
19937 simplify = function() {
19938 save();
19939 simplify_main();
19940 return restore();
19941 };
19942
19943 simplify_main = function() {
19944 var args, fbody;
19945 p1 = pop();
19946 if (codeGen && car(p1) === symbol(FUNCTION)) {
19947 fbody = cadr(p1);
19948 push(fbody);
19949 eval();
19950 simplify();
19951 p3 = pop();
19952 args = caddr(p1);
19953 push_symbol(FUNCTION);
19954 push(p3);
19955 push(args);
19956 list(3);
19957 p1 = pop();
19958 }
19959 if (istensor(p1)) {
19960 simplify_tensor();
19961 return;
19962 }
19963 if (Find(p1, symbol(FACTORIAL))) {
19964 push(p1);
19965 simfac();
19966 p2 = pop();
19967 push(p1);
19968 rationalize();
19969 simfac();
19970 p3 = pop();
19971 if (count(p2) < count(p3)) {
19972 p1 = p2;
19973 } else {
19974 p1 = p3;
19975 }
19976 }
19977 f10();
19978 f1();
19979 f2();
19980 f3();
19981 f4();
19982 f5();
19983 f9();
19984 simplify_polarRect();
19985 if (do_simplify_nested_radicals) {
19986 if (simplify_nested_radicals()) {
19987 if (DEBUG) {
19988 console.log("de-nesting successful into: " + p1.toString());
19989 }
19990 push(p1);
19991 simplify();
19992 return;
19993 }
19994 }
19995 simplify_rectToClock();
19996 return push(p1);
19997 };
19998
19999 simplify_tensor = function() {
20000 var i, l1, m1, ref2, ref3;
20001 i = 0;
20002 p2 = alloc_tensor(p1.tensor.nelem);
20003 p2.tensor.ndim = p1.tensor.ndim;
20004 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
20005 p2.tensor.dim[i] = p1.tensor.dim[i];
20006 }
20007 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
20008 push(p1.tensor.elem[i]);
20009 simplify();
20010 p2.tensor.elem[i] = pop();
20011 }
20012 check_tensor_dimensions(p2);
20013 if (iszero(p2)) {
20014 p2 = zero;
20015 }
20016 return push(p2);
20017 };
20018
20019 f1 = function() {
20020 if (car(p1) !== symbol(ADD)) {
20021 return;
20022 }
20023 push(p1);
20024 rationalize();
20025 p2 = pop();
20026 if (count(p2) < count(p1)) {
20027 return p1 = p2;
20028 }
20029 };
20030
20031 f2 = function() {
20032 if (car(p1) !== symbol(ADD)) {
20033 return;
20034 }
20035 push(p1);
20036 Condense();
20037 p2 = pop();
20038 if (count(p2) <= count(p1)) {
20039 return p1 = p2;
20040 }
20041 };
20042
20043 f3 = function() {
20044 push(p1);
20045 rationalize();
20046 negate();
20047 rationalize();
20048 negate();
20049 rationalize();
20050 p2 = pop();
20051 if (count(p2) < count(p1)) {
20052 return p1 = p2;
20053 }
20054 };
20055
20056 f10 = function() {
20057 var a, b, carp1, miao, originalexpanding;
20058 carp1 = car(p1);
20059 miao = cdr(p1);
20060 if (carp1 === symbol(MULTIPLY) || isinnerordot(p1)) {
20061 if ((car(car(cdr(p1))) === symbol(TRANSPOSE)) && (car(car(cdr(cdr(p1)))) === symbol(TRANSPOSE))) {
20062 if (DEBUG) {
20063 console.log("maybe collecting a transpose " + p1);
20064 }
20065 a = cadr(car(cdr(p1)));
20066 b = cadr(car(cdr(cdr(p1))));
20067 if (carp1 === symbol(MULTIPLY)) {
20068 push(a);
20069 push(b);
20070 multiply();
20071 } else if (isinnerordot(p1)) {
20072 push(b);
20073 push(a);
20074 inner();
20075 }
20076 push_integer(1);
20077 push_integer(2);
20078 originalexpanding = expanding;
20079 expanding = false;
20080 transpose();
20081 expanding = originalexpanding;
20082 p2 = pop();
20083 if (count(p2) < count(p1)) {
20084 p1 = p2;
20085 }
20086 if (DEBUG) {
20087 return console.log("collecting a transpose " + p2);
20088 }
20089 }
20090 }
20091 };
20092
20093 f4 = function() {
20094 if (iszero(p1)) {
20095 return;
20096 }
20097 push(p1);
20098 rationalize();
20099 inverse();
20100 rationalize();
20101 inverse();
20102 rationalize();
20103 p2 = pop();
20104 if (count(p2) < count(p1)) {
20105 return p1 = p2;
20106 }
20107 };
20108
20109 simplify_trig = function() {
20110 save();
20111 p1 = pop();
20112 f5();
20113 push(p1);
20114 return restore();
20115 };
20116
20117 f5 = function() {
20118 if (Find(p1, symbol(SIN)) === 0 && Find(p1, symbol(COS)) === 0) {
20119 return;
20120 }
20121 p2 = p1;
20122 trigmode = 1;
20123 push(p2);
20124 Eval();
20125 p3 = pop();
20126 trigmode = 2;
20127 push(p2);
20128 Eval();
20129 p4 = pop();
20130 trigmode = 0;
20131 if (count(p4) < count(p3) || nterms(p4) < nterms(p3)) {
20132 p3 = p4;
20133 }
20134 if (count(p3) < count(p1) || nterms(p3) < nterms(p1)) {
20135 return p1 = p3;
20136 }
20137 };
20138
20139 f9 = function() {
20140 if (car(p1) !== symbol(ADD)) {
20141 return;
20142 }
20143 push_integer(0);
20144 p2 = cdr(p1);
20145 while (iscons(p2)) {
20146 push(car(p2));
20147 simplify();
20148 add();
20149 p2 = cdr(p2);
20150 }
20151 p2 = pop();
20152 if (count(p2) < count(p1)) {
20153 return p1 = p2;
20154 }
20155 };
20156
20157 simplify_rectToClock = function() {
20158 if (Find(p1, symbol(SIN)) === 0 && Find(p1, symbol(COS)) === 0) {
20159 return;
20160 }
20161 push(p1);
20162 Eval();
20163 clockform();
20164 p2 = pop();
20165 if (DEBUG) {
20166 console.log("before simplification clockform: " + p1 + " after: " + p2);
20167 }
20168 if (count(p2) < count(p1)) {
20169 return p1 = p2;
20170 }
20171 };
20172
20173 simplify_polarRect = function() {
20174 push(p1);
20175 polarRectAMinusOneBase();
20176 Eval();
20177 p2 = pop();
20178 if (count(p2) < count(p1)) {
20179 return p1 = p2;
20180 }
20181 };
20182
20183 polarRectAMinusOneBase = function() {
20184 var h;
20185 save();
20186 p1 = pop();
20187 if (isimaginaryunit(p1)) {
20188 push(p1);
20189 restore();
20190 return;
20191 }
20192 if (equal(car(p1), symbol(POWER)) && isminusone(cadr(p1))) {
20193 push(one);
20194 negate();
20195 push(caddr(p1));
20196 polarRectAMinusOneBase();
20197 power();
20198 polar();
20199 rect();
20200 } else if (iscons(p1)) {
20201 h = tos;
20202 while (iscons(p1)) {
20203 push(car(p1));
20204 polarRectAMinusOneBase();
20205 p1 = cdr(p1);
20206 }
20207 list(tos - h);
20208 } else {
20209 push(p1);
20210 }
20211 restore();
20212 };
20213
20214 nterms = function(p) {
20215 if (car(p) !== symbol(ADD)) {
20216 return 1;
20217 } else {
20218 return length(p) - 1;
20219 }
20220 };
20221
20222 simplify_nested_radicals = function() {
20223 var prev_expanding, simplificationWithCondense, simplificationWithoutCondense, somethingSimplified;
20224 if (recursionLevelNestedRadicalsRemoval > 0) {
20225 if (DEBUG) {
20226 console.log("denesting bailing out because of too much recursion");
20227 }
20228 return false;
20229 }
20230 push(p1);
20231 somethingSimplified = take_care_of_nested_radicals();
20232 simplificationWithoutCondense = stack[tos - 1];
20233 prev_expanding = expanding;
20234 expanding = 0;
20235 yycondense();
20236 expanding = prev_expanding;
20237 simplificationWithCondense = pop();
20238 if (countOccurrencesOfSymbol(symbol(POWER), simplificationWithoutCondense) < countOccurrencesOfSymbol(symbol(POWER), simplificationWithCondense)) {
20239 push(simplificationWithoutCondense);
20240 } else {
20241 push(simplificationWithCondense);
20242 }
20243 p1 = pop();
20244 return somethingSimplified;
20245 };
20246
20247 take_care_of_nested_radicals = function() {
20248 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;
20249 if (recursionLevelNestedRadicalsRemoval > 0) {
20250 if (DEBUG) {
20251 console.log("denesting bailing out because of too much recursion");
20252 }
20253 return false;
20254 }
20255 save();
20256 p1 = pop();
20257 if (equal(car(p1), symbol(POWER))) {
20258 base = cadr(p1);
20259 exponent = caddr(p1);
20260 if (!isminusone(exponent) && equal(car(base), symbol(ADD)) && isfraction(exponent) && (equalq(exponent, 1, 3) || equalq(exponent, 1, 2))) {
20261 firstTerm = cadr(base);
20262 push(firstTerm);
20263 take_care_of_nested_radicals();
20264 pop();
20265 secondTerm = caddr(base);
20266 push(secondTerm);
20267 take_care_of_nested_radicals();
20268 pop();
20269 numberOfTerms = 0;
20270 countingTerms = base;
20271 while (cdr(countingTerms) !== symbol(NIL)) {
20272 numberOfTerms++;
20273 countingTerms = cdr(countingTerms);
20274 }
20275 if (numberOfTerms > 2) {
20276 push(p1);
20277 restore();
20278 return false;
20279 }
20280 commonInnerExponent = null;
20281 commonBases = [];
20282 termsThatAreNotPowers = [];
20283 if (car(secondTerm) === symbol(MULTIPLY)) {
20284 secondTermFactor = cdr(secondTerm);
20285 if (iscons(secondTermFactor)) {
20286 while (iscons(secondTermFactor)) {
20287 potentialPower = car(secondTermFactor);
20288 if (car(potentialPower) === symbol(POWER)) {
20289 innerbase = cadr(potentialPower);
20290 innerexponent = caddr(potentialPower);
20291 if (equalq(innerexponent, 1, 2)) {
20292 if (commonInnerExponent == null) {
20293 commonInnerExponent = innerexponent;
20294 commonBases.push(innerbase);
20295 } else {
20296 if (equal(innerexponent, commonInnerExponent)) {
20297 commonBases.push(innerbase);
20298 } else {
20299
20300 }
20301 }
20302 }
20303 } else {
20304 termsThatAreNotPowers.push(potentialPower);
20305 }
20306 secondTermFactor = cdr(secondTermFactor);
20307 }
20308 }
20309 } else if (car(secondTerm) === symbol(POWER)) {
20310 innerbase = cadr(secondTerm);
20311 innerexponent = caddr(secondTerm);
20312 if ((commonInnerExponent == null) && equalq(innerexponent, 1, 2)) {
20313 commonInnerExponent = innerexponent;
20314 commonBases.push(innerbase);
20315 }
20316 }
20317 if (commonBases.length === 0) {
20318 push(p1);
20319 restore();
20320 return false;
20321 }
20322 A = firstTerm;
20323 push_integer(1);
20324 for (l1 = 0, len = commonBases.length; l1 < len; l1++) {
20325 i = commonBases[l1];
20326 push(i);
20327 multiply();
20328 }
20329 C = pop();
20330 push_integer(1);
20331 for (m1 = 0, len1 = termsThatAreNotPowers.length; m1 < len1; m1++) {
20332 i = termsThatAreNotPowers[m1];
20333 push(i);
20334 multiply();
20335 }
20336 B = pop();
20337 if (equalq(exponent, 1, 3)) {
20338 push(A);
20339 negate();
20340 push(C);
20341 multiply();
20342 push(B);
20343 divide();
20344 checkSize = pop();
20345 push(checkSize);
20346 real();
20347 yyfloat();
20348 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20349 push(p1);
20350 restore();
20351 return false;
20352 }
20353 push(checkSize);
20354 push_integer(3);
20355 push(C);
20356 multiply();
20357 checkSize = pop();
20358 push(checkSize);
20359 real();
20360 yyfloat();
20361 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20362 pop();
20363 push(p1);
20364 restore();
20365 return false;
20366 }
20367 push(checkSize);
20368 push(symbol(SECRETX));
20369 multiply();
20370 push_integer(-3);
20371 push(A);
20372 multiply();
20373 push(B);
20374 divide();
20375 checkSize = pop();
20376 push(checkSize);
20377 real();
20378 yyfloat();
20379 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20380 pop();
20381 pop();
20382 push(p1);
20383 restore();
20384 return false;
20385 }
20386 push(checkSize);
20387 push(symbol(SECRETX));
20388 push_integer(2);
20389 power();
20390 multiply();
20391 push_integer(1);
20392 push(symbol(SECRETX));
20393 push_integer(3);
20394 power();
20395 multiply();
20396 add();
20397 add();
20398 add();
20399 } else if (equalq(exponent, 1, 2)) {
20400 push(C);
20401 checkSize = pop();
20402 push(checkSize);
20403 real();
20404 yyfloat();
20405 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20406 push(p1);
20407 restore();
20408 return false;
20409 }
20410 push(checkSize);
20411 push_integer(-2);
20412 push(A);
20413 multiply();
20414 push(B);
20415 divide();
20416 checkSize = pop();
20417 push(checkSize);
20418 real();
20419 yyfloat();
20420 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20421 pop();
20422 push(p1);
20423 restore();
20424 return false;
20425 }
20426 push(checkSize);
20427 push(symbol(SECRETX));
20428 multiply();
20429 push_integer(1);
20430 push(symbol(SECRETX));
20431 push_integer(2);
20432 power();
20433 multiply();
20434 add();
20435 add();
20436 }
20437 push(symbol(SECRETX));
20438 recursionLevelNestedRadicalsRemoval++;
20439 roots();
20440 recursionLevelNestedRadicalsRemoval--;
20441 if (equal(stack[tos - 1], symbol(NIL))) {
20442 if (DEBUG) {
20443 console.log("roots bailed out because of too much recursion");
20444 }
20445 pop();
20446 push(p1);
20447 restore();
20448 return false;
20449 }
20450 possibleSolutions = [];
20451 ref2 = stack[tos - 1].tensor.elem;
20452 for (n1 = 0, len2 = ref2.length; n1 < len2; n1++) {
20453 eachSolution = ref2[n1];
20454 if (!Find(eachSolution, symbol(POWER))) {
20455 possibleSolutions.push(eachSolution);
20456 }
20457 }
20458 pop();
20459 if (possibleSolutions.length === 0) {
20460 push(p1);
20461 restore();
20462 return false;
20463 }
20464 possibleRationalSolutions = [];
20465 realOfpossibleRationalSolutions = [];
20466 for (o1 = 0, len3 = possibleSolutions.length; o1 < len3; o1++) {
20467 i = possibleSolutions[o1];
20468 push(i);
20469 real();
20470 yyfloat();
20471 possibleRationalSolutions.push(i);
20472 realOfpossibleRationalSolutions.push(pop().d);
20473 }
20474 whichRationalSolution = realOfpossibleRationalSolutions.indexOf(Math.max.apply(Math, realOfpossibleRationalSolutions));
20475 SOLUTION = possibleRationalSolutions[whichRationalSolution];
20476
20477 /*
20478 #possibleNewExpressions = []
20479 #realOfPossibleNewExpressions = []
20480 * pick the solution which cubic root has no radicals
20481 lowercase_b = null
20482 for SOLUTION in possibleSolutions
20483 console.log("testing solution: " + SOLUTION.toString())
20484
20485 debugger
20486 if equalq(exponent,1,3)
20487 push(A)
20488 push(SOLUTION)
20489 push_integer(3)
20490 power()
20491 push_integer(3)
20492 push(C)
20493 multiply()
20494 push(SOLUTION)
20495 multiply()
20496 add()
20497 divide()
20498 console.log("argument of cubic root: " + stack[tos-1].toString())
20499 push_rational(1,3)
20500 power()
20501 else if equalq(exponent,1,2)
20502 push(A)
20503 push(SOLUTION)
20504 push_integer(2)
20505 power()
20506 push(C)
20507 add()
20508 divide()
20509 console.log("argument of cubic root: " + stack[tos-1].toString())
20510 push_rational(1,2)
20511 power()
20512 console.log("b is: " + stack[tos-1].toString())
20513
20514 lowercase_b = pop()
20515
20516 if !Find(lowercase_b, symbol(POWER))
20517 break
20518 */
20519 if (equalq(exponent, 1, 3)) {
20520 push(A);
20521 push(SOLUTION);
20522 push_integer(3);
20523 power();
20524 push_integer(3);
20525 push(C);
20526 multiply();
20527 push(SOLUTION);
20528 multiply();
20529 add();
20530 divide();
20531 push_rational(1, 3);
20532 power();
20533 } else if (equalq(exponent, 1, 2)) {
20534 push(A);
20535 push(SOLUTION);
20536 push_integer(2);
20537 power();
20538 push(C);
20539 add();
20540 divide();
20541 push_rational(1, 2);
20542 power();
20543 }
20544 lowercase_b = pop();
20545 if (lowercase_b == null) {
20546 push(p1);
20547 restore();
20548 return false;
20549 }
20550 push(lowercase_b);
20551 push(SOLUTION);
20552 multiply();
20553 if (equalq(exponent, 1, 3)) {
20554 lowercase_a = pop();
20555 push(lowercase_b);
20556 push(C);
20557 push_rational(1, 2);
20558 power();
20559 multiply();
20560 push(lowercase_a);
20561 add();
20562 simplify();
20563 } else if (equalq(exponent, 1, 2)) {
20564 lowercase_a = pop();
20565 push(lowercase_b);
20566 push(C);
20567 push_rational(1, 2);
20568 power();
20569 multiply();
20570 push(lowercase_a);
20571 add();
20572 simplify();
20573 possibleNewExpression = pop();
20574 push(possibleNewExpression);
20575 real();
20576 yyfloat();
20577 possibleNewExpressionValue = pop();
20578 if (!isnegativenumber(possibleNewExpressionValue)) {
20579 push(possibleNewExpression);
20580 } else {
20581 push(lowercase_b);
20582 negate();
20583 lowercase_b = pop();
20584 push(lowercase_a);
20585 negate();
20586 lowercase_a = pop();
20587 push(lowercase_b);
20588 push(C);
20589 push_rational(1, 2);
20590 power();
20591 multiply();
20592 push(lowercase_a);
20593 add();
20594 simplify();
20595 }
20596 }
20597 p1 = pop();
20598 push(p1);
20599 restore();
20600 return true;
20601 } else {
20602 push(p1);
20603 restore();
20604 return false;
20605 }
20606 } else if (iscons(p1)) {
20607 h = tos;
20608 anyRadicalSimplificationWorked = false;
20609 while (iscons(p1)) {
20610 push(car(p1));
20611 anyRadicalSimplificationWorked = anyRadicalSimplificationWorked || take_care_of_nested_radicals();
20612 p1 = cdr(p1);
20613 }
20614 list(tos - h);
20615 restore();
20616 return anyRadicalSimplificationWorked;
20617 } else {
20618 push(p1);
20619 restore();
20620 return false;
20621 }
20622 throw new Error("control flow should never reach here");
20623 };
20624
20625 Eval_sin = function() {
20626 push(cadr(p1));
20627 Eval();
20628 return sine();
20629 };
20630
20631 sine = function() {
20632 save();
20633 p1 = pop();
20634 if (car(p1) === symbol(ADD)) {
20635 sine_of_angle_sum();
20636 } else {
20637 sine_of_angle();
20638 }
20639 return restore();
20640 };
20641
20642 sine_of_angle_sum = function() {
20643 p2 = cdr(p1);
20644 while (iscons(p2)) {
20645 p4 = car(p2);
20646 if (isnpi(p4)) {
20647 push(p1);
20648 push(p4);
20649 subtract();
20650 p3 = pop();
20651 push(p3);
20652 sine();
20653 push(p4);
20654 cosine();
20655 multiply();
20656 push(p3);
20657 cosine();
20658 push(p4);
20659 sine();
20660 multiply();
20661 add();
20662 return;
20663 }
20664 p2 = cdr(p2);
20665 }
20666 return sine_of_angle();
20667 };
20668
20669 sine_of_angle = function() {
20670 var d, n;
20671 if (car(p1) === symbol(ARCSIN)) {
20672 push(cadr(p1));
20673 return;
20674 }
20675 if (isdouble(p1)) {
20676 d = Math.sin(p1.d);
20677 if (Math.abs(d) < 1e-10) {
20678 d = 0.0;
20679 }
20680 push_double(d);
20681 return;
20682 }
20683 if (isnegative(p1)) {
20684 push(p1);
20685 negate();
20686 sine();
20687 negate();
20688 return;
20689 }
20690 if (car(p1) === symbol(ARCTAN)) {
20691 push(cadr(p1));
20692 push_integer(1);
20693 push(cadr(p1));
20694 push_integer(2);
20695 power();
20696 add();
20697 push_rational(-1, 2);
20698 power();
20699 multiply();
20700 return;
20701 }
20702 push(p1);
20703 push_integer(180);
20704 multiply();
20705 if (evaluatingAsFloats) {
20706 push_double(Math.PI);
20707 } else {
20708 push_symbol(PI);
20709 }
20710 divide();
20711 n = pop_integer();
20712 if (n < 0 || isNaN(n)) {
20713 push(symbol(SIN));
20714 push(p1);
20715 list(2);
20716 return;
20717 }
20718 switch (n % 360) {
20719 case 0:
20720 case 180:
20721 return push_integer(0);
20722 case 30:
20723 case 150:
20724 return push_rational(1, 2);
20725 case 210:
20726 case 330:
20727 return push_rational(-1, 2);
20728 case 45:
20729 case 135:
20730 push_rational(1, 2);
20731 push_integer(2);
20732 push_rational(1, 2);
20733 power();
20734 return multiply();
20735 case 225:
20736 case 315:
20737 push_rational(-1, 2);
20738 push_integer(2);
20739 push_rational(1, 2);
20740 power();
20741 return multiply();
20742 case 60:
20743 case 120:
20744 push_rational(1, 2);
20745 push_integer(3);
20746 push_rational(1, 2);
20747 power();
20748 return multiply();
20749 case 240:
20750 case 300:
20751 push_rational(-1, 2);
20752 push_integer(3);
20753 push_rational(1, 2);
20754 power();
20755 return multiply();
20756 case 90:
20757 return push_integer(1);
20758 case 270:
20759 return push_integer(-1);
20760 default:
20761 push(symbol(SIN));
20762 push(p1);
20763 return list(2);
20764 }
20765 };
20766
20767 Eval_sinh = function() {
20768 push(cadr(p1));
20769 Eval();
20770 return ysinh();
20771 };
20772
20773 ysinh = function() {
20774 save();
20775 yysinh();
20776 return restore();
20777 };
20778
20779 yysinh = function() {
20780 var d;
20781 d = 0.0;
20782 p1 = pop();
20783 if (car(p1) === symbol(ARCSINH)) {
20784 push(cadr(p1));
20785 return;
20786 }
20787 if (isdouble(p1)) {
20788 d = Math.sinh(p1.d);
20789 if (Math.abs(d) < 1e-10) {
20790 d = 0.0;
20791 }
20792 push_double(d);
20793 return;
20794 }
20795 if (iszero(p1)) {
20796 push(zero);
20797 return;
20798 }
20799 push_symbol(SINH);
20800 push(p1);
20801 return list(2);
20802 };
20803
20804
20805 /*
20806 Substitute new expr for old expr in expr.
20807
20808 Input: push expr
20809
20810 push old expr
20811
20812 push new expr
20813
20814 Output: Result on stack
20815 */
20816
20817 subst = function() {
20818 var i, l1, m1, ref2, ref3;
20819 i = 0;
20820 save();
20821 p3 = pop();
20822 p2 = pop();
20823 if (p2 === symbol(NIL) || p3 === symbol(NIL)) {
20824 restore();
20825 return;
20826 }
20827 p1 = pop();
20828 if (istensor(p1)) {
20829 p4 = alloc_tensor(p1.tensor.nelem);
20830 p4.tensor.ndim = p1.tensor.ndim;
20831 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
20832 p4.tensor.dim[i] = p1.tensor.dim[i];
20833 }
20834 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
20835 push(p1.tensor.elem[i]);
20836 push(p2);
20837 push(p3);
20838 subst();
20839 p4.tensor.elem[i] = pop();
20840 check_tensor_dimensions(p4);
20841 }
20842 push(p4);
20843 } else if (equal(p1, p2)) {
20844 push(p3);
20845 } else if (iscons(p1)) {
20846 push(car(p1));
20847 push(p2);
20848 push(p3);
20849 subst();
20850 push(cdr(p1));
20851 push(p2);
20852 push(p3);
20853 subst();
20854 cons();
20855 } else {
20856 push(p1);
20857 }
20858 return restore();
20859 };
20860
20861 Eval_sum = function() {
20862 var body, i, indexVariable, j, k, l1, ref2, ref3;
20863 i = 0;
20864 j = 0;
20865 k = 0;
20866 body = cadr(p1);
20867 indexVariable = caddr(p1);
20868 if (!issymbol(p6)) {
20869 stop("sum: 1st arg?");
20870 }
20871 push(cadddr(p1));
20872 Eval();
20873 j = pop_integer();
20874 if (isNaN(j)) {
20875 push(p1);
20876 return;
20877 }
20878 push(caddddr(p1));
20879 Eval();
20880 k = pop_integer();
20881 if (isNaN(k)) {
20882 push(p1);
20883 return;
20884 }
20885 p4 = get_binding(indexVariable);
20886 push_integer(0);
20887 for (i = l1 = ref2 = j, ref3 = k; ref2 <= ref3 ? l1 <= ref3 : l1 >= ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
20888 push_integer(i);
20889 p5 = pop();
20890 set_binding(indexVariable, p5);
20891 push(body);
20892 Eval();
20893 add();
20894 }
20895 return set_binding(indexVariable, p4);
20896 };
20897
20898 Eval_tan = function() {
20899 push(cadr(p1));
20900 Eval();
20901 return tangent();
20902 };
20903
20904 tangent = function() {
20905 save();
20906 yytangent();
20907 return restore();
20908 };
20909
20910 yytangent = function() {
20911 var d, n;
20912 n = 0;
20913 d = 0.0;
20914 p1 = pop();
20915 if (car(p1) === symbol(ARCTAN)) {
20916 push(cadr(p1));
20917 return;
20918 }
20919 if (isdouble(p1)) {
20920 d = Math.tan(p1.d);
20921 if (Math.abs(d) < 1e-10) {
20922 d = 0.0;
20923 }
20924 push_double(d);
20925 return;
20926 }
20927 if (isnegative(p1)) {
20928 push(p1);
20929 negate();
20930 tangent();
20931 negate();
20932 return;
20933 }
20934 push(p1);
20935 push_integer(180);
20936 multiply();
20937 if (evaluatingAsFloats) {
20938 push_double(Math.PI);
20939 } else {
20940 push_symbol(PI);
20941 }
20942 divide();
20943 n = pop_integer();
20944 if (n < 0 || isNaN(n)) {
20945 push(symbol(TAN));
20946 push(p1);
20947 list(2);
20948 return;
20949 }
20950 switch (n % 360) {
20951 case 0:
20952 case 180:
20953 return push_integer(0);
20954 case 30:
20955 case 210:
20956 push_rational(1, 3);
20957 push_integer(3);
20958 push_rational(1, 2);
20959 power();
20960 return multiply();
20961 case 150:
20962 case 330:
20963 push_rational(-1, 3);
20964 push_integer(3);
20965 push_rational(1, 2);
20966 power();
20967 return multiply();
20968 case 45:
20969 case 225:
20970 return push_integer(1);
20971 case 135:
20972 case 315:
20973 return push_integer(-1);
20974 case 60:
20975 case 240:
20976 push_integer(3);
20977 push_rational(1, 2);
20978 return power();
20979 case 120:
20980 case 300:
20981 push_integer(3);
20982 push_rational(1, 2);
20983 power();
20984 return negate();
20985 default:
20986 push(symbol(TAN));
20987 push(p1);
20988 return list(2);
20989 }
20990 };
20991
20992 Eval_tanh = function() {
20993 var d;
20994 d = 0.0;
20995 push(cadr(p1));
20996 Eval();
20997 p1 = pop();
20998 if (car(p1) === symbol(ARCTANH)) {
20999 push(cadr(p1));
21000 return;
21001 }
21002 if (isdouble(p1)) {
21003 d = Math.tanh(p1.d);
21004 if (Math.abs(d) < 1e-10) {
21005 d = 0.0;
21006 }
21007 push_double(d);
21008 return;
21009 }
21010 if (iszero(p1)) {
21011 push(zero);
21012 return;
21013 }
21014 push_symbol(TANH);
21015 push(p1);
21016 return list(2);
21017 };
21018
21019
21020 /*
21021 Taylor expansion of a function
21022
21023 push(F)
21024 push(X)
21025 push(N)
21026 push(A)
21027 taylor()
21028 */
21029
21030 Eval_taylor = function() {
21031 p1 = cdr(p1);
21032 push(car(p1));
21033 Eval();
21034 p1 = cdr(p1);
21035 push(car(p1));
21036 Eval();
21037 p2 = pop();
21038 if (p2 === symbol(NIL)) {
21039 guess();
21040 } else {
21041 push(p2);
21042 }
21043 p1 = cdr(p1);
21044 push(car(p1));
21045 Eval();
21046 p2 = pop();
21047 if (p2 === symbol(NIL)) {
21048 push_integer(24);
21049 } else {
21050 push(p2);
21051 }
21052 p1 = cdr(p1);
21053 push(car(p1));
21054 Eval();
21055 p2 = pop();
21056 if (p2 === symbol(NIL)) {
21057 push_integer(0);
21058 } else {
21059 push(p2);
21060 }
21061 return taylor();
21062 };
21063
21064 taylor = function() {
21065 var i, k, l1, ref2;
21066 i = 0;
21067 k = 0;
21068 save();
21069 p4 = pop();
21070 p3 = pop();
21071 p2 = pop();
21072 p1 = pop();
21073 push(p3);
21074 k = pop_integer();
21075 if (isNaN(k)) {
21076 push_symbol(TAYLOR);
21077 push(p1);
21078 push(p2);
21079 push(p3);
21080 push(p4);
21081 list(5);
21082 restore();
21083 return;
21084 }
21085 push(p1);
21086 push(p2);
21087 push(p4);
21088 subst();
21089 Eval();
21090 push_integer(1);
21091 p5 = pop();
21092 for (i = l1 = 1, ref2 = k; 1 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 1 <= ref2 ? ++l1 : --l1) {
21093 push(p1);
21094 push(p2);
21095 derivative();
21096 p1 = pop();
21097 if (iszero(p1)) {
21098 break;
21099 }
21100 push(p5);
21101 push(p2);
21102 push(p4);
21103 subtract();
21104 multiply();
21105 p5 = pop();
21106 push(p1);
21107 push(p2);
21108 push(p4);
21109 subst();
21110 Eval();
21111 push(p5);
21112 multiply();
21113 push_integer(i);
21114 factorial();
21115 divide();
21116 add();
21117 }
21118 return restore();
21119 };
21120
21121
21122 /* tensor =====================================================================
21123
21124 Tags
21125 ----
21126 scripting, JS, internal, treenode, general concept
21127
21128 General description
21129 -------------------
21130 Tensors are a strange in-between of matrices and "computer"
21131 rectangular data structures.
21132
21133 Tensors, unlike matrices, and like rectangular data structures,
21134 can have an arbitrary number of dimensions (rank), although a tensor with
21135 rank zero is just a scalar.
21136
21137 Tensors, like matrices and unlike many computer rectangular data structures,
21138 must be "contiguous" i.e. have no empty spaces within its size, and "uniform",
21139 i.e. each element must have the same shape and hence the same rank.
21140
21141 Also tensors have necessarily to make a distinction between row vectors,
21142 column vectors (which have a rank of 2) and uni-dimensional vectors (rank 1).
21143 They look very similar but they are fundamentally different.
21144
21145 Tensors with elements that are also tensors get promoted to a higher rank
21146 , this is so we can represent and get the rank of a matrix correctly.
21147 Example:
21148 Start with a tensor of rank 1 with 2 elements (i.e. shape: 2)
21149 if you put in both its elements another 2 tensors
21150 of rank 1 with 2 elements (i.e. shape: 2)
21151 then the result is a tensor of rank 2 with shape 2,2
21152 i.e. the dimension of a tensor at all times must be
21153 the number of nested tensors in it.
21154 Also, all tensors must be "uniform" i.e. they must be accessed
21155 uniformly, which means that all existing elements of a tensor
21156 must be contiguous and have the same shape.
21157 Implication of it all is that you can't put arbitrary
21158 tensors inside tensors (like you would do to represent block matrices)
21159 Rather, all tensors inside tensors must have same shape (and hence, rank)
21160
21161 Limitations
21162 -----------
21163 n.a.
21164
21165 Implementation info
21166 -------------------
21167 Tensors are implemented...
21168 */
21169
21170 Eval_tensor = function() {
21171 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21172 i = 0;
21173 ndim = 0;
21174 nelem = 0;
21175 check_tensor_dimensions(p1);
21176 nelem = p1.tensor.nelem;
21177 ndim = p1.tensor.ndim;
21178 p2 = alloc_tensor(nelem);
21179 p2.tensor.ndim = ndim;
21180 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21181 p2.tensor.dim[i] = p1.tensor.dim[i];
21182 }
21183 a = p1.tensor.elem;
21184 b = p2.tensor.elem;
21185 check_tensor_dimensions(p2);
21186 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21187 push(a[i]);
21188 Eval();
21189 b[i] = pop();
21190 }
21191 check_tensor_dimensions(p1);
21192 check_tensor_dimensions(p2);
21193 push(p2);
21194 return promote_tensor();
21195 };
21196
21197 tensor_plus_tensor = function() {
21198 var a, b, c, i, l1, m1, n1, ndim, nelem, ref2, ref3, ref4;
21199 i = 0;
21200 ndim = 0;
21201 nelem = 0;
21202 save();
21203 p2 = pop();
21204 p1 = pop();
21205 ndim = p1.tensor.ndim;
21206 if (ndim !== p2.tensor.ndim) {
21207 push(symbol(NIL));
21208 restore();
21209 return;
21210 }
21211 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21212 if (p1.tensor.dim[i] !== p2.tensor.dim[i]) {
21213 push(symbol(NIL));
21214 restore();
21215 return;
21216 }
21217 }
21218 nelem = p1.tensor.nelem;
21219 p3 = alloc_tensor(nelem);
21220 p3.tensor.ndim = ndim;
21221 for (i = m1 = 0, ref3 = ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21222 p3.tensor.dim[i] = p1.tensor.dim[i];
21223 }
21224 a = p1.tensor.elem;
21225 b = p2.tensor.elem;
21226 c = p3.tensor.elem;
21227 for (i = n1 = 0, ref4 = nelem; 0 <= ref4 ? n1 < ref4 : n1 > ref4; i = 0 <= ref4 ? ++n1 : --n1) {
21228 push(a[i]);
21229 push(b[i]);
21230 add();
21231 c[i] = pop();
21232 }
21233 push(p3);
21234 return restore();
21235 };
21236
21237 tensor_times_scalar = function() {
21238 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21239 i = 0;
21240 ndim = 0;
21241 nelem = 0;
21242 save();
21243 p2 = pop();
21244 p1 = pop();
21245 ndim = p1.tensor.ndim;
21246 nelem = p1.tensor.nelem;
21247 p3 = alloc_tensor(nelem);
21248 p3.tensor.ndim = ndim;
21249 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21250 p3.tensor.dim[i] = p1.tensor.dim[i];
21251 }
21252 a = p1.tensor.elem;
21253 b = p3.tensor.elem;
21254 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21255 push(a[i]);
21256 push(p2);
21257 multiply();
21258 b[i] = pop();
21259 }
21260 push(p3);
21261 return restore();
21262 };
21263
21264 scalar_times_tensor = function() {
21265 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21266 i = 0;
21267 ndim = 0;
21268 nelem = 0;
21269 save();
21270 p2 = pop();
21271 p1 = pop();
21272 ndim = p2.tensor.ndim;
21273 nelem = p2.tensor.nelem;
21274 p3 = alloc_tensor(nelem);
21275 p3.tensor.ndim = ndim;
21276 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21277 p3.tensor.dim[i] = p2.tensor.dim[i];
21278 }
21279 a = p2.tensor.elem;
21280 b = p3.tensor.elem;
21281 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21282 push(p1);
21283 push(a[i]);
21284 multiply();
21285 b[i] = pop();
21286 }
21287 push(p3);
21288 return restore();
21289 };
21290
21291 check_tensor_dimensions = function(p) {
21292 if (p.tensor.nelem !== p.tensor.elem.length) {
21293 console.log("something wrong in tensor dimensions");
21294 debugger;
21295 }
21296 };
21297
21298 is_square_matrix = function(p) {
21299 if (istensor(p) && p.tensor.ndim === 2 && p.tensor.dim[0] === p.tensor.dim[1]) {
21300 return 1;
21301 } else {
21302 return 0;
21303 }
21304 };
21305
21306 d_tensor_tensor = function() {
21307 var a, b, c, i, j, l1, m1, n1, ndim, nelem, ref2, ref3, ref4;
21308 i = 0;
21309 j = 0;
21310 ndim = 0;
21311 nelem = 0;
21312 ndim = p1.tensor.ndim;
21313 nelem = p1.tensor.nelem;
21314 if (ndim + 1 >= MAXDIM) {
21315 push_symbol(DERIVATIVE);
21316 push(p1);
21317 push(p2);
21318 list(3);
21319 return;
21320 }
21321 p3 = alloc_tensor(nelem * p2.tensor.nelem);
21322 p3.tensor.ndim = ndim + 1;
21323 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21324 p3.tensor.dim[i] = p1.tensor.dim[i];
21325 }
21326 p3.tensor.dim[ndim] = p2.tensor.dim[0];
21327 a = p1.tensor.elem;
21328 b = p2.tensor.elem;
21329 c = p3.tensor.elem;
21330 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21331 for (j = n1 = 0, ref4 = p2.tensor.nelem; 0 <= ref4 ? n1 < ref4 : n1 > ref4; j = 0 <= ref4 ? ++n1 : --n1) {
21332 push(a[i]);
21333 push(b[j]);
21334 derivative();
21335 c[i * p2.tensor.nelem + j] = pop();
21336 }
21337 }
21338 return push(p3);
21339 };
21340
21341 d_scalar_tensor = function() {
21342 var a, b, i, l1, ref2;
21343 p3 = alloc_tensor(p2.tensor.nelem);
21344 p3.tensor.ndim = 1;
21345 p3.tensor.dim[0] = p2.tensor.dim[0];
21346 a = p2.tensor.elem;
21347 b = p3.tensor.elem;
21348 for (i = l1 = 0, ref2 = p2.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21349 push(p1);
21350 push(a[i]);
21351 derivative();
21352 b[i] = pop();
21353 }
21354 return push(p3);
21355 };
21356
21357 d_tensor_scalar = function() {
21358 var a, b, i, l1, m1, ref2, ref3;
21359 i = 0;
21360 p3 = alloc_tensor(p1.tensor.nelem);
21361 p3.tensor.ndim = p1.tensor.ndim;
21362 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21363 p3.tensor.dim[i] = p1.tensor.dim[i];
21364 }
21365 a = p1.tensor.elem;
21366 b = p3.tensor.elem;
21367 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21368 push(a[i]);
21369 push(p2);
21370 derivative();
21371 b[i] = pop();
21372 }
21373 return push(p3);
21374 };
21375
21376 compare_tensors = function(p1, p2) {
21377 var i, l1, m1, ref2, ref3;
21378 i = 0;
21379 if (p1.tensor.ndim < p2.tensor.ndim) {
21380 return -1;
21381 }
21382 if (p1.tensor.ndim > p2.tensor.ndim) {
21383 return 1;
21384 }
21385 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21386 if (p1.tensor.dim[i] < p2.tensor.dim[i]) {
21387 return -1;
21388 }
21389 if (p1.tensor.dim[i] > p2.tensor.dim[i]) {
21390 return 1;
21391 }
21392 }
21393 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21394 if (equal(p1.tensor.elem[i], p2.tensor.elem[i])) {
21395 continue;
21396 }
21397 if (lessp(p1.tensor.elem[i], p2.tensor.elem[i])) {
21398 return -1;
21399 } else {
21400 return 1;
21401 }
21402 }
21403 return 0;
21404 };
21405
21406 power_tensor = function() {
21407 var i, k, l1, m1, n, ref2, ref3, results;
21408 i = 0;
21409 k = 0;
21410 n = 0;
21411 k = p1.tensor.ndim - 1;
21412 if (p1.tensor.dim[0] !== p1.tensor.dim[k]) {
21413 push_symbol(POWER);
21414 push(p1);
21415 push(p2);
21416 list(3);
21417 return;
21418 }
21419 push(p2);
21420 n = pop_integer();
21421 if (isNaN(n)) {
21422 push_symbol(POWER);
21423 push(p1);
21424 push(p2);
21425 list(3);
21426 return;
21427 }
21428 if (n === 0) {
21429 if (p1.tensor.ndim !== 2) {
21430 stop("power(tensor,0) with tensor rank not equal to 2");
21431 }
21432 n = p1.tensor.dim[0];
21433 p1 = alloc_tensor(n * n);
21434 p1.tensor.ndim = 2;
21435 p1.tensor.dim[0] = n;
21436 p1.tensor.dim[1] = n;
21437 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21438 p1.tensor.elem[n * i + i] = one;
21439 }
21440 check_tensor_dimensions(p1);
21441 push(p1);
21442 return;
21443 }
21444 if (n < 0) {
21445 n = -n;
21446 push(p1);
21447 inv();
21448 p1 = pop();
21449 }
21450 push(p1);
21451 results = [];
21452 for (i = m1 = 1, ref3 = n; 1 <= ref3 ? m1 < ref3 : m1 > ref3; i = 1 <= ref3 ? ++m1 : --m1) {
21453 push(p1);
21454 inner();
21455 if (iszero(stack[tos - 1])) {
21456 break;
21457 } else {
21458 results.push(void 0);
21459 }
21460 }
21461 return results;
21462 };
21463
21464 copy_tensor = function() {
21465 var i, l1, m1, ref2, ref3;
21466 i = 0;
21467 save();
21468 p1 = pop();
21469 p2 = alloc_tensor(p1.tensor.nelem);
21470 p2.tensor.ndim = p1.tensor.ndim;
21471 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21472 p2.tensor.dim[i] = p1.tensor.dim[i];
21473 }
21474 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21475 p2.tensor.elem[i] = p1.tensor.elem[i];
21476 }
21477 check_tensor_dimensions(p1);
21478 check_tensor_dimensions(p2);
21479 push(p2);
21480 return restore();
21481 };
21482
21483 promote_tensor = function() {
21484 var i, j, k, l1, m1, n1, ndim, nelem, o1, q1, ref2, ref3, ref4, ref5, ref6;
21485 i = 0;
21486 j = 0;
21487 k = 0;
21488 nelem = 0;
21489 ndim = 0;
21490 save();
21491 p1 = pop();
21492 if (!istensor(p1)) {
21493 push(p1);
21494 restore();
21495 return;
21496 }
21497 p2 = p1.tensor.elem[0];
21498 for (i = l1 = 1, ref2 = p1.tensor.nelem; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
21499 if (!compatible(p2, p1.tensor.elem[i])) {
21500 stop("Cannot promote tensor due to inconsistent tensor components.");
21501 }
21502 }
21503 if (!istensor(p2)) {
21504 push(p1);
21505 restore();
21506 return;
21507 }
21508 ndim = p1.tensor.ndim + p2.tensor.ndim;
21509 if (ndim > MAXDIM) {
21510 stop("tensor rank > " + MAXDIM);
21511 }
21512 nelem = p1.tensor.nelem * p2.tensor.nelem;
21513 p3 = alloc_tensor(nelem);
21514 p3.tensor.ndim = ndim;
21515 for (i = m1 = 0, ref3 = p1.tensor.ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21516 p3.tensor.dim[i] = p1.tensor.dim[i];
21517 }
21518 for (j = n1 = 0, ref4 = p2.tensor.ndim; 0 <= ref4 ? n1 < ref4 : n1 > ref4; j = 0 <= ref4 ? ++n1 : --n1) {
21519 p3.tensor.dim[i + j] = p2.tensor.dim[j];
21520 }
21521 k = 0;
21522 for (i = o1 = 0, ref5 = p1.tensor.nelem; 0 <= ref5 ? o1 < ref5 : o1 > ref5; i = 0 <= ref5 ? ++o1 : --o1) {
21523 p2 = p1.tensor.elem[i];
21524 for (j = q1 = 0, ref6 = p2.tensor.nelem; 0 <= ref6 ? q1 < ref6 : q1 > ref6; j = 0 <= ref6 ? ++q1 : --q1) {
21525 p3.tensor.elem[k++] = p2.tensor.elem[j];
21526 }
21527 }
21528 check_tensor_dimensions(p2);
21529 check_tensor_dimensions(p3);
21530 push(p3);
21531 return restore();
21532 };
21533
21534 compatible = function(p, q) {
21535 var i, l1, ref2;
21536 if (!istensor(p) && !istensor(q)) {
21537 return 1;
21538 }
21539 if (!istensor(p) || !istensor(q)) {
21540 return 0;
21541 }
21542 if (p.tensor.ndim !== q.tensor.ndim) {
21543 return 0;
21544 }
21545 for (i = l1 = 0, ref2 = p.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21546 if (p.tensor.dim[i] !== q.tensor.dim[i]) {
21547 return 0;
21548 }
21549 }
21550 return 1;
21551 };
21552
21553 Eval_test = function() {
21554 var orig;
21555 orig = p1;
21556 p1 = cdr(p1);
21557 while (iscons(p1)) {
21558 if (cdr(p1) === symbol(NIL)) {
21559 push(car(p1));
21560 Eval();
21561 return;
21562 }
21563 push(car(p1));
21564 Eval_predicate();
21565 p2 = pop();
21566 if (isone(p2)) {
21567 push(cadr(p1));
21568 Eval();
21569 return;
21570 } else if (!iszero(p2)) {
21571 push(orig);
21572 return;
21573 }
21574 p1 = cddr(p1);
21575 }
21576 return push_integer(0);
21577 };
21578
21579 Eval_testeq = function() {
21580 var orig, subtractionResult;
21581 orig = p1;
21582 push(cadr(p1));
21583 Eval();
21584 push(caddr(p1));
21585 Eval();
21586 subtract();
21587 subtractionResult = pop();
21588 if (iszero(subtractionResult)) {
21589 p1 = subtractionResult;
21590 return push_integer(1);
21591 } else {
21592 push(cadr(p1));
21593 Eval();
21594 simplify();
21595 push(caddr(p1));
21596 Eval();
21597 simplify();
21598 subtract();
21599 p1 = pop();
21600 if (iszero(p1)) {
21601 return push_integer(1);
21602 } else {
21603 push(p1);
21604 yyfloat();
21605 p1 = pop();
21606 if (iszero(p1)) {
21607 return push_integer(1);
21608 } else if (isnum(p1)) {
21609 return push_integer(0);
21610 } else {
21611 return push(orig);
21612 }
21613 }
21614 }
21615 };
21616
21617 Eval_testge = function() {
21618 var comparison, orig;
21619 orig = p1;
21620 comparison = cmp_args();
21621 if (comparison == null) {
21622 push(orig);
21623 return;
21624 }
21625 if (comparison >= 0) {
21626 return push_integer(1);
21627 } else {
21628 return push_integer(0);
21629 }
21630 };
21631
21632 Eval_testgt = function() {
21633 var comparison, orig;
21634 orig = p1;
21635 comparison = cmp_args();
21636 if (comparison == null) {
21637 push(orig);
21638 return;
21639 }
21640 if (comparison > 0) {
21641 return push_integer(1);
21642 } else {
21643 return push_integer(0);
21644 }
21645 };
21646
21647 Eval_testle = function() {
21648 var comparison, orig;
21649 orig = p1;
21650 comparison = cmp_args();
21651 if (comparison == null) {
21652 push(orig);
21653 return;
21654 }
21655 if (comparison <= 0) {
21656 return push_integer(1);
21657 } else {
21658 return push_integer(0);
21659 }
21660 };
21661
21662 Eval_testlt = function() {
21663 var comparison, orig;
21664 orig = p1;
21665 comparison = cmp_args();
21666 if (comparison == null) {
21667 push(orig);
21668 return;
21669 }
21670 if (comparison < 0) {
21671 return push_integer(1);
21672 } else {
21673 return push_integer(0);
21674 }
21675 };
21676
21677 Eval_not = function() {
21678 push(cadr(p1));
21679 Eval_predicate();
21680 p1 = pop();
21681 if (iszero(p1)) {
21682 return push_integer(1);
21683 } else {
21684 return push_integer(0);
21685 }
21686 };
21687
21688
21689 /* and =====================================================================
21690
21691 Tags
21692 ----
21693 scripting, JS, internal, treenode, general concept
21694
21695 Parameters
21696 ----------
21697 a,b,...
21698
21699 General description
21700 -------------------
21701 Logical-and of predicate expressions.
21702 */
21703
21704 Eval_and = function() {
21705 p1 = cdr(p1);
21706 while (iscons(p1)) {
21707 push(car(p1));
21708 Eval_predicate();
21709 p2 = pop();
21710 if (iszero(p2)) {
21711 push_integer(0);
21712 return;
21713 }
21714 p1 = cdr(p1);
21715 }
21716 return push_integer(1);
21717 };
21718
21719 Eval_or = function() {
21720 p1 = cdr(p1);
21721 while (iscons(p1)) {
21722 push(car(p1));
21723 Eval_predicate();
21724 p2 = pop();
21725 if (!iszero(p2)) {
21726 push_integer(1);
21727 return;
21728 }
21729 p1 = cdr(p1);
21730 }
21731 return push_integer(0);
21732 };
21733
21734 cmp_args = function() {
21735 var t;
21736 t = 0;
21737 push(cadr(p1));
21738 Eval();
21739 simplify();
21740 push(caddr(p1));
21741 Eval();
21742 simplify();
21743 subtract();
21744 p1 = pop();
21745 if (p1.k !== NUM && p1.k !== DOUBLE) {
21746 push(p1);
21747 yyfloat();
21748 Eval();
21749 p1 = pop();
21750 }
21751 if (iszero(p1)) {
21752 return 0;
21753 }
21754 switch (p1.k) {
21755 case NUM:
21756 if (MSIGN(p1.q.a) === -1) {
21757 t = -1;
21758 } else {
21759 t = 1;
21760 }
21761 break;
21762 case DOUBLE:
21763 if (p1.d < 0.0) {
21764 t = -1;
21765 } else {
21766 t = 1;
21767 }
21768 break;
21769 default:
21770 t = null;
21771 }
21772 return t;
21773 };
21774
21775
21776 /*
21777 Transform an expression using a pattern. The
21778 pattern can come from the integrals table or
21779 the user-defined patterns.
21780
21781 The expression and free variable are on the stack.
21782
21783 The argument s is a null terminated list of transform rules.
21784
21785 For example, see the itab (integrals table)
21786
21787 Internally, the following symbols are used:
21788
21789 F input expression
21790
21791 X free variable, i.e. F of X
21792
21793 A template expression
21794
21795 B result expression
21796
21797 C list of conditional expressions
21798
21799 Puts the final expression on top of stack
21800 (whether it's transformed or not) and returns
21801 true is successful, false if not.
21802 */
21803
21804 transform = function(s, generalTransform) {
21805 var bookmarkTosToPrintDecomps, eachTransformEntry, i, l1, len, len1, m1, n1, numberOfDecomps, ref2, restTerm, secondTerm, success, theTransform, transform_h, transformationSuccessful, transformedTerms;
21806 transform_h = 0;
21807 save();
21808 p1 = null;
21809 p4 = pop();
21810 p3 = pop();
21811 if (DEBUG) {
21812 console.log(" !!!!!!!!! transform on: " + p3);
21813 }
21814 saveMetaBindings();
21815 set_binding(symbol(METAX), p4);
21816 transform_h = tos;
21817 push_integer(1);
21818 push(p3);
21819 push(p4);
21820 polyform();
21821 push(p4);
21822 bookmarkTosToPrintDecomps = tos - 2;
21823 decomp(generalTransform);
21824 numberOfDecomps = tos - bookmarkTosToPrintDecomps;
21825 if (DEBUG) {
21826 console.log(" " + numberOfDecomps + " decomposed elements ====== ");
21827 for (i = l1 = 0, ref2 = numberOfDecomps; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21828 console.log(" decomposition element " + i + ": " + stack[tos - 1 - i]);
21829 }
21830 }
21831 transformationSuccessful = false;
21832 if (generalTransform) {
21833 if (!isnum(p3)) {
21834 theTransform = s;
21835 if (DEBUG) {
21836 console.log("applying transform: " + theTransform);
21837 }
21838 if (DEBUG) {
21839 console.log("scanning table entry " + theTransform);
21840 }
21841 push(theTransform);
21842 push(symbol(SYMBOL_A_UNDERSCORE));
21843 push(symbol(METAA));
21844 subst();
21845 push(symbol(SYMBOL_B_UNDERSCORE));
21846 push(symbol(METAB));
21847 subst();
21848 push(symbol(SYMBOL_X_UNDERSCORE));
21849 push(symbol(METAX));
21850 subst();
21851 p1 = pop();
21852 p5 = car(p1);
21853 if (DEBUG) {
21854 console.log("template expression: " + p5);
21855 }
21856 p6 = cadr(p1);
21857 p7 = cddr(p1);
21858
21859 /*
21860 p5 = p1.tensor.elem[0]
21861 p6 = p1.tensor.elem[1]
21862 for i in [2..(p1.tensor.elem.length-1)]
21863 push p1.tensor.elem[i]
21864 list(p1.tensor.elem.length - 2)
21865 p7 = pop()
21866 */
21867 if (f_equals_a(transform_h, generalTransform)) {
21868 transformationSuccessful = true;
21869 } else {
21870 if (DEBUG) {
21871 console.log("p3 at this point: " + p3);
21872 }
21873 transformedTerms = [];
21874 if (DEBUG) {
21875 console.log("car(p3): " + car(p3));
21876 }
21877 restTerm = p3;
21878 if (iscons(restTerm)) {
21879 transformedTerms.push(car(p3));
21880 restTerm = cdr(p3);
21881 }
21882 while (iscons(restTerm)) {
21883 secondTerm = car(restTerm);
21884 restTerm = cdr(restTerm);
21885 if (DEBUG) {
21886 console.log("tos before recursive transform: " + tos);
21887 }
21888 push(secondTerm);
21889 push_symbol(NIL);
21890 if (DEBUG) {
21891 console.log("testing: " + secondTerm);
21892 }
21893 if (DEBUG) {
21894 console.log("about to try to simplify other term: " + secondTerm);
21895 }
21896 success = transform(s, generalTransform);
21897 transformationSuccessful = transformationSuccessful || success;
21898 transformedTerms.push(pop());
21899 if (DEBUG) {
21900 console.log("tried to simplify other term: " + secondTerm + " ...successful?: " + success + " ...transformed: " + transformedTerms[transformedTerms.length - 1]);
21901 }
21902 }
21903 if (transformedTerms.length !== 0) {
21904 for (m1 = 0, len = transformedTerms.length; m1 < len; m1++) {
21905 i = transformedTerms[m1];
21906 push(i);
21907 }
21908 list(transformedTerms.length);
21909 p6 = pop();
21910 }
21911 }
21912 }
21913 } else {
21914 for (n1 = 0, len1 = s.length; n1 < len1; n1++) {
21915 eachTransformEntry = s[n1];
21916 if (DEBUG) {
21917 console.log("scanning table entry " + eachTransformEntry);
21918 if ((eachTransformEntry + "").indexOf("f(sqrt(a+b*x),2/3*1/b*sqrt((a+b*x)^3))") !== -1) {
21919 debugger;
21920 }
21921 }
21922 if (eachTransformEntry) {
21923 scan_meta(eachTransformEntry);
21924 p1 = pop();
21925 p5 = cadr(p1);
21926 p6 = caddr(p1);
21927 p7 = cdddr(p1);
21928
21929 /*
21930 p5 = p1.tensor.elem[0]
21931 p6 = p1.tensor.elem[1]
21932 for i in [2..(p1.tensor.elem.length-1)]
21933 push p1.tensor.elem[i]
21934 list(p1.tensor.elem.length - 2)
21935 p7 = pop()
21936 */
21937 if (f_equals_a(transform_h, generalTransform)) {
21938 transformationSuccessful = true;
21939 break;
21940 }
21941 }
21942 }
21943 }
21944 moveTos(transform_h);
21945 if (transformationSuccessful) {
21946 push(p6);
21947 Eval();
21948 p1 = pop();
21949 transformationSuccessful = true;
21950 } else {
21951 if (generalTransform) {
21952 p1 = p3;
21953 } else {
21954 p1 = symbol(NIL);
21955 }
21956 }
21957 restoreMetaBindings();
21958 push(p1);
21959 restore();
21960 return transformationSuccessful;
21961 };
21962
21963 saveMetaBindings = function() {
21964 push(get_binding(symbol(METAA)));
21965 push(get_binding(symbol(METAB)));
21966 return push(get_binding(symbol(METAX)));
21967 };
21968
21969 restoreMetaBindings = function() {
21970 set_binding(symbol(METAX), pop());
21971 set_binding(symbol(METAB), pop());
21972 return set_binding(symbol(METAA), pop());
21973 };
21974
21975 f_equals_a = function(h, generalTransform) {
21976 var fea_i, fea_j, l1, m1, originalexpanding, ref2, ref3, ref4, ref5;
21977 fea_i = 0;
21978 fea_j = 0;
21979 for (fea_i = l1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; fea_i = ref2 <= ref3 ? ++l1 : --l1) {
21980 set_binding(symbol(METAA), stack[fea_i]);
21981 if (DEBUG) {
21982 console.log(" binding METAA to " + get_binding(symbol(METAA)));
21983 }
21984 for (fea_j = m1 = ref4 = h, ref5 = tos; ref4 <= ref5 ? m1 < ref5 : m1 > ref5; fea_j = ref4 <= ref5 ? ++m1 : --m1) {
21985 set_binding(symbol(METAB), stack[fea_j]);
21986 if (DEBUG) {
21987 console.log(" binding METAB to " + get_binding(symbol(METAB)));
21988 }
21989 p1 = p7;
21990 while (iscons(p1)) {
21991 push(car(p1));
21992 Eval();
21993 p2 = pop();
21994 if (iszero(p2)) {
21995 break;
21996 }
21997 p1 = cdr(p1);
21998 }
21999 if (iscons(p1)) {
22000 continue;
22001 }
22002 push(p3);
22003 if (DEBUG) {
22004 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)));
22005 }
22006 push(p5);
22007 if (generalTransform) {
22008 originalexpanding = expanding;
22009 expanding = false;
22010 }
22011 Eval();
22012 if (generalTransform) {
22013 expanding = originalexpanding;
22014 }
22015 if (DEBUG) {
22016 console.log(" comparing " + stack[tos - 1] + " to: " + stack[tos - 2]);
22017 }
22018 subtract();
22019 p1 = pop();
22020 if (iszero(p1)) {
22021 if (DEBUG) {
22022 console.log("binding METAA to " + get_binding(symbol(METAA)));
22023 console.log("binding METAB to " + get_binding(symbol(METAB)));
22024 console.log("binding METAX to " + get_binding(symbol(METAX)));
22025 console.log("comparing " + p3 + " to: " + p5);
22026 }
22027 return 1;
22028 }
22029 }
22030 }
22031 return 0;
22032 };
22033
22034 Eval_transpose = function() {
22035 push(cadr(p1));
22036 Eval();
22037 if (cddr(p1) === symbol(NIL)) {
22038 push_integer(1);
22039 push_integer(2);
22040 } else {
22041 push(caddr(p1));
22042 Eval();
22043 push(cadddr(p1));
22044 Eval();
22045 }
22046 return transpose();
22047 };
22048
22049 transpose = function() {
22050 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;
22051 i = 0;
22052 j = 0;
22053 k = 0;
22054 l = 0;
22055 m = 0;
22056 ndim = 0;
22057 nelem = 0;
22058 t = 0;
22059 ai = [];
22060 an = [];
22061 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22062 ai[i] = 0;
22063 an[i] = 0;
22064 }
22065 save();
22066 p3 = pop();
22067 p2 = pop();
22068 p1 = pop();
22069 if (isnum(p1)) {
22070 push(p1);
22071 restore();
22072 return;
22073 }
22074 if ((isplusone(p2) && isplustwo(p3)) || (isplusone(p3) && isplustwo(p2))) {
22075 if (isidentitymatrix(p1)) {
22076 push(p1);
22077 restore();
22078 return;
22079 }
22080 }
22081 if (istranspose(p1)) {
22082 innerTranspSwitch1 = car(cdr(cdr(p1)));
22083 innerTranspSwitch2 = car(cdr(cdr(cdr(p1))));
22084 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))))) {
22085 push(car(cdr(p1)));
22086 restore();
22087 return;
22088 }
22089 }
22090 if (expanding && isadd(p1)) {
22091 p1 = cdr(p1);
22092 push(zero);
22093 while (iscons(p1)) {
22094 push(car(p1));
22095 push(p2);
22096 push(p3);
22097 transpose();
22098 add();
22099 p1 = cdr(p1);
22100 }
22101 restore();
22102 return;
22103 }
22104 if (expanding && ismultiply(p1)) {
22105 p1 = cdr(p1);
22106 push(one);
22107 while (iscons(p1)) {
22108 push(car(p1));
22109 push(p2);
22110 push(p3);
22111 transpose();
22112 multiply();
22113 p1 = cdr(p1);
22114 }
22115 restore();
22116 return;
22117 }
22118 if (expanding && isinnerordot(p1)) {
22119 p1 = cdr(p1);
22120 accumulator = [];
22121 while (iscons(p1)) {
22122 accumulator.push([car(p1), p2, p3]);
22123 p1 = cdr(p1);
22124 }
22125 for (eachEntry = m1 = ref3 = accumulator.length - 1; ref3 <= 0 ? m1 <= 0 : m1 >= 0; eachEntry = ref3 <= 0 ? ++m1 : --m1) {
22126 push(accumulator[eachEntry][0]);
22127 push(accumulator[eachEntry][1]);
22128 push(accumulator[eachEntry][2]);
22129 transpose();
22130 if (eachEntry !== accumulator.length - 1) {
22131 inner();
22132 }
22133 }
22134 restore();
22135 return;
22136 }
22137 if (!istensor(p1)) {
22138 if (!iszero(p1)) {
22139 push_symbol(TRANSPOSE);
22140 push(p1);
22141 if ((!isplusone(p2) || !isplustwo(p3)) && (!isplusone(p3) || !isplustwo(p2))) {
22142 push(p2);
22143 push(p3);
22144 list(4);
22145 } else {
22146 list(2);
22147 }
22148 restore();
22149 return;
22150 }
22151 push(zero);
22152 restore();
22153 return;
22154 }
22155 ndim = p1.tensor.ndim;
22156 nelem = p1.tensor.nelem;
22157 if (ndim === 1) {
22158 push(p1);
22159 restore();
22160 return;
22161 }
22162 push(p2);
22163 l = pop_integer();
22164 push(p3);
22165 m = pop_integer();
22166 if (l < 1 || l > ndim || m < 1 || m > ndim) {
22167 stop("transpose: index out of range");
22168 }
22169 l--;
22170 m--;
22171 p2 = alloc_tensor(nelem);
22172 p2.tensor.ndim = ndim;
22173 for (i = n1 = 0, ref4 = ndim; 0 <= ref4 ? n1 < ref4 : n1 > ref4; i = 0 <= ref4 ? ++n1 : --n1) {
22174 p2.tensor.dim[i] = p1.tensor.dim[i];
22175 }
22176 p2.tensor.dim[l] = p1.tensor.dim[m];
22177 p2.tensor.dim[m] = p1.tensor.dim[l];
22178 a = p1.tensor.elem;
22179 b = p2.tensor.elem;
22180 for (i = o1 = 0, ref5 = ndim; 0 <= ref5 ? o1 < ref5 : o1 > ref5; i = 0 <= ref5 ? ++o1 : --o1) {
22181 ai[i] = 0;
22182 an[i] = p1.tensor.dim[i];
22183 }
22184 for (i = q1 = 0, ref6 = nelem; 0 <= ref6 ? q1 < ref6 : q1 > ref6; i = 0 <= ref6 ? ++q1 : --q1) {
22185 t = ai[l];
22186 ai[l] = ai[m];
22187 ai[m] = t;
22188 t = an[l];
22189 an[l] = an[m];
22190 an[m] = t;
22191 k = 0;
22192 for (j = r1 = 0, ref7 = ndim; 0 <= ref7 ? r1 < ref7 : r1 > ref7; j = 0 <= ref7 ? ++r1 : --r1) {
22193 k = (k * an[j]) + ai[j];
22194 }
22195 t = ai[l];
22196 ai[l] = ai[m];
22197 ai[m] = t;
22198 t = an[l];
22199 an[l] = an[m];
22200 an[m] = t;
22201 b[k] = a[i];
22202 for (j = s1 = ref8 = ndim - 1; ref8 <= 0 ? s1 <= 0 : s1 >= 0; j = ref8 <= 0 ? ++s1 : --s1) {
22203 if (++ai[j] < an[j]) {
22204 break;
22205 }
22206 ai[j] = 0;
22207 }
22208 }
22209 push(p2);
22210 return restore();
22211 };
22212
22213
22214 /* d =====================================================================
22215
22216 Tags
22217 ----
22218 scripting, JS, internal, treenode, general concept
22219
22220 Parameters
22221 ----------
22222 f,x
22223
22224 General description
22225 -------------------
22226 Returns the partial derivative of f with respect to x. x can be a vector e.g. [x,y].
22227 */
22228
22229 Eval_user_function = function() {
22230 var bodyAndFormalArguments, h;
22231 if (DEBUG) {
22232 console.log("Eval_user_function evaluating: " + car(p1));
22233 }
22234 if (car(p1) === symbol(SYMBOL_D) && get_binding(symbol(SYMBOL_D)) === symbol(SYMBOL_D)) {
22235 Eval_derivative();
22236 return;
22237 }
22238 push(car(p1));
22239 Eval();
22240 bodyAndFormalArguments = pop();
22241 p3 = car(cdr(bodyAndFormalArguments));
22242 p4 = car(cdr(cdr(bodyAndFormalArguments)));
22243 p5 = cdr(p1);
22244 if (bodyAndFormalArguments === car(p1)) {
22245 h = tos;
22246 push(bodyAndFormalArguments);
22247 p1 = p5;
22248 while (iscons(p1)) {
22249 push(car(p1));
22250 Eval();
22251 p1 = cdr(p1);
22252 }
22253 list(tos - h);
22254 return;
22255 }
22256 p1 = p4;
22257 p2 = p5;
22258 h = tos;
22259 while (iscons(p1) && iscons(p2)) {
22260 push(car(p1));
22261 push(car(p2));
22262 p1 = cdr(p1);
22263 p2 = cdr(p2);
22264 }
22265 list(tos - h);
22266 p6 = pop();
22267 push(p3);
22268 if (iscons(p6)) {
22269 push(p6);
22270 rewrite_args();
22271 }
22272 return Eval();
22273 };
22274
22275 rewrite_args = function() {
22276 var h, n;
22277 n = 0;
22278 save();
22279 p2 = pop();
22280 p1 = pop();
22281 if (istensor(p1)) {
22282 n = rewrite_args_tensor();
22283 restore();
22284 return n;
22285 }
22286 if (iscons(p1)) {
22287 h = tos;
22288 if (car(p1) === car(p2)) {
22289 push_symbol(EVAL);
22290 push(car(cdr(p2)));
22291 list(2);
22292 } else {
22293 push(car(p1));
22294 }
22295 p1 = cdr(p1);
22296 while (iscons(p1)) {
22297 push(car(p1));
22298 push(p2);
22299 n += rewrite_args();
22300 p1 = cdr(p1);
22301 }
22302 list(tos - h);
22303 restore();
22304 return n;
22305 }
22306 if (!issymbol(p1)) {
22307 push(p1);
22308 restore();
22309 return 0;
22310 }
22311 p3 = p2;
22312 while (iscons(p3)) {
22313 if (p1 === car(p3)) {
22314 push(cadr(p3));
22315 restore();
22316 return 1;
22317 }
22318 p3 = cddr(p3);
22319 }
22320 p3 = get_binding(p1);
22321 push(p3);
22322 if (p1 !== p3) {
22323 push(p2);
22324 n = rewrite_args();
22325 if (n === 0) {
22326 pop();
22327 push(p1);
22328 }
22329 }
22330 restore();
22331 return n;
22332 };
22333
22334 rewrite_args_tensor = function() {
22335 var i, l1, n, ref2;
22336 n = 0;
22337 i = 0;
22338 push(p1);
22339 copy_tensor();
22340 p1 = pop();
22341 for (i = l1 = 0, ref2 = p1.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22342 push(p1.tensor.elem[i]);
22343 push(p2);
22344 n += rewrite_args();
22345 p1.tensor.elem[i] = pop();
22346 }
22347 check_tensor_dimensions(p1);
22348 push(p1);
22349 return n;
22350 };
22351
22352 Eval_zero = function() {
22353 var i, k, l1, m, m1, n, ref2, ref3;
22354 i = 0;
22355 k = [];
22356 m = 0;
22357 n = 0;
22358 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22359 k[i] = 0;
22360 }
22361 m = 1;
22362 n = 0;
22363 p2 = cdr(p1);
22364 while (iscons(p2)) {
22365 push(car(p2));
22366 Eval();
22367 i = pop_integer();
22368 if (i < 1 || isNaN(i)) {
22369 push(zero);
22370 return;
22371 }
22372 m *= i;
22373 k[n++] = i;
22374 p2 = cdr(p2);
22375 }
22376 if (n === 0) {
22377 push(zero);
22378 return;
22379 }
22380 p1 = alloc_tensor(m);
22381 p1.tensor.ndim = n;
22382 for (i = m1 = 0, ref3 = n; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
22383 p1.tensor.dim[i] = k[i];
22384 }
22385 return push(p1);
22386 };
22387
22388
22389 /*
22390 // up to 100 blocks of 100,000 atoms
22391
22392 #define M 100
22393 #define N 100000
22394
22395 U *mem[M]
22396 int mcount
22397
22398 U *free_list
22399 int free_count
22400
22401 U *
22402 alloc(void)
22403 {
22404 U *p
22405 if (free_count == 0) {
22406 if (mcount == 0)
22407 alloc_mem()
22408 else {
22409 gc()
22410 if (free_count < N * mcount / 2)
22411 alloc_mem()
22412 }
22413 if (free_count == 0)
22414 stop("atom space exhausted")
22415 }
22416 p = free_list
22417 free_list = free_list->u.cons.cdr
22418 free_count--
22419 return p
22420 }
22421 */
22422
22423 allocatedId = 0;
22424
22425 alloc_tensor = function(nelem) {
22426 var i, l1, p, ref2;
22427 i = 0;
22428 p = new U();
22429 p.k = TENSOR;
22430 p.tensor = new tensor();
22431 p.tensor.nelem = nelem;
22432 for (i = l1 = 0, ref2 = nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22433 p.tensor.elem[i] = zero;
22434 }
22435 p.tensor.allocatedId = allocatedId;
22436 allocatedId++;
22437 check_tensor_dimensions(p);
22438 return p;
22439 };
22440
22441
22442 /*
22443 // garbage collector
22444
22445 void
22446 gc(void)
22447 {
22448 int i, j
22449 U *p
22450
22451 // tag everything
22452
22453 for (i = 0; i < mcount; i++) {
22454 p = mem[i]
22455 for (j = 0; j < N; j++)
22456 p[j].tag = 1
22457 }
22458
22459 // untag what's used
22460
22461 untag(p0)
22462 untag(p1)
22463 untag(p2)
22464 untag(p3)
22465 untag(p4)
22466 untag(p5)
22467 untag(p6)
22468 untag(p7)
22469 untag(p8)
22470 untag(p9)
22471
22472 untag(one)
22473 untag(zero)
22474 untag(imaginaryunit)
22475
22476 for (i = 0; i < NSYM; i++) {
22477 untag(binding[i])
22478 untag(arglist[i])
22479 }
22480
22481 for (i = 0; i < tos; i++)
22482 untag(stack[i])
22483
22484 for (i = (int) (frame - stack); i < TOS; i++)
22485 untag(stack[i])
22486
22487 // collect everything that's still tagged
22488
22489 free_count = 0
22490
22491 for (i = 0; i < mcount; i++) {
22492 p = mem[i]
22493 for (j = 0; j < N; j++) {
22494 if (p[j].tag == 0)
22495 continue
22496 // still tagged so it's unused, put on free list
22497 switch (p[j].k) {
22498 case TENSOR:
22499 free(p[j].u.tensor)
22500 break
22501 case STR:
22502 free(p[j].u.str)
22503 break
22504 case NUM:
22505 mfree(p[j].u.q.a)
22506 mfree(p[j].u.q.b)
22507 break
22508 }
22509 p[j].k = CONS; // so no double free occurs above
22510 p[j].u.cons.cdr = free_list
22511 free_list = p + j
22512 free_count++
22513 }
22514 }
22515 }
22516
22517 void
22518 untag(U *p)
22519 {
22520 int i
22521
22522 if (iscons(p)) {
22523 do {
22524 if (p->tag == 0)
22525 return
22526 p->tag = 0
22527 untag(p->u.cons.car)
22528 p = p->u.cons.cdr
22529 } while (iscons(p))
22530 untag(p)
22531 return
22532 }
22533
22534 if (p->tag) {
22535 p->tag = 0
22536 if (istensor(p)) {
22537 for (i = 0; i < p->u.tensor->nelem; i++)
22538 untag(p->u.tensor->elem[i])
22539 }
22540 }
22541 }
22542
22543 // get memory for 100,000 atoms
22544
22545 void
22546 alloc_mem(void)
22547 {
22548 int i
22549 U *p
22550 if (mcount == M)
22551 return
22552 p = (U *) malloc(N * sizeof (struct U))
22553 if (p == NULL)
22554 return
22555 mem[mcount++] = p
22556 for (i = 0; i < N; i++) {
22557 p[i].k = CONS; // so no free in gc
22558 p[i].u.cons.cdr = p + i + 1
22559 }
22560 p[N - 1].u.cons.cdr = free_list
22561 free_list = p
22562 free_count += N
22563 }
22564
22565 void
22566 print_mem_info(void)
22567 {
22568 char buf[100]
22569
22570 sprintf(buf, "%d blocks (%d bytes/block)\n", N * mcount, (int) sizeof (U))
22571 printstr(buf)
22572
22573 sprintf(buf, "%d free\n", free_count)
22574 printstr(buf)
22575
22576 sprintf(buf, "%d used\n", N * mcount - free_count)
22577 printstr(buf)
22578 }
22579 */
22580
22581 Find = function(p, q) {
22582 var i, l1, ref2;
22583 i = 0;
22584 if (equal(p, q)) {
22585 return 1;
22586 }
22587 if (istensor(p)) {
22588 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22589 if (Find(p.tensor.elem[i], q)) {
22590 return 1;
22591 }
22592 }
22593 return 0;
22594 }
22595 while (iscons(p)) {
22596 if (Find(car(p), q)) {
22597 return 1;
22598 }
22599 p = cdr(p);
22600 }
22601 return 0;
22602 };
22603
22604 findPossibleClockForm = function(p) {
22605 var i, l1, ref2;
22606 i = 0;
22607 if (isimaginaryunit(p)) {
22608 return 0;
22609 }
22610 if (car(p) === symbol(POWER) && !isinteger(caddr(p1))) {
22611 if (Find(cadr(p), imaginaryunit)) {
22612 return 1;
22613 }
22614 }
22615 if (car(p) === symbol(POWER) && equaln(cadr(p), -1) && !isinteger(caddr(p1))) {
22616 return 1;
22617 }
22618 if (istensor(p)) {
22619 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22620 if (findPossibleClockForm(p.tensor.elem[i])) {
22621 return 1;
22622 }
22623 }
22624 return 0;
22625 }
22626 while (iscons(p)) {
22627 if (findPossibleClockForm(car(p))) {
22628 return 1;
22629 }
22630 p = cdr(p);
22631 }
22632 return 0;
22633 };
22634
22635 findPossibleExponentialForm = function(p) {
22636 var i, l1, ref2;
22637 i = 0;
22638 if (car(p) === symbol(POWER) && cadr(p) === symbol(E)) {
22639 return Find(caddr(p), imaginaryunit);
22640 }
22641 if (istensor(p)) {
22642 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22643 if (findPossibleExponentialForm(p.tensor.elem[i])) {
22644 return 1;
22645 }
22646 }
22647 return 0;
22648 }
22649 while (iscons(p)) {
22650 if (findPossibleExponentialForm(car(p))) {
22651 return 1;
22652 }
22653 p = cdr(p);
22654 }
22655 return 0;
22656 };
22657
22658 $.Find = Find;
22659
22660 init = function() {
22661 var i, l1, ref2;
22662 i = 0;
22663 flag = 0;
22664 reset_after_error();
22665 chainOfUserSymbolsNotFunctionsBeingEvaluated = [];
22666 if (flag) {
22667 return;
22668 }
22669 flag = 1;
22670 for (i = l1 = 0, ref2 = NSYM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22671 symtab[i] = new U();
22672 symtab[i].k = SYM;
22673 binding[i] = symtab[i];
22674 isSymbolReclaimable[i] = false;
22675 }
22676 return defn();
22677 };
22678
22679
22680 /* cross =====================================================================
22681
22682 Tags
22683 ----
22684 scripting, JS, internal, treenode, general concept, script_defined
22685
22686 Parameters
22687 ----------
22688 u,v
22689
22690 General description
22691 -------------------
22692 Returns the cross product of vectors u and v.
22693 */
22694
22695
22696 /* curl =====================================================================
22697
22698 Tags
22699 ----
22700 scripting, JS, internal, treenode, general concept, script_defined
22701
22702 Parameters
22703 ----------
22704 u
22705
22706 General description
22707 -------------------
22708 Returns the curl of vector u.
22709 */
22710
22711 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)"];
22712
22713 defn = function() {
22714 var definitionOfInterest, defn_i, l1, originalCodeGen, ref2;
22715 p0 = symbol(NIL);
22716 p1 = symbol(NIL);
22717 p2 = symbol(NIL);
22718 p3 = symbol(NIL);
22719 p4 = symbol(NIL);
22720 p5 = symbol(NIL);
22721 p6 = symbol(NIL);
22722 p7 = symbol(NIL);
22723 p8 = symbol(NIL);
22724 p9 = symbol(NIL);
22725 std_symbol("abs", ABS);
22726 std_symbol("add", ADD);
22727 std_symbol("adj", ADJ);
22728 std_symbol("and", AND);
22729 std_symbol("approxratio", APPROXRATIO);
22730 std_symbol("arccos", ARCCOS);
22731 std_symbol("arccosh", ARCCOSH);
22732 std_symbol("arcsin", ARCSIN);
22733 std_symbol("arcsinh", ARCSINH);
22734 std_symbol("arctan", ARCTAN);
22735 std_symbol("arctanh", ARCTANH);
22736 std_symbol("arg", ARG);
22737 std_symbol("atomize", ATOMIZE);
22738 std_symbol("besselj", BESSELJ);
22739 std_symbol("bessely", BESSELY);
22740 std_symbol("binding", BINDING);
22741 std_symbol("binomial", BINOMIAL);
22742 std_symbol("ceiling", CEILING);
22743 std_symbol("check", CHECK);
22744 std_symbol("choose", CHOOSE);
22745 std_symbol("circexp", CIRCEXP);
22746 std_symbol("clear", CLEAR);
22747 std_symbol("clearall", CLEARALL);
22748 std_symbol("clearpatterns", CLEARPATTERNS);
22749 std_symbol("clock", CLOCK);
22750 std_symbol("coeff", COEFF);
22751 std_symbol("cofactor", COFACTOR);
22752 std_symbol("condense", CONDENSE);
22753 std_symbol("conj", CONJ);
22754 std_symbol("contract", CONTRACT);
22755 std_symbol("cos", COS);
22756 std_symbol("cosh", COSH);
22757 std_symbol("decomp", DECOMP);
22758 std_symbol("defint", DEFINT);
22759 std_symbol("deg", DEGREE);
22760 std_symbol("denominator", DENOMINATOR);
22761 std_symbol("det", DET);
22762 std_symbol("derivative", DERIVATIVE);
22763 std_symbol("dim", DIM);
22764 std_symbol("dirac", DIRAC);
22765 std_symbol("divisors", DIVISORS);
22766 std_symbol("do", DO);
22767 std_symbol("dot", DOT);
22768 std_symbol("draw", DRAW);
22769 std_symbol("dsolve", DSOLVE);
22770 std_symbol("erf", ERF);
22771 std_symbol("erfc", ERFC);
22772 std_symbol("eigen", EIGEN);
22773 std_symbol("eigenval", EIGENVAL);
22774 std_symbol("eigenvec", EIGENVEC);
22775 std_symbol("eval", EVAL);
22776 std_symbol("exp", EXP);
22777 std_symbol("expand", EXPAND);
22778 std_symbol("expcos", EXPCOS);
22779 std_symbol("expsin", EXPSIN);
22780 std_symbol("factor", FACTOR);
22781 std_symbol("factorial", FACTORIAL);
22782 std_symbol("factorpoly", FACTORPOLY);
22783 std_symbol("filter", FILTER);
22784 std_symbol("float", FLOATF);
22785 std_symbol("floor", FLOOR);
22786 std_symbol("for", FOR);
22787 std_symbol("function", FUNCTION);
22788 std_symbol("Gamma", GAMMA);
22789 std_symbol("gcd", GCD);
22790 std_symbol("hermite", HERMITE);
22791 std_symbol("hilbert", HILBERT);
22792 std_symbol("imag", IMAG);
22793 std_symbol("component", INDEX);
22794 std_symbol("inner", INNER);
22795 std_symbol("integral", INTEGRAL);
22796 std_symbol("inv", INV);
22797 std_symbol("invg", INVG);
22798 std_symbol("isinteger", ISINTEGER);
22799 std_symbol("isprime", ISPRIME);
22800 std_symbol("laguerre", LAGUERRE);
22801 std_symbol("lcm", LCM);
22802 std_symbol("leading", LEADING);
22803 std_symbol("legendre", LEGENDRE);
22804 std_symbol("log", LOG);
22805 std_symbol("lookup", LOOKUP);
22806 std_symbol("mod", MOD);
22807 std_symbol("multiply", MULTIPLY);
22808 std_symbol("not", NOT);
22809 std_symbol("nroots", NROOTS);
22810 std_symbol("number", NUMBER);
22811 std_symbol("numerator", NUMERATOR);
22812 std_symbol("operator", OPERATOR);
22813 std_symbol("or", OR);
22814 std_symbol("outer", OUTER);
22815 std_symbol("pattern", PATTERN);
22816 std_symbol("patternsinfo", PATTERNSINFO);
22817 std_symbol("polar", POLAR);
22818 std_symbol("power", POWER);
22819 std_symbol("prime", PRIME);
22820 std_symbol("print", PRINT);
22821 std_symbol("print2dascii", PRINT2DASCII);
22822 std_symbol("printfull", PRINTFULL);
22823 std_symbol("printlatex", PRINTLATEX);
22824 std_symbol("printlist", PRINTLIST);
22825 std_symbol("printplain", PRINTPLAIN);
22826 std_symbol("printLeaveEAlone", PRINT_LEAVE_E_ALONE);
22827 std_symbol("printLeaveXAlone", PRINT_LEAVE_X_ALONE);
22828 std_symbol("product", PRODUCT);
22829 std_symbol("quote", QUOTE);
22830 std_symbol("quotient", QUOTIENT);
22831 std_symbol("rank", RANK);
22832 std_symbol("rationalize", RATIONALIZE);
22833 std_symbol("real", REAL);
22834 std_symbol("rect", YYRECT);
22835 std_symbol("roots", ROOTS);
22836 std_symbol("round", ROUND);
22837 std_symbol("equals", SETQ);
22838 std_symbol("sgn", SGN);
22839 std_symbol("silentpattern", SILENTPATTERN);
22840 std_symbol("simplify", SIMPLIFY);
22841 std_symbol("sin", SIN);
22842 std_symbol("sinh", SINH);
22843 std_symbol("shape", SHAPE);
22844 std_symbol("sqrt", SQRT);
22845 std_symbol("stop", STOP);
22846 std_symbol("subst", SUBST);
22847 std_symbol("sum", SUM);
22848 std_symbol("symbolsinfo", SYMBOLSINFO);
22849 std_symbol("tan", TAN);
22850 std_symbol("tanh", TANH);
22851 std_symbol("taylor", TAYLOR);
22852 std_symbol("test", TEST);
22853 std_symbol("testeq", TESTEQ);
22854 std_symbol("testge", TESTGE);
22855 std_symbol("testgt", TESTGT);
22856 std_symbol("testle", TESTLE);
22857 std_symbol("testlt", TESTLT);
22858 std_symbol("transpose", TRANSPOSE);
22859 std_symbol("unit", UNIT);
22860 std_symbol("zero", ZERO);
22861 std_symbol("nil", NIL);
22862 std_symbol("autoexpand", AUTOEXPAND);
22863 std_symbol("bake", BAKE);
22864 std_symbol("assumeRealVariables", ASSUME_REAL_VARIABLES);
22865 std_symbol("last", LAST);
22866 std_symbol("lastprint", LAST_PRINT);
22867 std_symbol("last2dasciiprint", LAST_2DASCII_PRINT);
22868 std_symbol("lastfullprint", LAST_FULL_PRINT);
22869 std_symbol("lastlatexprint", LAST_LATEX_PRINT);
22870 std_symbol("lastlistprint", LAST_LIST_PRINT);
22871 std_symbol("lastplainprint", LAST_PLAIN_PRINT);
22872 std_symbol("trace", TRACE);
22873 std_symbol("~", YYE);
22874 std_symbol("$DRAWX", DRAWX);
22875 std_symbol("$METAA", METAA);
22876 std_symbol("$METAB", METAB);
22877 std_symbol("$METAX", METAX);
22878 std_symbol("$SECRETX", SECRETX);
22879 std_symbol("version", VERSION);
22880 std_symbol("pi", PI);
22881 std_symbol("a", SYMBOL_A);
22882 std_symbol("b", SYMBOL_B);
22883 std_symbol("c", SYMBOL_C);
22884 std_symbol("d", SYMBOL_D);
22885 std_symbol("i", SYMBOL_I);
22886 std_symbol("j", SYMBOL_J);
22887 std_symbol("n", SYMBOL_N);
22888 std_symbol("r", SYMBOL_R);
22889 std_symbol("s", SYMBOL_S);
22890 std_symbol("t", SYMBOL_T);
22891 std_symbol("x", SYMBOL_X);
22892 std_symbol("y", SYMBOL_Y);
22893 std_symbol("z", SYMBOL_Z);
22894 std_symbol("I", SYMBOL_IDENTITY_MATRIX);
22895 std_symbol("a_", SYMBOL_A_UNDERSCORE);
22896 std_symbol("b_", SYMBOL_B_UNDERSCORE);
22897 std_symbol("x_", SYMBOL_X_UNDERSCORE);
22898 std_symbol("$C1", C1);
22899 std_symbol("$C2", C2);
22900 std_symbol("$C3", C3);
22901 std_symbol("$C4", C4);
22902 std_symbol("$C5", C5);
22903 std_symbol("$C6", C6);
22904 defineSomeHandyConstants();
22905 originalCodeGen = codeGen;
22906 codeGen = false;
22907 for (defn_i = l1 = 0, ref2 = defn_str.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; defn_i = 0 <= ref2 ? ++l1 : --l1) {
22908 definitionOfInterest = defn_str[defn_i];
22909 scan(definitionOfInterest);
22910 if (DEBUG) {
22911 console.log("... evaling " + definitionOfInterest);
22912 console.log("top of stack:");
22913 console.log(print_list(stack[tos - 1]));
22914 }
22915 Eval();
22916 pop();
22917 }
22918 return codeGen = originalCodeGen;
22919 };
22920
22921 defineSomeHandyConstants = function() {
22922 push_integer(0);
22923 zero = pop();
22924 push_integer(1);
22925 one = pop();
22926 push_double(1.0);
22927 one_as_double = pop();
22928 push_symbol(POWER);
22929 if (DEBUG) {
22930 console.log(print_list(stack[tos - 1]));
22931 }
22932 push_integer(-1);
22933 if (DEBUG) {
22934 console.log(print_list(stack[tos - 1]));
22935 }
22936 push_rational(1, 2);
22937 if (DEBUG) {
22938 console.log(print_list(stack[tos - 1]));
22939 }
22940 list(3);
22941 if (DEBUG) {
22942 console.log(print_list(stack[tos - 1]));
22943 }
22944 return imaginaryunit = pop();
22945 };
22946
22947 mcmp = function(a, b) {
22948 return a.compare(b);
22949 };
22950
22951 mcmpint = function(a, n) {
22952 var b, t;
22953 b = bigInt(n);
22954 t = mcmp(a, b);
22955 return t;
22956 };
22957
22958
22959 /*
22960 #if SELFTEST
22961
22962 void
22963 test_mcmp(void)
22964 {
22965 int i, j, k
22966 unsigned int *x, *y
22967 logout("testing mcmp\n")
22968 for (i = -1000; i < 1000; i++) {
22969 x = mint(i)
22970 for (j = -1000; j < 1000; j++) {
22971 y = mint(j)
22972 k = mcmp(x, y)
22973 if (i == j && k != 0) {
22974 logout("failed\n")
22975 errout()
22976 }
22977 if (i < j && k != -1) {
22978 logout("failed\n")
22979 errout()
22980 }
22981 if (i > j && k != 1) {
22982 logout("failed\n")
22983 errout()
22984 }
22985 mfree(y)
22986 }
22987 mfree(x)
22988 }
22989 logout("ok\n")
22990 }
22991
22992 #endif
22993 */
22994
22995 strcmp = function(str1, str2) {
22996 if (str1 === str2) {
22997 return 0;
22998 } else if (str1 > str2) {
22999 return 1;
23000 } else {
23001 return -1;
23002 }
23003 };
23004
23005 doubleToReasonableString = function(d) {
23006 var stringRepresentation;
23007 if (codeGen) {
23008 return d + "";
23009 }
23010 stringRepresentation = "" + parseFloat(d.toPrecision(6));
23011 if (stringRepresentation.indexOf(".") === -1) {
23012 stringRepresentation += ".0";
23013 }
23014 return stringRepresentation;
23015 };
23016
23017 clear_term = function() {};
23018
23019 isspace = function(s) {
23020 if (s == null) {
23021 return false;
23022 }
23023 return s === ' ' || s === '\t' || s === '\n' || s === '\v' || s === '\f' || s === '\r';
23024 };
23025
23026 isdigit = function(str) {
23027 if (str == null) {
23028 return false;
23029 }
23030 return /^\d+$/.test(str);
23031 };
23032
23033 isalpha = function(str) {
23034 if (str == null) {
23035 return false;
23036 }
23037 return str.search(/[^A-Za-z]/) === -1;
23038 };
23039
23040 isalphaOrUnderscore = function(str) {
23041 if (str == null) {
23042 return false;
23043 }
23044 return str.search(/[^A-Za-z_]/) === -1;
23045 };
23046
23047 isunderscore = function(str) {
23048 if (str == null) {
23049 return false;
23050 }
23051 return str.search(/_/) === -1;
23052 };
23053
23054 isalnumorunderscore = function(str) {
23055 if (str == null) {
23056 return false;
23057 }
23058 return isalphaOrUnderscore(str) || isdigit(str);
23059 };
23060
23061 count = function(p) {
23062 var n;
23063 if (iscons(p)) {
23064 n = 0;
23065 while (iscons(p)) {
23066 n += count(car(p)) + 1;
23067 p = cdr(p);
23068 }
23069 } else {
23070 n = 1;
23071 }
23072 return n;
23073 };
23074
23075 countOccurrencesOfSymbol = function(needle, p) {
23076 var n;
23077 n = 0;
23078 if (iscons(p)) {
23079 while (iscons(p)) {
23080 n += countOccurrencesOfSymbol(needle, car(p));
23081 p = cdr(p);
23082 }
23083 } else {
23084 if (equal(needle, p)) {
23085 n = 1;
23086 }
23087 }
23088 return n;
23089 };
23090
23091 countsize = function(p) {
23092 var i, l1, n, ref2;
23093 n = 0;
23094 if (istensor(p)) {
23095 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
23096 n += p.tensor.elem[i];
23097 }
23098 } else if (iscons(p)) {
23099 while (iscons(p)) {
23100 n += count(car(p)) + 1;
23101 p = cdr(p);
23102 }
23103 } else {
23104 n = 1;
23105 }
23106 return n;
23107 };
23108
23109 stop = function(s) {
23110 var message;
23111 errorMessage += "Stop: ";
23112 errorMessage += s;
23113 message = errorMessage;
23114 errorMessage = '';
23115 moveTos(0);
23116 throw new Error(message);
23117 };
23118
23119 findDependenciesInScript = function(stringToBeParsed, dontGenerateCode) {
23120 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;
23121 if (DEBUG) {
23122 console.log("stringToBeParsed: " + stringToBeParsed);
23123 }
23124 timeStartFromAlgebra = new Date().getTime();
23125 if (CACHE_DEBUGS || CACHE_HITSMISS_DEBUGS || TIMING_DEBUGS) {
23126 console.log(" --------- findDependenciesInScript input: " + stringToBeParsed + " at: " + (new Date()));
23127 currentStateHash = getStateHash();
23128 console.log("state hash: " + currentStateHash);
23129 }
23130 inited = true;
23131 codeGen = true;
23132 symbolsDependencies = {};
23133 symbolsHavingReassignments = [];
23134 symbolsInExpressionsWithoutAssignments = [];
23135 patternHasBeenFound = false;
23136 indexOfPartRemainingToBeParsed = 0;
23137 allReturnedPlainStrings = "";
23138 allReturnedLatexStrings = "";
23139 n = 0;
23140 dependencyInfo = {
23141 affectsVariables: [],
23142 affectedBy: []
23143 };
23144 stringToBeRun = stringToBeParsed;
23145 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23146 currentStateHash = getStateHash();
23147 cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun + " - " + dontGenerateCode;
23148 if (CACHE_DEBUGS) {
23149 console.log("cached_findDependenciesInScript key: " + cacheKey);
23150 }
23151 possiblyCached = cached_findDependenciesInScript.get(cacheKey);
23152 if (possiblyCached != null) {
23153 if (CACHE_HITSMISS_DEBUGS) {
23154 console.log("cached_findDependenciesInScript hit on " + stringToBeRun);
23155 }
23156 unfreeze(possiblyCached);
23157 if (TIMING_DEBUGS) {
23158 totalTime = new Date().getTime() - timeStartFromAlgebra;
23159 console.log("findDependenciesInScript input: " + stringToBeRun + " time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length - 5] - totalTime) + "ms due to cache hit");
23160 }
23161 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]];
23162 } else {
23163 if (CACHE_HITSMISS_DEBUGS) {
23164 console.log("cached_findDependenciesInScript miss on: " + stringToBeRun);
23165 }
23166 if (TIMING_DEBUGS) {
23167 cacheMissPenalty = new Date().getTime() - timeStartFromAlgebra;
23168 }
23169 }
23170 }
23171 while (1) {
23172 try {
23173 errorMessage = "";
23174 check_stack();
23175 if (DEBUG) {
23176 console.log("findDependenciesInScript: scanning");
23177 }
23178 n = scan(stringToBeParsed.substring(indexOfPartRemainingToBeParsed));
23179 if (DEBUG) {
23180 console.log("scanned");
23181 }
23182 pop();
23183 check_stack();
23184 } catch (error1) {
23185 error = error1;
23186 if (PRINTOUTRESULT) {
23187 console.log(error);
23188 }
23189 errorMessage = error + "";
23190 reset_after_error();
23191 break;
23192 }
23193 if (n === 0) {
23194 break;
23195 }
23196 indexOfPartRemainingToBeParsed += n;
23197 }
23198 testableString = "";
23199 if (DEBUG) {
23200 console.log("all local dependencies ----------------");
23201 }
23202 testableString += "All local dependencies: ";
23203 for (key in symbolsDependencies) {
23204 value = symbolsDependencies[key];
23205 if (DEBUG) {
23206 console.log("variable " + key + " depends on: ");
23207 }
23208 dependencyInfo.affectsVariables.push(key);
23209 testableString += " variable " + key + " depends on: ";
23210 for (l1 = 0, len = value.length; l1 < len; l1++) {
23211 i = value[l1];
23212 if (DEBUG) {
23213 console.log(" " + i);
23214 }
23215 if (i[0] !== "'") {
23216 dependencyInfo.affectedBy.push(i);
23217 }
23218 testableString += i + ", ";
23219 }
23220 testableString += "; ";
23221 }
23222 testableString += ". ";
23223 if (DEBUG) {
23224 console.log("Symbols with reassignments ----------------");
23225 }
23226 testableString += "Symbols with reassignments: ";
23227 for (m1 = 0, len1 = symbolsHavingReassignments.length; m1 < len1; m1++) {
23228 key = symbolsHavingReassignments[m1];
23229 if (dependencyInfo.affectedBy.indexOf(key) === -1) {
23230 dependencyInfo.affectedBy.push(key);
23231 testableString += key + ", ";
23232 }
23233 }
23234 testableString += ". ";
23235 if (DEBUG) {
23236 console.log("Symbols in expressions without assignments ----------------");
23237 }
23238 testableString += "Symbols in expressions without assignments: ";
23239 for (n1 = 0, len2 = symbolsInExpressionsWithoutAssignments.length; n1 < len2; n1++) {
23240 key = symbolsInExpressionsWithoutAssignments[n1];
23241 if (dependencyInfo.affectedBy.indexOf(key) === -1) {
23242 dependencyInfo.affectedBy.push(key);
23243 testableString += key + ", ";
23244 }
23245 }
23246 testableString += ". ";
23247 dependencyInfo.affectedBy.push("PATTERN_DEPENDENCY");
23248 if (patternHasBeenFound) {
23249 dependencyInfo.affectsVariables.push("PATTERN_DEPENDENCY");
23250 testableString += " - PATTERN_DEPENDENCY inserted - ";
23251 }
23252 if (DEBUG) {
23253 console.log("All dependencies recursively ----------------");
23254 }
23255 testableString += "All dependencies recursively: ";
23256 scriptEvaluation = ["", ""];
23257 generatedCode = "";
23258 readableSummaryOfGeneratedCode = "";
23259 if (errorMessage === "" && !dontGenerateCode) {
23260 try {
23261 allReturnedPlainStrings = "";
23262 allReturnedLatexStrings = "";
23263 scriptEvaluation = run(stringToBeParsed, true);
23264 allReturnedPlainStrings = "";
23265 allReturnedLatexStrings = "";
23266 } catch (error1) {
23267 error = error1;
23268 if (PRINTOUTRESULT) {
23269 console.log(error);
23270 }
23271 errorMessage = error + "";
23272 init();
23273 }
23274 if (errorMessage === "") {
23275 for (key in symbolsDependencies) {
23276 codeGen = true;
23277 if (DEBUG) {
23278 console.log(" variable " + key + " is: " + get_binding(usr_symbol(key)).toString());
23279 }
23280 codeGen = false;
23281 if (DEBUG) {
23282 console.log(" variable " + key + " depends on: ");
23283 }
23284 testableString += " variable " + key + " depends on: ";
23285 recursedDependencies = [];
23286 variablesWithCycles = [];
23287 cyclesDescriptions = [];
23288 recursiveDependencies(key, recursedDependencies, [], variablesWithCycles, [], cyclesDescriptions);
23289 for (o1 = 0, len3 = variablesWithCycles.length; o1 < len3; o1++) {
23290 i = variablesWithCycles[o1];
23291 if (DEBUG) {
23292 console.log(" --> cycle through " + i);
23293 }
23294 }
23295 for (q1 = 0, len4 = recursedDependencies.length; q1 < len4; q1++) {
23296 i = recursedDependencies[q1];
23297 if (DEBUG) {
23298 console.log(" " + i);
23299 }
23300 testableString += i + ", ";
23301 }
23302 testableString += "; ";
23303 for (r1 = 0, len5 = cyclesDescriptions.length; r1 < len5; r1++) {
23304 i = cyclesDescriptions[r1];
23305 testableString += " " + i + ", ";
23306 }
23307 if (DEBUG) {
23308 console.log(" code generation:" + key + " is: " + get_binding(usr_symbol(key)).toString());
23309 }
23310 push(get_binding(usr_symbol(key)));
23311 replacementsFrom = [];
23312 replacementsTo = [];
23313 for (s1 = 0, len6 = recursedDependencies.length; s1 < len6; s1++) {
23314 eachDependency = recursedDependencies[s1];
23315 if (eachDependency[0] === "'") {
23316 deQuotedDep = eachDependency.substring(1);
23317 originalUserSymbol = usr_symbol(deQuotedDep);
23318 newUserSymbol = usr_symbol("AVOID_BINDING_TO_EXTERNAL_SCOPE_VALUE" + deQuotedDep);
23319 replacementsFrom.push(originalUserSymbol);
23320 replacementsTo.push(newUserSymbol);
23321 push(originalUserSymbol);
23322 push(newUserSymbol);
23323 subst();
23324 if (DEBUG) {
23325 console.log("after substitution: " + stack[tos - 1]);
23326 }
23327 }
23328 }
23329 try {
23330 simplifyForCodeGeneration();
23331 } catch (error1) {
23332 error = error1;
23333 if (PRINTOUTRESULT) {
23334 console.log(error);
23335 }
23336 errorMessage = error + "";
23337 init();
23338 }
23339 for (indexOfEachReplacement = t1 = 0, ref2 = replacementsFrom.length; 0 <= ref2 ? t1 < ref2 : t1 > ref2; indexOfEachReplacement = 0 <= ref2 ? ++t1 : --t1) {
23340 push(replacementsTo[indexOfEachReplacement]);
23341 push(replacementsFrom[indexOfEachReplacement]);
23342 subst();
23343 }
23344 clearRenamedVariablesToAvoidBindingToExternalScope();
23345 if (errorMessage === "") {
23346 toBePrinted = pop();
23347 userVariablesMentioned = [];
23348 collectUserSymbols(toBePrinted, userVariablesMentioned);
23349 allReturnedPlainStrings = "";
23350 allReturnedLatexStrings = "";
23351 codeGen = true;
23352 generatedBody = toBePrinted.toString();
23353 codeGen = false;
23354 origPrintMode = printMode;
23355 printMode = PRINTMODE_LATEX;
23356 bodyForReadableSummaryOfGeneratedCode = toBePrinted.toString();
23357 printMode = origPrintMode;
23358 if (variablesWithCycles.indexOf(key) !== -1) {
23359 generatedCode += "// " + key + " is part of a cyclic dependency, no code generated.";
23360 readableSummaryOfGeneratedCode += "#" + key + " is part of a cyclic dependency, no code generated.";
23361 } else {
23362
23363 /*
23364 * using this paragraph instead of the following one
23365 * creates methods signatures that
23366 * are slightly less efficient
23367 * i.e. variables compare even if they are
23368 * simplified away.
23369 * In theory these signatures are more stable, but
23370 * in practice signatures vary quite a bit anyways
23371 * depending on previous assignments for example,
23372 * so it's unclear whether going for stability
23373 * is sensible at all..
23374 if recursedDependencies.length != 0
23375 parameters = "("
23376 for i in recursedDependencies
23377 if i.indexOf("'") != 0
23378 parameters += i + ", "
23379 else
23380 if recursedDependencies.indexOf(i.substring(1)) == -1
23381 parameters += i.substring(1) + ", "
23382 */
23383 userVariablesMentioned = userVariablesMentioned.filter(function(x) {
23384 return predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(x + "") === -1;
23385 });
23386 userVariablesMentioned = userVariablesMentioned.filter(function(x) {
23387 return recursedDependencies.indexOf(x + "") !== -1 || recursedDependencies.indexOf("\'" + x + "") !== -1;
23388 });
23389 if (userVariablesMentioned.length !== 0) {
23390 parameters = "(";
23391 for (u1 = 0, len7 = userVariablesMentioned.length; u1 < len7; u1++) {
23392 i = userVariablesMentioned[u1];
23393 if (i.printname !== key) {
23394 parameters += i.printname + ", ";
23395 }
23396 }
23397 parameters = parameters.replace(/, $/gm, "");
23398 parameters += ")";
23399 generatedCode += key + " = function " + parameters + " { return ( " + generatedBody + " ); }";
23400 readableSummaryOfGeneratedCode += key + parameters + " = " + bodyForReadableSummaryOfGeneratedCode;
23401 } else {
23402 generatedCode += key + " = " + generatedBody + ";";
23403 readableSummaryOfGeneratedCode += key + " = " + bodyForReadableSummaryOfGeneratedCode;
23404 }
23405 }
23406 generatedCode += "\n";
23407 readableSummaryOfGeneratedCode += "\n";
23408 if (DEBUG) {
23409 console.log(" " + generatedCode);
23410 }
23411 }
23412 }
23413 }
23414 }
23415 generatedCode = generatedCode.replace(/\n$/gm, "");
23416 readableSummaryOfGeneratedCode = readableSummaryOfGeneratedCode.replace(/\n$/gm, "");
23417 symbolsDependencies = {};
23418 symbolsHavingReassignments = [];
23419 patternHasBeenFound = false;
23420 symbolsInExpressionsWithoutAssignments = [];
23421 if (DEBUG) {
23422 console.log("testable string: " + testableString);
23423 }
23424 if (TIMING_DEBUGS) {
23425 console.log("findDependenciesInScript time for: " + stringToBeRun + " : " + ((new Date().getTime()) - timeStartFromAlgebra) + "ms");
23426 }
23427 if (ENABLE_CACHING && stringToBeRun !== "clearall" && errorMessage === "") {
23428 frozen = freeze();
23429 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];
23430 if (CACHE_DEBUGS) {
23431 console.log("setting cached_findDependenciesInScript on key: " + cacheKey);
23432 }
23433 cached_findDependenciesInScript.set(cacheKey, toBeFrozen);
23434 }
23435 return [testableString, scriptEvaluation[0], generatedCode, readableSummaryOfGeneratedCode, scriptEvaluation[1], errorMessage, dependencyInfo];
23436 };
23437
23438 recursiveDependencies = function(variableToBeChecked, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions) {
23439 var cyclesDescription, i, k, l1, len, len1, m1, ref2;
23440 variablesAlreadyFleshedOut.push(variableToBeChecked);
23441 if (symbolsDependencies[chainBeingChecked[chainBeingChecked.length - 1]] != null) {
23442 if (symbolsDependencies[chainBeingChecked[chainBeingChecked.length - 1]].indexOf("'" + variableToBeChecked) !== -1) {
23443 if (DEBUG) {
23444 console.log("can't keep following the chain of " + variableToBeChecked + " because it's actually a variable bound to a parameter");
23445 }
23446 if (arrayWhereDependenciesWillBeAdded.indexOf("'" + variableToBeChecked) === -1 && arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) === -1) {
23447 arrayWhereDependenciesWillBeAdded.push(variableToBeChecked);
23448 }
23449 return arrayWhereDependenciesWillBeAdded;
23450 }
23451 }
23452 chainBeingChecked.push(variableToBeChecked);
23453 if (symbolsDependencies[variableToBeChecked] == null) {
23454 if (arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) === -1) {
23455 arrayWhereDependenciesWillBeAdded.push(variableToBeChecked);
23456 }
23457 return arrayWhereDependenciesWillBeAdded;
23458 } else {
23459 ref2 = symbolsDependencies[variableToBeChecked];
23460 for (l1 = 0, len = ref2.length; l1 < len; l1++) {
23461 i = ref2[l1];
23462 if (chainBeingChecked.indexOf(i) !== -1) {
23463 if (DEBUG) {
23464 console.log(" found cycle:");
23465 }
23466 cyclesDescription = "";
23467 for (m1 = 0, len1 = chainBeingChecked.length; m1 < len1; m1++) {
23468 k = chainBeingChecked[m1];
23469 if (variablesWithCycles.indexOf(k) === -1) {
23470 variablesWithCycles.push(k);
23471 }
23472 if (DEBUG) {
23473 console.log(k + " --> ");
23474 }
23475 cyclesDescription += k + " --> ";
23476 }
23477 if (DEBUG) {
23478 console.log(" ... then " + i + " again");
23479 }
23480 cyclesDescription += " ... then " + i + " again";
23481 cyclesDescriptions.push(cyclesDescription);
23482 if (variablesWithCycles.indexOf(i) === -1) {
23483 variablesWithCycles.push(i);
23484 }
23485 } else {
23486 recursiveDependencies(i, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions);
23487 chainBeingChecked.pop();
23488 }
23489 }
23490 return arrayWhereDependenciesWillBeAdded;
23491 }
23492 };
23493
23494 inited = false;
23495
23496 latexErrorSign = "\\rlap{\\large\\color{red}\\bigtriangleup}{\\ \\ \\tiny\\color{red}!}";
23497
23498 turnErrorMessageToLatex = function(theErrorMessage) {
23499 theErrorMessage = theErrorMessage.replace(/\n/g, "");
23500 theErrorMessage = theErrorMessage.replace(/_/g, "} \\_ \\text{");
23501 theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(transpose_unicode), 'g'), "}{}^{T}\\text{");
23502 theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(dotprod_unicode), 'g'), "}\\cdot \\text{");
23503 theErrorMessage = theErrorMessage.replace("Stop:", "} \\quad \\text{Stop:");
23504 theErrorMessage = theErrorMessage.replace("->", "} \\rightarrow \\text{");
23505 theErrorMessage = theErrorMessage.replace("?", "}\\enspace " + latexErrorSign + " \\enspace \\text{");
23506 theErrorMessage = "$$\\text{" + theErrorMessage.replace(/\n/g, "") + "}$$";
23507 return theErrorMessage;
23508 };
23509
23510 normaliseDots = function(stringToNormalise) {
23511 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8901), 'g'), String.fromCharCode(dotprod_unicode));
23512 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8226), 'g'), String.fromCharCode(dotprod_unicode));
23513 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(12539), 'g'), String.fromCharCode(dotprod_unicode));
23514 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(55296), 'g'), String.fromCharCode(dotprod_unicode));
23515 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(65381), 'g'), String.fromCharCode(dotprod_unicode));
23516 return stringToNormalise;
23517 };
23518
23519 CACHE_DEBUGS = false;
23520
23521 CACHE_HITSMISS_DEBUGS = false;
23522
23523 TIMING_DEBUGS = false;
23524
23525 cacheMissPenalty = 0;
23526
23527 run = function(stringToBeRun, generateLatex) {
23528 var allReturnedLatexStrings, allReturnedPlainStrings, cacheKey, collectedLatexResult, collectedPlainResult, currentStateHash, error, errorWhileExecution, frozen, i, indexOfPartRemainingToBeParsed, n, possiblyCached, stringToBeReturned, theErrorMessage, timeStart, timingDebugWrite, toBeFrozen, totalTime;
23529 if (generateLatex == null) {
23530 generateLatex = false;
23531 }
23532 timeStart = new Date().getTime();
23533 stringToBeRun = normaliseDots(stringToBeRun);
23534 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23535 currentStateHash = getStateHash();
23536 cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun;
23537 if (CACHE_DEBUGS) {
23538 console.log("cached_runs key: " + cacheKey);
23539 }
23540 possiblyCached = cached_runs.get(cacheKey);
23541 if (possiblyCached != null) {
23542 if (CACHE_HITSMISS_DEBUGS) {
23543 console.log("cached_runs hit on: " + stringToBeRun);
23544 }
23545 unfreeze(possiblyCached);
23546 if (TIMING_DEBUGS) {
23547 totalTime = new Date().getTime() - timeStart;
23548 console.log("run time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length - 2] - totalTime) + "ms due to cache hit");
23549 }
23550 return possiblyCached[possiblyCached.length - 1];
23551 } else {
23552 if (CACHE_HITSMISS_DEBUGS) {
23553 console.log("cached_runs miss on: " + stringToBeRun);
23554 }
23555 if (TIMING_DEBUGS) {
23556 cacheMissPenalty = new Date().getTime() - timeStart;
23557 }
23558 }
23559 }
23560 if (stringToBeRun === "selftest") {
23561 selftest();
23562 return;
23563 }
23564 if (!inited) {
23565 inited = true;
23566 init();
23567 }
23568 i = 0;
23569 n = 0;
23570 indexOfPartRemainingToBeParsed = 0;
23571 allReturnedPlainStrings = "";
23572 allReturnedLatexStrings = "";
23573 while (1) {
23574 try {
23575 errorMessage = "";
23576 check_stack();
23577 n = scan(stringToBeRun.substring(indexOfPartRemainingToBeParsed));
23578 p1 = pop();
23579 check_stack();
23580 } catch (error1) {
23581 error = error1;
23582 if (PRINTOUTRESULT) {
23583 console.log(error);
23584 }
23585 allReturnedPlainStrings += error.message;
23586 if (generateLatex) {
23587 theErrorMessage = turnErrorMessageToLatex(error.message);
23588 allReturnedLatexStrings += theErrorMessage;
23589 }
23590 reset_after_error();
23591 break;
23592 }
23593 if (n === 0) {
23594 break;
23595 }
23596 indexOfPartRemainingToBeParsed += n;
23597 push(p1);
23598 errorWhileExecution = false;
23599 try {
23600 stringsEmittedByUserPrintouts = "";
23601 top_level_eval();
23602 p2 = pop();
23603 check_stack();
23604 if (isstr(p2)) {
23605 if (DEBUG) {
23606 console.log(p2.str);
23607 }
23608 if (DEBUG) {
23609 console.log("\n");
23610 }
23611 }
23612 if (p2 === symbol(NIL)) {
23613 collectedPlainResult = stringsEmittedByUserPrintouts;
23614 if (generateLatex) {
23615 collectedLatexResult = "$$" + stringsEmittedByUserPrintouts + "$$";
23616 }
23617 } else {
23618 collectedPlainResult = print_expr(p2);
23619 collectedPlainResult += "\n";
23620 if (generateLatex) {
23621 collectedLatexResult = "$$" + collectLatexStringFromReturnValue(p2) + "$$";
23622 if (DEBUG) {
23623 console.log("collectedLatexResult: " + collectedLatexResult);
23624 }
23625 }
23626 }
23627 allReturnedPlainStrings += collectedPlainResult;
23628 if (generateLatex) {
23629 allReturnedLatexStrings += collectedLatexResult;
23630 }
23631 if (PRINTOUTRESULT) {
23632 if (DEBUG) {
23633 console.log("printline");
23634 }
23635 if (DEBUG) {
23636 console.log(collectedPlainResult);
23637 }
23638 }
23639 if (PRINTOUTRESULT) {
23640 if (DEBUG) {
23641 console.log("display:");
23642 }
23643 print2dascii(p2);
23644 }
23645 if (generateLatex) {
23646 allReturnedLatexStrings += "\n";
23647 }
23648 } catch (error1) {
23649 error = error1;
23650 errorWhileExecution = true;
23651 collectedPlainResult = error.message;
23652 if (generateLatex) {
23653 collectedLatexResult = turnErrorMessageToLatex(error.message);
23654 }
23655 if (PRINTOUTRESULT) {
23656 console.log(collectedPlainResult);
23657 }
23658 allReturnedPlainStrings += collectedPlainResult;
23659 if (collectedPlainResult !== "") {
23660 allReturnedPlainStrings += "\n";
23661 }
23662 if (generateLatex) {
23663 allReturnedLatexStrings += collectedLatexResult;
23664 allReturnedLatexStrings += "\n";
23665 }
23666 resetCache();
23667 init();
23668 }
23669 }
23670 if (allReturnedPlainStrings[allReturnedPlainStrings.length - 1] === "\n") {
23671 allReturnedPlainStrings = allReturnedPlainStrings.substring(0, allReturnedPlainStrings.length - 1);
23672 }
23673 if (generateLatex) {
23674 if (allReturnedLatexStrings[allReturnedLatexStrings.length - 1] === "\n") {
23675 allReturnedLatexStrings = allReturnedLatexStrings.substring(0, allReturnedLatexStrings.length - 1);
23676 }
23677 }
23678 if (generateLatex) {
23679 if (DEBUG) {
23680 console.log("allReturnedLatexStrings: " + allReturnedLatexStrings);
23681 }
23682 stringToBeReturned = [allReturnedPlainStrings, allReturnedLatexStrings];
23683 } else {
23684 stringToBeReturned = allReturnedPlainStrings;
23685 }
23686 if (ENABLE_CACHING && stringToBeRun !== "clearall" && !errorWhileExecution) {
23687 frozen = freeze();
23688 toBeFrozen = [frozen[0], frozen[1], frozen[2], frozen[3], frozen[4], frozen[5], new Date().getTime() - timeStart, stringToBeReturned];
23689 if (CACHE_DEBUGS) {
23690 console.log("setting cached_runs on key: " + cacheKey);
23691 }
23692 cached_runs.set(cacheKey, toBeFrozen);
23693 }
23694 if (TIMING_DEBUGS) {
23695 timingDebugWrite = "run time on: " + stringToBeRun + " : " + (new Date().getTime() - timeStart) + "ms";
23696 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23697 timingDebugWrite += ", of which cache miss penalty: " + cacheMissPenalty + "ms";
23698 }
23699 console.log(timingDebugWrite);
23700 }
23701 allReturnedPlainStrings = "";
23702 allReturnedLatexStrings = "";
23703 return stringToBeReturned;
23704 };
23705
23706 check_stack = function() {
23707 if (tos !== 0) {
23708 debugger;
23709 stop("stack error");
23710 }
23711 if (frame !== TOS) {
23712 debugger;
23713 stop("frame error");
23714 }
23715 if (chainOfUserSymbolsNotFunctionsBeingEvaluated.length !== 0) {
23716 debugger;
23717 stop("symbols evaluation still ongoing?");
23718 }
23719 if (evaluatingAsFloats !== 0) {
23720 debugger;
23721 stop("numeric evaluation still ongoing?");
23722 }
23723 if (evaluatingPolar !== 0) {
23724 debugger;
23725 return stop("evaluation of polar still ongoing?");
23726 }
23727 };
23728
23729 top_level_eval = function() {
23730 var doNothing;
23731 if (DEBUG) {
23732 console.log("#### top level eval");
23733 }
23734 save();
23735 trigmode = 0;
23736 p1 = symbol(AUTOEXPAND);
23737 if (iszero(get_binding(p1))) {
23738 expanding = 0;
23739 } else {
23740 expanding = 1;
23741 }
23742 p1 = pop();
23743 push(p1);
23744 Eval();
23745 p2 = pop();
23746 if (p2 === symbol(NIL)) {
23747 push(p2);
23748 restore();
23749 return;
23750 }
23751 set_binding(symbol(LAST), p2);
23752 if (!iszero(get_binding(symbol(BAKE)))) {
23753 push(p2);
23754 bake();
23755 p2 = pop();
23756 }
23757 if ((p1 === symbol(SYMBOL_I) || p1 === symbol(SYMBOL_J)) && isimaginaryunit(p2)) {
23758 doNothing = 0;
23759 } else if (isimaginaryunit(get_binding(symbol(SYMBOL_J)))) {
23760 push(p2);
23761 push(imaginaryunit);
23762 push_symbol(SYMBOL_J);
23763 subst();
23764 p2 = pop();
23765 } else if (isimaginaryunit(get_binding(symbol(SYMBOL_I)))) {
23766 push(p2);
23767 push(imaginaryunit);
23768 push_symbol(SYMBOL_I);
23769 subst();
23770 p2 = pop();
23771 }
23772 push(p2);
23773 return restore();
23774 };
23775
23776 check_esc_flag = function() {
23777 if (esc_flag) {
23778 return stop("esc key");
23779 }
23780 };
23781
23782 clearAlgebraEnvironment = function() {
23783 return do_clearall();
23784 };
23785
23786 computeDependenciesFromAlgebra = function(codeFromAlgebraBlock) {
23787 var i, keepState, l1, len, len1, m1, originalcodeFromAlgebraBlock, userSimplificationsInProgramForm;
23788 if (DEBUG) {
23789 console.log("computeDependenciesFromAlgebra!!!");
23790 }
23791 originalcodeFromAlgebraBlock = codeFromAlgebraBlock;
23792 keepState = true;
23793 called_from_Algebra_block = true;
23794 codeFromAlgebraBlock = normaliseDots(codeFromAlgebraBlock);
23795 if (!keepState) {
23796 userSimplificationsInListForm = [];
23797 userSimplificationsInProgramForm = "";
23798 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
23799 i = userSimplificationsInListForm[l1];
23800 userSimplificationsInProgramForm += "silentpattern(" + car(i) + "," + car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n";
23801 }
23802 do_clearall();
23803 codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock;
23804 if (DEBUG) {
23805 console.log("codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock);
23806 }
23807 }
23808 if (DEBUG) {
23809 console.log("computeDependenciesFromAlgebra: patterns in the list --------------- ");
23810 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
23811 i = userSimplificationsInListForm[m1];
23812 console.log(car(i) + "," + cdr(i) + ")");
23813 }
23814 console.log("...end of list --------------- ");
23815 }
23816 called_from_Algebra_block = false;
23817 return findDependenciesInScript(codeFromAlgebraBlock, true)[6];
23818 };
23819
23820 computeResultsAndJavaScriptFromAlgebra = function(codeFromAlgebraBlock) {
23821 var code, dependencyInfo, i, keepState, l1, latexResult, len, len1, m1, originalcodeFromAlgebraBlock, readableSummaryOfCode, ref2, result, stringToBeRun, testableStringIsIgnoredHere, timeStartFromAlgebra, userSimplificationsInProgramForm;
23822 originalcodeFromAlgebraBlock = codeFromAlgebraBlock;
23823 keepState = true;
23824 called_from_Algebra_block = true;
23825 timeStartFromAlgebra = new Date().getTime();
23826 if (TIMING_DEBUGS) {
23827 console.log(" --------- computeResultsAndJavaScriptFromAlgebra input: " + codeFromAlgebraBlock + " at: " + (new Date()));
23828 }
23829 codeFromAlgebraBlock = normaliseDots(codeFromAlgebraBlock);
23830 stringToBeRun = codeFromAlgebraBlock;
23831 if (DEBUG) {
23832 console.log("computeResultsAndJavaScriptFromAlgebra: patterns in the list --------------- ");
23833 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
23834 i = userSimplificationsInListForm[l1];
23835 console.log(car(i) + "," + cdr(i) + ")");
23836 }
23837 console.log("...end of list --------------- ");
23838 }
23839 if (!keepState) {
23840 userSimplificationsInListForm = [];
23841 userSimplificationsInProgramForm = "";
23842 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
23843 i = userSimplificationsInListForm[m1];
23844 userSimplificationsInProgramForm += "silentpattern(" + car(i) + "," + car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n";
23845 }
23846 do_clearall();
23847 codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock;
23848 if (DEBUG) {
23849 console.log("codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock);
23850 }
23851 }
23852 ref2 = findDependenciesInScript(codeFromAlgebraBlock), testableStringIsIgnoredHere = ref2[0], result = ref2[1], code = ref2[2], readableSummaryOfCode = ref2[3], latexResult = ref2[4], errorMessage = ref2[5], dependencyInfo = ref2[6];
23853 called_from_Algebra_block = false;
23854 if (readableSummaryOfCode !== "" || errorMessage !== "") {
23855 result += "\n" + readableSummaryOfCode;
23856 if (errorMessage !== "") {
23857 result += "\n" + errorMessage;
23858 }
23859 result = result.replace(/\n/g, "\n\n");
23860 latexResult += "\n" + "$$" + readableSummaryOfCode + "$$";
23861 if (errorMessage !== "") {
23862 latexResult += turnErrorMessageToLatex(errorMessage);
23863 }
23864 latexResult = latexResult.replace(/\n/g, "\n\n");
23865 }
23866 latexResult = latexResult.replace(/\n*/, "");
23867 latexResult = latexResult.replace(/\$\$\$\$\n*/g, "");
23868 code = code.replace(/Math\./g, "");
23869 code = code.replace(/\n/g, "\n\n");
23870 if (TIMING_DEBUGS) {
23871 console.log("computeResultsAndJavaScriptFromAlgebra time (total time from notebook and back) for: " + stringToBeRun + " : " + ((new Date().getTime()) - timeStartFromAlgebra) + "ms");
23872 }
23873 return {
23874 code: code,
23875 result: latexResult,
23876 latexResult: latexResult,
23877 dependencyInfo: dependencyInfo
23878 };
23879 };
23880
23881 enableCaching = function() {
23882 return ENABLE_CACHING = true;
23883 };
23884
23885 disableCaching = function() {
23886 return ENABLE_CACHING = false;
23887 };
23888
23889 (typeof exports !== "undefined" && exports !== null ? exports : this).run = run;
23890
23891 (typeof exports !== "undefined" && exports !== null ? exports : this).findDependenciesInScript = findDependenciesInScript;
23892
23893 (typeof exports !== "undefined" && exports !== null ? exports : this).computeDependenciesFromAlgebra = computeDependenciesFromAlgebra;
23894
23895 (typeof exports !== "undefined" && exports !== null ? exports : this).computeResultsAndJavaScriptFromAlgebra = computeResultsAndJavaScriptFromAlgebra;
23896
23897 (typeof exports !== "undefined" && exports !== null ? exports : this).clearAlgebraEnvironment = clearAlgebraEnvironment;
23898
23899 (typeof exports !== "undefined" && exports !== null ? exports : this).enableCaching = enableCaching;
23900
23901 (typeof exports !== "undefined" && exports !== null ? exports : this).disableCaching = disableCaching;
23902
23903 tos = 0;
23904
23905 nil_symbols = 0;
23906
23907 push = function(p) {
23908 if (p == null) {
23909 debugger;
23910 }
23911 if (p.isZero != null) {
23912 debugger;
23913 }
23914 if (p === symbol(NIL)) {
23915 nil_symbols++;
23916 if (DEBUG) {
23917 console.log("pushing symbol(NIL) #" + nil_symbols);
23918 }
23919 }
23920 if (tos >= frame) {
23921 stop("stack overflow");
23922 }
23923 return stack[tos++] = p;
23924 };
23925
23926 moveTos = function(stackPos) {
23927 if (tos <= stackPos) {
23928 tos = stackPos;
23929 return;
23930 }
23931 while (tos > stackPos) {
23932 stack[tos] = null;
23933 tos--;
23934 }
23935 };
23936
23937 top = function() {
23938 return stack[tos - 1];
23939 };
23940
23941 pop = function() {
23942 var elementToBeReturned;
23943 if (tos === 0) {
23944 debugger;
23945 stop("stack underflow");
23946 }
23947 if (stack[tos - 1] == null) {
23948 debugger;
23949 }
23950 elementToBeReturned = stack[--tos];
23951 stack[tos] = null;
23952 return elementToBeReturned;
23953 };
23954
23955 push_frame = function(n) {
23956 var i, l1, ref2, results;
23957 i = 0;
23958 frame -= n;
23959 if (frame < tos) {
23960 debugger;
23961 stop("frame overflow, circular reference?");
23962 }
23963 results = [];
23964 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
23965 results.push(stack[frame + i] = symbol(NIL));
23966 }
23967 return results;
23968 };
23969
23970 pop_frame = function(n) {
23971 frame += n;
23972 if (frame > TOS) {
23973 return stop("frame underflow");
23974 }
23975 };
23976
23977 save = function() {
23978 frame -= 10;
23979 if (frame < tos) {
23980 debugger;
23981 stop("frame overflow, circular reference?");
23982 }
23983 stack[frame + 0] = p0;
23984 stack[frame + 1] = p1;
23985 stack[frame + 2] = p2;
23986 stack[frame + 3] = p3;
23987 stack[frame + 4] = p4;
23988 stack[frame + 5] = p5;
23989 stack[frame + 6] = p6;
23990 stack[frame + 7] = p7;
23991 stack[frame + 8] = p8;
23992 return stack[frame + 9] = p9;
23993 };
23994
23995 restore = function() {
23996 if (frame > TOS - 10) {
23997 stop("frame underflow");
23998 }
23999 p0 = stack[frame + 0];
24000 p1 = stack[frame + 1];
24001 p2 = stack[frame + 2];
24002 p3 = stack[frame + 3];
24003 p4 = stack[frame + 4];
24004 p5 = stack[frame + 5];
24005 p6 = stack[frame + 6];
24006 p7 = stack[frame + 7];
24007 p8 = stack[frame + 8];
24008 p9 = stack[frame + 9];
24009 return frame += 10;
24010 };
24011
24012 swap = function() {
24013 var p, q;
24014 p = pop();
24015 q = pop();
24016 push(p);
24017 return push(q);
24018 };
24019
24020 dupl = function() {
24021 var p;
24022 p = pop();
24023 push(p);
24024 return push(p);
24025 };
24026
24027 $.dupl = dupl;
24028
24029 $.swap = swap;
24030
24031 $.restore = restore;
24032
24033 $.save = save;
24034
24035 $.push = push;
24036
24037 $.pop = pop;
24038
24039 Eval_symbolsinfo = function() {
24040 var symbolsinfoToBePrinted;
24041 symbolsinfoToBePrinted = symbolsinfo();
24042 if (symbolsinfoToBePrinted !== "") {
24043 return new_string(symbolsinfoToBePrinted);
24044 } else {
24045 return push_symbol(NIL);
24046 }
24047 };
24048
24049 symbolsinfo = function() {
24050 var bindingi, i, l1, ref2, ref3, symbolsinfoToBePrinted, symtabi;
24051 symbolsinfoToBePrinted = "";
24052 for (i = l1 = ref2 = NIL + 1, ref3 = symtab.length; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24053 if (symtab[i].printname === "") {
24054 if (isSymbolReclaimable[i] === false) {
24055 break;
24056 } else {
24057 continue;
24058 }
24059 }
24060 symtabi = symtab[i] + "";
24061 bindingi = (binding[i] + "").substring(0, 4);
24062 symbolsinfoToBePrinted += "symbol: " + symtabi + " size: " + countsize(binding[i]) + " value: " + bindingi + "...\n";
24063 }
24064 return symbolsinfoToBePrinted;
24065 };
24066
24067 std_symbol = function(s, n, latexPrint) {
24068 var p;
24069 p = symtab[n];
24070 if (p == null) {
24071 debugger;
24072 }
24073 p.printname = s;
24074 if (latexPrint != null) {
24075 return p.latexPrint = latexPrint;
24076 } else {
24077 return p.latexPrint = s;
24078 }
24079 };
24080
24081 usr_symbol = function(s) {
24082 var i, l1, ref2;
24083 i = 0;
24084 for (i = l1 = 0, ref2 = NSYM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24085 if (symtab[i].printname === "") {
24086 break;
24087 }
24088 if (s === symtab[i].printname) {
24089 return symtab[i];
24090 }
24091 }
24092 if (i === NSYM) {
24093 stop("symbol table overflow");
24094 }
24095 symtab[i] = new U();
24096 symtab[i].k = SYM;
24097 symtab[i].printname = s;
24098 binding[i] = symtab[i];
24099 isSymbolReclaimable[i] = false;
24100 return symtab[i];
24101 };
24102
24103 get_printname = function(p) {
24104 if (p.k !== SYM) {
24105 stop("symbol error");
24106 }
24107 return p.printname;
24108 };
24109
24110 set_binding = function(p, q) {
24111 var indexFound;
24112 if (p.k !== SYM) {
24113 stop("symbol error");
24114 }
24115 indexFound = symtab.indexOf(p);
24116
24117 /*
24118 if indexFound == -1
24119 debugger
24120 for i in [0...symtab.length]
24121 if p.printname == symtab[i].printname
24122 indexFound = i
24123 console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
24124 break
24125 */
24126 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24127 console.log("ops, more than one element!");
24128 debugger;
24129 }
24130 if (DEBUG) {
24131 console.log("lookup >> set_binding lookup " + indexFound);
24132 }
24133 isSymbolReclaimable[indexFound] = false;
24134 return binding[indexFound] = q;
24135 };
24136
24137 get_binding = function(p) {
24138 var indexFound;
24139 if (p.k !== SYM) {
24140 stop("symbol error");
24141 }
24142 indexFound = symtab.indexOf(p);
24143
24144 /*
24145 if indexFound == -1
24146 debugger
24147 for i in [0...symtab.length]
24148 if p.printname == symtab[i].printname
24149 indexFound = i
24150 console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
24151 break
24152 */
24153 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24154 console.log("ops, more than one element!");
24155 debugger;
24156 }
24157 if (DEBUG) {
24158 console.log("lookup >> get_binding lookup " + indexFound);
24159 }
24160 return binding[indexFound];
24161 };
24162
24163 is_usr_symbol = function(p) {
24164 var theSymnum;
24165 if (p.k !== SYM) {
24166 return false;
24167 }
24168 theSymnum = symnum(p);
24169 if (theSymnum > PI && theSymnum !== SYMBOL_I && theSymnum !== SYMBOL_IDENTITY_MATRIX) {
24170 return true;
24171 }
24172 return false;
24173 };
24174
24175 lookupsTotal = 0;
24176
24177 symnum = function(p) {
24178 var indexFound;
24179 lookupsTotal++;
24180 if (p.k !== SYM) {
24181 stop("symbol error");
24182 }
24183 indexFound = symtab.indexOf(p);
24184 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24185 console.log("ops, more than one element!");
24186 debugger;
24187 }
24188 if (DEBUG) {
24189 console.log("lookup >> symnum lookup " + indexFound + " lookup # " + lookupsTotal);
24190 }
24191 return indexFound;
24192 };
24193
24194 push_symbol = function(k) {
24195 return push(symtab[k]);
24196 };
24197
24198 clear_symbols = function() {
24199 var i, l1, ref2, ref3, results;
24200 results = [];
24201 for (i = l1 = ref2 = NIL + 1, ref3 = NSYM; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24202 if (symtab[i].printname === "") {
24203 if (isSymbolReclaimable[i] === false) {
24204 break;
24205 } else {
24206 continue;
24207 }
24208 }
24209 symtab[i] = new U();
24210 symtab[i].k = SYM;
24211 binding[i] = symtab[i];
24212 results.push(isSymbolReclaimable[i] = false);
24213 }
24214 return results;
24215 };
24216
24217 collectUserSymbols = function(p, accumulator) {
24218 var i, l1, ref2;
24219 if (accumulator == null) {
24220 accumulator = [];
24221 }
24222 if (is_usr_symbol(p)) {
24223 if (accumulator.indexOf(p) === -1) {
24224 accumulator.push(p);
24225 return;
24226 }
24227 }
24228 if (istensor(p)) {
24229 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24230 collectUserSymbols(p.tensor.elem[i], accumulator);
24231 }
24232 return;
24233 }
24234 while (iscons(p)) {
24235 collectUserSymbols(car(p), accumulator);
24236 p = cdr(p);
24237 }
24238 };
24239
24240 $.get_binding = get_binding;
24241
24242 $.set_binding = set_binding;
24243
24244 $.usr_symbol = usr_symbol;
24245
24246 $.symbolsinfo = symbolsinfo;
24247
24248 $.collectUserSymbols = collectUserSymbols;
24249
24250 if (!inited) {
24251 inited = true;
24252 init();
24253 }
24254
24255 $.init = init;
24256
24257 parse_internal = function(argu) {
24258 if (typeof argu === 'string') {
24259 return scan(argu);
24260 } else if (typeof argu === 'number') {
24261 if (argu % 1 === 0) {
24262 return push_integer(argu);
24263 } else {
24264 return push_double(argu);
24265 }
24266 } else if (argu instanceof U) {
24267 return push(argu);
24268 } else {
24269 console.warn('unknown argument type', argu);
24270 return push(symbol(NIL));
24271 }
24272 };
24273
24274 parse = function(argu) {
24275 var data, error;
24276 try {
24277 parse_internal(argu);
24278 data = pop();
24279 check_stack();
24280 } catch (error1) {
24281 error = error1;
24282 reset_after_error();
24283 throw error;
24284 }
24285 return data;
24286 };
24287
24288 exec = function() {
24289 var argu, argus, error, fn, l1, len, name, result;
24290 name = arguments[0], argus = 2 <= arguments.length ? slice.call(arguments, 1) : [];
24291 fn = get_binding(usr_symbol(name));
24292 check_stack();
24293 push(fn);
24294 for (l1 = 0, len = argus.length; l1 < len; l1++) {
24295 argu = argus[l1];
24296 parse_internal(argu);
24297 }
24298 list(1 + argus.length);
24299 p1 = pop();
24300 push(p1);
24301 try {
24302 fixed_top_level_eval();
24303 result = pop();
24304 check_stack();
24305 } catch (error1) {
24306 error = error1;
24307 reset_after_error();
24308 throw error;
24309 }
24310 return result;
24311 };
24312
24313 fixed_top_level_eval = function() {
24314 save();
24315 trigmode = 0;
24316 p1 = symbol(AUTOEXPAND);
24317 if (iszero(get_binding(p1))) {
24318 expanding = 0;
24319 } else {
24320 expanding = 1;
24321 }
24322 p1 = pop();
24323 push(p1);
24324 Eval();
24325 p2 = pop();
24326 if (p2 === symbol(NIL)) {
24327 push(p2);
24328 restore();
24329 return;
24330 }
24331 if (!iszero(get_binding(symbol(BAKE)))) {
24332 push(p2);
24333 bake();
24334 p2 = pop();
24335 }
24336 push(p2);
24337 return restore();
24338 };
24339
24340 $.exec = exec;
24341
24342 $.parse = parse;
24343
24344 (function() {
24345 var builtin_fns, fn, l1, len, results;
24346 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"];
24347 results = [];
24348 for (l1 = 0, len = builtin_fns.length; l1 < len; l1++) {
24349 fn = builtin_fns[l1];
24350 results.push($[fn] = exec.bind(this, fn));
24351 }
24352 return results;
24353 })();
24354
24355 DoubleLinkedList = (function() {
24356 function DoubleLinkedList() {
24357 this.headNode = this.tailNode = null;
24358 }
24359
24360 DoubleLinkedList.prototype.remove = function(node) {
24361 if (node.pre) {
24362 node.pre.next = node.next;
24363 } else {
24364 this.headNode = node.next;
24365 }
24366 if (node.next) {
24367 return node.next.pre = node.pre;
24368 } else {
24369 return this.tailNode = node.pre;
24370 }
24371 };
24372
24373 DoubleLinkedList.prototype.insertBeginning = function(node) {
24374 if (this.headNode) {
24375 node.next = this.headNode;
24376 this.headNode.pre = node;
24377 return this.headNode = node;
24378 } else {
24379 return this.headNode = this.tailNode = node;
24380 }
24381 };
24382
24383 DoubleLinkedList.prototype.moveToHead = function(node) {
24384 this.remove(node);
24385 return this.insertBeginning(node);
24386 };
24387
24388 DoubleLinkedList.prototype.clear = function() {
24389 return this.headNode = this.tailNode = null;
24390 };
24391
24392 return DoubleLinkedList;
24393
24394 })();
24395
24396 LRUCache = (function() {
24397 function LRUCache(capacity, maxAge) {
24398 this.capacity = capacity != null ? capacity : 10;
24399 this.maxAge = maxAge != null ? maxAge : 60000;
24400 this._linkList = new DoubleLinkedList();
24401 this.reset();
24402 this.hitCount = this.missCount = 0;
24403 }
24404
24405 LRUCache.prototype.resetHitMissCount = function() {
24406 return this.hitCount = this.missCount = 0;
24407 };
24408
24409 LRUCache.prototype.keys = function() {
24410 return Object.keys(this._hash);
24411 };
24412
24413 LRUCache.prototype.values = function() {
24414 var values;
24415 values = this.keys().map((function(_this) {
24416 return function(key) {
24417 return _this.get(key);
24418 };
24419 })(this));
24420 return values.filter(function(v) {
24421 return v !== void 0;
24422 });
24423 };
24424
24425 LRUCache.prototype.remove = function(key) {
24426 var node;
24427 if (this._hash[key] != null) {
24428 node = this._hash[key];
24429 this._linkList.remove(node);
24430 delete this._hash[key];
24431 if (node.data.onDispose) {
24432 node.data.onDispose.call(this, node.data.key, node.data.value);
24433 }
24434 return this.size--;
24435 }
24436 };
24437
24438 LRUCache.prototype.reset = function() {
24439 this._hash = {};
24440 this.size = 0;
24441 this.resetHitMissCount();
24442 return this._linkList.clear();
24443 };
24444
24445 LRUCache.prototype.set = function(key, value, onDispose) {
24446 var createNode, node;
24447 node = this._hash[key];
24448 if (node) {
24449 node.data.value = value;
24450 node.data.onDispose = onDispose;
24451 return this._refreshNode(node);
24452 } else {
24453 if (this.size === this.capacity) {
24454 this.remove(this._linkList.tailNode.data.key);
24455 }
24456 createNode = function(data, pre, next) {
24457 return {
24458 data: data,
24459 pre: pre,
24460 next: next
24461 };
24462 };
24463 node = createNode({
24464 key: key,
24465 value: value,
24466 onDispose: onDispose
24467 });
24468 node.data.lastVisitTime = Date.now();
24469 this._linkList.insertBeginning(node);
24470 this._hash[key] = node;
24471 this.size++;
24472 }
24473 };
24474
24475 LRUCache.prototype.get = function(key) {
24476 var node;
24477 node = this._hash[key];
24478 if (!node) {
24479 this.missCount++;
24480 return void 0;
24481 }
24482 if (this._isExpiredNode(node)) {
24483 this.remove(key);
24484 this.missCount++;
24485 return void 0;
24486 }
24487 this._refreshNode(node);
24488 this.hitCount++;
24489 return node.data.value;
24490 };
24491
24492 LRUCache.prototype._refreshNode = function(node) {
24493 node.data.lastVisitTime = Date.now();
24494 return this._linkList.moveToHead(node);
24495 };
24496
24497 LRUCache.prototype._isExpiredNode = function(node) {
24498 return Date.now() - node.data.lastVisitTime > this.maxAge;
24499 };
24500
24501 LRUCache.prototype.has = function(key) {
24502 return this._hash[key] != null;
24503 };
24504
24505 return LRUCache;
24506
24507 })();
24508
24509 cached_runs = new LRUCache(100, 60000 * 60 * 24 * 265);
24510
24511 cached_findDependenciesInScript = new LRUCache(100, 60000 * 60 * 24 * 265);
24512
24513 freeze = function() {
24514 var frozenContents, frozenHash, frozenPatterns, frozenSymbols, i, l1, ref2;
24515 frozenSymbols = [];
24516 frozenContents = [];
24517 frozenPatterns = [];
24518 frozenHash = "";
24519 for (i = l1 = 0, ref2 = symtab.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24520 if (isSymbolReclaimable[i] === false) {
24521 frozenSymbols.push(symtab[i]);
24522 frozenContents.push(binding[i]);
24523 }
24524 }
24525 frozenPatterns = userSimplificationsInListForm.slice(0);
24526 return [frozenSymbols, frozenContents, frozenPatterns, zero, one, imaginaryunit, getStateHash()];
24527 };
24528
24529 unfreeze = function(frozen) {
24530 var frozenContents, frozenPatterns, frozenSymbols, i, l1, ref2;
24531 frozenSymbols = frozen[0], frozenContents = frozen[1], frozenPatterns = frozen[2], zero = frozen[3], one = frozen[4], imaginaryunit = frozen[5];
24532 for (i = l1 = 0, ref2 = frozenSymbols.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24533 symtab[i] = frozenSymbols[i];
24534 binding[i] = frozenContents[i];
24535 }
24536 return userSimplificationsInListForm = frozenPatterns.slice(0);
24537 };
24538
24539 compareState = function(previousHash) {
24540 var frozenHash;
24541 frozenHash = getStateHash();
24542 if (frozenHash === previousHash) {
24543 return true;
24544 } else {
24545 return false;
24546 }
24547 };
24548
24549 resetCache = function() {
24550 if (cached_runs != null) {
24551 cached_runs.reset();
24552 if (DEBUG) {
24553 console.log("resetting cached_runs");
24554 }
24555 }
24556 if (cached_findDependenciesInScript != null) {
24557 cached_findDependenciesInScript.reset();
24558 if (DEBUG) {
24559 return console.log("resetting cached_findDependenciesInScript");
24560 }
24561 }
24562 };
24563
24564 resetCacheHitMissCounts = function() {
24565 if (cached_runs != null) {
24566 cached_runs.resetHitMissCount();
24567 }
24568 if (cached_findDependenciesInScript != null) {
24569 return cached_findDependenciesInScript.resetHitMissCount();
24570 }
24571 };
24572
24573 totalAllCachesHits = function() {
24574 return cached_runs.hitCount + cached_findDependenciesInScript.hitCount;
24575 };
24576
24577 totalAllCachesMisses = function() {
24578 return cached_runs.missCount + cached_findDependenciesInScript.missCount;
24579 };
24580
24581 getStateHash = function() {
24582 var bindingi, frozenHash, i, l1, len, m1, ref2, ref3, symtabi;
24583 frozenHash = "";
24584 for (i = l1 = ref2 = NIL + 1, ref3 = symtab.length; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24585 if (symtab[i].printname === "") {
24586 if (isSymbolReclaimable[i] === false) {
24587 break;
24588 } else {
24589 continue;
24590 }
24591 }
24592 symtabi = print_list(symtab[i]);
24593 bindingi = print_list(binding[i]);
24594 frozenHash += " //" + symtabi + " : " + bindingi;
24595 }
24596 for (m1 = 0, len = userSimplificationsInListForm.length; m1 < len; m1++) {
24597 i = userSimplificationsInListForm[m1];
24598 frozenHash += " pattern: " + i;
24599 }
24600 if (DEBUG) {
24601 console.log("frozenHash: " + frozenHash);
24602 }
24603 return frozenHash;
24604 };
24605
24606}).call(this);
24607
24608},{"big-integer":2}],2:[function(require,module,exports){
24609var bigInt = (function (undefined) {
24610 "use strict";
24611
24612 var BASE = 1e7,
24613 LOG_BASE = 7,
24614 MAX_INT = 9007199254740992,
24615 MAX_INT_ARR = smallToArray(MAX_INT),
24616 LOG_MAX_INT = Math.log(MAX_INT);
24617
24618 function Integer(v, radix) {
24619 if (typeof v === "undefined") return Integer[0];
24620 if (typeof radix !== "undefined") return +radix === 10 ? parseValue(v) : parseBase(v, radix);
24621 return parseValue(v);
24622 }
24623
24624 function BigInteger(value, sign) {
24625 this.value = value;
24626 this.sign = sign;
24627 this.isSmall = false;
24628 }
24629 BigInteger.prototype = Object.create(Integer.prototype);
24630
24631 function SmallInteger(value) {
24632 this.value = value;
24633 this.sign = value < 0;
24634 this.isSmall = true;
24635 }
24636 SmallInteger.prototype = Object.create(Integer.prototype);
24637
24638 function isPrecise(n) {
24639 return -MAX_INT < n && n < MAX_INT;
24640 }
24641
24642 function smallToArray(n) { // For performance reasons doesn't reference BASE, need to change this function if BASE changes
24643 if (n < 1e7)
24644 return [n];
24645 if (n < 1e14)
24646 return [n % 1e7, Math.floor(n / 1e7)];
24647 return [n % 1e7, Math.floor(n / 1e7) % 1e7, Math.floor(n / 1e14)];
24648 }
24649
24650 function arrayToSmall(arr) { // If BASE changes this function may need to change
24651 trim(arr);
24652 var length = arr.length;
24653 if (length < 4 && compareAbs(arr, MAX_INT_ARR) < 0) {
24654 switch (length) {
24655 case 0: return 0;
24656 case 1: return arr[0];
24657 case 2: return arr[0] + arr[1] * BASE;
24658 default: return arr[0] + (arr[1] + arr[2] * BASE) * BASE;
24659 }
24660 }
24661 return arr;
24662 }
24663
24664 function trim(v) {
24665 var i = v.length;
24666 while (v[--i] === 0);
24667 v.length = i + 1;
24668 }
24669
24670 function createArray(length) { // function shamelessly stolen from Yaffle's library https://github.com/Yaffle/BigInteger
24671 var x = new Array(length);
24672 var i = -1;
24673 while (++i < length) {
24674 x[i] = 0;
24675 }
24676 return x;
24677 }
24678
24679 function truncate(n) {
24680 if (n > 0) return Math.floor(n);
24681 return Math.ceil(n);
24682 }
24683
24684 function add(a, b) { // assumes a and b are arrays with a.length >= b.length
24685 var l_a = a.length,
24686 l_b = b.length,
24687 r = new Array(l_a),
24688 carry = 0,
24689 base = BASE,
24690 sum, i;
24691 for (i = 0; i < l_b; i++) {
24692 sum = a[i] + b[i] + carry;
24693 carry = sum >= base ? 1 : 0;
24694 r[i] = sum - carry * base;
24695 }
24696 while (i < l_a) {
24697 sum = a[i] + carry;
24698 carry = sum === base ? 1 : 0;
24699 r[i++] = sum - carry * base;
24700 }
24701 if (carry > 0) r.push(carry);
24702 return r;
24703 }
24704
24705 function addAny(a, b) {
24706 if (a.length >= b.length) return add(a, b);
24707 return add(b, a);
24708 }
24709
24710 function addSmall(a, carry) { // assumes a is array, carry is number with 0 <= carry < MAX_INT
24711 var l = a.length,
24712 r = new Array(l),
24713 base = BASE,
24714 sum, i;
24715 for (i = 0; i < l; i++) {
24716 sum = a[i] - base + carry;
24717 carry = Math.floor(sum / base);
24718 r[i] = sum - carry * base;
24719 carry += 1;
24720 }
24721 while (carry > 0) {
24722 r[i++] = carry % base;
24723 carry = Math.floor(carry / base);
24724 }
24725 return r;
24726 }
24727
24728 BigInteger.prototype.add = function (v) {
24729 var value, n = parseValue(v);
24730 if (this.sign !== n.sign) {
24731 return this.subtract(n.negate());
24732 }
24733 var a = this.value, b = n.value;
24734 if (n.isSmall) {
24735 return new BigInteger(addSmall(a, Math.abs(b)), this.sign);
24736 }
24737 return new BigInteger(addAny(a, b), this.sign);
24738 };
24739 BigInteger.prototype.plus = BigInteger.prototype.add;
24740
24741 SmallInteger.prototype.add = function (v) {
24742 var n = parseValue(v);
24743 var a = this.value;
24744 if (a < 0 !== n.sign) {
24745 return this.subtract(n.negate());
24746 }
24747 var b = n.value;
24748 if (n.isSmall) {
24749 if (isPrecise(a + b)) return new SmallInteger(a + b);
24750 b = smallToArray(Math.abs(b));
24751 }
24752 return new BigInteger(addSmall(b, Math.abs(a)), a < 0);
24753 };
24754 SmallInteger.prototype.plus = SmallInteger.prototype.add;
24755
24756 function subtract(a, b) { // assumes a and b are arrays with a >= b
24757 var a_l = a.length,
24758 b_l = b.length,
24759 r = new Array(a_l),
24760 borrow = 0,
24761 base = BASE,
24762 i, difference;
24763 for (i = 0; i < b_l; i++) {
24764 difference = a[i] - borrow - b[i];
24765 if (difference < 0) {
24766 difference += base;
24767 borrow = 1;
24768 } else borrow = 0;
24769 r[i] = difference;
24770 }
24771 for (i = b_l; i < a_l; i++) {
24772 difference = a[i] - borrow;
24773 if (difference < 0) difference += base;
24774 else {
24775 r[i++] = difference;
24776 break;
24777 }
24778 r[i] = difference;
24779 }
24780 for (; i < a_l; i++) {
24781 r[i] = a[i];
24782 }
24783 trim(r);
24784 return r;
24785 }
24786
24787 function subtractAny(a, b, sign) {
24788 var value, isSmall;
24789 if (compareAbs(a, b) >= 0) {
24790 value = subtract(a,b);
24791 } else {
24792 value = subtract(b, a);
24793 sign = !sign;
24794 }
24795 value = arrayToSmall(value);
24796 if (typeof value === "number") {
24797 if (sign) value = -value;
24798 return new SmallInteger(value);
24799 }
24800 return new BigInteger(value, sign);
24801 }
24802
24803 function subtractSmall(a, b, sign) { // assumes a is array, b is number with 0 <= b < MAX_INT
24804 var l = a.length,
24805 r = new Array(l),
24806 carry = -b,
24807 base = BASE,
24808 i, difference;
24809 for (i = 0; i < l; i++) {
24810 difference = a[i] + carry;
24811 carry = Math.floor(difference / base);
24812 difference %= base;
24813 r[i] = difference < 0 ? difference + base : difference;
24814 }
24815 r = arrayToSmall(r);
24816 if (typeof r === "number") {
24817 if (sign) r = -r;
24818 return new SmallInteger(r);
24819 } return new BigInteger(r, sign);
24820 }
24821
24822 BigInteger.prototype.subtract = function (v) {
24823 var n = parseValue(v);
24824 if (this.sign !== n.sign) {
24825 return this.add(n.negate());
24826 }
24827 var a = this.value, b = n.value;
24828 if (n.isSmall)
24829 return subtractSmall(a, Math.abs(b), this.sign);
24830 return subtractAny(a, b, this.sign);
24831 };
24832 BigInteger.prototype.minus = BigInteger.prototype.subtract;
24833
24834 SmallInteger.prototype.subtract = function (v) {
24835 var n = parseValue(v);
24836 var a = this.value;
24837 if (a < 0 !== n.sign) {
24838 return this.add(n.negate());
24839 }
24840 var b = n.value;
24841 if (n.isSmall) {
24842 return new SmallInteger(a - b);
24843 }
24844 return subtractSmall(b, Math.abs(a), a >= 0);
24845 };
24846 SmallInteger.prototype.minus = SmallInteger.prototype.subtract;
24847
24848 BigInteger.prototype.negate = function () {
24849 return new BigInteger(this.value, !this.sign);
24850 };
24851 SmallInteger.prototype.negate = function () {
24852 var sign = this.sign;
24853 var small = new SmallInteger(-this.value);
24854 small.sign = !sign;
24855 return small;
24856 };
24857
24858 BigInteger.prototype.abs = function () {
24859 return new BigInteger(this.value, false);
24860 };
24861 SmallInteger.prototype.abs = function () {
24862 return new SmallInteger(Math.abs(this.value));
24863 };
24864
24865 function multiplyLong(a, b) {
24866 var a_l = a.length,
24867 b_l = b.length,
24868 l = a_l + b_l,
24869 r = createArray(l),
24870 base = BASE,
24871 product, carry, i, a_i, b_j;
24872 for (i = 0; i < a_l; ++i) {
24873 a_i = a[i];
24874 for (var j = 0; j < b_l; ++j) {
24875 b_j = b[j];
24876 product = a_i * b_j + r[i + j];
24877 carry = Math.floor(product / base);
24878 r[i + j] = product - carry * base;
24879 r[i + j + 1] += carry;
24880 }
24881 }
24882 trim(r);
24883 return r;
24884 }
24885
24886 function multiplySmall(a, b) { // assumes a is array, b is number with |b| < BASE
24887 var l = a.length,
24888 r = new Array(l),
24889 base = BASE,
24890 carry = 0,
24891 product, i;
24892 for (i = 0; i < l; i++) {
24893 product = a[i] * b + carry;
24894 carry = Math.floor(product / base);
24895 r[i] = product - carry * base;
24896 }
24897 while (carry > 0) {
24898 r[i++] = carry % base;
24899 carry = Math.floor(carry / base);
24900 }
24901 return r;
24902 }
24903
24904 function shiftLeft(x, n) {
24905 var r = [];
24906 while (n-- > 0) r.push(0);
24907 return r.concat(x);
24908 }
24909
24910 function multiplyKaratsuba(x, y) {
24911 var n = Math.max(x.length, y.length);
24912
24913 if (n <= 30) return multiplyLong(x, y);
24914 n = Math.ceil(n / 2);
24915
24916 var b = x.slice(n),
24917 a = x.slice(0, n),
24918 d = y.slice(n),
24919 c = y.slice(0, n);
24920
24921 var ac = multiplyKaratsuba(a, c),
24922 bd = multiplyKaratsuba(b, d),
24923 abcd = multiplyKaratsuba(addAny(a, b), addAny(c, d));
24924
24925 var product = addAny(addAny(ac, shiftLeft(subtract(subtract(abcd, ac), bd), n)), shiftLeft(bd, 2 * n));
24926 trim(product);
24927 return product;
24928 }
24929
24930 // The following function is derived from a surface fit of a graph plotting the performance difference
24931 // between long multiplication and karatsuba multiplication versus the lengths of the two arrays.
24932 function useKaratsuba(l1, l2) {
24933 return -0.012 * l1 - 0.012 * l2 + 0.000015 * l1 * l2 > 0;
24934 }
24935
24936 BigInteger.prototype.multiply = function (v) {
24937 var value, n = parseValue(v),
24938 a = this.value, b = n.value,
24939 sign = this.sign !== n.sign,
24940 abs;
24941 if (n.isSmall) {
24942 if (b === 0) return Integer[0];
24943 if (b === 1) return this;
24944 if (b === -1) return this.negate();
24945 abs = Math.abs(b);
24946 if (abs < BASE) {
24947 return new BigInteger(multiplySmall(a, abs), sign);
24948 }
24949 b = smallToArray(abs);
24950 }
24951 if (useKaratsuba(a.length, b.length)) // Karatsuba is only faster for certain array sizes
24952 return new BigInteger(multiplyKaratsuba(a, b), sign);
24953 return new BigInteger(multiplyLong(a, b), sign);
24954 };
24955
24956 BigInteger.prototype.times = BigInteger.prototype.multiply;
24957
24958 function multiplySmallAndArray(a, b, sign) { // a >= 0
24959 if (a < BASE) {
24960 return new BigInteger(multiplySmall(b, a), sign);
24961 }
24962 return new BigInteger(multiplyLong(b, smallToArray(a)), sign);
24963 }
24964 SmallInteger.prototype._multiplyBySmall = function (a) {
24965 if (isPrecise(a.value * this.value)) {
24966 return new SmallInteger(a.value * this.value);
24967 }
24968 return multiplySmallAndArray(Math.abs(a.value), smallToArray(Math.abs(this.value)), this.sign !== a.sign);
24969 };
24970 BigInteger.prototype._multiplyBySmall = function (a) {
24971 if (a.value === 0) return Integer[0];
24972 if (a.value === 1) return this;
24973 if (a.value === -1) return this.negate();
24974 return multiplySmallAndArray(Math.abs(a.value), this.value, this.sign !== a.sign);
24975 };
24976 SmallInteger.prototype.multiply = function (v) {
24977 return parseValue(v)._multiplyBySmall(this);
24978 };
24979 SmallInteger.prototype.times = SmallInteger.prototype.multiply;
24980
24981 function square(a) {
24982 var l = a.length,
24983 r = createArray(l + l),
24984 base = BASE,
24985 product, carry, i, a_i, a_j;
24986 for (i = 0; i < l; i++) {
24987 a_i = a[i];
24988 for (var j = 0; j < l; j++) {
24989 a_j = a[j];
24990 product = a_i * a_j + r[i + j];
24991 carry = Math.floor(product / base);
24992 r[i + j] = product - carry * base;
24993 r[i + j + 1] += carry;
24994 }
24995 }
24996 trim(r);
24997 return r;
24998 }
24999
25000 BigInteger.prototype.square = function () {
25001 return new BigInteger(square(this.value), false);
25002 };
25003
25004 SmallInteger.prototype.square = function () {
25005 var value = this.value * this.value;
25006 if (isPrecise(value)) return new SmallInteger(value);
25007 return new BigInteger(square(smallToArray(Math.abs(this.value))), false);
25008 };
25009
25010 function divMod1(a, b) { // Left over from previous version. Performs faster than divMod2 on smaller input sizes.
25011 var a_l = a.length,
25012 b_l = b.length,
25013 base = BASE,
25014 result = createArray(b.length),
25015 divisorMostSignificantDigit = b[b_l - 1],
25016 // normalization
25017 lambda = Math.ceil(base / (2 * divisorMostSignificantDigit)),
25018 remainder = multiplySmall(a, lambda),
25019 divisor = multiplySmall(b, lambda),
25020 quotientDigit, shift, carry, borrow, i, l, q;
25021 if (remainder.length <= a_l) remainder.push(0);
25022 divisor.push(0);
25023 divisorMostSignificantDigit = divisor[b_l - 1];
25024 for (shift = a_l - b_l; shift >= 0; shift--) {
25025 quotientDigit = base - 1;
25026 if (remainder[shift + b_l] !== divisorMostSignificantDigit) {
25027 quotientDigit = Math.floor((remainder[shift + b_l] * base + remainder[shift + b_l - 1]) / divisorMostSignificantDigit);
25028 }
25029 // quotientDigit <= base - 1
25030 carry = 0;
25031 borrow = 0;
25032 l = divisor.length;
25033 for (i = 0; i < l; i++) {
25034 carry += quotientDigit * divisor[i];
25035 q = Math.floor(carry / base);
25036 borrow += remainder[shift + i] - (carry - q * base);
25037 carry = q;
25038 if (borrow < 0) {
25039 remainder[shift + i] = borrow + base;
25040 borrow = -1;
25041 } else {
25042 remainder[shift + i] = borrow;
25043 borrow = 0;
25044 }
25045 }
25046 while (borrow !== 0) {
25047 quotientDigit -= 1;
25048 carry = 0;
25049 for (i = 0; i < l; i++) {
25050 carry += remainder[shift + i] - base + divisor[i];
25051 if (carry < 0) {
25052 remainder[shift + i] = carry + base;
25053 carry = 0;
25054 } else {
25055 remainder[shift + i] = carry;
25056 carry = 1;
25057 }
25058 }
25059 borrow += carry;
25060 }
25061 result[shift] = quotientDigit;
25062 }
25063 // denormalization
25064 remainder = divModSmall(remainder, lambda)[0];
25065 return [arrayToSmall(result), arrayToSmall(remainder)];
25066 }
25067
25068 function divMod2(a, b) { // Implementation idea shamelessly stolen from Silent Matt's library http://silentmatt.com/biginteger/
25069 // Performs faster than divMod1 on larger input sizes.
25070 var a_l = a.length,
25071 b_l = b.length,
25072 result = [],
25073 part = [],
25074 base = BASE,
25075 guess, xlen, highx, highy, check;
25076 while (a_l) {
25077 part.unshift(a[--a_l]);
25078 if (compareAbs(part, b) < 0) {
25079 result.push(0);
25080 continue;
25081 }
25082 xlen = part.length;
25083 highx = part[xlen - 1] * base + part[xlen - 2];
25084 highy = b[b_l - 1] * base + b[b_l - 2];
25085 if (xlen > b_l) {
25086 highx = (highx + 1) * base;
25087 }
25088 guess = Math.ceil(highx / highy);
25089 do {
25090 check = multiplySmall(b, guess);
25091 if (compareAbs(check, part) <= 0) break;
25092 guess--;
25093 } while (guess);
25094 result.push(guess);
25095 part = subtract(part, check);
25096 }
25097 result.reverse();
25098 return [arrayToSmall(result), arrayToSmall(part)];
25099 }
25100
25101 function divModSmall(value, lambda) {
25102 var length = value.length,
25103 quotient = createArray(length),
25104 base = BASE,
25105 i, q, remainder, divisor;
25106 remainder = 0;
25107 for (i = length - 1; i >= 0; --i) {
25108 divisor = remainder * base + value[i];
25109 q = truncate(divisor / lambda);
25110 remainder = divisor - q * lambda;
25111 quotient[i] = q | 0;
25112 }
25113 return [quotient, remainder | 0];
25114 }
25115
25116 function divModAny(self, v) {
25117 var value, n = parseValue(v);
25118 var a = self.value, b = n.value;
25119 var quotient;
25120 if (b === 0) throw new Error("Cannot divide by zero");
25121 if (self.isSmall) {
25122 if (n.isSmall) {
25123 return [new SmallInteger(truncate(a / b)), new SmallInteger(a % b)];
25124 }
25125 return [Integer[0], self];
25126 }
25127 if (n.isSmall) {
25128 if (b === 1) return [self, Integer[0]];
25129 if (b == -1) return [self.negate(), Integer[0]];
25130 var abs = Math.abs(b);
25131 if (abs < BASE) {
25132 value = divModSmall(a, abs);
25133 quotient = arrayToSmall(value[0]);
25134 var remainder = value[1];
25135 if (self.sign) remainder = -remainder;
25136 if (typeof quotient === "number") {
25137 if (self.sign !== n.sign) quotient = -quotient;
25138 return [new SmallInteger(quotient), new SmallInteger(remainder)];
25139 }
25140 return [new BigInteger(quotient, self.sign !== n.sign), new SmallInteger(remainder)];
25141 }
25142 b = smallToArray(abs);
25143 }
25144 var comparison = compareAbs(a, b);
25145 if (comparison === -1) return [Integer[0], self];
25146 if (comparison === 0) return [Integer[self.sign === n.sign ? 1 : -1], Integer[0]];
25147
25148 // divMod1 is faster on smaller input sizes
25149 if (a.length + b.length <= 200)
25150 value = divMod1(a, b);
25151 else value = divMod2(a, b);
25152
25153 quotient = value[0];
25154 var qSign = self.sign !== n.sign,
25155 mod = value[1],
25156 mSign = self.sign;
25157 if (typeof quotient === "number") {
25158 if (qSign) quotient = -quotient;
25159 quotient = new SmallInteger(quotient);
25160 } else quotient = new BigInteger(quotient, qSign);
25161 if (typeof mod === "number") {
25162 if (mSign) mod = -mod;
25163 mod = new SmallInteger(mod);
25164 } else mod = new BigInteger(mod, mSign);
25165 return [quotient, mod];
25166 }
25167
25168 BigInteger.prototype.divmod = function (v) {
25169 var result = divModAny(this, v);
25170 return {
25171 quotient: result[0],
25172 remainder: result[1]
25173 };
25174 };
25175 SmallInteger.prototype.divmod = BigInteger.prototype.divmod;
25176
25177 BigInteger.prototype.divide = function (v) {
25178 return divModAny(this, v)[0];
25179 };
25180 SmallInteger.prototype.over = SmallInteger.prototype.divide = BigInteger.prototype.over = BigInteger.prototype.divide;
25181
25182 BigInteger.prototype.mod = function (v) {
25183 return divModAny(this, v)[1];
25184 };
25185 SmallInteger.prototype.remainder = SmallInteger.prototype.mod = BigInteger.prototype.remainder = BigInteger.prototype.mod;
25186
25187 BigInteger.prototype.pow = function (v) {
25188 var n = parseValue(v),
25189 a = this.value,
25190 b = n.value,
25191 value, x, y;
25192 if (b === 0) return Integer[1];
25193 if (a === 0) return Integer[0];
25194 if (a === 1) return Integer[1];
25195 if (a === -1) return n.isEven() ? Integer[1] : Integer[-1];
25196 if (n.sign) {
25197 return Integer[0];
25198 }
25199 if (!n.isSmall) throw new Error("The exponent " + n.toString() + " is too large.");
25200 if (this.isSmall) {
25201 if (isPrecise(value = Math.pow(a, b)))
25202 return new SmallInteger(truncate(value));
25203 }
25204 x = this;
25205 y = Integer[1];
25206 while (true) {
25207 if (b & 1 === 1) {
25208 y = y.times(x);
25209 --b;
25210 }
25211 if (b === 0) break;
25212 b /= 2;
25213 x = x.square();
25214 }
25215 return y;
25216 };
25217 SmallInteger.prototype.pow = BigInteger.prototype.pow;
25218
25219 BigInteger.prototype.modPow = function (exp, mod) {
25220 exp = parseValue(exp);
25221 mod = parseValue(mod);
25222 if (mod.isZero()) throw new Error("Cannot take modPow with modulus 0");
25223 var r = Integer[1],
25224 base = this.mod(mod);
25225 while (exp.isPositive()) {
25226 if (base.isZero()) return Integer[0];
25227 if (exp.isOdd()) r = r.multiply(base).mod(mod);
25228 exp = exp.divide(2);
25229 base = base.square().mod(mod);
25230 }
25231 return r;
25232 };
25233 SmallInteger.prototype.modPow = BigInteger.prototype.modPow;
25234
25235 function compareAbs(a, b) {
25236 if (a.length !== b.length) {
25237 return a.length > b.length ? 1 : -1;
25238 }
25239 for (var i = a.length - 1; i >= 0; i--) {
25240 if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1;
25241 }
25242 return 0;
25243 }
25244
25245 BigInteger.prototype.compareAbs = function (v) {
25246 var n = parseValue(v),
25247 a = this.value,
25248 b = n.value;
25249 if (n.isSmall) return 1;
25250 return compareAbs(a, b);
25251 };
25252 SmallInteger.prototype.compareAbs = function (v) {
25253 var n = parseValue(v),
25254 a = Math.abs(this.value),
25255 b = n.value;
25256 if (n.isSmall) {
25257 b = Math.abs(b);
25258 return a === b ? 0 : a > b ? 1 : -1;
25259 }
25260 return -1;
25261 };
25262
25263 BigInteger.prototype.compare = function (v) {
25264 // See discussion about comparison with Infinity:
25265 // https://github.com/peterolson/BigInteger.js/issues/61
25266 if (v === Infinity) {
25267 return -1;
25268 }
25269 if (v === -Infinity) {
25270 return 1;
25271 }
25272
25273 var n = parseValue(v),
25274 a = this.value,
25275 b = n.value;
25276 if (this.sign !== n.sign) {
25277 return n.sign ? 1 : -1;
25278 }
25279 if (n.isSmall) {
25280 return this.sign ? -1 : 1;
25281 }
25282 return compareAbs(a, b) * (this.sign ? -1 : 1);
25283 };
25284 BigInteger.prototype.compareTo = BigInteger.prototype.compare;
25285
25286 SmallInteger.prototype.compare = function (v) {
25287 if (v === Infinity) {
25288 return -1;
25289 }
25290 if (v === -Infinity) {
25291 return 1;
25292 }
25293
25294 var n = parseValue(v),
25295 a = this.value,
25296 b = n.value;
25297 if (n.isSmall) {
25298 return a == b ? 0 : a > b ? 1 : -1;
25299 }
25300 if (a < 0 !== n.sign) {
25301 return a < 0 ? -1 : 1;
25302 }
25303 return a < 0 ? 1 : -1;
25304 };
25305 SmallInteger.prototype.compareTo = SmallInteger.prototype.compare;
25306
25307 BigInteger.prototype.equals = function (v) {
25308 return this.compare(v) === 0;
25309 };
25310 SmallInteger.prototype.eq = SmallInteger.prototype.equals = BigInteger.prototype.eq = BigInteger.prototype.equals;
25311
25312 BigInteger.prototype.notEquals = function (v) {
25313 return this.compare(v) !== 0;
25314 };
25315 SmallInteger.prototype.neq = SmallInteger.prototype.notEquals = BigInteger.prototype.neq = BigInteger.prototype.notEquals;
25316
25317 BigInteger.prototype.greater = function (v) {
25318 return this.compare(v) > 0;
25319 };
25320 SmallInteger.prototype.gt = SmallInteger.prototype.greater = BigInteger.prototype.gt = BigInteger.prototype.greater;
25321
25322 BigInteger.prototype.lesser = function (v) {
25323 return this.compare(v) < 0;
25324 };
25325 SmallInteger.prototype.lt = SmallInteger.prototype.lesser = BigInteger.prototype.lt = BigInteger.prototype.lesser;
25326
25327 BigInteger.prototype.greaterOrEquals = function (v) {
25328 return this.compare(v) >= 0;
25329 };
25330 SmallInteger.prototype.geq = SmallInteger.prototype.greaterOrEquals = BigInteger.prototype.geq = BigInteger.prototype.greaterOrEquals;
25331
25332 BigInteger.prototype.lesserOrEquals = function (v) {
25333 return this.compare(v) <= 0;
25334 };
25335 SmallInteger.prototype.leq = SmallInteger.prototype.lesserOrEquals = BigInteger.prototype.leq = BigInteger.prototype.lesserOrEquals;
25336
25337 BigInteger.prototype.isEven = function () {
25338 return (this.value[0] & 1) === 0;
25339 };
25340 SmallInteger.prototype.isEven = function () {
25341 return (this.value & 1) === 0;
25342 };
25343
25344 BigInteger.prototype.isOdd = function () {
25345 return (this.value[0] & 1) === 1;
25346 };
25347 SmallInteger.prototype.isOdd = function () {
25348 return (this.value & 1) === 1;
25349 };
25350
25351 BigInteger.prototype.isPositive = function () {
25352 return !this.sign;
25353 };
25354 SmallInteger.prototype.isPositive = function () {
25355 return this.value > 0;
25356 };
25357
25358 BigInteger.prototype.isNegative = function () {
25359 return this.sign;
25360 };
25361 SmallInteger.prototype.isNegative = function () {
25362 return this.value < 0;
25363 };
25364
25365 BigInteger.prototype.isUnit = function () {
25366 return false;
25367 };
25368 SmallInteger.prototype.isUnit = function () {
25369 return Math.abs(this.value) === 1;
25370 };
25371
25372 BigInteger.prototype.isZero = function () {
25373 return false;
25374 };
25375 SmallInteger.prototype.isZero = function () {
25376 return this.value === 0;
25377 };
25378 BigInteger.prototype.isDivisibleBy = function (v) {
25379 var n = parseValue(v);
25380 var value = n.value;
25381 if (value === 0) return false;
25382 if (value === 1) return true;
25383 if (value === 2) return this.isEven();
25384 return this.mod(n).equals(Integer[0]);
25385 };
25386 SmallInteger.prototype.isDivisibleBy = BigInteger.prototype.isDivisibleBy;
25387
25388 function isBasicPrime(v) {
25389 var n = v.abs();
25390 if (n.isUnit()) return false;
25391 if (n.equals(2) || n.equals(3) || n.equals(5)) return true;
25392 if (n.isEven() || n.isDivisibleBy(3) || n.isDivisibleBy(5)) return false;
25393 if (n.lesser(25)) return true;
25394 // we don't know if it's prime: let the other functions figure it out
25395 }
25396
25397 BigInteger.prototype.isPrime = function () {
25398 var isPrime = isBasicPrime(this);
25399 if (isPrime !== undefined) return isPrime;
25400 var n = this.abs(),
25401 nPrev = n.prev();
25402 var a = [2, 3, 5, 7, 11, 13, 17, 19],
25403 b = nPrev,
25404 d, t, i, x;
25405 while (b.isEven()) b = b.divide(2);
25406 for (i = 0; i < a.length; i++) {
25407 x = bigInt(a[i]).modPow(b, n);
25408 if (x.equals(Integer[1]) || x.equals(nPrev)) continue;
25409 for (t = true, d = b; t && d.lesser(nPrev) ; d = d.multiply(2)) {
25410 x = x.square().mod(n);
25411 if (x.equals(nPrev)) t = false;
25412 }
25413 if (t) return false;
25414 }
25415 return true;
25416 };
25417 SmallInteger.prototype.isPrime = BigInteger.prototype.isPrime;
25418
25419 BigInteger.prototype.isProbablePrime = function (iterations) {
25420 var isPrime = isBasicPrime(this);
25421 if (isPrime !== undefined) return isPrime;
25422 var n = this.abs();
25423 var t = iterations === undefined ? 5 : iterations;
25424 // use the Fermat primality test
25425 for (var i = 0; i < t; i++) {
25426 var a = bigInt.randBetween(2, n.minus(2));
25427 if (!a.modPow(n.prev(), n).isUnit()) return false; // definitely composite
25428 }
25429 return true; // large chance of being prime
25430 };
25431 SmallInteger.prototype.isProbablePrime = BigInteger.prototype.isProbablePrime;
25432
25433 BigInteger.prototype.next = function () {
25434 var value = this.value;
25435 if (this.sign) {
25436 return subtractSmall(value, 1, this.sign);
25437 }
25438 return new BigInteger(addSmall(value, 1), this.sign);
25439 };
25440 SmallInteger.prototype.next = function () {
25441 var value = this.value;
25442 if (value + 1 < MAX_INT) return new SmallInteger(value + 1);
25443 return new BigInteger(MAX_INT_ARR, false);
25444 };
25445
25446 BigInteger.prototype.prev = function () {
25447 var value = this.value;
25448 if (this.sign) {
25449 return new BigInteger(addSmall(value, 1), true);
25450 }
25451 return subtractSmall(value, 1, this.sign);
25452 };
25453 SmallInteger.prototype.prev = function () {
25454 var value = this.value;
25455 if (value - 1 > -MAX_INT) return new SmallInteger(value - 1);
25456 return new BigInteger(MAX_INT_ARR, true);
25457 };
25458
25459 var powersOfTwo = [1];
25460 while (powersOfTwo[powersOfTwo.length - 1] <= BASE) powersOfTwo.push(2 * powersOfTwo[powersOfTwo.length - 1]);
25461 var powers2Length = powersOfTwo.length, highestPower2 = powersOfTwo[powers2Length - 1];
25462
25463 function shift_isSmall(n) {
25464 return ((typeof n === "number" || typeof n === "string") && +Math.abs(n) <= BASE) ||
25465 (n instanceof BigInteger && n.value.length <= 1);
25466 }
25467
25468 BigInteger.prototype.shiftLeft = function (n) {
25469 if (!shift_isSmall(n)) {
25470 throw new Error(String(n) + " is too large for shifting.");
25471 }
25472 n = +n;
25473 if (n < 0) return this.shiftRight(-n);
25474 var result = this;
25475 while (n >= powers2Length) {
25476 result = result.multiply(highestPower2);
25477 n -= powers2Length - 1;
25478 }
25479 return result.multiply(powersOfTwo[n]);
25480 };
25481 SmallInteger.prototype.shiftLeft = BigInteger.prototype.shiftLeft;
25482
25483 BigInteger.prototype.shiftRight = function (n) {
25484 var remQuo;
25485 if (!shift_isSmall(n)) {
25486 throw new Error(String(n) + " is too large for shifting.");
25487 }
25488 n = +n;
25489 if (n < 0) return this.shiftLeft(-n);
25490 var result = this;
25491 while (n >= powers2Length) {
25492 if (result.isZero()) return result;
25493 remQuo = divModAny(result, highestPower2);
25494 result = remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
25495 n -= powers2Length - 1;
25496 }
25497 remQuo = divModAny(result, powersOfTwo[n]);
25498 return remQuo[1].isNegative() ? remQuo[0].prev() : remQuo[0];
25499 };
25500 SmallInteger.prototype.shiftRight = BigInteger.prototype.shiftRight;
25501
25502 function bitwise(x, y, fn) {
25503 y = parseValue(y);
25504 var xSign = x.isNegative(), ySign = y.isNegative();
25505 var xRem = xSign ? x.not() : x,
25506 yRem = ySign ? y.not() : y;
25507 var xBits = [], yBits = [];
25508 var xStop = false, yStop = false;
25509 while (!xStop || !yStop) {
25510 if (xRem.isZero()) { // virtual sign extension for simulating two's complement
25511 xStop = true;
25512 xBits.push(xSign ? 1 : 0);
25513 }
25514 else if (xSign) xBits.push(xRem.isEven() ? 1 : 0); // two's complement for negative numbers
25515 else xBits.push(xRem.isEven() ? 0 : 1);
25516
25517 if (yRem.isZero()) {
25518 yStop = true;
25519 yBits.push(ySign ? 1 : 0);
25520 }
25521 else if (ySign) yBits.push(yRem.isEven() ? 1 : 0);
25522 else yBits.push(yRem.isEven() ? 0 : 1);
25523
25524 xRem = xRem.over(2);
25525 yRem = yRem.over(2);
25526 }
25527 var result = [];
25528 for (var i = 0; i < xBits.length; i++) result.push(fn(xBits[i], yBits[i]));
25529 var sum = bigInt(result.pop()).negate().times(bigInt(2).pow(result.length));
25530 while (result.length) {
25531 sum = sum.add(bigInt(result.pop()).times(bigInt(2).pow(result.length)));
25532 }
25533 return sum;
25534 }
25535
25536 BigInteger.prototype.not = function () {
25537 return this.negate().prev();
25538 };
25539 SmallInteger.prototype.not = BigInteger.prototype.not;
25540
25541 BigInteger.prototype.and = function (n) {
25542 return bitwise(this, n, function (a, b) { return a & b; });
25543 };
25544 SmallInteger.prototype.and = BigInteger.prototype.and;
25545
25546 BigInteger.prototype.or = function (n) {
25547 return bitwise(this, n, function (a, b) { return a | b; });
25548 };
25549 SmallInteger.prototype.or = BigInteger.prototype.or;
25550
25551 BigInteger.prototype.xor = function (n) {
25552 return bitwise(this, n, function (a, b) { return a ^ b; });
25553 };
25554 SmallInteger.prototype.xor = BigInteger.prototype.xor;
25555
25556 var LOBMASK_I = 1 << 30, LOBMASK_BI = (BASE & -BASE) * (BASE & -BASE) | LOBMASK_I;
25557 function roughLOB(n) { // get lowestOneBit (rough)
25558 // SmallInteger: return Min(lowestOneBit(n), 1 << 30)
25559 // BigInteger: return Min(lowestOneBit(n), 1 << 14) [BASE=1e7]
25560 var v = n.value, x = typeof v === "number" ? v | LOBMASK_I : v[0] + v[1] * BASE | LOBMASK_BI;
25561 return x & -x;
25562 }
25563
25564 function max(a, b) {
25565 a = parseValue(a);
25566 b = parseValue(b);
25567 return a.greater(b) ? a : b;
25568 }
25569 function min(a,b) {
25570 a = parseValue(a);
25571 b = parseValue(b);
25572 return a.lesser(b) ? a : b;
25573 }
25574 function gcd(a, b) {
25575 a = parseValue(a).abs();
25576 b = parseValue(b).abs();
25577 if (a.equals(b)) return a;
25578 if (a.isZero()) return b;
25579 if (b.isZero()) return a;
25580 var c = Integer[1], d, t;
25581 while (a.isEven() && b.isEven()) {
25582 d = Math.min(roughLOB(a), roughLOB(b));
25583 a = a.divide(d);
25584 b = b.divide(d);
25585 c = c.multiply(d);
25586 }
25587 while (a.isEven()) {
25588 a = a.divide(roughLOB(a));
25589 }
25590 do {
25591 while (b.isEven()) {
25592 b = b.divide(roughLOB(b));
25593 }
25594 if (a.greater(b)) {
25595 t = b; b = a; a = t;
25596 }
25597 b = b.subtract(a);
25598 } while (!b.isZero());
25599 return c.isUnit() ? a : a.multiply(c);
25600 }
25601 function lcm(a, b) {
25602 a = parseValue(a).abs();
25603 b = parseValue(b).abs();
25604 return a.divide(gcd(a, b)).multiply(b);
25605 }
25606 function randBetween(a, b) {
25607 a = parseValue(a);
25608 b = parseValue(b);
25609 var low = min(a, b), high = max(a, b);
25610 var range = high.subtract(low);
25611 if (range.isSmall) return low.add(Math.round(Math.random() * range));
25612 var length = range.value.length - 1;
25613 var result = [], restricted = true;
25614 for (var i = length; i >= 0; i--) {
25615 var top = restricted ? range.value[i] : BASE;
25616 var digit = truncate(Math.random() * top);
25617 result.unshift(digit);
25618 if (digit < top) restricted = false;
25619 }
25620 result = arrayToSmall(result);
25621 return low.add(typeof result === "number" ? new SmallInteger(result) : new BigInteger(result, false));
25622 }
25623 var parseBase = function (text, base) {
25624 var val = Integer[0], pow = Integer[1],
25625 length = text.length;
25626 if (2 <= base && base <= 36) {
25627 if (length <= LOG_MAX_INT / Math.log(base)) {
25628 return new SmallInteger(parseInt(text, base));
25629 }
25630 }
25631 base = parseValue(base);
25632 var digits = [];
25633 var i;
25634 var isNegative = text[0] === "-";
25635 for (i = isNegative ? 1 : 0; i < text.length; i++) {
25636 var c = text[i].toLowerCase(),
25637 charCode = c.charCodeAt(0);
25638 if (48 <= charCode && charCode <= 57) digits.push(parseValue(c));
25639 else if (97 <= charCode && charCode <= 122) digits.push(parseValue(c.charCodeAt(0) - 87));
25640 else if (c === "<") {
25641 var start = i;
25642 do { i++; } while (text[i] !== ">");
25643 digits.push(parseValue(text.slice(start + 1, i)));
25644 }
25645 else throw new Error(c + " is not a valid character");
25646 }
25647 digits.reverse();
25648 for (i = 0; i < digits.length; i++) {
25649 val = val.add(digits[i].times(pow));
25650 pow = pow.times(base);
25651 }
25652 return isNegative ? val.negate() : val;
25653 };
25654
25655 function stringify(digit) {
25656 var v = digit.value;
25657 if (typeof v === "number") v = [v];
25658 if (v.length === 1 && v[0] <= 35) {
25659 return "0123456789abcdefghijklmnopqrstuvwxyz".charAt(v[0]);
25660 }
25661 return "<" + v + ">";
25662 }
25663 function toBase(n, base) {
25664 base = bigInt(base);
25665 if (base.isZero()) {
25666 if (n.isZero()) return "0";
25667 throw new Error("Cannot convert nonzero numbers to base 0.");
25668 }
25669 if (base.equals(-1)) {
25670 if (n.isZero()) return "0";
25671 if (n.isNegative()) return new Array(1 - n).join("10");
25672 return "1" + new Array(+n).join("01");
25673 }
25674 var minusSign = "";
25675 if (n.isNegative() && base.isPositive()) {
25676 minusSign = "-";
25677 n = n.abs();
25678 }
25679 if (base.equals(1)) {
25680 if (n.isZero()) return "0";
25681 return minusSign + new Array(+n + 1).join(1);
25682 }
25683 var out = [];
25684 var left = n, divmod;
25685 while (left.isNegative() || left.compareAbs(base) >= 0) {
25686 divmod = left.divmod(base);
25687 left = divmod.quotient;
25688 var digit = divmod.remainder;
25689 if (digit.isNegative()) {
25690 digit = base.minus(digit).abs();
25691 left = left.next();
25692 }
25693 out.push(stringify(digit));
25694 }
25695 out.push(stringify(left));
25696 return minusSign + out.reverse().join("");
25697 }
25698
25699 BigInteger.prototype.toString = function (radix) {
25700 if (radix === undefined) radix = 10;
25701 if (radix !== 10) return toBase(this, radix);
25702 var v = this.value, l = v.length, str = String(v[--l]), zeros = "0000000", digit;
25703 while (--l >= 0) {
25704 digit = String(v[l]);
25705 str += zeros.slice(digit.length) + digit;
25706 }
25707 var sign = this.sign ? "-" : "";
25708 return sign + str;
25709 };
25710 SmallInteger.prototype.toString = function (radix) {
25711 if (radix === undefined) radix = 10;
25712 if (radix != 10) return toBase(this, radix);
25713 return String(this.value);
25714 };
25715
25716 BigInteger.prototype.valueOf = function () {
25717 return +this.toString();
25718 };
25719 BigInteger.prototype.toJSNumber = BigInteger.prototype.valueOf;
25720
25721 SmallInteger.prototype.valueOf = function () {
25722 return this.value;
25723 };
25724 SmallInteger.prototype.toJSNumber = SmallInteger.prototype.valueOf;
25725
25726 function parseStringValue(v) {
25727 if (isPrecise(+v)) {
25728 var x = +v;
25729 if (x === truncate(x))
25730 return new SmallInteger(x);
25731 throw "Invalid integer: " + v;
25732 }
25733 var sign = v[0] === "-";
25734 if (sign) v = v.slice(1);
25735 var split = v.split(/e/i);
25736 if (split.length > 2) throw new Error("Invalid integer: " + split.join("e"));
25737 if (split.length === 2) {
25738 var exp = split[1];
25739 if (exp[0] === "+") exp = exp.slice(1);
25740 exp = +exp;
25741 if (exp !== truncate(exp) || !isPrecise(exp)) throw new Error("Invalid integer: " + exp + " is not a valid exponent.");
25742 var text = split[0];
25743 var decimalPlace = text.indexOf(".");
25744 if (decimalPlace >= 0) {
25745 exp -= text.length - decimalPlace - 1;
25746 text = text.slice(0, decimalPlace) + text.slice(decimalPlace + 1);
25747 }
25748 if (exp < 0) throw new Error("Cannot include negative exponent part for integers");
25749 text += (new Array(exp + 1)).join("0");
25750 v = text;
25751 }
25752 var isValid = /^([0-9][0-9]*)$/.test(v);
25753 if (!isValid) throw new Error("Invalid integer: " + v);
25754 var r = [], max = v.length, l = LOG_BASE, min = max - l;
25755 while (max > 0) {
25756 r.push(+v.slice(min, max));
25757 min -= l;
25758 if (min < 0) min = 0;
25759 max -= l;
25760 }
25761 trim(r);
25762 return new BigInteger(r, sign);
25763 }
25764
25765 function parseNumberValue(v) {
25766 if (isPrecise(v)) {
25767 if (v !== truncate(v)) throw new Error(v + " is not an integer.");
25768 return new SmallInteger(v);
25769 }
25770 return parseStringValue(v.toString());
25771 }
25772
25773 function parseValue(v) {
25774 if (typeof v === "number") {
25775 return parseNumberValue(v);
25776 }
25777 if (typeof v === "string") {
25778 return parseStringValue(v);
25779 }
25780 return v;
25781 }
25782 // Pre-define numbers in range [-999,999]
25783 for (var i = 0; i < 1000; i++) {
25784 Integer[i] = new SmallInteger(i);
25785 if (i > 0) Integer[-i] = new SmallInteger(-i);
25786 }
25787 // Backwards compatibility
25788 Integer.one = Integer[1];
25789 Integer.zero = Integer[0];
25790 Integer.minusOne = Integer[-1];
25791 Integer.max = max;
25792 Integer.min = min;
25793 Integer.gcd = gcd;
25794 Integer.lcm = lcm;
25795 Integer.isInstance = function (x) { return x instanceof BigInteger || x instanceof SmallInteger; };
25796 Integer.randBetween = randBetween;
25797 return Integer;
25798})();
25799
25800// Node.js check
25801if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
25802 module.exports = bigInt;
25803}
25804
25805},{}],3:[function(require,module,exports){
25806window.Algebrite = require('../dist/algebrite')
25807},{"../dist/algebrite":1}]},{},[3]);