UNPKG

615 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.12.7
2(function() {
3 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,
4 slice = [].slice;
5
6 bigInt = require('big-integer');
7
8 version = "1.1.2";
9
10 SELFTEST = 1;
11
12 NSYM = 1000;
13
14 DEBUG = false;
15
16 PRINTOUTRESULT = false;
17
18 PRINTMODE_LATEX = "PRINTMODE_LATEX";
19
20 PRINTMODE_2DASCII = "PRINTMODE_2DASCII";
21
22 PRINTMODE_FULL = "PRINTMODE_FULL";
23
24 PRINTMODE_PLAIN = "PRINTMODE_PLAIN";
25
26 PRINTMODE_LIST = "PRINTMODE_LIST";
27
28 environment_printmode = PRINTMODE_PLAIN;
29
30 printMode = PRINTMODE_PLAIN;
31
32 dontCreateNewRadicalsInDenominatorWhenEvalingMultiplication = true;
33
34 recursionLevelNestedRadicalsRemoval = 0;
35
36 do_simplify_nested_radicals = true;
37
38 avoidCalculatingPowersIntoArctans = true;
39
40 rational = (function() {
41 function rational() {}
42
43 rational.prototype.a = null;
44
45 rational.prototype.b = null;
46
47 return rational;
48
49 })();
50
51 U = (function() {
52 U.prototype.cons = null;
53
54 U.prototype.printname = "";
55
56 U.prototype.str = "";
57
58 U.prototype.tensor = null;
59
60 U.prototype.q = null;
61
62 U.prototype.d = 0.0;
63
64 U.prototype.k = 0;
65
66 U.prototype.tag = 0;
67
68 U.prototype.toString = function() {
69 return print_expr(this);
70 };
71
72 U.prototype.toLatexString = function() {
73 return collectLatexStringFromReturnValue(this);
74 };
75
76 function U() {
77 this.cons = {};
78 this.cons.car = null;
79 this.cons.cdr = null;
80 this.q = new rational();
81 }
82
83 return U;
84
85 })();
86
87 errorMessage = "";
88
89 CONS = 0;
90
91 NUM = 1;
92
93 DOUBLE = 2;
94
95 STR = 3;
96
97 TENSOR = 4;
98
99 SYM = 5;
100
101 counter = 0;
102
103 ABS = counter++;
104
105 ADD = counter++;
106
107 ADJ = counter++;
108
109 AND = counter++;
110
111 APPROXRATIO = counter++;
112
113 ARCCOS = counter++;
114
115 ARCCOSH = counter++;
116
117 ARCSIN = counter++;
118
119 ARCSINH = counter++;
120
121 ARCTAN = counter++;
122
123 ARCTANH = counter++;
124
125 ARG = counter++;
126
127 ATOMIZE = counter++;
128
129 BESSELJ = counter++;
130
131 BESSELY = counter++;
132
133 BINDING = counter++;
134
135 BINOMIAL = counter++;
136
137 CEILING = counter++;
138
139 CHECK = counter++;
140
141 CHOOSE = counter++;
142
143 CIRCEXP = counter++;
144
145 CLEAR = counter++;
146
147 CLEARALL = counter++;
148
149 CLEARPATTERNS = counter++;
150
151 CLOCK = counter++;
152
153 COEFF = counter++;
154
155 COFACTOR = counter++;
156
157 CONDENSE = counter++;
158
159 CONJ = counter++;
160
161 CONTRACT = counter++;
162
163 COS = counter++;
164
165 COSH = counter++;
166
167 DECOMP = counter++;
168
169 DEFINT = counter++;
170
171 DEGREE = counter++;
172
173 DENOMINATOR = counter++;
174
175 DERIVATIVE = counter++;
176
177 DET = counter++;
178
179 DIM = counter++;
180
181 DIRAC = counter++;
182
183 DIVISORS = counter++;
184
185 DO = counter++;
186
187 DOT = counter++;
188
189 DRAW = counter++;
190
191 DSOLVE = counter++;
192
193 EIGEN = counter++;
194
195 EIGENVAL = counter++;
196
197 EIGENVEC = counter++;
198
199 ERF = counter++;
200
201 ERFC = counter++;
202
203 EVAL = counter++;
204
205 EXP = counter++;
206
207 EXPAND = counter++;
208
209 EXPCOS = counter++;
210
211 EXPSIN = counter++;
212
213 FACTOR = counter++;
214
215 FACTORIAL = counter++;
216
217 FACTORPOLY = counter++;
218
219 FILTER = counter++;
220
221 FLOATF = counter++;
222
223 FLOOR = counter++;
224
225 FOR = counter++;
226
227 FUNCTION = counter++;
228
229 GAMMA = counter++;
230
231 GCD = counter++;
232
233 HERMITE = counter++;
234
235 HILBERT = counter++;
236
237 IMAG = counter++;
238
239 INDEX = counter++;
240
241 INNER = counter++;
242
243 INTEGRAL = counter++;
244
245 INV = counter++;
246
247 INVG = counter++;
248
249 ISINTEGER = counter++;
250
251 ISPRIME = counter++;
252
253 LAGUERRE = counter++;
254
255 LCM = counter++;
256
257 LEADING = counter++;
258
259 LEGENDRE = counter++;
260
261 LOG = counter++;
262
263 LOOKUP = counter++;
264
265 MOD = counter++;
266
267 MULTIPLY = counter++;
268
269 NOT = counter++;
270
271 NROOTS = counter++;
272
273 NUMBER = counter++;
274
275 NUMERATOR = counter++;
276
277 OPERATOR = counter++;
278
279 OR = counter++;
280
281 OUTER = counter++;
282
283 PATTERN = counter++;
284
285 PATTERNSINFO = counter++;
286
287 POLAR = counter++;
288
289 POWER = counter++;
290
291 PRIME = counter++;
292
293 PRINT_LEAVE_E_ALONE = counter++;
294
295 PRINT_LEAVE_X_ALONE = counter++;
296
297 PRINT = counter++;
298
299 PRINT2DASCII = counter++;
300
301 PRINTFULL = counter++;
302
303 PRINTLATEX = counter++;
304
305 PRINTLIST = counter++;
306
307 PRINTPLAIN = counter++;
308
309 PRODUCT = counter++;
310
311 QUOTE = counter++;
312
313 QUOTIENT = counter++;
314
315 RANK = counter++;
316
317 RATIONALIZE = counter++;
318
319 REAL = counter++;
320
321 ROUND = counter++;
322
323 YYRECT = counter++;
324
325 ROOTS = counter++;
326
327 SETQ = counter++;
328
329 SGN = counter++;
330
331 SILENTPATTERN = counter++;
332
333 SIMPLIFY = counter++;
334
335 SIN = counter++;
336
337 SINH = counter++;
338
339 SHAPE = counter++;
340
341 SQRT = counter++;
342
343 STOP = counter++;
344
345 SUBST = counter++;
346
347 SUM = counter++;
348
349 SYMBOLSINFO = counter++;
350
351 TAN = counter++;
352
353 TANH = counter++;
354
355 TAYLOR = counter++;
356
357 TEST = counter++;
358
359 TESTEQ = counter++;
360
361 TESTGE = counter++;
362
363 TESTGT = counter++;
364
365 TESTLE = counter++;
366
367 TESTLT = counter++;
368
369 TRANSPOSE = counter++;
370
371 UNIT = counter++;
372
373 ZERO = counter++;
374
375 NIL = counter++;
376
377 LAST = counter++;
378
379 LAST_PRINT = counter++;
380
381 LAST_2DASCII_PRINT = counter++;
382
383 LAST_FULL_PRINT = counter++;
384
385 LAST_LATEX_PRINT = counter++;
386
387 LAST_LIST_PRINT = counter++;
388
389 LAST_PLAIN_PRINT = counter++;
390
391 AUTOEXPAND = counter++;
392
393 BAKE = counter++;
394
395 ASSUME_REAL_VARIABLES = counter++;
396
397 TRACE = counter++;
398
399 YYE = counter++;
400
401 DRAWX = counter++;
402
403 METAA = counter++;
404
405 METAB = counter++;
406
407 METAX = counter++;
408
409 SECRETX = counter++;
410
411 VERSION = counter++;
412
413 PI = counter++;
414
415 SYMBOL_A = counter++;
416
417 SYMBOL_B = counter++;
418
419 SYMBOL_C = counter++;
420
421 SYMBOL_D = counter++;
422
423 SYMBOL_I = counter++;
424
425 SYMBOL_J = counter++;
426
427 SYMBOL_N = counter++;
428
429 SYMBOL_R = counter++;
430
431 SYMBOL_S = counter++;
432
433 SYMBOL_T = counter++;
434
435 SYMBOL_X = counter++;
436
437 SYMBOL_Y = counter++;
438
439 SYMBOL_Z = counter++;
440
441 SYMBOL_IDENTITY_MATRIX = counter++;
442
443 SYMBOL_A_UNDERSCORE = counter++;
444
445 SYMBOL_B_UNDERSCORE = counter++;
446
447 SYMBOL_X_UNDERSCORE = counter++;
448
449 C1 = counter++;
450
451 C2 = counter++;
452
453 C3 = counter++;
454
455 C4 = counter++;
456
457 C5 = counter++;
458
459 C6 = counter++;
460
461 USR_SYMBOLS = counter++;
462
463 E = YYE;
464
465 TOS = 100000;
466
467 BUF = 10000;
468
469 MAX_PROGRAM_SIZE = 100001;
470
471 MAXPRIMETAB = 10000;
472
473 MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES = 5;
474
475 MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE = 10;
476
477 ENABLE_CACHING = true;
478
479 cached_runs = null;
480
481 cached_findDependenciesInScript = null;
482
483 MAXDIM = 24;
484
485 symbolsDependencies = {};
486
487 symbolsHavingReassignments = [];
488
489 symbolsInExpressionsWithoutAssignments = [];
490
491 patternHasBeenFound = false;
492
493 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"];
494
495 parse_time_simplifications = true;
496
497 chainOfUserSymbolsNotFunctionsBeingEvaluated = [];
498
499 stringsEmittedByUserPrintouts = "";
500
501 called_from_Algebra_block = false;
502
503 tensor = (function() {
504 tensor.prototype.ndim = 0;
505
506 tensor.prototype.dim = null;
507
508 tensor.prototype.nelem = 0;
509
510 tensor.prototype.elem = null;
511
512 function tensor() {
513 this.dim = (function() {
514 var o, ref, results;
515 results = [];
516 for (o = 0, ref = MAXDIM; 0 <= ref ? o <= ref : o >= ref; 0 <= ref ? o++ : o--) {
517 results.push(0);
518 }
519 return results;
520 })();
521 this.elem = [];
522 }
523
524 return tensor;
525
526 })();
527
528 display = (function() {
529 function display() {}
530
531 display.prototype.h = 0;
532
533 display.prototype.w = 0;
534
535 display.prototype.n = 0;
536
537 display.prototype.a = [];
538
539 return display;
540
541 })();
542
543 text_metric = (function() {
544 function text_metric() {}
545
546 text_metric.prototype.ascent = 0;
547
548 text_metric.prototype.descent = 0;
549
550 text_metric.prototype.width = 0;
551
552 return text_metric;
553
554 })();
555
556 tos = 0;
557
558 expanding = 0;
559
560 evaluatingAsFloats = 0;
561
562 evaluatingPolar = 0;
563
564 fmt_x = 0;
565
566 fmt_index = 0;
567
568 fmt_level = 0;
569
570 verbosing = 0;
571
572 primetab = (function() {
573 var ceil, i, j, primes;
574 primes = [2];
575 i = 3;
576 while (primes.length < MAXPRIMETAB) {
577 j = 0;
578 ceil = Math.sqrt(i);
579 while (j < primes.length && primes[j] <= ceil) {
580 if (i % primes[j] === 0) {
581 j = -1;
582 break;
583 }
584 j++;
585 }
586 if (j !== -1) {
587 primes.push(i);
588 }
589 i += 2;
590 }
591 primes[MAXPRIMETAB] = 0;
592 return primes;
593 })();
594
595 esc_flag = 0;
596
597 draw_flag = 0;
598
599 mtotal = 0;
600
601 trigmode = 0;
602
603 logbuf = "";
604
605 program_buf = "";
606
607 symtab = [];
608
609 binding = [];
610
611 isSymbolReclaimable = [];
612
613 arglist = [];
614
615 stack = [];
616
617 frame = 0;
618
619 p0 = null;
620
621 p1 = null;
622
623 p2 = null;
624
625 p3 = null;
626
627 p4 = null;
628
629 p5 = null;
630
631 p6 = null;
632
633 p7 = null;
634
635 p8 = null;
636
637 p9 = null;
638
639 zero = null;
640
641 one = null;
642
643 one_as_double = null;
644
645 imaginaryunit = null;
646
647 out_buf = "";
648
649 out_count = 0;
650
651 test_flag = 0;
652
653 codeGen = false;
654
655 draw_stop_return = null;
656
657 userSimplificationsInListForm = [];
658
659 userSimplificationsInStringForm = [];
660
661 transpose_unicode = 7488;
662
663 dotprod_unicode = 183;
664
665 symbol = function(x) {
666 return symtab[x];
667 };
668
669 iscons = function(p) {
670 return p.k === CONS;
671 };
672
673 isrational = function(p) {
674 return p.k === NUM;
675 };
676
677 isdouble = function(p) {
678 return p.k === DOUBLE;
679 };
680
681 isnum = function(p) {
682 return isrational(p) || isdouble(p);
683 };
684
685 isstr = function(p) {
686 return p.k === STR;
687 };
688
689 istensor = function(p) {
690 if (p == null) {
691 debugger;
692 } else {
693 return p.k === TENSOR;
694 }
695 };
696
697 isnumerictensor = function(p) {
698 var a, i, n, o, ref;
699 if (isnum(p) || p === symbol(SYMBOL_IDENTITY_MATRIX)) {
700 return 1;
701 }
702 if (!istensor(p) && !isnum(p)) {
703 return 0;
704 }
705 n = p.tensor.nelem;
706 a = p.tensor.elem;
707 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
708 if (!isnumerictensor(a[i])) {
709 return 0;
710 }
711 }
712 return 1;
713 };
714
715 issymbol = function(p) {
716 return p.k === SYM;
717 };
718
719 iskeyword = function(p) {
720 return issymbol(p) && symnum(p) < NIL;
721 };
722
723 car = function(p) {
724 if (iscons(p)) {
725 return p.cons.car;
726 } else {
727 return symbol(NIL);
728 }
729 };
730
731 cdr = function(p) {
732 if (iscons(p)) {
733 return p.cons.cdr;
734 } else {
735 return symbol(NIL);
736 }
737 };
738
739 caar = function(p) {
740 return car(car(p));
741 };
742
743 cadr = function(p) {
744 return car(cdr(p));
745 };
746
747 cdar = function(p) {
748 return cdr(car(p));
749 };
750
751 cddr = function(p) {
752 return cdr(cdr(p));
753 };
754
755 caadr = function(p) {
756 return car(car(cdr(p)));
757 };
758
759 caddr = function(p) {
760 return car(cdr(cdr(p)));
761 };
762
763 cadar = function(p) {
764 return car(cdr(car(p)));
765 };
766
767 cdadr = function(p) {
768 return cdr(car(cdr(p)));
769 };
770
771 cddar = function(p) {
772 return cdr(cdr(car(p)));
773 };
774
775 cdddr = function(p) {
776 return cdr(cdr(cdr(p)));
777 };
778
779 caaddr = function(p) {
780 return car(car(cdr(cdr(p))));
781 };
782
783 cadadr = function(p) {
784 return car(cdr(car(cdr(p))));
785 };
786
787 caddar = function(p) {
788 return car(cdr(cdr(car(p))));
789 };
790
791 cdaddr = function(p) {
792 return cdr(car(cdr(cdr(p))));
793 };
794
795 cadddr = function(p) {
796 return car(cdr(cdr(cdr(p))));
797 };
798
799 cddddr = function(p) {
800 return cdr(cdr(cdr(cdr(p))));
801 };
802
803 caddddr = function(p) {
804 return car(cdr(cdr(cdr(cdr(p)))));
805 };
806
807 cadaddr = function(p) {
808 return car(cdr(car(cdr(cdr(p)))));
809 };
810
811 cddaddr = function(p) {
812 return cdr(cdr(car(cdr(cdr(p)))));
813 };
814
815 caddadr = function(p) {
816 return car(cdr(cdr(car(cdr(p)))));
817 };
818
819 cdddaddr = function(p) {
820 return cdr(cdr(cdr(car(cdr(cdr(p))))));
821 };
822
823 caddaddr = function(p) {
824 return car(cdr(cdr(car(cdr(cdr(p))))));
825 };
826
827 listLength = function(p) {
828 var startCount;
829 startCount = -1;
830 while (iscons(p)) {
831 p = cdr(p);
832 startCount++;
833 }
834 return startCount;
835 };
836
837 nthCadr = function(p, n) {
838 var startCount;
839 startCount = 0;
840 while (startCount <= n) {
841 p = cdr(p);
842 startCount++;
843 }
844 return car(p);
845 };
846
847 isadd = function(p) {
848 return car(p) === symbol(ADD);
849 };
850
851 ismultiply = function(p) {
852 return car(p) === symbol(MULTIPLY);
853 };
854
855 ispower = function(p) {
856 return car(p) === symbol(POWER);
857 };
858
859 isfactorial = function(p) {
860 return car(p) === symbol(FACTORIAL);
861 };
862
863 isinnerordot = function(p) {
864 return (car(p) === symbol(INNER)) || (car(p) === symbol(DOT));
865 };
866
867 istranspose = function(p) {
868 return car(p) === symbol(TRANSPOSE);
869 };
870
871 isinv = function(p) {
872 return car(p) === symbol(INV);
873 };
874
875 isidentitymatrix = function(p) {
876 return p === symbol(SYMBOL_IDENTITY_MATRIX);
877 };
878
879 MSIGN = function(p) {
880 if (p.isPositive()) {
881 return 1;
882 } else if (p.isZero()) {
883 return 0;
884 } else {
885 return -1;
886 }
887 };
888
889 MLENGTH = function(p) {
890 return p.toString().length;
891 };
892
893 MZERO = function(p) {
894 return p.isZero();
895 };
896
897 MEQUAL = function(p, n) {
898 if (p == null) {
899 debugger;
900 }
901 return p.equals(n);
902 };
903
904 reset_after_error = function() {
905 moveTos(0);
906 esc_flag = 0;
907 draw_flag = 0;
908 frame = TOS;
909 evaluatingAsFloats = 0;
910 return evaluatingPolar = 0;
911 };
912
913 $ = typeof exports !== "undefined" && exports !== null ? exports : this;
914
915 $.version = version;
916
917 $.isadd = isadd;
918
919 $.ismultiply = ismultiply;
920
921 $.ispower = ispower;
922
923 $.isfactorial = isfactorial;
924
925 $.car = car;
926
927 $.cdr = cdr;
928
929 $.caar = caar;
930
931 $.cadr = cadr;
932
933 $.cdar = cdar;
934
935 $.cddr = cddr;
936
937 $.caadr = caadr;
938
939 $.caddr = caddr;
940
941 $.cadar = cadar;
942
943 $.cdadr = cdadr;
944
945 $.cddar = cddar;
946
947 $.cdddr = cdddr;
948
949 $.caaddr = caaddr;
950
951 $.cadadr = cadadr;
952
953 $.caddar = caddar;
954
955 $.cdaddr = cdaddr;
956
957 $.cadddr = cadddr;
958
959 $.cddddr = cddddr;
960
961 $.caddddr = caddddr;
962
963 $.cadaddr = cadaddr;
964
965 $.cddaddr = cddaddr;
966
967 $.caddadr = caddadr;
968
969 $.cdddaddr = cdddaddr;
970
971 $.caddaddr = caddaddr;
972
973 $.symbol = symbol;
974
975 $.iscons = iscons;
976
977 $.isrational = isrational;
978
979 $.isdouble = isdouble;
980
981 $.isnum = isnum;
982
983 $.isstr = isstr;
984
985 $.istensor = istensor;
986
987 $.issymbol = issymbol;
988
989 $.iskeyword = iskeyword;
990
991 $.CONS = CONS;
992
993 $.NUM = NUM;
994
995 $.DOUBLE = DOUBLE;
996
997 $.STR = STR;
998
999 $.TENSOR = TENSOR;
1000
1001 $.SYM = SYM;
1002
1003
1004 /* abs =====================================================================
1005
1006 Tags
1007 ----
1008 scripting, JS, internal, treenode, general concept
1009
1010 Parameters
1011 ----------
1012 x
1013
1014 General description
1015 -------------------
1016 Returns the absolute value of a real number, the magnitude of a complex number, or the vector length.
1017 */
1018
1019
1020 /*
1021 Absolute value of a number,or magnitude of complex z, or norm of a vector
1022
1023 z abs(z)
1024 - ------
1025
1026 a a
1027
1028 -a a
1029
1030 (-1)^a 1
1031
1032 exp(a + i b) exp(a)
1033
1034 a b abs(a) abs(b)
1035
1036 a + i b sqrt(a^2 + b^2)
1037
1038 Notes
1039
1040 1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3)
1041
1042 2. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then
1043
1044 abs(numerator(z)) / abs(denominator(z))
1045
1046 must be used to get the correct answer. Now the operation is
1047 automatic.
1048 */
1049
1050 DEBUG_ABS = false;
1051
1052 Eval_abs = function() {
1053 push(cadr(p1));
1054 Eval();
1055 return abs();
1056 };
1057
1058 absValFloat = function() {
1059 Eval();
1060 absval();
1061 Eval();
1062 return zzfloat();
1063 };
1064
1065 abs = function() {
1066 save();
1067 p1 = pop();
1068 push(p1);
1069 numerator();
1070 absval();
1071 push(p1);
1072 denominator();
1073 absval();
1074 divide();
1075 return restore();
1076 };
1077
1078 absval = function() {
1079 var input;
1080 save();
1081 p1 = pop();
1082 input = p1;
1083 if (DEBUG_ABS) {
1084 console.log("ABS of " + p1);
1085 }
1086 if (iszero(p1)) {
1087 if (DEBUG_ABS) {
1088 console.log(" abs: " + p1 + " just zero");
1089 }
1090 push(zero);
1091 if (DEBUG_ABS) {
1092 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1093 }
1094 restore();
1095 return;
1096 }
1097 if (isnegativenumber(p1)) {
1098 if (DEBUG_ABS) {
1099 console.log(" abs: " + p1 + " just a negative");
1100 }
1101 push(p1);
1102 negate();
1103 restore();
1104 return;
1105 }
1106 if (ispositivenumber(p1)) {
1107 if (DEBUG_ABS) {
1108 console.log(" abs: " + p1 + " just a positive");
1109 }
1110 push(p1);
1111 if (DEBUG_ABS) {
1112 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1113 }
1114 restore();
1115 return;
1116 }
1117 if (p1 === symbol(PI)) {
1118 if (DEBUG_ABS) {
1119 console.log(" abs: " + p1 + " of PI");
1120 }
1121 push(p1);
1122 if (DEBUG_ABS) {
1123 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1124 }
1125 restore();
1126 return;
1127 }
1128 if (car(p1) === symbol(ADD) && (findPossibleClockForm(p1) || findPossibleExponentialForm(p1) || Find(p1, imaginaryunit))) {
1129 if (DEBUG_ABS) {
1130 console.log(" abs: " + p1 + " is a sum");
1131 }
1132 if (DEBUG_ABS) {
1133 console.log("abs of a sum");
1134 }
1135 push(p1);
1136 rect();
1137 p1 = pop();
1138 push(p1);
1139 real();
1140 push_integer(2);
1141 power();
1142 push(p1);
1143 imag();
1144 push_integer(2);
1145 power();
1146 add();
1147 push_rational(1, 2);
1148 power();
1149 simplify_trig();
1150 if (DEBUG_ABS) {
1151 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1152 }
1153 restore();
1154 return;
1155 }
1156 if (car(p1) === symbol(POWER) && equaln(cadr(p1), -1)) {
1157 if (DEBUG_ABS) {
1158 console.log(" abs: " + p1 + " is -1 to any power");
1159 }
1160 if (evaluatingAsFloats) {
1161 if (DEBUG_ABS) {
1162 console.log(" abs: numeric, so result is 1.0");
1163 }
1164 push_double(1.0);
1165 } else {
1166 if (DEBUG_ABS) {
1167 console.log(" abs: symbolic, so result is 1");
1168 }
1169 push_integer(1);
1170 }
1171 if (DEBUG_ABS) {
1172 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1173 }
1174 restore();
1175 return;
1176 }
1177 if (car(p1) === symbol(POWER) && ispositivenumber(caddr(p1))) {
1178 if (DEBUG_ABS) {
1179 console.log(" abs: " + p1 + " is something to the power of a positive number");
1180 }
1181 push(cadr(p1));
1182 abs();
1183 push(caddr(p1));
1184 power();
1185 if (DEBUG_ABS) {
1186 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1187 }
1188 restore();
1189 return;
1190 }
1191 if (car(p1) === symbol(POWER) && cadr(p1) === symbol(E)) {
1192 if (DEBUG_ABS) {
1193 console.log(" abs: " + p1 + " is an exponential");
1194 }
1195 push(caddr(p1));
1196 real();
1197 exponential();
1198 if (DEBUG_ABS) {
1199 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1200 }
1201 restore();
1202 return;
1203 }
1204 if (car(p1) === symbol(MULTIPLY)) {
1205 if (DEBUG_ABS) {
1206 console.log(" abs: " + p1 + " is a product");
1207 }
1208 push_integer(1);
1209 p1 = cdr(p1);
1210 while (iscons(p1)) {
1211 push(car(p1));
1212 abs();
1213 multiply();
1214 p1 = cdr(p1);
1215 }
1216 if (DEBUG_ABS) {
1217 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1218 }
1219 restore();
1220 return;
1221 }
1222 if (car(p1) === symbol(ABS)) {
1223 if (DEBUG_ABS) {
1224 console.log(" abs: " + p1 + " is abs of a abs");
1225 }
1226 push_symbol(ABS);
1227 push(cadr(p1));
1228 list(2);
1229 if (DEBUG_ABS) {
1230 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1231 }
1232 restore();
1233 return;
1234 }
1235
1236 /*
1237 * Evaluation via zzfloat()
1238 * ...while this is in theory a powerful mechanism, I've commented it
1239 * out because I've refined this method enough to not need this.
1240 * Evaling via zzfloat() is in principle more problematic because it could
1241 * require further evaluations which could end up in further "abs" which
1242 * would end up in infinite loops. Better not use it if not necessary.
1243
1244 * we look directly at the float evaluation of the argument
1245 * to see if we end up with a number, which would mean that there
1246 * is no imaginary component and we can just return the input
1247 * (or its negation) as the result.
1248 push p1
1249 zzfloat()
1250 floatEvaluation = pop()
1251
1252 if (isnegativenumber(floatEvaluation))
1253 if DEBUG_ABS then console.log " abs: " + p1 + " just a negative"
1254 push(p1)
1255 negate()
1256 restore()
1257 return
1258
1259 if (ispositivenumber(floatEvaluation))
1260 if DEBUG_ABS then console.log " abs: " + p1 + " just a positive"
1261 push(p1)
1262 if DEBUG_ABS then console.log " --> ABS of " + input + " : " + stack[tos-1]
1263 restore()
1264 return
1265 */
1266 if (istensor(p1)) {
1267 absval_tensor();
1268 restore();
1269 return;
1270 }
1271 if (isnegativeterm(p1) || (car(p1) === symbol(ADD) && isnegativeterm(cadr(p1)))) {
1272 push(p1);
1273 negate();
1274 p1 = pop();
1275 }
1276 if (DEBUG_ABS) {
1277 console.log(" abs: " + p1 + " is nothing decomposable");
1278 }
1279 push_symbol(ABS);
1280 push(p1);
1281 list(2);
1282 if (DEBUG_ABS) {
1283 console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
1284 }
1285 return restore();
1286 };
1287
1288 absval_tensor = function() {
1289 if (p1.tensor.ndim !== 1) {
1290 stop("abs(tensor) with tensor rank > 1");
1291 }
1292 push(p1);
1293 push(p1);
1294 conjugate();
1295 inner();
1296 push_rational(1, 2);
1297 power();
1298 simplify();
1299 return Eval();
1300 };
1301
1302
1303 /*
1304 Symbolic addition
1305
1306 Terms in a sum are combined if they are identical modulo rational
1307 coefficients.
1308
1309 For example, A + 2A becomes 3A.
1310
1311 However, the sum A + sqrt(2) A is not modified.
1312
1313 Combining terms can lead to second-order effects.
1314
1315 For example, consider the case of
1316
1317 1/sqrt(2) A + 3/sqrt(2) A + sqrt(2) A
1318
1319 The first two terms are combined to yield 2 sqrt(2) A.
1320
1321 This result can now be combined with the third term to yield
1322
1323 3 sqrt(2) A
1324 */
1325
1326 flag = 0;
1327
1328 Eval_add = function() {
1329 var h;
1330 h = tos;
1331 p1 = cdr(p1);
1332 while (iscons(p1)) {
1333 push(car(p1));
1334 Eval();
1335 p2 = pop();
1336 push_terms(p2);
1337 p1 = cdr(p1);
1338 }
1339 return add_terms(tos - h);
1340 };
1341
1342 stackAddsCount = 0;
1343
1344 add_terms = function(n) {
1345 var h, i, i1, j1, o, ref, ref1, results, s, subsetOfStack;
1346 stackAddsCount++;
1347 i = 0;
1348 h = tos - n;
1349 s = h;
1350 if (DEBUG) {
1351 console.log("stack before adding terms #" + stackAddsCount);
1352 }
1353 if (DEBUG) {
1354 for (i = o = 0, ref = tos; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1355 console.log(print_list(stack[i]));
1356 }
1357 }
1358 for (i = i1 = 0; i1 < 10; i = ++i1) {
1359 if (n < 2) {
1360 break;
1361 }
1362 flag = 0;
1363 subsetOfStack = stack.slice(h, h + n);
1364 subsetOfStack.sort(cmp_terms);
1365 stack = stack.slice(0, h).concat(subsetOfStack).concat(stack.slice(h + n));
1366 if (flag === 0) {
1367 break;
1368 }
1369 n = combine_terms(h, n);
1370 }
1371 moveTos(h + n);
1372 switch (n) {
1373 case 0:
1374 if (evaluatingAsFloats) {
1375 push_double(0.0);
1376 } else {
1377 push(zero);
1378 }
1379 break;
1380 case 1:
1381 break;
1382 default:
1383 list(n);
1384 p1 = pop();
1385 push_symbol(ADD);
1386 push(p1);
1387 cons();
1388 }
1389 if (DEBUG) {
1390 console.log("stack after adding terms #" + stackAddsCount);
1391 }
1392 if (DEBUG) {
1393 results = [];
1394 for (i = j1 = 0, ref1 = tos; 0 <= ref1 ? j1 < ref1 : j1 > ref1; i = 0 <= ref1 ? ++j1 : --j1) {
1395 results.push(console.log(print_list(stack[i])));
1396 }
1397 return results;
1398 }
1399 };
1400
1401 cmp_terms_count = 0;
1402
1403 cmp_terms = function(p1, p2) {
1404 var i, o, ref, t;
1405 cmp_terms_count++;
1406 i = 0;
1407 if (isnum(p1) && isnum(p2)) {
1408 flag = 1;
1409 return 0;
1410 }
1411 if (istensor(p1) && istensor(p2)) {
1412 if (p1.tensor.ndim < p2.tensor.ndim) {
1413 return -1;
1414 }
1415 if (p1.tensor.ndim > p2.tensor.ndim) {
1416 return 1;
1417 }
1418 for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1419 if (p1.tensor.dim[i] < p2.tensor.dim[i]) {
1420 return -1;
1421 }
1422 if (p1.tensor.dim[i] > p2.tensor.dim[i]) {
1423 return 1;
1424 }
1425 }
1426 flag = 1;
1427 return 0;
1428 }
1429 if (car(p1) === symbol(MULTIPLY)) {
1430 p1 = cdr(p1);
1431 if (isnum(car(p1))) {
1432 p1 = cdr(p1);
1433 if (cdr(p1) === symbol(NIL)) {
1434 p1 = car(p1);
1435 }
1436 }
1437 }
1438 if (car(p2) === symbol(MULTIPLY)) {
1439 p2 = cdr(p2);
1440 if (isnum(car(p2))) {
1441 p2 = cdr(p2);
1442 if (cdr(p2) === symbol(NIL)) {
1443 p2 = car(p2);
1444 }
1445 }
1446 }
1447 t = cmp_expr(p1, p2);
1448 if (t === 0) {
1449 flag = 1;
1450 }
1451 return t;
1452 };
1453
1454
1455 /*
1456 Compare adjacent terms in s[] and combine if possible.
1457
1458 Returns the number of terms remaining in s[].
1459
1460 n number of terms in s[] initially
1461 */
1462
1463 combine_terms = function(s, n) {
1464 var i, i1, j, j1, l1, m1, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, t;
1465 i = 0;
1466 while (i < (n - 1)) {
1467 check_esc_flag();
1468 p3 = stack[s + i];
1469 p4 = stack[s + i + 1];
1470 if (istensor(p3) && istensor(p4)) {
1471 push(p3);
1472 push(p4);
1473 tensor_plus_tensor();
1474 p1 = pop();
1475 if (p1 !== symbol(NIL)) {
1476 stack[s + i] = p1;
1477 for (j = o = ref = i + 1, ref1 = n - 1; ref <= ref1 ? o < ref1 : o > ref1; j = ref <= ref1 ? ++o : --o) {
1478 stack[s + j] = stack[s + j + 1];
1479 }
1480 n--;
1481 i--;
1482 }
1483 i++;
1484 continue;
1485 }
1486 if (istensor(p3) || istensor(p4)) {
1487 i++;
1488 continue;
1489 }
1490 if (isnum(p3) && isnum(p4)) {
1491 push(p3);
1492 push(p4);
1493 add_numbers();
1494 p1 = pop();
1495 if (iszero(p1)) {
1496 for (j = i1 = ref2 = i, ref3 = n - 2; ref2 <= ref3 ? i1 < ref3 : i1 > ref3; j = ref2 <= ref3 ? ++i1 : --i1) {
1497 stack[s + j] = stack[s + j + 2];
1498 }
1499 n -= 2;
1500 } else {
1501 stack[s + i] = p1;
1502 for (j = j1 = ref4 = i + 1, ref5 = n - 1; ref4 <= ref5 ? j1 < ref5 : j1 > ref5; j = ref4 <= ref5 ? ++j1 : --j1) {
1503 stack[s + j] = stack[s + j + 1];
1504 }
1505 n--;
1506 }
1507 i--;
1508 i++;
1509 continue;
1510 }
1511 if (isnum(p3) || isnum(p4)) {
1512 i++;
1513 continue;
1514 }
1515 if (evaluatingAsFloats) {
1516 p1 = one_as_double;
1517 p2 = one_as_double;
1518 } else {
1519 p1 = one;
1520 p2 = one;
1521 }
1522 t = 0;
1523 if (car(p3) === symbol(MULTIPLY)) {
1524 p3 = cdr(p3);
1525 t = 1;
1526 if (isnum(car(p3))) {
1527 p1 = car(p3);
1528 p3 = cdr(p3);
1529 if (cdr(p3) === symbol(NIL)) {
1530 p3 = car(p3);
1531 t = 0;
1532 }
1533 }
1534 }
1535 if (car(p4) === symbol(MULTIPLY)) {
1536 p4 = cdr(p4);
1537 if (isnum(car(p4))) {
1538 p2 = car(p4);
1539 p4 = cdr(p4);
1540 if (cdr(p4) === symbol(NIL)) {
1541 p4 = car(p4);
1542 }
1543 }
1544 }
1545 if (!equal(p3, p4)) {
1546 i++;
1547 continue;
1548 }
1549 push(p1);
1550 push(p2);
1551 add_numbers();
1552 p1 = pop();
1553 if (iszero(p1)) {
1554 for (j = l1 = ref6 = i, ref7 = n - 2; ref6 <= ref7 ? l1 < ref7 : l1 > ref7; j = ref6 <= ref7 ? ++l1 : --l1) {
1555 stack[s + j] = stack[s + j + 2];
1556 }
1557 n -= 2;
1558 i--;
1559 i++;
1560 continue;
1561 }
1562 push(p1);
1563 if (t) {
1564 push(symbol(MULTIPLY));
1565 push(p3);
1566 cons();
1567 } else {
1568 push(p3);
1569 }
1570 multiply();
1571 stack[s + i] = pop();
1572 for (j = m1 = ref8 = i + 1, ref9 = n - 1; ref8 <= ref9 ? m1 < ref9 : m1 > ref9; j = ref8 <= ref9 ? ++m1 : --m1) {
1573 stack[s + j] = stack[s + j + 1];
1574 }
1575 n--;
1576 i--;
1577 i++;
1578 }
1579 return n;
1580 };
1581
1582 push_terms = function(p) {
1583 var results;
1584 if (car(p) === symbol(ADD)) {
1585 p = cdr(p);
1586 results = [];
1587 while (iscons(p)) {
1588 push(car(p));
1589 results.push(p = cdr(p));
1590 }
1591 return results;
1592 } else if (!iszero(p)) {
1593 return push(p);
1594 }
1595 };
1596
1597 add = function() {
1598 var h;
1599 save();
1600 p2 = pop();
1601 p1 = pop();
1602 h = tos;
1603 push_terms(p1);
1604 push_terms(p2);
1605 add_terms(tos - h);
1606 return restore();
1607 };
1608
1609 add_all = function(k) {
1610 var h, i, o, ref, s;
1611 i = 0;
1612 save();
1613 s = tos - k;
1614 h = tos;
1615 for (i = o = 0, ref = k; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1616 push_terms(stack[s + i]);
1617 }
1618 add_terms(tos - h);
1619 p1 = pop();
1620 moveTos(tos - k);
1621 push(p1);
1622 return restore();
1623 };
1624
1625 subtract = function() {
1626 negate();
1627 return add();
1628 };
1629
1630
1631 /* adj =====================================================================
1632
1633 Tags
1634 ----
1635 scripting, JS, internal, treenode, general concept
1636
1637 Parameters
1638 ----------
1639 m
1640
1641 General description
1642 -------------------
1643 Returns the adjunct of matrix m. The inverse of m is equal to adj(m) divided by det(m).
1644 */
1645
1646 Eval_adj = function() {
1647 push(cadr(p1));
1648 Eval();
1649 return adj();
1650 };
1651
1652 adj = function() {
1653 var doNothing, i, i1, j, n, o, ref, ref1;
1654 i = 0;
1655 j = 0;
1656 n = 0;
1657 save();
1658 p1 = pop();
1659 if (istensor(p1) && p1.tensor.ndim === 2 && p1.tensor.dim[0] === p1.tensor.dim[1]) {
1660 doNothing = 1;
1661 } else {
1662 stop("adj: square matrix expected");
1663 }
1664 n = p1.tensor.dim[0];
1665 p2 = alloc_tensor(n * n);
1666 p2.tensor.ndim = 2;
1667 p2.tensor.dim[0] = n;
1668 p2.tensor.dim[1] = n;
1669 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1670 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
1671 cofactor(p1, n, i, j);
1672 p2.tensor.elem[n * j + i] = pop();
1673 }
1674 }
1675 push(p2);
1676 return restore();
1677 };
1678
1679
1680 /*
1681 Guesses a rational for each float in the passed expression
1682 */
1683
1684 Eval_approxratio = function() {
1685 var theArgument;
1686 theArgument = cadr(p1);
1687 push(theArgument);
1688 return approxratioRecursive();
1689 };
1690
1691 approxratioRecursive = function() {
1692 var i, i1, o, ref, ref1;
1693 i = 0;
1694 save();
1695 p1 = pop();
1696 if (istensor(p1)) {
1697 p4 = alloc_tensor(p1.tensor.nelem);
1698 p4.tensor.ndim = p1.tensor.ndim;
1699 for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
1700 p4.tensor.dim[i] = p1.tensor.dim[i];
1701 }
1702 for (i = i1 = 0, ref1 = p1.tensor.nelem; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
1703 push(p1.tensor.elem[i]);
1704 approxratioRecursive();
1705 p4.tensor.elem[i] = pop();
1706 check_tensor_dimensions(p4);
1707 }
1708 push(p4);
1709 } else if (p1.k === DOUBLE) {
1710 push(p1);
1711 approxOneRatioOnly();
1712 } else if (iscons(p1)) {
1713 push(car(p1));
1714 approxratioRecursive();
1715 push(cdr(p1));
1716 approxratioRecursive();
1717 cons();
1718 } else {
1719 push(p1);
1720 }
1721 return restore();
1722 };
1723
1724 approxOneRatioOnly = function() {
1725 var numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot, supposedlyTheFloat, theFloat, theRatio;
1726 zzfloat();
1727 supposedlyTheFloat = pop();
1728 if (supposedlyTheFloat.k === DOUBLE) {
1729 theFloat = supposedlyTheFloat.d;
1730 splitBeforeAndAfterDot = theFloat.toString().split(".");
1731 if (splitBeforeAndAfterDot.length === 2) {
1732 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1733 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1734 theRatio = floatToRatioRoutine(theFloat, precision);
1735 push_rational(theRatio[0], theRatio[1]);
1736 } else {
1737 push_integer(theFloat);
1738 }
1739 return;
1740 }
1741 push_symbol(APPROXRATIO);
1742 push(theArgument);
1743 return list(2);
1744 };
1745
1746 floatToRatioRoutine = function(decimal, AccuracyFactor) {
1747 var DecimalSign, FractionDenominator, FractionNumerator, PreviousDenominator, ScratchValue, Z, ret;
1748 FractionNumerator = void 0;
1749 FractionDenominator = void 0;
1750 DecimalSign = void 0;
1751 Z = void 0;
1752 PreviousDenominator = void 0;
1753 ScratchValue = void 0;
1754 ret = [0, 0];
1755 if (isNaN(decimal)) {
1756 return ret;
1757 }
1758 if (decimal === 2e308) {
1759 ret[0] = 1;
1760 ret[1] = 0;
1761 return ret;
1762 }
1763 if (decimal === -2e308) {
1764 ret[0] = -1;
1765 ret[1] = 0;
1766 return ret;
1767 }
1768 if (decimal < 0.0) {
1769 DecimalSign = -1.0;
1770 } else {
1771 DecimalSign = 1.0;
1772 }
1773 decimal = Math.abs(decimal);
1774 if (Math.abs(decimal - Math.floor(decimal)) < AccuracyFactor) {
1775 FractionNumerator = decimal * DecimalSign;
1776 FractionDenominator = 1.0;
1777 ret[0] = FractionNumerator;
1778 ret[1] = FractionDenominator;
1779 return ret;
1780 }
1781 if (decimal < 1.0e-19) {
1782 FractionNumerator = DecimalSign;
1783 FractionDenominator = 9999999999999999999.0;
1784 ret[0] = FractionNumerator;
1785 ret[1] = FractionDenominator;
1786 return ret;
1787 }
1788 if (decimal > 1.0e19) {
1789 FractionNumerator = 9999999999999999999.0 * DecimalSign;
1790 FractionDenominator = 1.0;
1791 ret[0] = FractionNumerator;
1792 ret[1] = FractionDenominator;
1793 return ret;
1794 }
1795 Z = decimal;
1796 PreviousDenominator = 0.0;
1797 FractionDenominator = 1.0;
1798 while (true) {
1799 Z = 1.0 / (Z - Math.floor(Z));
1800 ScratchValue = FractionDenominator;
1801 FractionDenominator = FractionDenominator * Math.floor(Z) + PreviousDenominator;
1802 PreviousDenominator = ScratchValue;
1803 FractionNumerator = Math.floor(decimal * FractionDenominator + 0.5);
1804 if (!(Math.abs(decimal - (FractionNumerator / FractionDenominator)) > AccuracyFactor && Z !== Math.floor(Z))) {
1805 break;
1806 }
1807 }
1808 FractionNumerator = DecimalSign * FractionNumerator;
1809 ret[0] = FractionNumerator;
1810 ret[1] = FractionDenominator;
1811 return ret;
1812 };
1813
1814 approx_just_an_integer = 0;
1815
1816 approx_sine_of_rational = 1;
1817
1818 approx_sine_of_pi_times_rational = 2;
1819
1820 approx_rationalOfPi = 3;
1821
1822 approx_radicalOfRatio = 4;
1823
1824 approx_nothingUseful = 5;
1825
1826 approx_ratioOfRadical = 6;
1827
1828 approx_rationalOfE = 7;
1829
1830 approx_logarithmsOfRationals = 8;
1831
1832 approx_rationalsOfLogarithms = 9;
1833
1834 approxRationalsOfRadicals = function(theFloat) {
1835 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, len, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, ref, result, splitBeforeAndAfterDot;
1836 splitBeforeAndAfterDot = theFloat.toString().split(".");
1837 if (splitBeforeAndAfterDot.length === 2) {
1838 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1839 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1840 } else {
1841 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1842 }
1843 console.log("precision: " + precision);
1844 bestResultSoFar = null;
1845 minimumComplexity = Number.MAX_VALUE;
1846 ref = [2, 3, 5, 6, 7, 8, 10];
1847 for (o = 0, len = ref.length; o < len; o++) {
1848 i = ref[o];
1849 for (j = i1 = 1; i1 <= 10; j = ++i1) {
1850 hypothesis = Math.sqrt(i) / j;
1851 if (Math.abs(hypothesis) > 1e-10) {
1852 ratio = theFloat / hypothesis;
1853 likelyMultiplier = Math.round(ratio);
1854 error = Math.abs(1 - ratio / likelyMultiplier);
1855 } else {
1856 ratio = 1;
1857 likelyMultiplier = 1;
1858 error = Math.abs(theFloat - hypothesis);
1859 }
1860 if (error < 2 * precision) {
1861 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
1862 if (complexity < minimumComplexity) {
1863 minimumComplexity = complexity;
1864 result = likelyMultiplier + " * sqrt( " + i + " ) / " + j;
1865 bestResultSoFar = [result, approx_ratioOfRadical, likelyMultiplier, i, j];
1866 }
1867 }
1868 }
1869 }
1870 return bestResultSoFar;
1871 };
1872
1873 approxRadicalsOfRationals = function(theFloat) {
1874 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, len, len1, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, ref, ref1, result, splitBeforeAndAfterDot;
1875 splitBeforeAndAfterDot = theFloat.toString().split(".");
1876 if (splitBeforeAndAfterDot.length === 2) {
1877 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1878 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1879 } else {
1880 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1881 }
1882 console.log("precision: " + precision);
1883 bestResultSoFar = null;
1884 minimumComplexity = Number.MAX_VALUE;
1885 ref = [1, 2, 3, 5, 6, 7, 8, 10];
1886 for (o = 0, len = ref.length; o < len; o++) {
1887 i = ref[o];
1888 ref1 = [1, 2, 3, 5, 6, 7, 8, 10];
1889 for (i1 = 0, len1 = ref1.length; i1 < len1; i1++) {
1890 j = ref1[i1];
1891 hypothesis = Math.sqrt(i / j);
1892 if (Math.abs(hypothesis) > 1e-10) {
1893 ratio = theFloat / hypothesis;
1894 likelyMultiplier = Math.round(ratio);
1895 error = Math.abs(1 - ratio / likelyMultiplier);
1896 } else {
1897 ratio = 1;
1898 likelyMultiplier = 1;
1899 error = Math.abs(theFloat - hypothesis);
1900 }
1901 if (error < 2 * precision) {
1902 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
1903 if (complexity < minimumComplexity) {
1904 minimumComplexity = complexity;
1905 result = likelyMultiplier + " * (sqrt( " + i + " / " + j + " )";
1906 bestResultSoFar = [result, approx_radicalOfRatio, likelyMultiplier, i, j];
1907 }
1908 }
1909 }
1910 }
1911 return bestResultSoFar;
1912 };
1913
1914 approxRadicals = function(theFloat) {
1915 var approxRadicalsOfRationalsResult, approxRationalsOfRadicalsResult, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
1916 splitBeforeAndAfterDot = theFloat.toString().split(".");
1917 if (splitBeforeAndAfterDot.length === 2) {
1918 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1919 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1920 } else {
1921 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1922 }
1923 console.log("precision: " + precision);
1924 approxRationalsOfRadicalsResult = approxRationalsOfRadicals(theFloat);
1925 if (approxRationalsOfRadicalsResult != null) {
1926 return approxRationalsOfRadicalsResult;
1927 }
1928 approxRadicalsOfRationalsResult = approxRadicalsOfRationals(theFloat);
1929 if (approxRadicalsOfRationalsResult != null) {
1930 return approxRadicalsOfRationalsResult;
1931 }
1932 return null;
1933 };
1934
1935 approxLogs = function(theFloat) {
1936 var approxLogsOfRationalsResult, approxRationalsOfLogsResult, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
1937 splitBeforeAndAfterDot = theFloat.toString().split(".");
1938 if (splitBeforeAndAfterDot.length === 2) {
1939 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1940 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1941 } else {
1942 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1943 }
1944 console.log("precision: " + precision);
1945 approxRationalsOfLogsResult = approxRationalsOfLogs(theFloat);
1946 if (approxRationalsOfLogsResult != null) {
1947 return approxRationalsOfLogsResult;
1948 }
1949 approxLogsOfRationalsResult = approxLogsOfRationals(theFloat);
1950 if (approxLogsOfRationalsResult != null) {
1951 return approxLogsOfRationalsResult;
1952 }
1953 return null;
1954 };
1955
1956 approxRationalsOfLogs = function(theFloat) {
1957 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
1958 splitBeforeAndAfterDot = theFloat.toString().split(".");
1959 if (splitBeforeAndAfterDot.length === 2) {
1960 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
1961 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
1962 } else {
1963 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
1964 }
1965 console.log("precision: " + precision);
1966 bestResultSoFar = null;
1967 minimumComplexity = Number.MAX_VALUE;
1968 for (i = o = 2; o <= 5; i = ++o) {
1969 for (j = i1 = 1; i1 <= 5; j = ++i1) {
1970 hypothesis = Math.log(i) / j;
1971 if (Math.abs(hypothesis) > 1e-10) {
1972 ratio = theFloat / hypothesis;
1973 likelyMultiplier = Math.round(ratio);
1974 error = Math.abs(1 - ratio / likelyMultiplier);
1975 } else {
1976 ratio = 1;
1977 likelyMultiplier = 1;
1978 error = Math.abs(theFloat - hypothesis);
1979 }
1980 if (likelyMultiplier !== 1 && Math.abs(Math.floor(likelyMultiplier / j)) === Math.abs(likelyMultiplier / j)) {
1981 continue;
1982 }
1983 if (error < 2.2 * precision) {
1984 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
1985 if (complexity < minimumComplexity) {
1986 minimumComplexity = complexity;
1987 result = likelyMultiplier + " * log( " + i + " ) / " + j;
1988 bestResultSoFar = [result, approx_rationalsOfLogarithms, likelyMultiplier, i, j];
1989 }
1990 }
1991 }
1992 }
1993 return bestResultSoFar;
1994 };
1995
1996 approxLogsOfRationals = function(theFloat) {
1997 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
1998 splitBeforeAndAfterDot = theFloat.toString().split(".");
1999 if (splitBeforeAndAfterDot.length === 2) {
2000 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2001 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2002 } else {
2003 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2004 }
2005 console.log("precision: " + precision);
2006 bestResultSoFar = null;
2007 minimumComplexity = Number.MAX_VALUE;
2008 for (i = o = 1; o <= 5; i = ++o) {
2009 for (j = i1 = 1; i1 <= 5; j = ++i1) {
2010 hypothesis = Math.log(i / j);
2011 if (Math.abs(hypothesis) > 1e-10) {
2012 ratio = theFloat / hypothesis;
2013 likelyMultiplier = Math.round(ratio);
2014 error = Math.abs(1 - ratio / likelyMultiplier);
2015 } else {
2016 ratio = 1;
2017 likelyMultiplier = 1;
2018 error = Math.abs(theFloat - hypothesis);
2019 }
2020 if (error < 1.96 * precision) {
2021 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2022 if (complexity < minimumComplexity) {
2023 minimumComplexity = complexity;
2024 result = likelyMultiplier + " * log( " + i + " / " + j + " )";
2025 bestResultSoFar = [result, approx_logarithmsOfRationals, likelyMultiplier, i, j];
2026 }
2027 }
2028 }
2029 }
2030 return bestResultSoFar;
2031 };
2032
2033 approxRationalsOfPowersOfE = function(theFloat) {
2034 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2035 splitBeforeAndAfterDot = theFloat.toString().split(".");
2036 if (splitBeforeAndAfterDot.length === 2) {
2037 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2038 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2039 } else {
2040 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2041 }
2042 console.log("precision: " + precision);
2043 bestResultSoFar = null;
2044 minimumComplexity = Number.MAX_VALUE;
2045 for (i = o = 1; o <= 2; i = ++o) {
2046 for (j = i1 = 1; i1 <= 12; j = ++i1) {
2047 hypothesis = Math.pow(Math.E, i) / j;
2048 if (Math.abs(hypothesis) > 1e-10) {
2049 ratio = theFloat / hypothesis;
2050 likelyMultiplier = Math.round(ratio);
2051 error = Math.abs(1 - ratio / likelyMultiplier);
2052 } else {
2053 ratio = 1;
2054 likelyMultiplier = 1;
2055 error = Math.abs(theFloat - hypothesis);
2056 }
2057 if (error < 2 * precision) {
2058 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2059 if (complexity < minimumComplexity) {
2060 minimumComplexity = complexity;
2061 result = likelyMultiplier + " * (e ^ " + i + " ) / " + j;
2062 bestResultSoFar = [result, approx_rationalOfE, likelyMultiplier, i, j];
2063 }
2064 }
2065 }
2066 }
2067 return bestResultSoFar;
2068 };
2069
2070 approxRationalsOfPowersOfPI = function(theFloat) {
2071 var bestResultSoFar, complexity, error, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2072 splitBeforeAndAfterDot = theFloat.toString().split(".");
2073 if (splitBeforeAndAfterDot.length === 2) {
2074 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2075 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2076 } else {
2077 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2078 }
2079 console.log("precision: " + precision);
2080 bestResultSoFar = null;
2081 minimumComplexity = Number.MAX_VALUE;
2082 for (i = o = 1; o <= 5; i = ++o) {
2083 for (j = i1 = 1; i1 <= 12; j = ++i1) {
2084 hypothesis = Math.pow(Math.PI, i) / j;
2085 if (Math.abs(hypothesis) > 1e-10) {
2086 ratio = theFloat / hypothesis;
2087 likelyMultiplier = Math.round(ratio);
2088 error = Math.abs(1 - ratio / likelyMultiplier);
2089 } else {
2090 ratio = 1;
2091 likelyMultiplier = 1;
2092 error = Math.abs(theFloat - hypothesis);
2093 }
2094 if (error < 2 * precision) {
2095 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2096 if (complexity < minimumComplexity) {
2097 minimumComplexity = complexity;
2098 result = likelyMultiplier + " * (pi ^ " + i + " ) / " + j + " )";
2099 bestResultSoFar = [result, approx_rationalOfPi, likelyMultiplier, i, j];
2100 }
2101 }
2102 }
2103 }
2104 return bestResultSoFar;
2105 };
2106
2107 approxTrigonometric = function(theFloat) {
2108 var approxSineOfRationalMultiplesOfPIResult, approxSineOfRationalsResult, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
2109 splitBeforeAndAfterDot = theFloat.toString().split(".");
2110 if (splitBeforeAndAfterDot.length === 2) {
2111 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2112 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2113 } else {
2114 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2115 }
2116 console.log("precision: " + precision);
2117 approxSineOfRationalsResult = approxSineOfRationals(theFloat);
2118 if (approxSineOfRationalsResult != null) {
2119 return approxSineOfRationalsResult;
2120 }
2121 approxSineOfRationalMultiplesOfPIResult = approxSineOfRationalMultiplesOfPI(theFloat);
2122 if (approxSineOfRationalMultiplesOfPIResult != null) {
2123 return approxSineOfRationalMultiplesOfPIResult;
2124 }
2125 return null;
2126 };
2127
2128 approxSineOfRationals = function(theFloat) {
2129 var bestResultSoFar, complexity, error, fraction, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2130 splitBeforeAndAfterDot = theFloat.toString().split(".");
2131 if (splitBeforeAndAfterDot.length === 2) {
2132 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2133 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2134 } else {
2135 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2136 }
2137 console.log("precision: " + precision);
2138 bestResultSoFar = null;
2139 minimumComplexity = Number.MAX_VALUE;
2140 for (i = o = 1; o <= 4; i = ++o) {
2141 for (j = i1 = 1; i1 <= 4; j = ++i1) {
2142 fraction = i / j;
2143 hypothesis = Math.sin(fraction);
2144 if (Math.abs(hypothesis) > 1e-10) {
2145 ratio = theFloat / hypothesis;
2146 likelyMultiplier = Math.round(ratio);
2147 error = Math.abs(1 - ratio / likelyMultiplier);
2148 } else {
2149 ratio = 1;
2150 likelyMultiplier = 1;
2151 error = Math.abs(theFloat - hypothesis);
2152 }
2153 if (error < 2 * precision) {
2154 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2155 if (complexity < minimumComplexity) {
2156 minimumComplexity = complexity;
2157 result = likelyMultiplier + " * sin( " + i + "/" + j + " )";
2158 bestResultSoFar = [result, approx_sine_of_rational, likelyMultiplier, i, j];
2159 }
2160 }
2161 }
2162 }
2163 return bestResultSoFar;
2164 };
2165
2166 approxSineOfRationalMultiplesOfPI = function(theFloat) {
2167 var bestResultSoFar, complexity, error, fraction, hypothesis, i, i1, j, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, result, splitBeforeAndAfterDot;
2168 splitBeforeAndAfterDot = theFloat.toString().split(".");
2169 if (splitBeforeAndAfterDot.length === 2) {
2170 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2171 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2172 } else {
2173 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2174 }
2175 console.log("precision: " + precision);
2176 bestResultSoFar = null;
2177 minimumComplexity = Number.MAX_VALUE;
2178 for (i = o = 1; o <= 13; i = ++o) {
2179 for (j = i1 = 1; i1 <= 13; j = ++i1) {
2180 fraction = i / j;
2181 hypothesis = Math.sin(Math.PI * fraction);
2182 if (Math.abs(hypothesis) > 1e-10) {
2183 ratio = theFloat / hypothesis;
2184 likelyMultiplier = Math.round(ratio);
2185 error = Math.abs(1 - ratio / likelyMultiplier);
2186 } else {
2187 ratio = 1;
2188 likelyMultiplier = 1;
2189 error = Math.abs(theFloat - hypothesis);
2190 }
2191 if (error < 23 * precision) {
2192 complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
2193 if (complexity < minimumComplexity) {
2194 minimumComplexity = complexity;
2195 result = likelyMultiplier + " * sin( " + i + "/" + j + " * pi )";
2196 bestResultSoFar = [result, approx_sine_of_pi_times_rational, likelyMultiplier, i, j];
2197 }
2198 }
2199 }
2200 }
2201 return bestResultSoFar;
2202 };
2203
2204 approxAll = function(theFloat) {
2205 var LOG_EXPLANATIONS, approxLogsResult, approxRadicalsResult, approxRationalsOfPowersOfEResult, approxRationalsOfPowersOfPIResult, approxTrigonometricResult, bestApproxSoFar, constantsSum, constantsSumMin, numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot;
2206 splitBeforeAndAfterDot = theFloat.toString().split(".");
2207 if (splitBeforeAndAfterDot.length === 2) {
2208 numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
2209 precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
2210 } else {
2211 return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
2212 }
2213 console.log("precision: " + precision);
2214 constantsSumMin = Number.MAX_VALUE;
2215 constantsSum = 0;
2216 bestApproxSoFar = null;
2217 LOG_EXPLANATIONS = true;
2218 approxRadicalsResult = approxRadicals(theFloat);
2219 if (approxRadicalsResult != null) {
2220 constantsSum = simpleComplexityMeasure(approxRadicalsResult);
2221 if (constantsSum < constantsSumMin) {
2222 if (LOG_EXPLANATIONS) {
2223 console.log("better explanation by approxRadicals: " + approxRadicalsResult + " complexity: " + constantsSum);
2224 }
2225 constantsSumMin = constantsSum;
2226 bestApproxSoFar = approxRadicalsResult;
2227 } else {
2228 if (LOG_EXPLANATIONS) {
2229 console.log("subpar explanation by approxRadicals: " + approxRadicalsResult + " complexity: " + constantsSum);
2230 }
2231 }
2232 }
2233 approxLogsResult = approxLogs(theFloat);
2234 if (approxLogsResult != null) {
2235 constantsSum = simpleComplexityMeasure(approxLogsResult);
2236 if (constantsSum < constantsSumMin) {
2237 if (LOG_EXPLANATIONS) {
2238 console.log("better explanation by approxLogs: " + approxLogsResult + " complexity: " + constantsSum);
2239 }
2240 constantsSumMin = constantsSum;
2241 bestApproxSoFar = approxLogsResult;
2242 } else {
2243 if (LOG_EXPLANATIONS) {
2244 console.log("subpar explanation by approxLogs: " + approxLogsResult + " complexity: " + constantsSum);
2245 }
2246 }
2247 }
2248 approxRationalsOfPowersOfEResult = approxRationalsOfPowersOfE(theFloat);
2249 if (approxRationalsOfPowersOfEResult != null) {
2250 constantsSum = simpleComplexityMeasure(approxRationalsOfPowersOfEResult);
2251 if (constantsSum < constantsSumMin) {
2252 if (LOG_EXPLANATIONS) {
2253 console.log("better explanation by approxRationalsOfPowersOfE: " + approxRationalsOfPowersOfEResult + " complexity: " + constantsSum);
2254 }
2255 constantsSumMin = constantsSum;
2256 bestApproxSoFar = approxRationalsOfPowersOfEResult;
2257 } else {
2258 if (LOG_EXPLANATIONS) {
2259 console.log("subpar explanation by approxRationalsOfPowersOfE: " + approxRationalsOfPowersOfEResult + " complexity: " + constantsSum);
2260 }
2261 }
2262 }
2263 approxRationalsOfPowersOfPIResult = approxRationalsOfPowersOfPI(theFloat);
2264 if (approxRationalsOfPowersOfPIResult != null) {
2265 constantsSum = simpleComplexityMeasure(approxRationalsOfPowersOfPIResult);
2266 if (constantsSum < constantsSumMin) {
2267 if (LOG_EXPLANATIONS) {
2268 console.log("better explanation by approxRationalsOfPowersOfPI: " + approxRationalsOfPowersOfPIResult + " complexity: " + constantsSum);
2269 }
2270 constantsSumMin = constantsSum;
2271 bestApproxSoFar = approxRationalsOfPowersOfPIResult;
2272 } else {
2273 if (LOG_EXPLANATIONS) {
2274 console.log("subpar explanation by approxRationalsOfPowersOfPI: " + approxRationalsOfPowersOfPIResult + " complexity: " + constantsSum);
2275 }
2276 }
2277 }
2278 approxTrigonometricResult = approxTrigonometric(theFloat);
2279 if (approxTrigonometricResult != null) {
2280 constantsSum = simpleComplexityMeasure(approxTrigonometricResult);
2281 if (constantsSum < constantsSumMin) {
2282 if (LOG_EXPLANATIONS) {
2283 console.log("better explanation by approxTrigonometric: " + approxTrigonometricResult + " complexity: " + constantsSum);
2284 }
2285 constantsSumMin = constantsSum;
2286 bestApproxSoFar = approxTrigonometricResult;
2287 } else {
2288 if (LOG_EXPLANATIONS) {
2289 console.log("subpar explanation by approxTrigonometric: " + approxTrigonometricResult + " complexity: " + constantsSum);
2290 }
2291 }
2292 }
2293 return bestApproxSoFar;
2294 };
2295
2296 simpleComplexityMeasure = function(aResult, b, c) {
2297 var theSum;
2298 theSum = null;
2299 if (aResult instanceof Array) {
2300 switch (aResult[1]) {
2301 case approx_sine_of_pi_times_rational:
2302 theSum = 4;
2303 break;
2304 case approx_rationalOfPi:
2305 theSum = Math.pow(4, Math.abs(aResult[3])) * Math.abs(aResult[2]);
2306 break;
2307 case approx_rationalOfE:
2308 theSum = Math.pow(3, Math.abs(aResult[3])) * Math.abs(aResult[2]);
2309 break;
2310 default:
2311 theSum = 0;
2312 }
2313 theSum += Math.abs(aResult[2]) * (Math.abs(aResult[3]) + Math.abs(aResult[4]));
2314 } else {
2315 theSum += Math.abs(aResult) * (Math.abs(b) + Math.abs(c));
2316 }
2317 if (aResult[2] === 1) {
2318 theSum -= 1;
2319 } else {
2320 theSum += 1;
2321 }
2322 if (aResult[3] === 1) {
2323 theSum -= 1;
2324 } else {
2325 theSum += 1;
2326 }
2327 if (aResult[4] === 1) {
2328 theSum -= 1;
2329 } else {
2330 theSum += 1;
2331 }
2332 if (theSum < 0) {
2333 theSum = 0;
2334 }
2335 return theSum;
2336 };
2337
2338 testApprox = function() {
2339 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;
2340 ref = [2, 3, 5, 6, 7, 8, 10];
2341 for (o = 0, len = ref.length; o < len; o++) {
2342 i = ref[o];
2343 ref1 = [2, 3, 5, 6, 7, 8, 10];
2344 for (i1 = 0, len1 = ref1.length; i1 < len1; i1++) {
2345 j = ref1[i1];
2346 if (i === j) {
2347 continue;
2348 }
2349 console.log("testapproxRadicals testing: " + "1 * sqrt( " + i + " ) / " + j);
2350 fraction = i / j;
2351 value = Math.sqrt(i) / j;
2352 returned = approxRadicals(value);
2353 returnedValue = returned[2] * Math.sqrt(returned[3]) / returned[4];
2354 if (Math.abs(value - returnedValue) > 1e-15) {
2355 console.log("fail testapproxRadicals: " + "1 * sqrt( " + i + " ) / " + j + " . obtained: " + returned);
2356 }
2357 }
2358 }
2359 ref2 = [2, 3, 5, 6, 7, 8, 10];
2360 for (j1 = 0, len2 = ref2.length; j1 < len2; j1++) {
2361 i = ref2[j1];
2362 ref3 = [2, 3, 5, 6, 7, 8, 10];
2363 for (l1 = 0, len3 = ref3.length; l1 < len3; l1++) {
2364 j = ref3[l1];
2365 if (i === j) {
2366 continue;
2367 }
2368 console.log("testapproxRadicals testing with 4 digits: " + "1 * sqrt( " + i + " ) / " + j);
2369 fraction = i / j;
2370 originalValue = Math.sqrt(i) / j;
2371 value = originalValue.toFixed(4);
2372 returned = approxRadicals(value);
2373 returnedValue = returned[2] * Math.sqrt(returned[3]) / returned[4];
2374 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2375 console.log("fail testapproxRadicals with 4 digits: " + "1 * sqrt( " + i + " ) / " + j + " . obtained: " + returned);
2376 }
2377 }
2378 }
2379 ref4 = [2, 3, 5, 6, 7, 8, 10];
2380 for (m1 = 0, len4 = ref4.length; m1 < len4; m1++) {
2381 i = ref4[m1];
2382 ref5 = [2, 3, 5, 6, 7, 8, 10];
2383 for (n1 = 0, len5 = ref5.length; n1 < len5; n1++) {
2384 j = ref5[n1];
2385 if (i === j) {
2386 continue;
2387 }
2388 console.log("testapproxRadicals testing: " + "1 * sqrt( " + i + " / " + j + " )");
2389 fraction = i / j;
2390 value = Math.sqrt(i / j);
2391 returned = approxRadicals(value);
2392 if (returned != null) {
2393 returnedValue = returned[2] * Math.sqrt(returned[3] / returned[4]);
2394 if (returned[1] === approx_radicalOfRatio && Math.abs(value - returnedValue) > 1e-15) {
2395 console.log("fail testapproxRadicals: " + "1 * sqrt( " + i + " / " + j + " ) . obtained: " + returned);
2396 }
2397 }
2398 }
2399 }
2400 ref6 = [1, 2, 3, 5, 6, 7, 8, 10];
2401 for (o1 = 0, len6 = ref6.length; o1 < len6; o1++) {
2402 i = ref6[o1];
2403 ref7 = [1, 2, 3, 5, 6, 7, 8, 10];
2404 for (q1 = 0, len7 = ref7.length; q1 < len7; q1++) {
2405 j = ref7[q1];
2406 if (i === 1 && j === 1) {
2407 continue;
2408 }
2409 console.log("testapproxRadicals testing with 4 digits:: " + "1 * sqrt( " + i + " / " + j + " )");
2410 fraction = i / j;
2411 originalValue = Math.sqrt(i / j);
2412 value = originalValue.toFixed(4);
2413 returned = approxRadicals(value);
2414 returnedValue = returned[2] * Math.sqrt(returned[3] / returned[4]);
2415 if (returned[1] === approx_radicalOfRatio && Math.abs(originalValue - returnedValue) > 1e-15) {
2416 console.log("fail testapproxRadicals with 4 digits:: " + "1 * sqrt( " + i + " / " + j + " ) . obtained: " + returned);
2417 }
2418 }
2419 }
2420 for (i = r1 = 1; r1 <= 5; i = ++r1) {
2421 for (j = s1 = 1; s1 <= 5; j = ++s1) {
2422 console.log("testApproxAll testing: " + "1 * log(" + i + " ) / " + j);
2423 fraction = i / j;
2424 value = Math.log(i) / j;
2425 returned = approxAll(value);
2426 returnedValue = returned[2] * Math.log(returned[3]) / returned[4];
2427 if (Math.abs(value - returnedValue) > 1e-15) {
2428 console.log("fail testApproxAll: " + "1 * log(" + i + " ) / " + j + " . obtained: " + returned);
2429 }
2430 }
2431 }
2432 for (i = t1 = 1; t1 <= 5; i = ++t1) {
2433 for (j = u1 = 1; u1 <= 5; j = ++u1) {
2434 console.log("testApproxAll testing with 4 digits: " + "1 * log(" + i + " ) / " + j);
2435 fraction = i / j;
2436 originalValue = Math.log(i) / j;
2437 value = originalValue.toFixed(4);
2438 returned = approxAll(value);
2439 returnedValue = returned[2] * Math.log(returned[3]) / returned[4];
2440 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2441 console.log("fail testApproxAll with 4 digits: " + "1 * log(" + i + " ) / " + j + " . obtained: " + returned);
2442 }
2443 }
2444 }
2445 for (i = v1 = 1; v1 <= 5; i = ++v1) {
2446 for (j = x1 = 1; x1 <= 5; j = ++x1) {
2447 console.log("testApproxAll testing: " + "1 * log(" + i + " / " + j + " )");
2448 fraction = i / j;
2449 value = Math.log(i / j);
2450 returned = approxAll(value);
2451 returnedValue = returned[2] * Math.log(returned[3] / returned[4]);
2452 if (Math.abs(value - returnedValue) > 1e-15) {
2453 console.log("fail testApproxAll: " + "1 * log(" + i + " / " + j + " )" + " . obtained: " + returned);
2454 }
2455 }
2456 }
2457 for (i = z1 = 1; z1 <= 5; i = ++z1) {
2458 for (j = i2 = 1; i2 <= 5; j = ++i2) {
2459 console.log("testApproxAll testing with 4 digits: " + "1 * log(" + i + " / " + j + " )");
2460 fraction = i / j;
2461 originalValue = Math.log(i / j);
2462 value = originalValue.toFixed(4);
2463 returned = approxAll(value);
2464 returnedValue = returned[2] * Math.log(returned[3] / returned[4]);
2465 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2466 console.log("fail testApproxAll with 4 digits: " + "1 * log(" + i + " / " + j + " )" + " . obtained: " + returned);
2467 }
2468 }
2469 }
2470 for (i = j2 = 1; j2 <= 2; i = ++j2) {
2471 for (j = l2 = 1; l2 <= 12; j = ++l2) {
2472 console.log("testApproxAll testing: " + "1 * (e ^ " + i + " ) / " + j);
2473 fraction = i / j;
2474 value = Math.pow(Math.E, i) / j;
2475 returned = approxAll(value);
2476 returnedValue = returned[2] * Math.pow(Math.E, returned[3]) / returned[4];
2477 if (Math.abs(value - returnedValue) > 1e-15) {
2478 console.log("fail testApproxAll: " + "1 * (e ^ " + i + " ) / " + j + " . obtained: " + returned);
2479 }
2480 }
2481 }
2482 for (i = m2 = 1; m2 <= 2; i = ++m2) {
2483 for (j = n2 = 1; n2 <= 12; j = ++n2) {
2484 console.log("approxRationalsOfPowersOfE testing with 4 digits: " + "1 * (e ^ " + i + " ) / " + j);
2485 fraction = i / j;
2486 originalValue = Math.pow(Math.E, i) / j;
2487 value = originalValue.toFixed(4);
2488 returned = approxRationalsOfPowersOfE(value);
2489 returnedValue = returned[2] * Math.pow(Math.E, returned[3]) / returned[4];
2490 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2491 console.log("fail approxRationalsOfPowersOfE with 4 digits: " + "1 * (e ^ " + i + " ) / " + j + " . obtained: " + returned);
2492 }
2493 }
2494 }
2495 for (i = o2 = 1; o2 <= 2; i = ++o2) {
2496 for (j = q2 = 1; q2 <= 12; j = ++q2) {
2497 console.log("testApproxAll testing: " + "1 * pi ^ " + i + " / " + j);
2498 fraction = i / j;
2499 value = Math.pow(Math.PI, i) / j;
2500 returned = approxAll(value);
2501 returnedValue = returned[2] * Math.pow(Math.PI, returned[3]) / returned[4];
2502 if (Math.abs(value - returnedValue) > 1e-15) {
2503 console.log("fail testApproxAll: " + "1 * pi ^ " + i + " / " + j + " ) . obtained: " + returned);
2504 }
2505 }
2506 }
2507 for (i = r2 = 1; r2 <= 2; i = ++r2) {
2508 for (j = s2 = 1; s2 <= 12; j = ++s2) {
2509 console.log("approxRationalsOfPowersOfPI testing with 4 digits: " + "1 * pi ^ " + i + " / " + j);
2510 fraction = i / j;
2511 originalValue = Math.pow(Math.PI, i) / j;
2512 value = originalValue.toFixed(4);
2513 returned = approxRationalsOfPowersOfPI(value);
2514 returnedValue = returned[2] * Math.pow(Math.PI, returned[3]) / returned[4];
2515 if (Math.abs(originalValue - returnedValue) > 1e-15) {
2516 console.log("fail approxRationalsOfPowersOfPI with 4 digits: " + "1 * pi ^ " + i + " / " + j + " ) . obtained: " + returned);
2517 }
2518 }
2519 }
2520 for (i = t2 = 1; t2 <= 4; i = ++t2) {
2521 for (j = u2 = 1; u2 <= 4; j = ++u2) {
2522 console.log("testApproxAll testing: " + "1 * sin( " + i + "/" + j + " )");
2523 fraction = i / j;
2524 value = Math.sin(fraction);
2525 returned = approxAll(value);
2526 returnedFraction = returned[3] / returned[4];
2527 returnedValue = returned[2] * Math.sin(returnedFraction);
2528 if (Math.abs(value - returnedValue) > 1e-15) {
2529 console.log("fail testApproxAll: " + "1 * sin( " + i + "/" + j + " ) . obtained: " + returned);
2530 }
2531 }
2532 }
2533 for (i = v2 = 1; v2 <= 4; i = ++v2) {
2534 for (j = x2 = 1; x2 <= 4; j = ++x2) {
2535 console.log("testApproxAll testing with 5 digits: " + "1 * sin( " + i + "/" + j + " )");
2536 fraction = i / j;
2537 originalValue = Math.sin(fraction);
2538 value = originalValue.toFixed(5);
2539 returned = approxAll(value);
2540 if (returned == null) {
2541 console.log("fail testApproxAll with 5 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: undefined ");
2542 }
2543 returnedFraction = returned[3] / returned[4];
2544 returnedValue = returned[2] * Math.sin(returnedFraction);
2545 error = Math.abs(originalValue - returnedValue);
2546 if (error > 1e-14) {
2547 console.log("fail testApproxAll with 5 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: " + returned + " error: " + error);
2548 }
2549 }
2550 }
2551 for (i = z2 = 1; z2 <= 4; i = ++z2) {
2552 for (j = i3 = 1; i3 <= 4; j = ++i3) {
2553 console.log("testApproxAll testing with 4 digits: " + "1 * sin( " + i + "/" + j + " )");
2554 fraction = i / j;
2555 originalValue = Math.sin(fraction);
2556 value = originalValue.toFixed(4);
2557 returned = approxAll(value);
2558 if (returned == null) {
2559 console.log("fail testApproxAll with 4 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: undefined ");
2560 }
2561 returnedFraction = returned[3] / returned[4];
2562 returnedValue = returned[2] * Math.sin(returnedFraction);
2563 error = Math.abs(originalValue - returnedValue);
2564 if (error > 1e-14) {
2565 console.log("fail testApproxAll with 4 digits: " + "1 * sin( " + i + "/" + j + " ) . obtained: " + returned + " error: " + error);
2566 }
2567 }
2568 }
2569 value = 0;
2570 if (approxAll(value)[0] !== "0") {
2571 console.log("fail testApproxAll: 0");
2572 }
2573 value = 0.0;
2574 if (approxAll(value)[0] !== "0") {
2575 console.log("fail testApproxAll: 0.0");
2576 }
2577 value = 0.00;
2578 if (approxAll(value)[0] !== "0") {
2579 console.log("fail testApproxAll: 0.00");
2580 }
2581 value = 0.000;
2582 if (approxAll(value)[0] !== "0") {
2583 console.log("fail testApproxAll: 0.000");
2584 }
2585 value = 0.0000;
2586 if (approxAll(value)[0] !== "0") {
2587 console.log("fail testApproxAll: 0.0000");
2588 }
2589 value = 1;
2590 if (approxAll(value)[0] !== "1") {
2591 console.log("fail testApproxAll: 1");
2592 }
2593 value = 1.0;
2594 if (approxAll(value)[0] !== "1") {
2595 console.log("fail testApproxAll: 1.0");
2596 }
2597 value = 1.00;
2598 if (approxAll(value)[0] !== "1") {
2599 console.log("fail testApproxAll: 1.00");
2600 }
2601 value = 1.000;
2602 if (approxAll(value)[0] !== "1") {
2603 console.log("fail testApproxAll: 1.000");
2604 }
2605 value = 1.0000;
2606 if (approxAll(value)[0] !== "1") {
2607 console.log("fail testApproxAll: 1.0000");
2608 }
2609 value = 1.00000;
2610 if (approxAll(value)[0] !== "1") {
2611 console.log("fail testApproxAll: 1.00000");
2612 }
2613 value = Math.sqrt(2);
2614 if (approxAll(value)[0] !== "1 * sqrt( 2 ) / 1") {
2615 console.log("fail testApproxAll: Math.sqrt(2)");
2616 }
2617 value = 1.41;
2618 if (approxAll(value)[0] !== "1 * sqrt( 2 ) / 1") {
2619 console.log("fail testApproxAll: 1.41");
2620 }
2621 value = 1.4;
2622 if (approxRadicals(value)[0] !== "1 * sqrt( 2 ) / 1") {
2623 console.log("fail approxRadicals: 1.4");
2624 }
2625 value = 0.6;
2626 if (approxLogs(value)[0] !== "1 * log( 2 ) / 1") {
2627 console.log("fail approxLogs: 0.6");
2628 }
2629 value = 0.69;
2630 if (approxLogs(value)[0] !== "1 * log( 2 ) / 1") {
2631 console.log("fail approxLogs: 0.69");
2632 }
2633 value = 0.7;
2634 if (approxLogs(value)[0] !== "1 * log( 2 ) / 1") {
2635 console.log("fail approxLogs: 0.7");
2636 }
2637 value = 1.09;
2638 if (approxLogs(value)[0] !== "1 * log( 3 ) / 1") {
2639 console.log("fail approxLogs: 1.09");
2640 }
2641 value = 1.09;
2642 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2643 console.log("fail approxAll: 1.09");
2644 }
2645 value = 1.098;
2646 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2647 console.log("fail approxAll: 1.098");
2648 }
2649 value = 1.1;
2650 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2651 console.log("fail approxAll: 1.1");
2652 }
2653 value = 1.11;
2654 if (approxAll(value)[0] !== "1 * log( 3 ) / 1") {
2655 console.log("fail approxAll: 1.11");
2656 }
2657 value = Math.sqrt(3);
2658 if (approxAll(value)[0] !== "1 * sqrt( 3 ) / 1") {
2659 console.log("fail testApproxAll: Math.sqrt(3)");
2660 }
2661 value = 1.0000;
2662 if (approxAll(value)[0] !== "1") {
2663 console.log("fail testApproxAll: 1.0000");
2664 }
2665 value = 3.141592;
2666 if (approxAll(value)[0] !== "1 * (pi ^ 1 ) / 1 )") {
2667 console.log("fail testApproxAll: 3.141592");
2668 }
2669 value = 31.41592;
2670 if (approxAll(value)[0] !== "10 * (pi ^ 1 ) / 1 )") {
2671 console.log("fail testApproxAll: 31.41592");
2672 }
2673 value = 314.1592;
2674 if (approxAll(value)[0] !== "100 * (pi ^ 1 ) / 1 )") {
2675 console.log("fail testApproxAll: 314.1592");
2676 }
2677 value = 31415926.53589793;
2678 if (approxAll(value)[0] !== "10000000 * (pi ^ 1 ) / 1 )") {
2679 console.log("fail testApproxAll: 31415926.53589793");
2680 }
2681 value = Math.sqrt(2);
2682 if (approxTrigonometric(value)[0] !== "2 * sin( 1/4 * pi )") {
2683 console.log("fail approxTrigonometric: Math.sqrt(2)");
2684 }
2685 value = Math.sqrt(3);
2686 if (approxTrigonometric(value)[0] !== "2 * sin( 1/3 * pi )") {
2687 console.log("fail approxTrigonometric: Math.sqrt(3)");
2688 }
2689 value = (Math.sqrt(6) - Math.sqrt(2)) / 4;
2690 if (approxAll(value)[0] !== "1 * sin( 1/12 * pi )") {
2691 console.log("fail testApproxAll: (Math.sqrt(6) - Math.sqrt(2))/4");
2692 }
2693 value = Math.sqrt(2 - Math.sqrt(2)) / 2;
2694 if (approxAll(value)[0] !== "1 * sin( 1/8 * pi )") {
2695 console.log("fail testApproxAll: Math.sqrt(2 - Math.sqrt(2))/2");
2696 }
2697 value = (Math.sqrt(6) + Math.sqrt(2)) / 4;
2698 if (approxAll(value)[0] !== "1 * sin( 5/12 * pi )") {
2699 console.log("fail testApproxAll: (Math.sqrt(6) + Math.sqrt(2))/4");
2700 }
2701 value = Math.sqrt(2 + Math.sqrt(3)) / 2;
2702 if (approxAll(value)[0] !== "1 * sin( 5/12 * pi )") {
2703 console.log("fail testApproxAll: Math.sqrt(2 + Math.sqrt(3))/2");
2704 }
2705 value = (Math.sqrt(5) - 1) / 4;
2706 if (approxAll(value)[0] !== "1 * sin( 1/10 * pi )") {
2707 console.log("fail testApproxAll: (Math.sqrt(5) - 1)/4");
2708 }
2709 value = Math.sqrt(10 - 2 * Math.sqrt(5)) / 4;
2710 if (approxAll(value)[0] !== "1 * sin( 1/5 * pi )") {
2711 console.log("fail testApproxAll: Math.sqrt(10 - 2*Math.sqrt(5))/4");
2712 }
2713 value = Math.sin(Math.PI / 7);
2714 if (approxAll(value)[0] !== "1 * sin( 1/7 * pi )") {
2715 console.log("fail testApproxAll: Math.sin(Math.PI/7)");
2716 }
2717 value = Math.sin(Math.PI / 9);
2718 if (approxAll(value)[0] !== "1 * sin( 1/9 * pi )") {
2719 console.log("fail testApproxAll: Math.sin(Math.PI/9)");
2720 }
2721 value = 1836.15267;
2722 if (approxRationalsOfPowersOfPI(value)[0] !== "6 * (pi ^ 5 ) / 1 )") {
2723 console.log("fail approxRationalsOfPowersOfPI: 1836.15267");
2724 }
2725 for (i = j3 = 1; j3 <= 13; i = ++j3) {
2726 for (j = k3 = 1; k3 <= 13; j = ++k3) {
2727 console.log("approxTrigonometric testing: " + "1 * sin( " + i + "/" + j + " * pi )");
2728 fraction = i / j;
2729 value = Math.sin(Math.PI * fraction);
2730 returned = approxTrigonometric(value);
2731 returnedFraction = returned[3] / returned[4];
2732 returnedValue = returned[2] * Math.sin(Math.PI * returnedFraction);
2733 if (Math.abs(value - returnedValue) > 1e-15) {
2734 console.log("fail approxTrigonometric: " + "1 * sin( " + i + "/" + j + " * pi ) . obtained: " + returned);
2735 }
2736 }
2737 }
2738 for (i = l3 = 1; l3 <= 13; i = ++l3) {
2739 for (j = m3 = 1; m3 <= 13; j = ++m3) {
2740 if (i === 5 && j === 11 || i === 6 && j === 11) {
2741 continue;
2742 }
2743 console.log("approxTrigonometric testing with 4 digits: " + "1 * sin( " + i + "/" + j + " * pi )");
2744 fraction = i / j;
2745 originalValue = Math.sin(Math.PI * fraction);
2746 value = originalValue.toFixed(4);
2747 returned = approxTrigonometric(value);
2748 returnedFraction = returned[3] / returned[4];
2749 returnedValue = returned[2] * Math.sin(Math.PI * returnedFraction);
2750 error = Math.abs(originalValue - returnedValue);
2751 if (error > 1e-14) {
2752 console.log("fail approxTrigonometric with 4 digits: " + "1 * sin( " + i + "/" + j + " * pi ) . obtained: " + returned + " error: " + error);
2753 }
2754 }
2755 }
2756 return console.log("testApprox done");
2757 };
2758
2759 $.approxRadicals = approxRadicals;
2760
2761 $.approxRationalsOfLogs = approxRationalsOfLogs;
2762
2763 $.approxAll = approxAll;
2764
2765 $.testApprox = testApprox;
2766
2767
2768 /* arccos =====================================================================
2769
2770 Tags
2771 ----
2772 scripting, JS, internal, treenode, general concept
2773
2774 Parameters
2775 ----------
2776 x
2777
2778 General description
2779 -------------------
2780 Returns the inverse cosine of x.
2781 */
2782
2783 Eval_arccos = function() {
2784 push(cadr(p1));
2785 Eval();
2786 return arccos();
2787 };
2788
2789 arccos = function() {
2790 var d, errno, n;
2791 n = 0;
2792 d = 0.0;
2793 save();
2794 p1 = pop();
2795 if (car(p1) === symbol(COS)) {
2796 push(cadr(p1));
2797 restore();
2798 return;
2799 }
2800 if (isdouble(p1)) {
2801 errno = 0;
2802 d = Math.acos(p1.d);
2803 if (errno) {
2804 stop("arccos function argument is not in the interval [-1,1]");
2805 }
2806 push_double(d);
2807 restore();
2808 return;
2809 }
2810 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))) {
2811 if (evaluatingAsFloats) {
2812 push_double(Math.PI / 4.0);
2813 } else {
2814 push_rational(1, 4);
2815 push_symbol(PI);
2816 multiply();
2817 }
2818 restore();
2819 return;
2820 }
2821 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))) {
2822 if (evaluatingAsFloats) {
2823 push_double(Math.PI * 3.0 / 4.0);
2824 } else {
2825 push_rational(3, 4);
2826 push_symbol(PI);
2827 multiply();
2828 }
2829 restore();
2830 return;
2831 }
2832 if (!isrational(p1)) {
2833 push_symbol(ARCCOS);
2834 push(p1);
2835 list(2);
2836 restore();
2837 return;
2838 }
2839 push(p1);
2840 push_integer(2);
2841 multiply();
2842 n = pop_integer();
2843 switch (n) {
2844 case -2:
2845 if (evaluatingAsFloats) {
2846 push_double(Math.PI);
2847 } else {
2848 push_symbol(PI);
2849 }
2850 break;
2851 case -1:
2852 if (evaluatingAsFloats) {
2853 push_double(Math.PI * 2.0 / 3.0);
2854 } else {
2855 push_rational(2, 3);
2856 push_symbol(PI);
2857 multiply();
2858 }
2859 break;
2860 case 0:
2861 if (evaluatingAsFloats) {
2862 push_double(Math.PI / 2.0);
2863 } else {
2864 push_rational(1, 2);
2865 push_symbol(PI);
2866 multiply();
2867 }
2868 break;
2869 case 1:
2870 if (evaluatingAsFloats) {
2871 push_double(Math.PI / 3.0);
2872 } else {
2873 push_rational(1, 3);
2874 push_symbol(PI);
2875 multiply();
2876 }
2877 break;
2878 case 2:
2879 if (evaluatingAsFloats) {
2880 push_double(0.0);
2881 } else {
2882 push(zero);
2883 }
2884 break;
2885 default:
2886 push_symbol(ARCCOS);
2887 push(p1);
2888 list(2);
2889 }
2890 return restore();
2891 };
2892
2893
2894 /* arccosh =====================================================================
2895
2896 Tags
2897 ----
2898 scripting, JS, internal, treenode, general concept
2899
2900 Parameters
2901 ----------
2902 x
2903
2904 General description
2905 -------------------
2906 Returns the inverse hyperbolic cosine of x.
2907 */
2908
2909 Eval_arccosh = function() {
2910 push(cadr(p1));
2911 Eval();
2912 return arccosh();
2913 };
2914
2915 arccosh = function() {
2916 var d;
2917 d = 0.0;
2918 save();
2919 p1 = pop();
2920 if (car(p1) === symbol(COSH)) {
2921 push(cadr(p1));
2922 restore();
2923 return;
2924 }
2925 if (isdouble(p1)) {
2926 d = p1.d;
2927 if (d < 1.0) {
2928 stop("arccosh function argument is less than 1.0");
2929 }
2930 d = Math.log(d + Math.sqrt(d * d - 1.0));
2931 push_double(d);
2932 restore();
2933 return;
2934 }
2935 if (isplusone(p1)) {
2936 push(zero);
2937 restore();
2938 return;
2939 }
2940 push_symbol(ARCCOSH);
2941 push(p1);
2942 list(2);
2943 return restore();
2944 };
2945
2946
2947 /* arcsin =====================================================================
2948
2949 Tags
2950 ----
2951 scripting, JS, internal, treenode, general concept
2952
2953 Parameters
2954 ----------
2955 x
2956
2957 General description
2958 -------------------
2959 Returns the inverse sine of x.
2960 */
2961
2962 Eval_arcsin = function() {
2963 push(cadr(p1));
2964 Eval();
2965 return arcsin();
2966 };
2967
2968 arcsin = function() {
2969 var d, errno, n;
2970 n = 0;
2971 d = 0;
2972 save();
2973 p1 = pop();
2974 if (car(p1) === symbol(SIN)) {
2975 push(cadr(p1));
2976 restore();
2977 return;
2978 }
2979 if (isdouble(p1)) {
2980 errno = 0;
2981 d = Math.asin(p1.d);
2982 if (errno) {
2983 stop("arcsin function argument is not in the interval [-1,1]");
2984 }
2985 push_double(d);
2986 restore();
2987 return;
2988 }
2989 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))) {
2990 push_rational(1, 4);
2991 push_symbol(PI);
2992 multiply();
2993 restore();
2994 return;
2995 }
2996 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))) {
2997 if (evaluatingAsFloats) {
2998 push_double(-Math.PI / 4.0);
2999 } else {
3000 push_rational(-1, 4);
3001 push_symbol(PI);
3002 multiply();
3003 }
3004 restore();
3005 return;
3006 }
3007 if (!isrational(p1)) {
3008 push_symbol(ARCSIN);
3009 push(p1);
3010 list(2);
3011 restore();
3012 return;
3013 }
3014 push(p1);
3015 push_integer(2);
3016 multiply();
3017 n = pop_integer();
3018 switch (n) {
3019 case -2:
3020 if (evaluatingAsFloats) {
3021 push_double(-Math.PI / 2.0);
3022 } else {
3023 push_rational(-1, 2);
3024 push_symbol(PI);
3025 multiply();
3026 }
3027 break;
3028 case -1:
3029 if (evaluatingAsFloats) {
3030 push_double(-Math.PI / 6.0);
3031 } else {
3032 push_rational(-1, 6);
3033 push_symbol(PI);
3034 multiply();
3035 }
3036 break;
3037 case 0:
3038 if (evaluatingAsFloats) {
3039 push_double(0.0);
3040 } else {
3041 push(zero);
3042 }
3043 break;
3044 case 1:
3045 if (evaluatingAsFloats) {
3046 push_double(Math.PI / 6.0);
3047 } else {
3048 push_rational(1, 6);
3049 push_symbol(PI);
3050 multiply();
3051 }
3052 break;
3053 case 2:
3054 if (evaluatingAsFloats) {
3055 push_double(Math.PI / 2.0);
3056 } else {
3057 push_rational(1, 2);
3058 push_symbol(PI);
3059 multiply();
3060 }
3061 break;
3062 default:
3063 push_symbol(ARCSIN);
3064 push(p1);
3065 list(2);
3066 }
3067 return restore();
3068 };
3069
3070
3071 /* arcsinh =====================================================================
3072
3073 Tags
3074 ----
3075 scripting, JS, internal, treenode, general concept
3076
3077 Parameters
3078 ----------
3079 x
3080
3081 General description
3082 -------------------
3083 Returns the inverse hyperbolic sine of x.
3084 */
3085
3086 Eval_arcsinh = function() {
3087 push(cadr(p1));
3088 Eval();
3089 return arcsinh();
3090 };
3091
3092 arcsinh = function() {
3093 var d;
3094 d = 0.0;
3095 save();
3096 p1 = pop();
3097 if (car(p1) === symbol(SINH)) {
3098 push(cadr(p1));
3099 restore();
3100 return;
3101 }
3102 if (isdouble(p1)) {
3103 d = p1.d;
3104 d = Math.log(d + Math.sqrt(d * d + 1.0));
3105 push_double(d);
3106 restore();
3107 return;
3108 }
3109 if (iszero(p1)) {
3110 push(zero);
3111 restore();
3112 return;
3113 }
3114 push_symbol(ARCSINH);
3115 push(p1);
3116 list(2);
3117 return restore();
3118 };
3119
3120
3121 /* arctan =====================================================================
3122
3123 Tags
3124 ----
3125 scripting, JS, internal, treenode, general concept
3126
3127 Parameters
3128 ----------
3129 x
3130
3131 General description
3132 -------------------
3133 Returns the inverse tangent of x.
3134 */
3135
3136 Eval_arctan = function() {
3137 push(cadr(p1));
3138 Eval();
3139 return arctan();
3140 };
3141
3142 arctan = function() {
3143 var d, errno;
3144 d = 0;
3145 save();
3146 p1 = pop();
3147 if (car(p1) === symbol(TAN)) {
3148 push(cadr(p1));
3149 restore();
3150 return;
3151 }
3152 if (isdouble(p1)) {
3153 errno = 0;
3154 d = Math.atan(p1.d);
3155 if (errno) {
3156 stop("arctan function error");
3157 }
3158 push_double(d);
3159 restore();
3160 return;
3161 }
3162 if (iszero(p1)) {
3163 push(zero);
3164 restore();
3165 return;
3166 }
3167 if (isnegative(p1)) {
3168 push(p1);
3169 negate();
3170 arctan();
3171 negate();
3172 restore();
3173 return;
3174 }
3175 if (Find(p1, symbol(SIN)) && Find(p1, symbol(COS))) {
3176 push(p1);
3177 numerator();
3178 p2 = pop();
3179 push(p1);
3180 denominator();
3181 p3 = pop();
3182 if (car(p2) === symbol(SIN) && car(p3) === symbol(COS) && equal(cadr(p2), cadr(p3))) {
3183 push(cadr(p2));
3184 restore();
3185 return;
3186 }
3187 }
3188 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))) {
3189 push_rational(1, 6);
3190 if (evaluatingAsFloats) {
3191 push_double(Math.PI);
3192 } else {
3193 push(symbol(PI));
3194 }
3195 multiply();
3196 restore();
3197 return;
3198 }
3199 if (equaln(p1, 1)) {
3200 push_rational(1, 4);
3201 if (evaluatingAsFloats) {
3202 push_double(Math.PI);
3203 } else {
3204 push(symbol(PI));
3205 }
3206 multiply();
3207 restore();
3208 return;
3209 }
3210 if (car(p1) === symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), 1, 2)) {
3211 push_rational(1, 3);
3212 if (evaluatingAsFloats) {
3213 push_double(Math.PI);
3214 } else {
3215 push(symbol(PI));
3216 }
3217 multiply();
3218 restore();
3219 return;
3220 }
3221 push_symbol(ARCTAN);
3222 push(p1);
3223 list(2);
3224 return restore();
3225 };
3226
3227
3228 /* arctanh =====================================================================
3229
3230 Tags
3231 ----
3232 scripting, JS, internal, treenode, general concept
3233
3234 Parameters
3235 ----------
3236 x
3237
3238 General description
3239 -------------------
3240 Returns the inverse hyperbolic tangent of x.
3241 */
3242
3243 Eval_arctanh = function() {
3244 push(cadr(p1));
3245 Eval();
3246 return arctanh();
3247 };
3248
3249 arctanh = function() {
3250 var d;
3251 d = 0.0;
3252 save();
3253 p1 = pop();
3254 if (car(p1) === symbol(TANH)) {
3255 push(cadr(p1));
3256 restore();
3257 return;
3258 }
3259 if (isdouble(p1)) {
3260 d = p1.d;
3261 if (d < -1.0 || d > 1.0) {
3262 stop("arctanh function argument is not in the interval [-1,1]");
3263 }
3264 d = Math.log((1.0 + d) / (1.0 - d)) / 2.0;
3265 push_double(d);
3266 restore();
3267 return;
3268 }
3269 if (iszero(p1)) {
3270 push(zero);
3271 restore();
3272 return;
3273 }
3274 push_symbol(ARCTANH);
3275 push(p1);
3276 list(2);
3277 return restore();
3278 };
3279
3280
3281 /* arg =====================================================================
3282
3283 Tags
3284 ----
3285 scripting, JS, internal, treenode, general concept
3286
3287 Parameters
3288 ----------
3289 z
3290
3291 General description
3292 -------------------
3293 Returns the angle of complex z.
3294 */
3295
3296
3297 /*
3298 Argument (angle) of complex z
3299
3300 z arg(z)
3301 - ------
3302
3303 a 0
3304
3305 -a -pi See note 3 below
3306
3307 (-1)^a a pi
3308
3309 exp(a + i b) b
3310
3311 a b arg(a) + arg(b)
3312
3313 a + i b arctan(b/a)
3314
3315 Result by quadrant
3316
3317 z arg(z)
3318 - ------
3319
3320 1 + i 1/4 pi
3321
3322 1 - i -1/4 pi
3323
3324 -1 + i 3/4 pi
3325
3326 -1 - i -3/4 pi
3327
3328 Notes
3329
3330 1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3)
3331
3332 2. Symbols in z are assumed to be positive and real.
3333
3334 3. Negative direction adds -pi to angle.
3335
3336 Example: z = (-1)^(1/3), abs(z) = 1/3 pi, abs(-z) = -2/3 pi
3337
3338 4. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then
3339
3340 arg(numerator(z)) - arg(denominator(z))
3341
3342 must be used to get the correct answer. Now the operation is
3343 automatic.
3344 */
3345
3346 DEBUG_ARG = false;
3347
3348 Eval_arg = function() {
3349 push(cadr(p1));
3350 Eval();
3351 return arg();
3352 };
3353
3354 arg = function() {
3355 save();
3356 p1 = pop();
3357 push(p1);
3358 numerator();
3359 yyarg();
3360 push(p1);
3361 denominator();
3362 yyarg();
3363 subtract();
3364 return restore();
3365 };
3366
3367 yyarg = function() {
3368 save();
3369 p1 = pop();
3370 if (ispositivenumber(p1) || p1 === symbol(PI)) {
3371 if (isdouble(p1) || evaluatingAsFloats) {
3372 push_double(0);
3373 } else {
3374 push_integer(0);
3375 }
3376 } else if (isnegativenumber(p1)) {
3377 if (isdouble(p1) || evaluatingAsFloats) {
3378 push_double(Math.PI);
3379 } else {
3380 push(symbol(PI));
3381 }
3382 negate();
3383 } else if (issymbol(p1)) {
3384 push_symbol(ARG);
3385 push(p1);
3386 list(2);
3387 } else if (car(p1) === symbol(POWER) && equaln(cadr(p1), -1)) {
3388 if (evaluatingAsFloats) {
3389 push_double(Math.PI);
3390 } else {
3391 push(symbol(PI));
3392 }
3393 push(caddr(p1));
3394 multiply();
3395 } else if (car(p1) === symbol(POWER) && cadr(p1) === symbol(E)) {
3396 push(caddr(p1));
3397 imag();
3398 } else if (car(p1) === symbol(POWER) && isoneovertwo(caddr(p1))) {
3399 if (DEBUG_ARG) {
3400 console.log("arg of a sqrt: " + p1);
3401 }
3402 if (DEBUG_ARG) {
3403 debugger;
3404 }
3405 push(cadr(p1));
3406 arg();
3407 if (DEBUG_ARG) {
3408 console.log(" = 1/2 * " + stack[tos - 1]);
3409 }
3410 push(caddr(p1));
3411 multiply();
3412 } else if (car(p1) === symbol(MULTIPLY)) {
3413 push_integer(0);
3414 p1 = cdr(p1);
3415 while (iscons(p1)) {
3416 push(car(p1));
3417 arg();
3418 add();
3419 p1 = cdr(p1);
3420 }
3421 } else if (car(p1) === symbol(ADD)) {
3422 push(p1);
3423 rect();
3424 p1 = pop();
3425 push(p1);
3426 real();
3427 p2 = pop();
3428 push(p1);
3429 imag();
3430 p3 = pop();
3431 if (iszero(p2)) {
3432 if (evaluatingAsFloats) {
3433 push_double(Math.PI);
3434 } else {
3435 push(symbol(PI));
3436 }
3437 if (isnegative(p3)) {
3438 negate();
3439 }
3440 } else {
3441 push(p3);
3442 push(p2);
3443 divide();
3444 arctan();
3445 if (isnegative(p2)) {
3446 if (evaluatingAsFloats) {
3447 push_double(Math.PI);
3448 } else {
3449 push_symbol(PI);
3450 }
3451 if (isnegative(p3)) {
3452 subtract();
3453 } else {
3454 add();
3455 }
3456 }
3457 }
3458 } else {
3459 if (!iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
3460 push_integer(0);
3461 } else {
3462 push_symbol(ARG);
3463 push(p1);
3464 list(2);
3465 }
3466 }
3467 return restore();
3468 };
3469
3470 bake = function() {
3471 var h, s, t, x, y, z;
3472 h = 0;
3473 s = 0;
3474 t = 0;
3475 x = 0;
3476 y = 0;
3477 z = 0;
3478 expanding++;
3479 save();
3480 p1 = pop();
3481 s = ispoly(p1, symbol(SYMBOL_S));
3482 t = ispoly(p1, symbol(SYMBOL_T));
3483 x = ispoly(p1, symbol(SYMBOL_X));
3484 y = ispoly(p1, symbol(SYMBOL_Y));
3485 z = ispoly(p1, symbol(SYMBOL_Z));
3486 if (s === 1 && t === 0 && x === 0 && y === 0 && z === 0) {
3487 p2 = symbol(SYMBOL_S);
3488 bake_poly();
3489 } else if (s === 0 && t === 1 && x === 0 && y === 0 && z === 0) {
3490 p2 = symbol(SYMBOL_T);
3491 bake_poly();
3492 } else if (s === 0 && t === 0 && x === 1 && y === 0 && z === 0) {
3493 p2 = symbol(SYMBOL_X);
3494 bake_poly();
3495 } else if (s === 0 && t === 0 && x === 0 && y === 1 && z === 0) {
3496 p2 = symbol(SYMBOL_Y);
3497 bake_poly();
3498 } else if (s === 0 && t === 0 && x === 0 && y === 0 && z === 1) {
3499 p2 = symbol(SYMBOL_Z);
3500 bake_poly();
3501 } else if ((iscons(p1)) && car(p1) !== symbol(FOR)) {
3502 h = tos;
3503 push(car(p1));
3504 p1 = cdr(p1);
3505 while (iscons(p1)) {
3506 push(car(p1));
3507 bake();
3508 p1 = cdr(p1);
3509 }
3510 list(tos - h);
3511 } else {
3512 push(p1);
3513 }
3514 restore();
3515 return expanding--;
3516 };
3517
3518 polyform = function() {
3519 var h;
3520 h = 0;
3521 save();
3522 p2 = pop();
3523 p1 = pop();
3524 if (ispoly(p1, p2)) {
3525 bake_poly();
3526 } else if (iscons(p1)) {
3527 h = tos;
3528 push(car(p1));
3529 p1 = cdr(p1);
3530 while (iscons(p1)) {
3531 push(car(p1));
3532 push(p2);
3533 polyform();
3534 p1 = cdr(p1);
3535 }
3536 list(tos - h);
3537 } else {
3538 push(p1);
3539 }
3540 return restore();
3541 };
3542
3543 bake_poly = function() {
3544 var a, h, i, k, n, o, ref;
3545 h = 0;
3546 i = 0;
3547 k = 0;
3548 n = 0;
3549 a = tos;
3550 push(p1);
3551 push(p2);
3552 k = coeff();
3553 h = tos;
3554 for (i = o = ref = k - 1; o >= 0; i = o += -1) {
3555 p1 = stack[a + i];
3556 bake_poly_term(i);
3557 }
3558 n = tos - h;
3559 if (n > 1) {
3560 list(n);
3561 push(symbol(ADD));
3562 swap();
3563 cons();
3564 }
3565 p1 = pop();
3566 moveTos(tos - k);
3567 return push(p1);
3568 };
3569
3570 bake_poly_term = function(k) {
3571 var h, n;
3572 h = 0;
3573 n = 0;
3574 if (iszero(p1)) {
3575 return;
3576 }
3577 if (k === 0) {
3578 if (car(p1) === symbol(ADD)) {
3579 p1 = cdr(p1);
3580 while (iscons(p1)) {
3581 push(car(p1));
3582 p1 = cdr(p1);
3583 }
3584 } else {
3585 push(p1);
3586 }
3587 return;
3588 }
3589 h = tos;
3590 if (car(p1) === symbol(MULTIPLY)) {
3591 p1 = cdr(p1);
3592 while (iscons(p1)) {
3593 push(car(p1));
3594 p1 = cdr(p1);
3595 }
3596 } else if (!equaln(p1, 1)) {
3597 push(p1);
3598 }
3599 if (k === 1) {
3600 push(p2);
3601 } else {
3602 push(symbol(POWER));
3603 push(p2);
3604 push_integer(k);
3605 list(3);
3606 }
3607 n = tos - h;
3608 if (n > 1) {
3609 list(n);
3610 push(symbol(MULTIPLY));
3611 swap();
3612 return cons();
3613 }
3614 };
3615
3616
3617 /* besselj =====================================================================
3618
3619 Tags
3620 ----
3621 scripting, JS, internal, treenode, general concept
3622
3623 Parameters
3624 ----------
3625 x,n
3626
3627 General description
3628 -------------------
3629
3630 Returns a solution to the Bessel differential equation (Bessel function of first kind).
3631
3632 Recurrence relation:
3633
3634 besselj(x,n) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n-2)
3635
3636 besselj(x,1/2) = sqrt(2/pi/x) sin(x)
3637
3638 besselj(x,-1/2) = sqrt(2/pi/x) cos(x)
3639
3640 For negative n, reorder the recurrence relation as:
3641
3642 besselj(x,n-2) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n)
3643
3644 Substitute n+2 for n to obtain
3645
3646 besselj(x,n) = (2/x) (n+1) besselj(x,n+1) - besselj(x,n+2)
3647
3648 Examples:
3649
3650 besselj(x,3/2) = (1/x) besselj(x,1/2) - besselj(x,-1/2)
3651
3652 besselj(x,-3/2) = -(1/x) besselj(x,-1/2) - besselj(x,1/2)
3653 */
3654
3655 Eval_besselj = function() {
3656 push(cadr(p1));
3657 Eval();
3658 push(caddr(p1));
3659 Eval();
3660 return besselj();
3661 };
3662
3663 besselj = function() {
3664 save();
3665 yybesselj();
3666 return restore();
3667 };
3668
3669 yybesselj = function() {
3670 var d, n;
3671 d = 0.0;
3672 n = 0;
3673 p2 = pop();
3674 p1 = pop();
3675 push(p2);
3676 n = pop_integer();
3677 if (isdouble(p1) && !isNaN(n)) {
3678 d = jn(n, p1.d);
3679 push_double(d);
3680 return;
3681 }
3682 if (iszero(p1) && iszero(p2)) {
3683 push_integer(1);
3684 return;
3685 }
3686 if (iszero(p1) && !isNaN(n)) {
3687 push_integer(0);
3688 return;
3689 }
3690 if (p2.k === NUM && MEQUAL(p2.q.b, 2)) {
3691 if (MEQUAL(p2.q.a, 1)) {
3692 if (evaluatingAsFloats) {
3693 push_double(2.0 / Math.PI);
3694 } else {
3695 push_integer(2);
3696 push_symbol(PI);
3697 divide();
3698 }
3699 push(p1);
3700 divide();
3701 push_rational(1, 2);
3702 power();
3703 push(p1);
3704 sine();
3705 multiply();
3706 return;
3707 }
3708 if (MEQUAL(p2.q.a, -1)) {
3709 if (evaluatingAsFloats) {
3710 push_double(2.0 / Math.PI);
3711 } else {
3712 push_integer(2);
3713 push_symbol(PI);
3714 divide();
3715 }
3716 push(p1);
3717 divide();
3718 push_rational(1, 2);
3719 power();
3720 push(p1);
3721 cosine();
3722 multiply();
3723 return;
3724 }
3725 push_integer(MSIGN(p2.q.a));
3726 p3 = pop();
3727 push_integer(2);
3728 push(p1);
3729 divide();
3730 push(p2);
3731 push(p3);
3732 subtract();
3733 multiply();
3734 push(p1);
3735 push(p2);
3736 push(p3);
3737 subtract();
3738 besselj();
3739 multiply();
3740 push(p1);
3741 push(p2);
3742 push_integer(2);
3743 push(p3);
3744 multiply();
3745 subtract();
3746 besselj();
3747 subtract();
3748 return;
3749 }
3750 if (isnegativeterm(p1)) {
3751 push(p1);
3752 negate();
3753 push(p2);
3754 power();
3755 push(p1);
3756 push(p2);
3757 negate();
3758 power();
3759 multiply();
3760 push_symbol(BESSELJ);
3761 push(p1);
3762 negate();
3763 push(p2);
3764 list(3);
3765 multiply();
3766 return;
3767 }
3768 if (isnegativeterm(p2)) {
3769 push_integer(-1);
3770 push(p2);
3771 power();
3772 push_symbol(BESSELJ);
3773 push(p1);
3774 push(p2);
3775 negate();
3776 list(3);
3777 multiply();
3778 return;
3779 }
3780 push(symbol(BESSELJ));
3781 push(p1);
3782 push(p2);
3783 return list(3);
3784 };
3785
3786
3787 /* bessely =====================================================================
3788
3789 Tags
3790 ----
3791 scripting, JS, internal, treenode, general concept
3792
3793 Parameters
3794 ----------
3795 x,n
3796
3797 General description
3798 -------------------
3799
3800 Bessel function of second kind.
3801 */
3802
3803 Eval_bessely = function() {
3804 push(cadr(p1));
3805 Eval();
3806 push(caddr(p1));
3807 Eval();
3808 return bessely();
3809 };
3810
3811 bessely = function() {
3812 save();
3813 yybessely();
3814 return restore();
3815 };
3816
3817 yybessely = function() {
3818 var d, n;
3819 d = 0.0;
3820 n = 0;
3821 p2 = pop();
3822 p1 = pop();
3823 push(p2);
3824 n = pop_integer();
3825 if (isdouble(p1) && !isNaN(n)) {
3826 d = yn(n, p1.d);
3827 push_double(d);
3828 return;
3829 }
3830 if (isnegativeterm(p2)) {
3831 push_integer(-1);
3832 push(p2);
3833 power();
3834 push_symbol(BESSELY);
3835 push(p1);
3836 push(p2);
3837 negate();
3838 list(3);
3839 multiply();
3840 return;
3841 }
3842 push_symbol(BESSELY);
3843 push(p1);
3844 push(p2);
3845 list(3);
3846 };
3847
3848 mint = function(a) {
3849 return bigInt(a);
3850 };
3851
3852 setSignTo = function(a, b) {
3853 if (a.isPositive()) {
3854 if (b < 0) {
3855 return a.multiply(bigInt(-1));
3856 }
3857 } else {
3858 if (b > 0) {
3859 return a.multiply(bigInt(-1));
3860 }
3861 }
3862 return a;
3863 };
3864
3865 makeSignSameAs = function(a, b) {
3866 if (a.isPositive()) {
3867 if (b.isNegative()) {
3868 return a.multiply(bigInt(-1));
3869 }
3870 } else {
3871 if (b.isPositive()) {
3872 return a.multiply(bigInt(-1));
3873 }
3874 }
3875 return a;
3876 };
3877
3878 makePositive = function(a) {
3879 if (a.isNegative()) {
3880 return a.multiply(bigInt(-1));
3881 }
3882 return a;
3883 };
3884
3885
3886 /*
3887 mtotal = 0
3888 MP_MIN_SIZE = 2
3889 MP_MAX_FREE = 1000
3890
3891 mnew = (n) ->
3892 if (n < MP_MIN_SIZE)
3893 n = MP_MIN_SIZE
3894 if (n == MP_MIN_SIZE && mfreecount)
3895 p = free_stack[--mfreecount]
3896 else
3897 p = [] #(unsigned int *) malloc((n + 3) * sizeof (int))
3898 #if (p == 0)
3899 * stop("malloc failure")
3900 p[0] = n
3901 mtotal += n
3902 return p[3]
3903 */
3904
3905
3906 /*
3907 free_stack = []
3908
3909 mfree = (array, p) ->
3910 p -= 3
3911 mtotal -= array[p]
3912 if (array[p] == MP_MIN_SIZE && mfreecount < MP_MAX_FREE)
3913 free_stack[mfreecount++] = p
3914 else
3915 free(p)
3916 */
3917
3918
3919 /*
3920 mint = (n) ->
3921 p = mnew(1)
3922 if (n < 0)
3923 * !!! this is FU
3924 * MSIGN(p) = -1
3925 fu = true
3926 else
3927 * !!! this is FU
3928 #MSIGN(p) = 1
3929 fu = true
3930 * !!! this is FU
3931 #MLENGTH(p) = 1
3932 p[0] = Math.abs(n)
3933 return p
3934 */
3935
3936
3937 /*
3938 mcopy = (a) ->
3939 #unsigned int *b
3940
3941 b = mnew(MLENGTH(a))
3942
3943 * !!! fu
3944 #MSIGN(b) = MSIGN(a)
3945 #MLENGTH(b) = MLENGTH(a)
3946
3947 for i in [0...MLENGTH(a)]
3948 b[i] = a[i]
3949
3950 return b
3951 */
3952
3953
3954 /*
3955 *
3956 * ge not invoked from anywhere - is you need ge
3957 * just use the bigNum's ge implementation
3958 * leaving it here just in case I decide to backport to C
3959 *
3960 * a >= b ?
3961 * and and b arrays of ints, len is an int
3962 ge = (a, b, len) ->
3963 i = 0
3964 for i in [0...len]
3965 if (a[i] == b[i])
3966 continue
3967 else
3968 break
3969 if (a[i] >= b[i])
3970 return 1
3971 else
3972 return 0
3973 */
3974
3975 add_numbers = function() {
3976 var a, b, theResult;
3977 a = 1.0;
3978 b = 1.0;
3979 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
3980 qadd();
3981 return;
3982 }
3983 save();
3984 p2 = pop();
3985 p1 = pop();
3986 if (isdouble(p1)) {
3987 a = p1.d;
3988 } else {
3989 a = convert_rational_to_double(p1);
3990 }
3991 if (isdouble(p2)) {
3992 b = p2.d;
3993 } else {
3994 b = convert_rational_to_double(p2);
3995 }
3996 theResult = a + b;
3997 push_double(theResult);
3998 return restore();
3999 };
4000
4001 subtract_numbers = function() {
4002 var a, b;
4003 a = 0.0;
4004 b = 0.0;
4005 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
4006 qsub();
4007 return;
4008 }
4009 save();
4010 p2 = pop();
4011 p1 = pop();
4012 if (isdouble(p1)) {
4013 a = p1.d;
4014 } else {
4015 a = convert_rational_to_double(p1);
4016 }
4017 if (isdouble(p2)) {
4018 b = p2.d;
4019 } else {
4020 b = convert_rational_to_double(p2);
4021 }
4022 push_double(a - b);
4023 return restore();
4024 };
4025
4026 multiply_numbers = function() {
4027 var a, b;
4028 a = 0.0;
4029 b = 0.0;
4030 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
4031 qmul();
4032 return;
4033 }
4034 save();
4035 p2 = pop();
4036 p1 = pop();
4037 if (isdouble(p1)) {
4038 a = p1.d;
4039 } else {
4040 a = convert_rational_to_double(p1);
4041 }
4042 if (isdouble(p2)) {
4043 b = p2.d;
4044 } else {
4045 b = convert_rational_to_double(p2);
4046 }
4047 push_double(a * b);
4048 return restore();
4049 };
4050
4051 divide_numbers = function() {
4052 var a, b;
4053 a = 0.0;
4054 b = 0.0;
4055 if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
4056 qdiv();
4057 return;
4058 }
4059 save();
4060 p2 = pop();
4061 p1 = pop();
4062 if (iszero(p2)) {
4063 stop("divide by zero");
4064 }
4065 if (isdouble(p1)) {
4066 a = p1.d;
4067 } else {
4068 a = convert_rational_to_double(p1);
4069 }
4070 if (isdouble(p2)) {
4071 b = p2.d;
4072 } else {
4073 b = convert_rational_to_double(p2);
4074 }
4075 push_double(a / b);
4076 return restore();
4077 };
4078
4079 invert_number = function() {
4080 var a, b;
4081 save();
4082 p1 = pop();
4083 if (iszero(p1)) {
4084 stop("divide by zero");
4085 }
4086 if (isdouble(p1)) {
4087 push_double(1 / p1.d);
4088 restore();
4089 return;
4090 }
4091 a = bigInt(p1.q.a);
4092 b = bigInt(p1.q.b);
4093 b = makeSignSameAs(b, a);
4094 a = setSignTo(a, 1);
4095 p1 = new U();
4096 p1.k = NUM;
4097 p1.q.a = b;
4098 p1.q.b = a;
4099 push(p1);
4100 return restore();
4101 };
4102
4103 compare_rationals = function(a, b) {
4104 var ab, ba, t;
4105 t = 0;
4106 ab = mmul(a.q.a, b.q.b);
4107 ba = mmul(a.q.b, b.q.a);
4108 t = mcmp(ab, ba);
4109 return t;
4110 };
4111
4112 compare_numbers = function(a, b) {
4113 var x, y;
4114 x = 0.0;
4115 y = 0.0;
4116 if (isrational(a) && isrational(b)) {
4117 return compare_rationals(a, b);
4118 }
4119 if (isdouble(a)) {
4120 x = a.d;
4121 } else {
4122 x = convert_rational_to_double(a);
4123 }
4124 if (isdouble(b)) {
4125 y = b.d;
4126 } else {
4127 y = convert_rational_to_double(b);
4128 }
4129 if (x < y) {
4130 return -1;
4131 }
4132 if (x > y) {
4133 return 1;
4134 }
4135 return 0;
4136 };
4137
4138 negate_number = function() {
4139 save();
4140 p1 = pop();
4141 if (iszero(p1)) {
4142 push(p1);
4143 restore();
4144 return;
4145 }
4146 switch (p1.k) {
4147 case NUM:
4148 p2 = new U();
4149 p2.k = NUM;
4150 p2.q.a = bigInt(p1.q.a.multiply(bigInt.minusOne));
4151 p2.q.b = bigInt(p1.q.b);
4152 push(p2);
4153 break;
4154 case DOUBLE:
4155 push_double(-p1.d);
4156 break;
4157 default:
4158 stop("bug caught in mp_negate_number");
4159 }
4160 return restore();
4161 };
4162
4163 bignum_truncate = function() {
4164 var a;
4165 save();
4166 p1 = pop();
4167 a = mdiv(p1.q.a, p1.q.b);
4168 p1 = new U();
4169 p1.k = NUM;
4170 p1.q.a = a;
4171 p1.q.b = bigInt(1);
4172 push(p1);
4173 return restore();
4174 };
4175
4176 mp_numerator = function() {
4177 save();
4178 p1 = pop();
4179 if (p1.k !== NUM) {
4180 push(one);
4181 restore();
4182 return;
4183 }
4184 p2 = new U();
4185 p2.k = NUM;
4186 p2.q.a = bigInt(p1.q.a);
4187 p2.q.b = bigInt(1);
4188 push(p2);
4189 return restore();
4190 };
4191
4192 mp_denominator = function() {
4193 save();
4194 p1 = pop();
4195 if (p1.k !== NUM) {
4196 push(one);
4197 restore();
4198 return;
4199 }
4200 p2 = new U();
4201 p2.k = NUM;
4202 p2.q.a = bigInt(p1.q.b);
4203 p2.q.b = bigInt(1);
4204 push(p2);
4205 return restore();
4206 };
4207
4208 bignum_power_number = function(expo) {
4209 var a, b, t;
4210 save();
4211 p1 = pop();
4212 a = mpow(p1.q.a, Math.abs(expo));
4213 b = mpow(p1.q.b, Math.abs(expo));
4214 if (expo < 0) {
4215 t = a;
4216 a = b;
4217 b = t;
4218 a = makeSignSameAs(a, b);
4219 b = setSignTo(b, 1);
4220 }
4221 p1 = new U();
4222 p1.k = NUM;
4223 p1.q.a = a;
4224 p1.q.b = b;
4225 push(p1);
4226 return restore();
4227 };
4228
4229 convert_bignum_to_double = function(p) {
4230 return p.toJSNumber();
4231 };
4232
4233 convert_rational_to_double = function(p) {
4234 var quotientAndRemainder, result;
4235 if (p.q == null) {
4236 debugger;
4237 }
4238 quotientAndRemainder = p.q.a.divmod(p.q.b);
4239 result = quotientAndRemainder.quotient + quotientAndRemainder.remainder / p.q.b.toJSNumber();
4240 return result;
4241 };
4242
4243 push_integer = function(n) {
4244 if (DEBUG) {
4245 console.log("pushing integer " + n);
4246 }
4247 save();
4248 p1 = new U();
4249 p1.k = NUM;
4250 p1.q.a = bigInt(n);
4251 p1.q.b = bigInt(1);
4252 push(p1);
4253 return restore();
4254 };
4255
4256 push_double = function(d) {
4257 save();
4258 p1 = new U();
4259 p1.k = DOUBLE;
4260 p1.d = d;
4261 push(p1);
4262 return restore();
4263 };
4264
4265 push_rational = function(a, b) {
4266
4267 /*
4268 save()
4269 p1 = new U()
4270 p1.k = NUM
4271 p1.q.a = bigInt(a)
4272 p1.q.b = bigInt(b)
4273 ## FIXME -- normalize ##
4274 push(p1)
4275 restore()
4276 */
4277 var p;
4278 p = new U();
4279 p.k = NUM;
4280 p.q.a = bigInt(a);
4281 p.q.b = bigInt(b);
4282 return push(p);
4283 };
4284
4285 pop_integer = function() {
4286 var n;
4287 n = 0/0;
4288 save();
4289 p1 = pop();
4290 switch (p1.k) {
4291 case NUM:
4292 if (isinteger(p1) && p1.q.a.isSmall) {
4293 n = p1.q.a.toJSNumber();
4294 }
4295 break;
4296 case DOUBLE:
4297 if (DEBUG) {
4298 console.log("popping integer but double is found");
4299 }
4300 if (Math.floor(p1.d) === p1.d) {
4301 if (DEBUG) {
4302 console.log("...altough it's an integer");
4303 }
4304 n = p1.d;
4305 }
4306 }
4307 restore();
4308 return n;
4309 };
4310
4311 print_double = function(p, flag) {
4312 var accumulator, buf;
4313 accumulator = "";
4314 buf = doubleToReasonableString(p.d);
4315 if (flag === 1 && buf === '-') {
4316 accumulator += print_str(buf + 1);
4317 } else {
4318 accumulator += print_str(buf);
4319 }
4320 return accumulator;
4321 };
4322
4323 bignum_scan_integer = function(s) {
4324 var a, scounter, sign_;
4325 save();
4326 scounter = 0;
4327 sign_ = s[scounter];
4328 if (sign_ === '+' || sign_ === '-') {
4329 scounter++;
4330 }
4331 a = bigInt(s.substring(scounter));
4332 p1 = new U();
4333 p1.k = NUM;
4334 p1.q.a = a;
4335 p1.q.b = bigInt(1);
4336 push(p1);
4337 if (sign_ === '-') {
4338 negate();
4339 }
4340 return restore();
4341 };
4342
4343 bignum_scan_float = function(s) {
4344 return push_double(parseFloat(s));
4345 };
4346
4347 print_number = function(p, signed) {
4348 var aAsString, accumulator, buf, denominatorString;
4349 accumulator = "";
4350 denominatorString = "";
4351 buf = "";
4352 switch (p.k) {
4353 case NUM:
4354 aAsString = p.q.a.toString();
4355 if (!signed) {
4356 if (aAsString[0] === "-") {
4357 aAsString = aAsString.substring(1);
4358 }
4359 }
4360 if (printMode === PRINTMODE_LATEX && isfraction(p)) {
4361 aAsString = "\\frac{" + aAsString + "}{";
4362 }
4363 accumulator += aAsString;
4364 if (isfraction(p)) {
4365 if (printMode !== PRINTMODE_LATEX) {
4366 accumulator += "/";
4367 }
4368 denominatorString = p.q.b.toString();
4369 if (printMode === PRINTMODE_LATEX) {
4370 denominatorString += "}";
4371 }
4372 accumulator += denominatorString;
4373 }
4374 break;
4375 case DOUBLE:
4376 aAsString = doubleToReasonableString(p.d);
4377 if (!signed) {
4378 if (aAsString[0] === "-") {
4379 aAsString = aAsString.substring(1);
4380 }
4381 }
4382 accumulator += aAsString;
4383 }
4384 return accumulator;
4385 };
4386
4387 gcd_numbers = function() {
4388 save();
4389 p2 = pop();
4390 p1 = pop();
4391 p3 = new U();
4392 p3.k = NUM;
4393 p3.q.a = mgcd(p1.q.a, p2.q.a);
4394 p3.q.b = mgcd(p1.q.b, p2.q.b);
4395 p3.q.a = setSignTo(p3.q.a, 1);
4396 push(p3);
4397 return restore();
4398 };
4399
4400 pop_double = function() {
4401 var d;
4402 d = 0.0;
4403 save();
4404 p1 = pop();
4405 switch (p1.k) {
4406 case NUM:
4407 d = convert_rational_to_double(p1);
4408 break;
4409 case DOUBLE:
4410 d = p1.d;
4411 break;
4412 default:
4413 d = 0.0;
4414 }
4415 restore();
4416 return d;
4417 };
4418
4419 bignum_float = function() {
4420 var d;
4421 d = 0.0;
4422 d = convert_rational_to_double(pop());
4423 return push_double(d);
4424 };
4425
4426 bignum_factorial = function(n) {
4427 save();
4428 p1 = new U();
4429 p1.k = NUM;
4430 p1.q.a = __factorial(n);
4431 p1.q.b = bigInt(1);
4432 push(p1);
4433 return restore();
4434 };
4435
4436 __factorial = function(n) {
4437 var a, b, i, o, ref, t;
4438 i = 0;
4439 if (n === 0 || n === 1) {
4440 a = bigInt(1);
4441 return a;
4442 }
4443 a = bigInt(2);
4444 b = bigInt(0);
4445 if (3 <= n) {
4446 for (i = o = 3, ref = n; 3 <= ref ? o <= ref : o >= ref; i = 3 <= ref ? ++o : --o) {
4447 b = bigInt(i);
4448 t = mmul(a, b);
4449 a = t;
4450 }
4451 }
4452 return a;
4453 };
4454
4455 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];
4456
4457 mp_set_bit = function(x, k) {
4458 console.log("not implemented yet");
4459 debugger;
4460 return x[k / 32] |= mask[k % 32];
4461 };
4462
4463 mp_clr_bit = function(x, k) {
4464 console.log("not implemented yet");
4465 debugger;
4466 return x[k / 32] &= ~mask[k % 32];
4467 };
4468
4469 mshiftright = function(a) {
4470 return a = a.shiftRight();
4471 };
4472
4473 Eval_binomial = function() {
4474 push(cadr(p1));
4475 Eval();
4476 push(caddr(p1));
4477 Eval();
4478 return binomial();
4479 };
4480
4481 binomial = function() {
4482 save();
4483 ybinomial();
4484 return restore();
4485 };
4486
4487 ybinomial = function() {
4488 p2 = pop();
4489 p1 = pop();
4490 if (BINOM_check_args() === 0) {
4491 push(zero);
4492 return;
4493 }
4494 push(p1);
4495 factorial();
4496 push(p2);
4497 factorial();
4498 divide();
4499 push(p1);
4500 push(p2);
4501 subtract();
4502 factorial();
4503 return divide();
4504 };
4505
4506 BINOM_check_args = function() {
4507 if (isnum(p1) && lessp(p1, zero)) {
4508 return 0;
4509 } else if (isnum(p2) && lessp(p2, zero)) {
4510 return 0;
4511 } else if (isnum(p1) && isnum(p2) && lessp(p1, p2)) {
4512 return 0;
4513 } else {
4514 return 1;
4515 }
4516 };
4517
4518
4519 /* ceiling =====================================================================
4520
4521 Tags
4522 ----
4523 scripting, JS, internal, treenode, general concept
4524
4525 Parameters
4526 ----------
4527 x
4528
4529 General description
4530 -------------------
4531
4532 Returns the smallest integer not less than x.
4533 */
4534
4535 Eval_ceiling = function() {
4536 push(cadr(p1));
4537 Eval();
4538 return ceiling();
4539 };
4540
4541 ceiling = function() {
4542 save();
4543 yyceiling();
4544 return restore();
4545 };
4546
4547 yyceiling = function() {
4548 var d, doNothing;
4549 d = 0.0;
4550 p1 = pop();
4551 if (!isnum(p1)) {
4552 push_symbol(CEILING);
4553 push(p1);
4554 list(2);
4555 return;
4556 }
4557 if (isdouble(p1)) {
4558 d = Math.ceil(p1.d);
4559 push_double(d);
4560 return;
4561 }
4562 if (isinteger(p1)) {
4563 push(p1);
4564 return;
4565 }
4566 p3 = new U();
4567 p3.k = NUM;
4568 p3.q.a = mdiv(p1.q.a, p1.q.b);
4569 p3.q.b = mint(1);
4570 push(p3);
4571 if (isnegativenumber(p1)) {
4572 return doNothing = 1;
4573 } else {
4574 push_integer(1);
4575 return add();
4576 }
4577 };
4578
4579
4580 /* choose =====================================================================
4581
4582 Tags
4583 ----
4584 scripting, JS, internal, treenode, general concept
4585
4586 Parameters
4587 ----------
4588 n,k
4589
4590 General description
4591 -------------------
4592
4593 Returns the number of combinations of n items taken k at a time.
4594
4595 For example, the number of five card hands is choose(52,5)
4596
4597 ```
4598 n!
4599 choose(n,k) = -------------
4600 k! (n - k)!
4601 ```
4602 */
4603
4604 Eval_choose = function() {
4605 push(cadr(p1));
4606 Eval();
4607 push(caddr(p1));
4608 Eval();
4609 return choose();
4610 };
4611
4612 choose = function() {
4613 save();
4614 p2 = pop();
4615 p1 = pop();
4616 if (choose_check_args() === 0) {
4617 push_integer(0);
4618 restore();
4619 return;
4620 }
4621 push(p1);
4622 factorial();
4623 push(p2);
4624 factorial();
4625 divide();
4626 push(p1);
4627 push(p2);
4628 subtract();
4629 factorial();
4630 divide();
4631 return restore();
4632 };
4633
4634 choose_check_args = function() {
4635 if (isnum(p1) && lessp(p1, zero)) {
4636 return 0;
4637 } else if (isnum(p2) && lessp(p2, zero)) {
4638 return 0;
4639 } else if (isnum(p1) && isnum(p2) && lessp(p1, p2)) {
4640 return 0;
4641 } else {
4642 return 1;
4643 }
4644 };
4645
4646
4647 /* circexp =====================================================================
4648
4649 Tags
4650 ----
4651 scripting, JS, internal, treenode, general concept
4652
4653 Parameters
4654 ----------
4655 x
4656
4657 General description
4658 -------------------
4659
4660 Returns expression x with circular and hyperbolic functions converted to exponential forms. Sometimes this will simplify an expression.
4661 */
4662
4663 Eval_circexp = function() {
4664 push(cadr(p1));
4665 Eval();
4666 circexp();
4667 return Eval();
4668 };
4669
4670 circexp = function() {
4671 var h, i, o, ref;
4672 i = 0;
4673 h = 0;
4674 save();
4675 p1 = pop();
4676 if (car(p1) === symbol(COS)) {
4677 push(cadr(p1));
4678 expcos();
4679 restore();
4680 return;
4681 }
4682 if (car(p1) === symbol(SIN)) {
4683 push(cadr(p1));
4684 expsin();
4685 restore();
4686 return;
4687 }
4688 if (car(p1) === symbol(TAN)) {
4689 p1 = cadr(p1);
4690 push(imaginaryunit);
4691 push(p1);
4692 multiply();
4693 exponential();
4694 p2 = pop();
4695 push(imaginaryunit);
4696 push(p1);
4697 multiply();
4698 negate();
4699 exponential();
4700 p3 = pop();
4701 push(p3);
4702 push(p2);
4703 subtract();
4704 push(imaginaryunit);
4705 multiply();
4706 push(p2);
4707 push(p3);
4708 add();
4709 divide();
4710 restore();
4711 return;
4712 }
4713 if (car(p1) === symbol(COSH)) {
4714 p1 = cadr(p1);
4715 push(p1);
4716 exponential();
4717 push(p1);
4718 negate();
4719 exponential();
4720 add();
4721 push_rational(1, 2);
4722 multiply();
4723 restore();
4724 return;
4725 }
4726 if (car(p1) === symbol(SINH)) {
4727 p1 = cadr(p1);
4728 push(p1);
4729 exponential();
4730 push(p1);
4731 negate();
4732 exponential();
4733 subtract();
4734 push_rational(1, 2);
4735 multiply();
4736 restore();
4737 return;
4738 }
4739 if (car(p1) === symbol(TANH)) {
4740 p1 = cadr(p1);
4741 push(p1);
4742 push_integer(2);
4743 multiply();
4744 exponential();
4745 p1 = pop();
4746 push(p1);
4747 push_integer(1);
4748 subtract();
4749 push(p1);
4750 push_integer(1);
4751 add();
4752 divide();
4753 restore();
4754 return;
4755 }
4756 if (iscons(p1)) {
4757 h = tos;
4758 while (iscons(p1)) {
4759 push(car(p1));
4760 circexp();
4761 p1 = cdr(p1);
4762 }
4763 list(tos - h);
4764 restore();
4765 return;
4766 }
4767 if (p1.k === TENSOR) {
4768 push(p1);
4769 copy_tensor();
4770 p1 = pop();
4771 for (i = o = 0, ref = p1.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
4772 push(p1.tensor.elem[i]);
4773 circexp();
4774 p1.tensor.elem[i] = pop();
4775 }
4776 push(p1);
4777 restore();
4778 return;
4779 }
4780 push(p1);
4781 return restore();
4782 };
4783
4784
4785 /* clearall =====================================================================
4786
4787 Tags
4788 ----
4789 scripting, JS, internal, treenode, general concept
4790
4791
4792 General description
4793 -------------------
4794
4795 Completely wipes all variables from the environment.
4796 */
4797
4798 Eval_clearall = function() {
4799 do_clearall();
4800 return push(symbol(NIL));
4801 };
4802
4803 do_clearall = function() {
4804 if (test_flag === 0) {
4805 clear_term();
4806 }
4807 do_clearPatterns();
4808 clear_symbols();
4809 defn();
4810 return codeGen = false;
4811 };
4812
4813 clearall = function() {
4814 return run("clearall");
4815 };
4816
4817 clearRenamedVariablesToAvoidBindingToExternalScope = function() {
4818 var i, o, ref, results;
4819 results = [];
4820 for (i = o = 0, ref = symtab.length; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
4821 if (symtab[i].printname.indexOf("AVOID_BINDING_TO_EXTERNAL_SCOPE_VALUE") !== -1) {
4822 symtab[i].k = SYM;
4823 symtab[i].printname = "";
4824 binding[i] = symtab[i];
4825 results.push(isSymbolReclaimable[i] = true);
4826 } else {
4827 results.push(void 0);
4828 }
4829 }
4830 return results;
4831 };
4832
4833
4834 /* clear =====================================================================
4835
4836 Tags
4837 ----
4838 scripting, JS, internal, treenode, general concept
4839
4840 Parameters
4841 ----------
4842 x
4843
4844 General description
4845 -------------------
4846
4847 Completely wipes a variable from the environment (while doing x = quote(x) just unassigns it).
4848 */
4849
4850 Eval_clear = function() {
4851 var indexFound, variableToBeCleared;
4852 p2 = cdr(p1);
4853 while (iscons(p2)) {
4854 variableToBeCleared = car(p2);
4855 if (variableToBeCleared.k !== SYM) {
4856 stop("symbol error");
4857 }
4858 indexFound = symtab.indexOf(variableToBeCleared);
4859 symtab[indexFound].k = SYM;
4860 symtab[indexFound].printname = "";
4861 binding[indexFound] = symtab[indexFound];
4862 isSymbolReclaimable[indexFound] = true;
4863 p2 = cdr(p2);
4864 }
4865 return push(symbol(NIL));
4866 };
4867
4868
4869 /*
4870 Convert complex z to clock form
4871
4872 Input: push z
4873
4874 Output: Result on stack
4875
4876 clock(z) = abs(z) * (-1) ^ (arg(z) / pi)
4877
4878 For example, clock(exp(i pi/3)) gives the result (-1)^(1/3)
4879 */
4880
4881 DEBUG_CLOCKFORM = false;
4882
4883 Eval_clock = function() {
4884 push(cadr(p1));
4885 Eval();
4886 return clockform();
4887 };
4888
4889 clockform = function() {
4890 save();
4891 p1 = pop();
4892 push(p1);
4893 abs();
4894 if (DEBUG_CLOCKFORM) {
4895 console.log("clockform: abs of " + p1 + " : " + stack[tos - 1]);
4896 }
4897 push_symbol(POWER);
4898 push_integer(-1);
4899 push(p1);
4900 arg();
4901 if (DEBUG_CLOCKFORM) {
4902 console.log("clockform: arg of " + p1 + " : " + stack[tos - 1]);
4903 }
4904 if (evaluatingAsFloats) {
4905 push_double(Math.PI);
4906 } else {
4907 push(symbol(PI));
4908 }
4909 divide();
4910 if (DEBUG_CLOCKFORM) {
4911 console.log("clockform: divide : " + stack[tos - 1]);
4912 }
4913 list(3);
4914 if (DEBUG_CLOCKFORM) {
4915 console.log("clockform: power : " + stack[tos - 1]);
4916 }
4917 multiply();
4918 if (DEBUG_CLOCKFORM) {
4919 console.log("clockform: multiply : " + stack[tos - 1]);
4920 }
4921
4922 /*
4923 p1 = pop()
4924 push(p1)
4925 abs()
4926 push(symbol(E))
4927 push(p1)
4928 arg()
4929 push(imaginaryunit)
4930 multiply()
4931 power()
4932 multiply()
4933 */
4934 return restore();
4935 };
4936
4937
4938 /* coeff =====================================================================
4939
4940 Tags
4941 ----
4942 scripting, JS, internal, treenode, general concept
4943
4944 Parameters
4945 ----------
4946 p,x,n
4947
4948 General description
4949 -------------------
4950 Returns the coefficient of x^n in polynomial p. The x argument can be omitted for polynomials in x.
4951 */
4952
4953 Eval_coeff = function() {
4954 push(cadr(p1));
4955 Eval();
4956 push(caddr(p1));
4957 Eval();
4958 push(cadddr(p1));
4959 Eval();
4960 p3 = pop();
4961 p2 = pop();
4962 p1 = pop();
4963 if (p3 === symbol(NIL)) {
4964 p3 = p2;
4965 p2 = symbol(SYMBOL_X);
4966 }
4967 push(p1);
4968 push(p2);
4969 push(p3);
4970 power();
4971 divide();
4972 push(p2);
4973 return filter();
4974 };
4975
4976 coeff = function() {
4977 var h, n, prev_expanding;
4978 save();
4979 p2 = pop();
4980 p1 = pop();
4981 h = tos;
4982 while (1) {
4983 push(p1);
4984 push(p2);
4985 push(zero);
4986 subst();
4987 Eval();
4988 p3 = pop();
4989 push(p3);
4990 push(p1);
4991 push(p3);
4992 subtract();
4993 p1 = pop();
4994 if (equal(p1, zero)) {
4995 n = tos - h;
4996 restore();
4997 return n;
4998 }
4999 push(p1);
5000 push(p2);
5001 prev_expanding = expanding;
5002 expanding = 1;
5003 divide();
5004 expanding = prev_expanding;
5005 p1 = pop();
5006 }
5007 };
5008
5009
5010 /* cofactor =====================================================================
5011
5012 Tags
5013 ----
5014 scripting, JS, internal, treenode, general concept
5015
5016 Parameters
5017 ----------
5018 m,i,j
5019
5020 General description
5021 -------------------
5022 Cofactor of a matrix component.
5023 Let c be the cofactor matrix of matrix m, i.e. tranpose(c) = adj(m).
5024 This function returns c[i,j].
5025 */
5026
5027 Eval_cofactor = function() {
5028 var doNothing, i, j, n;
5029 i = 0;
5030 j = 0;
5031 n = 0;
5032 push(cadr(p1));
5033 Eval();
5034 p2 = pop();
5035 if (istensor(p2) && p2.tensor.ndim === 2 && p2.tensor.dim[0] === p2.tensor.dim[1]) {
5036 doNothing = 1;
5037 } else {
5038 stop("cofactor: 1st arg: square matrix expected");
5039 }
5040 n = p2.tensor.dim[0];
5041 push(caddr(p1));
5042 Eval();
5043 i = pop_integer();
5044 if (i < 1 || i > n) {
5045 stop("cofactor: 2nd arg: row index expected");
5046 }
5047 push(cadddr(p1));
5048 Eval();
5049 j = pop_integer();
5050 if (j < 1 || j > n) {
5051 stop("cofactor: 3rd arg: column index expected");
5052 }
5053 return cofactor(p2, n, i - 1, j - 1);
5054 };
5055
5056 cofactor = function(p, n, row, col) {
5057 var i, i1, j, o, ref, ref1;
5058 i = 0;
5059 j = 0;
5060 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
5061 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
5062 if (i !== row && j !== col) {
5063 push(p.tensor.elem[n * i + j]);
5064 }
5065 }
5066 }
5067 determinant(n - 1);
5068 if ((row + col) % 2) {
5069 return negate();
5070 }
5071 };
5072
5073 Eval_condense = function() {
5074 push(cadr(p1));
5075 Eval();
5076 return Condense();
5077 };
5078
5079 Condense = function() {
5080 var prev_expanding;
5081 prev_expanding = expanding;
5082 expanding = 0;
5083 save();
5084 yycondense();
5085 restore();
5086 return expanding = prev_expanding;
5087 };
5088
5089 yycondense = function() {
5090 p1 = pop();
5091 if (car(p1) !== symbol(ADD)) {
5092 push(p1);
5093 return;
5094 }
5095 p3 = cdr(p1);
5096 push(car(p3));
5097 p3 = cdr(p3);
5098 while (iscons(p3)) {
5099 push(car(p3));
5100 gcd();
5101 p3 = cdr(p3);
5102 }
5103 inverse();
5104 p2 = pop();
5105 push(zero);
5106 p3 = cdr(p1);
5107 while (iscons(p3)) {
5108 push(p2);
5109 push(car(p3));
5110 multiply();
5111 add();
5112 p3 = cdr(p3);
5113 }
5114 yyexpand();
5115 push(p2);
5116 return divide();
5117 };
5118
5119
5120 /* conj =====================================================================
5121
5122 Tags
5123 ----
5124 scripting, JS, internal, treenode, general concept
5125
5126 Parameters
5127 ----------
5128 z
5129
5130 General description
5131 -------------------
5132 Returns the complex conjugate of z.
5133 */
5134
5135 Eval_conj = function() {
5136 push(cadr(p1));
5137 Eval();
5138 p1 = pop();
5139 push(p1);
5140 if (!Find(p1, imaginaryunit)) {
5141 polar();
5142 conjugate();
5143 return clockform();
5144 } else {
5145 return conjugate();
5146 }
5147 };
5148
5149 conjugate = function() {
5150 push(imaginaryunit);
5151 push(imaginaryunit);
5152 negate();
5153 subst();
5154 return Eval();
5155 };
5156
5157 consCount = 0;
5158
5159 cons = function() {
5160 var p;
5161 consCount++;
5162 if (DEBUG) {
5163 console.log("cons tos: " + tos + " # " + consCount);
5164 }
5165 p = new U();
5166 p.k = CONS;
5167 p.cons.cdr = pop();
5168 if (p === p.cons.cdr) {
5169 debugger;
5170 console.log("something wrong p == its cdr");
5171 }
5172 p.cons.car = pop();
5173
5174 /*
5175 console.log "cons new cdr.k = " + p.cons.cdr.k + "\nor more in detail:"
5176 console.log print_list p.cons.cdr
5177 console.log "cons new car.k = " + p.cons.car.k + "\nor more in detail:"
5178 console.log print_list p.cons.car
5179 */
5180 return push(p);
5181 };
5182
5183
5184 /* contract =====================================================================
5185
5186 Tags
5187 ----
5188 scripting, JS, internal, treenode, general concept
5189
5190 Parameters
5191 ----------
5192 a,i,j
5193
5194 General description
5195 -------------------
5196 Contract across tensor indices i.e. returns "a" summed over indices i and j.
5197 If i and j are omitted then 1 and 2 are used.
5198 contract(m) is equivalent to the trace of matrix m.
5199 */
5200
5201 Eval_contract = function() {
5202 push(cadr(p1));
5203 Eval();
5204 if (cddr(p1) === symbol(NIL)) {
5205 push_integer(1);
5206 push_integer(2);
5207 } else {
5208 push(caddr(p1));
5209 Eval();
5210 push(cadddr(p1));
5211 Eval();
5212 }
5213 return contract();
5214 };
5215
5216 contract = function() {
5217 save();
5218 yycontract();
5219 return restore();
5220 };
5221
5222 yycontract = function() {
5223 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;
5224 h = 0;
5225 i = 0;
5226 j = 0;
5227 k = 0;
5228 l = 0;
5229 m = 0;
5230 n = 0;
5231 ndim = 0;
5232 nelem = 0;
5233 ai = [];
5234 an = [];
5235 p3 = pop();
5236 p2 = pop();
5237 p1 = pop();
5238 if (!istensor(p1)) {
5239 if (!iszero(p1)) {
5240 stop("contract: tensor expected, 1st arg is not a tensor");
5241 }
5242 push(zero);
5243 return;
5244 }
5245 push(p2);
5246 l = pop_integer();
5247 push(p3);
5248 m = pop_integer();
5249 ndim = p1.tensor.ndim;
5250 if (l < 1 || l > ndim || m < 1 || m > ndim || l === m || p1.tensor.dim[l - 1] !== p1.tensor.dim[m - 1]) {
5251 stop("contract: index out of range");
5252 }
5253 l--;
5254 m--;
5255 n = p1.tensor.dim[l];
5256 nelem = 1;
5257 for (i = o = 0, ref = ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
5258 if (i !== l && i !== m) {
5259 nelem *= p1.tensor.dim[i];
5260 }
5261 }
5262 p2 = alloc_tensor(nelem);
5263 p2.tensor.ndim = ndim - 2;
5264 j = 0;
5265 for (i = i1 = 0, ref1 = ndim; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
5266 if (i !== l && i !== m) {
5267 p2.tensor.dim[j++] = p1.tensor.dim[i];
5268 }
5269 }
5270 a = p1.tensor.elem;
5271 b = p2.tensor.elem;
5272 for (i = j1 = 0, ref2 = ndim; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
5273 ai[i] = 0;
5274 an[i] = p1.tensor.dim[i];
5275 }
5276 for (i = l1 = 0, ref3 = nelem; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
5277 push(zero);
5278 for (j = m1 = 0, ref4 = n; 0 <= ref4 ? m1 < ref4 : m1 > ref4; j = 0 <= ref4 ? ++m1 : --m1) {
5279 ai[l] = j;
5280 ai[m] = j;
5281 h = 0;
5282 for (k = n1 = 0, ref5 = ndim; 0 <= ref5 ? n1 < ref5 : n1 > ref5; k = 0 <= ref5 ? ++n1 : --n1) {
5283 h = (h * an[k]) + ai[k];
5284 }
5285 push(a[h]);
5286 add();
5287 }
5288 b[i] = pop();
5289 for (j = o1 = ref6 = ndim - 1; ref6 <= 0 ? o1 <= 0 : o1 >= 0; j = ref6 <= 0 ? ++o1 : --o1) {
5290 if (j === l || j === m) {
5291 continue;
5292 }
5293 if (++ai[j] < an[j]) {
5294 break;
5295 }
5296 ai[j] = 0;
5297 }
5298 }
5299 if (nelem === 1) {
5300 return push(b[0]);
5301 } else {
5302 return push(p2);
5303 }
5304 };
5305
5306
5307 /* cos =====================================================================
5308
5309 Tags
5310 ----
5311 scripting, JS, internal, treenode, general concept
5312
5313 Parameters
5314 ----------
5315 x
5316
5317 General description
5318 -------------------
5319 Returns the cosine of x.
5320 */
5321
5322 Eval_cos = function() {
5323 push(cadr(p1));
5324 Eval();
5325 return cosine();
5326 };
5327
5328 cosine = function() {
5329 save();
5330 p1 = pop();
5331 if (car(p1) === symbol(ADD)) {
5332 cosine_of_angle_sum();
5333 } else {
5334 cosine_of_angle();
5335 }
5336 return restore();
5337 };
5338
5339 cosine_of_angle_sum = function() {
5340 p2 = cdr(p1);
5341 while (iscons(p2)) {
5342 p4 = car(p2);
5343 if (isnpi(p4)) {
5344 push(p1);
5345 push(p4);
5346 subtract();
5347 p3 = pop();
5348 push(p3);
5349 cosine();
5350 push(p4);
5351 cosine();
5352 multiply();
5353 push(p3);
5354 sine();
5355 push(p4);
5356 sine();
5357 multiply();
5358 subtract();
5359 return;
5360 }
5361 p2 = cdr(p2);
5362 }
5363 return cosine_of_angle();
5364 };
5365
5366 cosine_of_angle = function() {
5367 var d, n;
5368 if (car(p1) === symbol(ARCCOS)) {
5369 push(cadr(p1));
5370 return;
5371 }
5372 if (isdouble(p1)) {
5373 d = Math.cos(p1.d);
5374 if (Math.abs(d) < 1e-10) {
5375 d = 0.0;
5376 }
5377 push_double(d);
5378 return;
5379 }
5380 if (isnegative(p1)) {
5381 push(p1);
5382 negate();
5383 p1 = pop();
5384 }
5385 if (car(p1) === symbol(ARCTAN)) {
5386 push_integer(1);
5387 push(cadr(p1));
5388 push_integer(2);
5389 power();
5390 add();
5391 push_rational(-1, 2);
5392 power();
5393 return;
5394 }
5395 push(p1);
5396 push_integer(180);
5397 multiply();
5398 if (evaluatingAsFloats) {
5399 push_double(Math.PI);
5400 } else {
5401 push_symbol(PI);
5402 }
5403 divide();
5404 n = pop_integer();
5405 if (n < 0 || isNaN(n)) {
5406 push(symbol(COS));
5407 push(p1);
5408 list(2);
5409 return;
5410 }
5411 switch (n % 360) {
5412 case 90:
5413 case 270:
5414 return push_integer(0);
5415 case 60:
5416 case 300:
5417 return push_rational(1, 2);
5418 case 120:
5419 case 240:
5420 return push_rational(-1, 2);
5421 case 45:
5422 case 315:
5423 push_rational(1, 2);
5424 push_integer(2);
5425 push_rational(1, 2);
5426 power();
5427 return multiply();
5428 case 135:
5429 case 225:
5430 push_rational(-1, 2);
5431 push_integer(2);
5432 push_rational(1, 2);
5433 power();
5434 return multiply();
5435 case 30:
5436 case 330:
5437 push_rational(1, 2);
5438 push_integer(3);
5439 push_rational(1, 2);
5440 power();
5441 return multiply();
5442 case 150:
5443 case 210:
5444 push_rational(-1, 2);
5445 push_integer(3);
5446 push_rational(1, 2);
5447 power();
5448 return multiply();
5449 case 0:
5450 return push_integer(1);
5451 case 180:
5452 return push_integer(-1);
5453 default:
5454 push(symbol(COS));
5455 push(p1);
5456 return list(2);
5457 }
5458 };
5459
5460
5461 /* cosh =====================================================================
5462
5463 Tags
5464 ----
5465 scripting, JS, internal, treenode, general concept
5466
5467 Parameters
5468 ----------
5469 x
5470
5471 General description
5472 -------------------
5473 Returns the hyperbolic cosine of x
5474
5475 ```
5476 exp(x) + exp(-x)
5477 cosh(x) = ----------------
5478 2
5479 ```
5480 */
5481
5482 Eval_cosh = function() {
5483 push(cadr(p1));
5484 Eval();
5485 return ycosh();
5486 };
5487
5488 ycosh = function() {
5489 save();
5490 yycosh();
5491 return restore();
5492 };
5493
5494 yycosh = function() {
5495 var d;
5496 d = 0.0;
5497 p1 = pop();
5498 if (car(p1) === symbol(ARCCOSH)) {
5499 push(cadr(p1));
5500 return;
5501 }
5502 if (isdouble(p1)) {
5503 d = Math.cosh(p1.d);
5504 if (Math.abs(d) < 1e-10) {
5505 d = 0.0;
5506 }
5507 push_double(d);
5508 return;
5509 }
5510 if (iszero(p1)) {
5511 push(one);
5512 return;
5513 }
5514 push_symbol(COSH);
5515 push(p1);
5516 return list(2);
5517 };
5518
5519 Eval_decomp = function() {
5520 var h;
5521 save();
5522 console.log("Eval_decomp is being called!!!!!!!!!!!!!!!!!!!!");
5523 h = tos;
5524 push(symbol(NIL));
5525 push(cadr(p1));
5526 Eval();
5527 push(caddr(p1));
5528 Eval();
5529 p1 = pop();
5530 if (p1 === symbol(NIL)) {
5531 guess();
5532 } else {
5533 push(p1);
5534 }
5535 decomp(false);
5536 list(tos - h);
5537 return restore();
5538 };
5539
5540 pushTryNotToDuplicate = function(toBePushed) {
5541 if (tos > 0) {
5542 if (DEBUG) {
5543 console.log("comparing " + toBePushed + " to: " + stack[tos - 1]);
5544 }
5545 if (equal(toBePushed, stack[tos - 1])) {
5546 if (DEBUG) {
5547 console.log("skipping " + toBePushed + " because it's already on stack ");
5548 }
5549 return;
5550 }
5551 }
5552 return push(toBePushed);
5553 };
5554
5555 decomp = function(generalTransform) {
5556 save();
5557 p2 = pop();
5558 p1 = pop();
5559 if (DEBUG) {
5560 console.log("DECOMPOSING " + p1);
5561 }
5562 if (generalTransform) {
5563 if (!iscons(p1)) {
5564 if (DEBUG) {
5565 console.log(" ground thing: " + p1);
5566 }
5567 pushTryNotToDuplicate(p1);
5568 restore();
5569 return;
5570 }
5571 } else {
5572 if (Find(p1, p2) === 0) {
5573 if (DEBUG) {
5574 console.log(" entire expression is constant");
5575 }
5576 pushTryNotToDuplicate(p1);
5577 restore();
5578 return;
5579 }
5580 }
5581 if (isadd(p1)) {
5582 decomp_sum(generalTransform);
5583 restore();
5584 return;
5585 }
5586 if (ismultiply(p1)) {
5587 decomp_product(generalTransform);
5588 restore();
5589 return;
5590 }
5591 if (DEBUG) {
5592 console.log(" naive decomp");
5593 }
5594 p3 = cdr(p1);
5595 if (DEBUG) {
5596 console.log("startig p3: " + p3);
5597 }
5598 while (iscons(p3)) {
5599 if (generalTransform) {
5600 push(car(p3));
5601 }
5602 if (DEBUG) {
5603 console.log("recursive decomposition");
5604 }
5605 push(car(p3));
5606 if (DEBUG) {
5607 console.log("car(p3): " + car(p3));
5608 }
5609 push(p2);
5610 if (DEBUG) {
5611 console.log("p2: " + p2);
5612 }
5613 decomp(generalTransform);
5614 p3 = cdr(p3);
5615 }
5616 return restore();
5617 };
5618
5619 decomp_sum = function(generalTransform) {
5620 var h;
5621 if (DEBUG) {
5622 console.log(" decomposing the sum ");
5623 }
5624 h = 0;
5625 p3 = cdr(p1);
5626 while (iscons(p3)) {
5627 if (Find(car(p3), p2) || generalTransform) {
5628 push(car(p3));
5629 push(p2);
5630 decomp(generalTransform);
5631 }
5632 p3 = cdr(p3);
5633 }
5634 h = tos;
5635 p3 = cdr(p1);
5636 while (iscons(p3)) {
5637 if (Find(car(p3), p2) === 0) {
5638 pushTryNotToDuplicate(car(p3));
5639 }
5640 p3 = cdr(p3);
5641 }
5642 if (tos - h) {
5643 add_all(tos - h);
5644 p3 = pop();
5645 pushTryNotToDuplicate(p3);
5646 push(p3);
5647 return negate();
5648 }
5649 };
5650
5651 decomp_product = function(generalTransform) {
5652 var h;
5653 if (DEBUG) {
5654 console.log(" decomposing the product ");
5655 }
5656 h = 0;
5657 p3 = cdr(p1);
5658 while (iscons(p3)) {
5659 if (Find(car(p3), p2) || generalTransform) {
5660 push(car(p3));
5661 push(p2);
5662 decomp(generalTransform);
5663 }
5664 p3 = cdr(p3);
5665 }
5666 h = tos;
5667 p3 = cdr(p1);
5668 while (iscons(p3)) {
5669 if (Find(car(p3), p2) === 0) {
5670 pushTryNotToDuplicate(car(p3));
5671 }
5672 p3 = cdr(p3);
5673 }
5674 if (tos - h) {
5675 return multiply_all(tos - h);
5676 }
5677 };
5678
5679 define_user_function = function() {
5680 p3 = caadr(p1);
5681 p4 = cdadr(p1);
5682 p5 = caddr(p1);
5683 if (!issymbol(p3)) {
5684 stop("function name?");
5685 }
5686 if (car(p5) === symbol(EVAL)) {
5687 push(cadr(p5));
5688 Eval();
5689 p5 = pop();
5690 }
5691 push_symbol(FUNCTION);
5692 push(p5);
5693 push(p4);
5694 list(3);
5695 p5 = pop();
5696 set_binding(p3, p5);
5697 return push_symbol(NIL);
5698 };
5699
5700 Eval_function_reference = function() {
5701 return push(p1);
5702 };
5703
5704
5705 /* defint =====================================================================
5706
5707 Tags
5708 ----
5709 scripting, JS, internal, treenode, general concept
5710
5711 Parameters
5712 ----------
5713 f,x,a,b[,y,c,d...]
5714
5715 General description
5716 -------------------
5717 Returns the definite integral of f with respect to x evaluated from "a" to b.
5718 The argument list can be extended for multiple integrals (or "iterated
5719 integrals"), for example a double integral (which can represent for
5720 example a volume under a surface), or a triple integral, etc. For
5721 example, defint(f,x,a,b,y,c,d).
5722 */
5723
5724 Eval_defint = function() {
5725 push(cadr(p1));
5726 Eval();
5727 p2 = pop();
5728 p1 = cddr(p1);
5729 while (iscons(p1)) {
5730 push(car(p1));
5731 p1 = cdr(p1);
5732 Eval();
5733 p3 = pop();
5734 push(car(p1));
5735 p1 = cdr(p1);
5736 Eval();
5737 p4 = pop();
5738 push(car(p1));
5739 p1 = cdr(p1);
5740 Eval();
5741 p5 = pop();
5742 push(p2);
5743 push(p3);
5744 integral();
5745 p2 = pop();
5746 push(p2);
5747 push(p3);
5748 push(p5);
5749 subst();
5750 Eval();
5751 push(p2);
5752 push(p3);
5753 push(p4);
5754 subst();
5755 Eval();
5756 subtract();
5757 p2 = pop();
5758 }
5759 return push(p2);
5760 };
5761
5762
5763 /* deg =====================================================================
5764
5765 Tags
5766 ----
5767 scripting, JS, internal, treenode, general concept
5768
5769 Parameters
5770 ----------
5771 p,x
5772
5773 General description
5774 -------------------
5775 Returns the degree of polynomial p(x).
5776 */
5777
5778 Eval_degree = function() {
5779 push(cadr(p1));
5780 Eval();
5781 push(caddr(p1));
5782 Eval();
5783 p1 = pop();
5784 if (p1 === symbol(NIL)) {
5785 guess();
5786 } else {
5787 push(p1);
5788 }
5789 return degree();
5790 };
5791
5792 degree = function() {
5793 save();
5794 p2 = pop();
5795 p1 = pop();
5796 p3 = zero;
5797 yydegree(p1);
5798 push(p3);
5799 return restore();
5800 };
5801
5802 yydegree = function(p) {
5803 var results;
5804 if (equal(p, p2)) {
5805 if (iszero(p3)) {
5806 return p3 = one;
5807 }
5808 } else if (car(p) === symbol(POWER)) {
5809 if (equal(cadr(p), p2) && isnum(caddr(p)) && lessp(p3, caddr(p))) {
5810 return p3 = caddr(p);
5811 }
5812 } else if (iscons(p)) {
5813 p = cdr(p);
5814 results = [];
5815 while (iscons(p)) {
5816 yydegree(car(p));
5817 results.push(p = cdr(p));
5818 }
5819 return results;
5820 }
5821 };
5822
5823
5824 /* denominator =====================================================================
5825
5826 Tags
5827 ----
5828 scripting, JS, internal, treenode, general concept
5829
5830 Parameters
5831 ----------
5832 x
5833
5834 General description
5835 -------------------
5836 Returns the denominator of expression x.
5837 */
5838
5839 Eval_denominator = function() {
5840 push(cadr(p1));
5841 Eval();
5842 return denominator();
5843 };
5844
5845 denominator = function() {
5846 var h;
5847 h = 0;
5848 save();
5849 p1 = pop();
5850 if (car(p1) === symbol(ADD)) {
5851 push(p1);
5852 rationalize();
5853 p1 = pop();
5854 }
5855 if (car(p1) === symbol(MULTIPLY)) {
5856 h = tos;
5857 p1 = cdr(p1);
5858 while (iscons(p1)) {
5859 push(car(p1));
5860 denominator();
5861 p1 = cdr(p1);
5862 }
5863 multiply_all(tos - h);
5864 } else if (isrational(p1)) {
5865 push(p1);
5866 mp_denominator();
5867 } else if (car(p1) === symbol(POWER) && isnegativeterm(caddr(p1))) {
5868 push(p1);
5869 reciprocate();
5870 } else {
5871 push(one);
5872 }
5873 return restore();
5874 };
5875
5876 Eval_derivative = function() {
5877 var doNothing, i, i1, n, o, ref, ref1;
5878 i = 0;
5879 p1 = cdr(p1);
5880 push(car(p1));
5881 Eval();
5882 p1 = cdr(p1);
5883 push(car(p1));
5884 Eval();
5885 p2 = pop();
5886 if (p2 === symbol(NIL)) {
5887 guess();
5888 push(symbol(NIL));
5889 } else if (isnum(p2)) {
5890 guess();
5891 push(p2);
5892 } else {
5893 push(p2);
5894 p1 = cdr(p1);
5895 push(car(p1));
5896 Eval();
5897 }
5898 p5 = pop();
5899 p4 = pop();
5900 p3 = pop();
5901 while (1) {
5902 if (isnum(p5)) {
5903 push(p5);
5904 n = pop_integer();
5905 if (isNaN(n)) {
5906 stop("nth derivative: check n");
5907 }
5908 } else {
5909 n = 1;
5910 }
5911 push(p3);
5912 if (n >= 0) {
5913 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
5914 push(p4);
5915 derivative();
5916 }
5917 } else {
5918 n = -n;
5919 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
5920 push(p4);
5921 integral();
5922 }
5923 }
5924 p3 = pop();
5925 if (p5 === symbol(NIL)) {
5926 break;
5927 }
5928 if (isnum(p5)) {
5929 p1 = cdr(p1);
5930 push(car(p1));
5931 Eval();
5932 p5 = pop();
5933 if (p5 === symbol(NIL)) {
5934 break;
5935 }
5936 if (isnum(p5)) {
5937 doNothing = 1;
5938 } else {
5939 p4 = p5;
5940 p1 = cdr(p1);
5941 push(car(p1));
5942 Eval();
5943 p5 = pop();
5944 }
5945 } else {
5946 p4 = p5;
5947 p1 = cdr(p1);
5948 push(car(p1));
5949 Eval();
5950 p5 = pop();
5951 }
5952 }
5953 return push(p3);
5954 };
5955
5956 derivative = function() {
5957 save();
5958 p2 = pop();
5959 p1 = pop();
5960 if (isnum(p2)) {
5961 stop("undefined function");
5962 }
5963 if (istensor(p1)) {
5964 if (istensor(p2)) {
5965 d_tensor_tensor();
5966 } else {
5967 d_tensor_scalar();
5968 }
5969 } else {
5970 if (istensor(p2)) {
5971 d_scalar_tensor();
5972 } else {
5973 d_scalar_scalar();
5974 }
5975 }
5976 return restore();
5977 };
5978
5979 d_scalar_scalar = function() {
5980 if (issymbol(p2)) {
5981 return d_scalar_scalar_1();
5982 } else {
5983 push(p1);
5984 push(p2);
5985 push(symbol(SECRETX));
5986 subst();
5987 push(symbol(SECRETX));
5988 derivative();
5989 push(symbol(SECRETX));
5990 push(p2);
5991 return subst();
5992 }
5993 };
5994
5995 d_scalar_scalar_1 = function() {
5996 if (equal(p1, p2)) {
5997 push(one);
5998 return;
5999 }
6000 if (!iscons(p1)) {
6001 push(zero);
6002 return;
6003 }
6004 if (isadd(p1)) {
6005 dsum();
6006 return;
6007 }
6008 if (car(p1) === symbol(MULTIPLY)) {
6009 dproduct();
6010 return;
6011 }
6012 if (car(p1) === symbol(POWER)) {
6013 dpower();
6014 return;
6015 }
6016 if (car(p1) === symbol(DERIVATIVE)) {
6017 dd();
6018 return;
6019 }
6020 if (car(p1) === symbol(LOG)) {
6021 dlog();
6022 return;
6023 }
6024 if (car(p1) === symbol(SIN)) {
6025 dsin();
6026 return;
6027 }
6028 if (car(p1) === symbol(COS)) {
6029 dcos();
6030 return;
6031 }
6032 if (car(p1) === symbol(TAN)) {
6033 dtan();
6034 return;
6035 }
6036 if (car(p1) === symbol(ARCSIN)) {
6037 darcsin();
6038 return;
6039 }
6040 if (car(p1) === symbol(ARCCOS)) {
6041 darccos();
6042 return;
6043 }
6044 if (car(p1) === symbol(ARCTAN)) {
6045 darctan();
6046 return;
6047 }
6048 if (car(p1) === symbol(SINH)) {
6049 dsinh();
6050 return;
6051 }
6052 if (car(p1) === symbol(COSH)) {
6053 dcosh();
6054 return;
6055 }
6056 if (car(p1) === symbol(TANH)) {
6057 dtanh();
6058 return;
6059 }
6060 if (car(p1) === symbol(ARCSINH)) {
6061 darcsinh();
6062 return;
6063 }
6064 if (car(p1) === symbol(ARCCOSH)) {
6065 darccosh();
6066 return;
6067 }
6068 if (car(p1) === symbol(ARCTANH)) {
6069 darctanh();
6070 return;
6071 }
6072 if (car(p1) === symbol(ABS)) {
6073 dabs();
6074 return;
6075 }
6076 if (car(p1) === symbol(SGN)) {
6077 dsgn();
6078 return;
6079 }
6080 if (car(p1) === symbol(HERMITE)) {
6081 dhermite();
6082 return;
6083 }
6084 if (car(p1) === symbol(ERF)) {
6085 derf();
6086 return;
6087 }
6088 if (car(p1) === symbol(ERFC)) {
6089 derfc();
6090 return;
6091 }
6092 if (car(p1) === symbol(BESSELJ)) {
6093 if (iszero(caddr(p1))) {
6094 dbesselj0();
6095 } else {
6096 dbesseljn();
6097 }
6098 return;
6099 }
6100 if (car(p1) === symbol(BESSELY)) {
6101 if (iszero(caddr(p1))) {
6102 dbessely0();
6103 } else {
6104 dbesselyn();
6105 }
6106 return;
6107 }
6108 if (car(p1) === symbol(INTEGRAL) && caddr(p1) === p2) {
6109 derivative_of_integral();
6110 return;
6111 }
6112 return dfunction();
6113 };
6114
6115 dsum = function() {
6116 var h;
6117 h = tos;
6118 p1 = cdr(p1);
6119 while (iscons(p1)) {
6120 push(car(p1));
6121 push(p2);
6122 derivative();
6123 p1 = cdr(p1);
6124 }
6125 return add_all(tos - h);
6126 };
6127
6128 dproduct = function() {
6129 var i, i1, j, n, o, ref, ref1;
6130 i = 0;
6131 j = 0;
6132 n = 0;
6133 n = length(p1) - 1;
6134 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6135 p3 = cdr(p1);
6136 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
6137 push(car(p3));
6138 if (i === j) {
6139 push(p2);
6140 derivative();
6141 }
6142 p3 = cdr(p3);
6143 }
6144 multiply_all(n);
6145 }
6146 return add_all(n);
6147 };
6148
6149 dpower = function() {
6150 push(caddr(p1));
6151 push(cadr(p1));
6152 divide();
6153 push(cadr(p1));
6154 push(p2);
6155 derivative();
6156 multiply();
6157 push(cadr(p1));
6158 logarithm();
6159 push(caddr(p1));
6160 push(p2);
6161 derivative();
6162 multiply();
6163 add();
6164 push(p1);
6165 return multiply();
6166 };
6167
6168 dlog = function() {
6169 push(cadr(p1));
6170 push(p2);
6171 derivative();
6172 push(cadr(p1));
6173 return divide();
6174 };
6175
6176 dd = function() {
6177 push(cadr(p1));
6178 push(p2);
6179 derivative();
6180 p3 = pop();
6181 if (car(p3) === symbol(DERIVATIVE)) {
6182 push_symbol(DERIVATIVE);
6183 push_symbol(DERIVATIVE);
6184 push(cadr(p3));
6185 if (lessp(caddr(p3), caddr(p1))) {
6186 push(caddr(p3));
6187 list(3);
6188 push(caddr(p1));
6189 } else {
6190 push(caddr(p1));
6191 list(3);
6192 push(caddr(p3));
6193 }
6194 return list(3);
6195 } else {
6196 push(p3);
6197 push(caddr(p1));
6198 return derivative();
6199 }
6200 };
6201
6202 dfunction = function() {
6203 p3 = cdr(p1);
6204 if (p3 === symbol(NIL) || Find(p3, p2)) {
6205 push_symbol(DERIVATIVE);
6206 push(p1);
6207 push(p2);
6208 return list(3);
6209 } else {
6210 return push(zero);
6211 }
6212 };
6213
6214 dsin = function() {
6215 push(cadr(p1));
6216 push(p2);
6217 derivative();
6218 push(cadr(p1));
6219 cosine();
6220 return multiply();
6221 };
6222
6223 dcos = function() {
6224 push(cadr(p1));
6225 push(p2);
6226 derivative();
6227 push(cadr(p1));
6228 sine();
6229 multiply();
6230 return negate();
6231 };
6232
6233 dtan = function() {
6234 push(cadr(p1));
6235 push(p2);
6236 derivative();
6237 push(cadr(p1));
6238 cosine();
6239 push_integer(-2);
6240 power();
6241 return multiply();
6242 };
6243
6244 darcsin = function() {
6245 push(cadr(p1));
6246 push(p2);
6247 derivative();
6248 push_integer(1);
6249 push(cadr(p1));
6250 push_integer(2);
6251 power();
6252 subtract();
6253 push_rational(-1, 2);
6254 power();
6255 return multiply();
6256 };
6257
6258 darccos = function() {
6259 push(cadr(p1));
6260 push(p2);
6261 derivative();
6262 push_integer(1);
6263 push(cadr(p1));
6264 push_integer(2);
6265 power();
6266 subtract();
6267 push_rational(-1, 2);
6268 power();
6269 multiply();
6270 return negate();
6271 };
6272
6273 darctan = function() {
6274 push(cadr(p1));
6275 push(p2);
6276 derivative();
6277 push_integer(1);
6278 push(cadr(p1));
6279 push_integer(2);
6280 power();
6281 add();
6282 inverse();
6283 multiply();
6284 return simplify();
6285 };
6286
6287 dsinh = function() {
6288 push(cadr(p1));
6289 push(p2);
6290 derivative();
6291 push(cadr(p1));
6292 ycosh();
6293 return multiply();
6294 };
6295
6296 dcosh = function() {
6297 push(cadr(p1));
6298 push(p2);
6299 derivative();
6300 push(cadr(p1));
6301 ysinh();
6302 return multiply();
6303 };
6304
6305 dtanh = function() {
6306 push(cadr(p1));
6307 push(p2);
6308 derivative();
6309 push(cadr(p1));
6310 ycosh();
6311 push_integer(-2);
6312 power();
6313 return multiply();
6314 };
6315
6316 darcsinh = function() {
6317 push(cadr(p1));
6318 push(p2);
6319 derivative();
6320 push(cadr(p1));
6321 push_integer(2);
6322 power();
6323 push_integer(1);
6324 add();
6325 push_rational(-1, 2);
6326 power();
6327 return multiply();
6328 };
6329
6330 darccosh = function() {
6331 push(cadr(p1));
6332 push(p2);
6333 derivative();
6334 push(cadr(p1));
6335 push_integer(2);
6336 power();
6337 push_integer(-1);
6338 add();
6339 push_rational(-1, 2);
6340 power();
6341 return multiply();
6342 };
6343
6344 darctanh = function() {
6345 push(cadr(p1));
6346 push(p2);
6347 derivative();
6348 push_integer(1);
6349 push(cadr(p1));
6350 push_integer(2);
6351 power();
6352 subtract();
6353 inverse();
6354 return multiply();
6355 };
6356
6357 dabs = function() {
6358 push(cadr(p1));
6359 push(p2);
6360 derivative();
6361 push(cadr(p1));
6362 sgn();
6363 return multiply();
6364 };
6365
6366 dsgn = function() {
6367 push(cadr(p1));
6368 push(p2);
6369 derivative();
6370 push(cadr(p1));
6371 dirac();
6372 multiply();
6373 push_integer(2);
6374 return multiply();
6375 };
6376
6377 dhermite = function() {
6378 push(cadr(p1));
6379 push(p2);
6380 derivative();
6381 push_integer(2);
6382 push(caddr(p1));
6383 multiply();
6384 multiply();
6385 push(cadr(p1));
6386 push(caddr(p1));
6387 push_integer(-1);
6388 add();
6389 hermite();
6390 return multiply();
6391 };
6392
6393 derf = function() {
6394 push(cadr(p1));
6395 push_integer(2);
6396 power();
6397 push_integer(-1);
6398 multiply();
6399 exponential();
6400 if (evaluatingAsFloats) {
6401 push_double(Math.PI);
6402 } else {
6403 push_symbol(PI);
6404 }
6405 push_rational(-1, 2);
6406 power();
6407 multiply();
6408 push_integer(2);
6409 multiply();
6410 push(cadr(p1));
6411 push(p2);
6412 derivative();
6413 return multiply();
6414 };
6415
6416 derfc = function() {
6417 push(cadr(p1));
6418 push_integer(2);
6419 power();
6420 push_integer(-1);
6421 multiply();
6422 exponential();
6423 if (evaluatingAsFloats) {
6424 push_double(Math.PI);
6425 } else {
6426 push_symbol(PI);
6427 }
6428 push_rational(-1, 2);
6429 power();
6430 multiply();
6431 push_integer(-2);
6432 multiply();
6433 push(cadr(p1));
6434 push(p2);
6435 derivative();
6436 return multiply();
6437 };
6438
6439 dbesselj0 = function() {
6440 push(cadr(p1));
6441 push(p2);
6442 derivative();
6443 push(cadr(p1));
6444 push_integer(1);
6445 besselj();
6446 multiply();
6447 push_integer(-1);
6448 return multiply();
6449 };
6450
6451 dbesseljn = function() {
6452 push(cadr(p1));
6453 push(p2);
6454 derivative();
6455 push(cadr(p1));
6456 push(caddr(p1));
6457 push_integer(-1);
6458 add();
6459 besselj();
6460 push(caddr(p1));
6461 push_integer(-1);
6462 multiply();
6463 push(cadr(p1));
6464 divide();
6465 push(cadr(p1));
6466 push(caddr(p1));
6467 besselj();
6468 multiply();
6469 add();
6470 return multiply();
6471 };
6472
6473 dbessely0 = function() {
6474 push(cadr(p1));
6475 push(p2);
6476 derivative();
6477 push(cadr(p1));
6478 push_integer(1);
6479 besselj();
6480 multiply();
6481 push_integer(-1);
6482 return multiply();
6483 };
6484
6485 dbesselyn = function() {
6486 push(cadr(p1));
6487 push(p2);
6488 derivative();
6489 push(cadr(p1));
6490 push(caddr(p1));
6491 push_integer(-1);
6492 add();
6493 bessely();
6494 push(caddr(p1));
6495 push_integer(-1);
6496 multiply();
6497 push(cadr(p1));
6498 divide();
6499 push(cadr(p1));
6500 push(caddr(p1));
6501 bessely();
6502 multiply();
6503 add();
6504 return multiply();
6505 };
6506
6507 derivative_of_integral = function() {
6508 return push(cadr(p1));
6509 };
6510
6511
6512 /* det =====================================================================
6513
6514 Tags
6515 ----
6516 scripting, JS, internal, treenode, general concept
6517
6518 Parameters
6519 ----------
6520 m
6521
6522 General description
6523 -------------------
6524 Returns the determinant of matrix m.
6525 Uses Gaussian elimination for numerical matrices.
6526
6527 Example:
6528
6529 det(((1,2),(3,4)))
6530 > -2
6531 */
6532
6533 DET_check_arg = function() {
6534 if (!istensor(p1)) {
6535 return 0;
6536 } else if (p1.tensor.ndim !== 2) {
6537 return 0;
6538 } else if (p1.tensor.dim[0] !== p1.tensor.dim[1]) {
6539 return 0;
6540 } else {
6541 return 1;
6542 }
6543 };
6544
6545 det = function() {
6546 var a, i, i1, n, o, ref, ref1;
6547 i = 0;
6548 n = 0;
6549 save();
6550 p1 = pop();
6551 if (DET_check_arg() === 0) {
6552 push_symbol(DET);
6553 push(p1);
6554 list(2);
6555 restore();
6556 return;
6557 }
6558 n = p1.tensor.nelem;
6559 a = p1.tensor.elem;
6560 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6561 if (!isnum(a[i])) {
6562 break;
6563 }
6564 }
6565 if (i === n) {
6566 yydetg();
6567 } else {
6568 for (i = i1 = 0, ref1 = p1.tensor.nelem; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
6569 push(p1.tensor.elem[i]);
6570 }
6571 determinant(p1.tensor.dim[0]);
6572 }
6573 return restore();
6574 };
6575
6576 determinant = function(n) {
6577 var a, breakFromOutherWhile, h, i, i1, j, k, o, q, ref, ref1, s, sign_, t;
6578 h = 0;
6579 i = 0;
6580 j = 0;
6581 k = 0;
6582 q = 0;
6583 s = 0;
6584 sign_ = 0;
6585 t = 0;
6586 a = [];
6587 h = tos - n * n;
6588 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6589 a[i] = i;
6590 a[i + n] = 0;
6591 a[i + n + n] = 1;
6592 }
6593 sign_ = 1;
6594 push(zero);
6595 while (1) {
6596 if (sign_ === 1) {
6597 push_integer(1);
6598 } else {
6599 push_integer(-1);
6600 }
6601 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
6602 k = n * a[i] + i;
6603 push(stack[h + k]);
6604 multiply();
6605 }
6606 add();
6607 j = n - 1;
6608 s = 0;
6609 breakFromOutherWhile = false;
6610 while (1) {
6611 q = a[n + j] + a[n + n + j];
6612 if (q < 0) {
6613 a[n + n + j] = -a[n + n + j];
6614 j--;
6615 continue;
6616 }
6617 if (q === j + 1) {
6618 if (j === 0) {
6619 breakFromOutherWhile = true;
6620 break;
6621 }
6622 s++;
6623 a[n + n + j] = -a[n + n + j];
6624 j--;
6625 continue;
6626 }
6627 break;
6628 }
6629 if (breakFromOutherWhile) {
6630 break;
6631 }
6632 t = a[j - a[n + j] + s];
6633 a[j - a[n + j] + s] = a[j - q + s];
6634 a[j - q + s] = t;
6635 a[n + j] = q;
6636 sign_ = -sign_;
6637 }
6638 stack[h] = stack[tos - 1];
6639 return moveTos(h + 1);
6640 };
6641
6642 detg = function() {
6643 save();
6644 p1 = pop();
6645 if (DET_check_arg() === 0) {
6646 push_symbol(DET);
6647 push(p1);
6648 list(2);
6649 restore();
6650 return;
6651 }
6652 yydetg();
6653 return restore();
6654 };
6655
6656 yydetg = function() {
6657 var i, n, o, ref;
6658 i = 0;
6659 n = 0;
6660 n = p1.tensor.dim[0];
6661 for (i = o = 0, ref = n * n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6662 push(p1.tensor.elem[i]);
6663 }
6664 lu_decomp(n);
6665 moveTos(tos - n * n);
6666 return push(p1);
6667 };
6668
6669 M = function(h, n, i, j) {
6670 return stack[h + n * i + j];
6671 };
6672
6673 setM = function(h, n, i, j, value) {
6674 return stack[h + n * i + j] = value;
6675 };
6676
6677 lu_decomp = function(n) {
6678 var d, h, i, i1, j, j1, l1, m1, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8;
6679 d = 0;
6680 h = 0;
6681 i = 0;
6682 j = 0;
6683 h = tos - n * n;
6684 p1 = one;
6685 for (d = o = 0, ref = n - 1; 0 <= ref ? o < ref : o > ref; d = 0 <= ref ? ++o : --o) {
6686 if (equal(M(h, n, d, d), zero)) {
6687 for (i = i1 = ref1 = d + 1, ref2 = n; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
6688 if (!equal(M(h, n, i, d), zero)) {
6689 break;
6690 }
6691 }
6692 if (i === n) {
6693 p1 = zero;
6694 break;
6695 }
6696 for (j = j1 = ref3 = d, ref4 = n; ref3 <= ref4 ? j1 < ref4 : j1 > ref4; j = ref3 <= ref4 ? ++j1 : --j1) {
6697 p2 = M(h, n, d, j);
6698 setM(h, n, d, j, M(h, n, i, j));
6699 setM(h, n, i, j, p2);
6700 }
6701 push(p1);
6702 negate();
6703 p1 = pop();
6704 }
6705 push(p1);
6706 push(M(h, n, d, d));
6707 multiply();
6708 p1 = pop();
6709 for (i = l1 = ref5 = d + 1, ref6 = n; ref5 <= ref6 ? l1 < ref6 : l1 > ref6; i = ref5 <= ref6 ? ++l1 : --l1) {
6710 push(M(h, n, i, d));
6711 push(M(h, n, d, d));
6712 divide();
6713 negate();
6714 p2 = pop();
6715 setM(h, n, i, d, zero);
6716 for (j = m1 = ref7 = d + 1, ref8 = n; ref7 <= ref8 ? m1 < ref8 : m1 > ref8; j = ref7 <= ref8 ? ++m1 : --m1) {
6717 push(M(h, n, d, j));
6718 push(p2);
6719 multiply();
6720 push(M(h, n, i, j));
6721 add();
6722 setM(h, n, i, j, pop());
6723 }
6724 }
6725 }
6726 push(p1);
6727 push(M(h, n, n - 1, n - 1));
6728 multiply();
6729 return p1 = pop();
6730 };
6731
6732 Eval_dirac = function() {
6733 push(cadr(p1));
6734 Eval();
6735 return dirac();
6736 };
6737
6738 dirac = function() {
6739 save();
6740 ydirac();
6741 return restore();
6742 };
6743
6744 ydirac = function() {
6745 p1 = pop();
6746 if (isdouble(p1)) {
6747 if (p1.d === 0) {
6748 push_integer(1);
6749 return;
6750 } else {
6751 push_integer(0);
6752 return;
6753 }
6754 }
6755 if (isrational(p1)) {
6756 if (MZERO(mmul(p1.q.a, p1.q.b))) {
6757 push_integer(1);
6758 return;
6759 } else {
6760 push_integer(0);
6761 return;
6762 }
6763 }
6764 if (car(p1) === symbol(POWER)) {
6765 push_symbol(DIRAC);
6766 push(cadr(p1));
6767 list(2);
6768 return;
6769 }
6770 if (isnegativeterm(p1)) {
6771 push_symbol(DIRAC);
6772 push(p1);
6773 negate();
6774 list(2);
6775 return;
6776 }
6777 if (isnegativeterm(p1) || (car(p1) === symbol(ADD) && isnegativeterm(cadr(p1)))) {
6778 push(p1);
6779 negate();
6780 p1 = pop();
6781 }
6782 push_symbol(DIRAC);
6783 push(p1);
6784 return list(2);
6785 };
6786
6787 divisors = function() {
6788 var h, i, n, o, ref, subsetOfStack;
6789 i = 0;
6790 h = 0;
6791 n = 0;
6792 save();
6793 h = tos - 1;
6794 divisors_onstack();
6795 n = tos - h;
6796 subsetOfStack = stack.slice(h, h + n);
6797 subsetOfStack.sort(cmp_expr);
6798 stack = stack.slice(0, h).concat(subsetOfStack).concat(stack.slice(h + n));
6799 p1 = alloc_tensor(n);
6800 p1.tensor.ndim = 1;
6801 p1.tensor.dim[0] = n;
6802 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6803 p1.tensor.elem[i] = stack[h + i];
6804 }
6805 moveTos(h);
6806 push(p1);
6807 return restore();
6808 };
6809
6810 divisors_onstack = function() {
6811 var h, i, k, n, o, ref;
6812 h = 0;
6813 i = 0;
6814 k = 0;
6815 n = 0;
6816 save();
6817 p1 = pop();
6818 h = tos;
6819 if (isnum(p1)) {
6820 push(p1);
6821 factor_small_number();
6822 } else if (car(p1) === symbol(ADD)) {
6823 push(p1);
6824 __factor_add();
6825 } else if (car(p1) === symbol(MULTIPLY)) {
6826 p1 = cdr(p1);
6827 if (isnum(car(p1))) {
6828 push(car(p1));
6829 factor_small_number();
6830 p1 = cdr(p1);
6831 }
6832 while (iscons(p1)) {
6833 p2 = car(p1);
6834 if (car(p2) === symbol(POWER)) {
6835 push(cadr(p2));
6836 push(caddr(p2));
6837 } else {
6838 push(p2);
6839 push(one);
6840 }
6841 p1 = cdr(p1);
6842 }
6843 } else if (car(p1) === symbol(POWER)) {
6844 push(cadr(p1));
6845 push(caddr(p1));
6846 } else {
6847 push(p1);
6848 push(one);
6849 }
6850 k = tos;
6851 push(one);
6852 gen(h, k);
6853 n = tos - k;
6854 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
6855 stack[h + i] = stack[k + i];
6856 }
6857 moveTos(h + n);
6858 return restore();
6859 };
6860
6861 gen = function(h, k) {
6862 var expo, i, o, ref;
6863 expo = 0;
6864 i = 0;
6865 save();
6866 p1 = pop();
6867 if (h === k) {
6868 push(p1);
6869 restore();
6870 return;
6871 }
6872 p2 = stack[h + 0];
6873 p3 = stack[h + 1];
6874 push(p3);
6875 expo = pop_integer();
6876 if (!isNaN(expo)) {
6877 for (i = o = 0, ref = Math.abs(expo); 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) {
6878 push(p1);
6879 push(p2);
6880 push_integer(sign(expo) * i);
6881 power();
6882 multiply();
6883 gen(h + 2, k);
6884 }
6885 }
6886 return restore();
6887 };
6888
6889 __factor_add = function() {
6890 save();
6891 p1 = pop();
6892 p3 = cdr(p1);
6893 push(car(p3));
6894 p3 = cdr(p3);
6895 while (iscons(p3)) {
6896 push(car(p3));
6897 gcd();
6898 p3 = cdr(p3);
6899 }
6900 p2 = pop();
6901 if (isplusone(p2)) {
6902 push(p1);
6903 push(one);
6904 restore();
6905 return;
6906 }
6907 if (isnum(p2)) {
6908 push(p2);
6909 factor_small_number();
6910 } else if (car(p2) === symbol(MULTIPLY)) {
6911 p3 = cdr(p2);
6912 if (isnum(car(p3))) {
6913 push(car(p3));
6914 factor_small_number();
6915 } else {
6916 push(car(p3));
6917 push(one);
6918 }
6919 p3 = cdr(p3);
6920 while (iscons(p3)) {
6921 push(car(p3));
6922 push(one);
6923 p3 = cdr(p3);
6924 }
6925 } else {
6926 push(p2);
6927 push(one);
6928 }
6929 push(p2);
6930 inverse();
6931 p2 = pop();
6932 push(zero);
6933 p3 = cdr(p1);
6934 while (iscons(p3)) {
6935 push(p2);
6936 push(car(p3));
6937 multiply();
6938 add();
6939 p3 = cdr(p3);
6940 }
6941 push(one);
6942 return restore();
6943 };
6944
6945 dpow = function() {
6946 var a, b, base, expo, result, theta;
6947 a = 0.0;
6948 b = 0.0;
6949 base = 0.0;
6950 expo = 0.0;
6951 result = 0.0;
6952 theta = 0.0;
6953 expo = pop_double();
6954 base = pop_double();
6955 if (base === 0.0 && expo < 0.0) {
6956 stop("divide by zero");
6957 }
6958 if (base >= 0.0 || (expo % 1.0) === 0.0) {
6959 result = Math.pow(base, expo);
6960 push_double(result);
6961 return;
6962 }
6963 result = Math.pow(Math.abs(base), expo);
6964 theta = Math.PI * expo;
6965 if ((expo % 0.5) === 0.0) {
6966 a = 0.0;
6967 b = Math.sin(theta);
6968 } else {
6969 a = Math.cos(theta);
6970 b = Math.sin(theta);
6971 }
6972 push_double(a * result);
6973 push_double(b * result);
6974 push(imaginaryunit);
6975 multiply();
6976 return add();
6977 };
6978
6979
6980 /* eigen =====================================================================
6981
6982 Tags
6983 ----
6984 scripting, JS, internal, treenode, general concept
6985
6986 Parameters
6987 ----------
6988 m
6989
6990 General description
6991 -------------------
6992 Compute eigenvalues and eigenvectors. Matrix m must be both numerical and symmetric.
6993 The eigenval function returns a matrix with the eigenvalues along the diagonal.
6994 The eigenvec function returns a matrix with the eigenvectors arranged as row vectors.
6995 The eigen function does not return anything but stores the eigenvalue matrix in D
6996 and the eigenvector matrix in Q.
6997
6998 Input: stack[tos - 1] symmetric matrix
6999
7000 Output: D diagnonal matrix
7001 Q eigenvector matrix
7002
7003 D and Q have the property that
7004
7005 A == dot(transpose(Q),D,Q)
7006
7007 where A is the original matrix.
7008
7009 The eigenvalues are on the diagonal of D.
7010 The eigenvectors are row vectors in Q.
7011
7012 The eigenvalue relation:
7013
7014 A X = lambda X
7015
7016 can be checked as follows:
7017
7018 lambda = D[1,1]
7019 X = Q[1]
7020 dot(A,X) - lambda X
7021
7022 Example 1. Check the relation AX = lambda X where lambda is an eigenvalue and X is the associated eigenvector.
7023
7024 Enter:
7025
7026 A = hilbert(3)
7027
7028 eigen(A)
7029
7030 lambda = D[1,1]
7031
7032 X = Q[1]
7033
7034 dot(A,X) - lambda X
7035
7036 Result:
7037
7038 -1.16435e-14
7039
7040 -6.46705e-15
7041
7042 -4.55191e-15
7043
7044 Example 2: Check the relation A = QTDQ.
7045
7046 Enter:
7047
7048 A - dot(transpose(Q),D,Q)
7049
7050 Result:
7051
7052 6.27365e-12 -1.58236e-11 1.81902e-11
7053
7054 -1.58236e-11 -1.95365e-11 2.56514e-12
7055
7056 1.81902e-11 2.56514e-12 1.32627e-11
7057 */
7058
7059 EIG_N = 0;
7060
7061 EIG_yydd = [];
7062
7063 EIG_yyqq = [];
7064
7065 Eval_eigen = function() {
7066 if (EIG_check_arg() === 0) {
7067 stop("eigen: argument is not a square matrix");
7068 }
7069 eigen(EIGEN);
7070 p1 = usr_symbol("D");
7071 set_binding(p1, p2);
7072 p1 = usr_symbol("Q");
7073 set_binding(p1, p3);
7074 return push(symbol(NIL));
7075 };
7076
7077
7078 /* eigenval =====================================================================
7079
7080 Tags
7081 ----
7082 scripting, JS, internal, treenode, general concept
7083
7084 Parameters
7085 ----------
7086 m
7087
7088 General description
7089 -------------------
7090 Compute eigenvalues of m. See "eigen" for more info.
7091 */
7092
7093 Eval_eigenval = function() {
7094 if (EIG_check_arg() === 0) {
7095 push_symbol(EIGENVAL);
7096 push(p1);
7097 list(2);
7098 return;
7099 }
7100 eigen(EIGENVAL);
7101 return push(p2);
7102 };
7103
7104
7105 /* eigenvec =====================================================================
7106
7107 Tags
7108 ----
7109 scripting, JS, internal, treenode, general concept
7110
7111 Parameters
7112 ----------
7113 m
7114
7115 General description
7116 -------------------
7117 Compute eigenvectors of m. See "eigen" for more info.
7118 */
7119
7120 Eval_eigenvec = function() {
7121 if (EIG_check_arg() === 0) {
7122 push_symbol(EIGENVEC);
7123 push(p1);
7124 list(2);
7125 return;
7126 }
7127 eigen(EIGENVEC);
7128 return push(p3);
7129 };
7130
7131 EIG_check_arg = function() {
7132 var i, i1, j, j1, l1, o, ref, ref1, ref2, ref3, ref4;
7133 i = 0;
7134 j = 0;
7135 push(cadr(p1));
7136 Eval();
7137 yyfloat();
7138 Eval();
7139 p1 = pop();
7140 if (!istensor(p1)) {
7141 return 0;
7142 }
7143 if (p1.tensor.ndim !== 2 || p1.tensor.dim[0] !== p1.tensor.dim[1]) {
7144 stop("eigen: argument is not a square matrix");
7145 }
7146 EIG_N = p1.tensor.dim[0];
7147 for (i = o = 0, ref = EIG_N; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
7148 for (j = i1 = 0, ref1 = EIG_N; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
7149 if (!isdouble(p1.tensor.elem[EIG_N * i + j])) {
7150 stop("eigen: matrix is not numerical");
7151 }
7152 }
7153 }
7154 for (i = j1 = 0, ref2 = EIG_N - 1; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
7155 for (j = l1 = ref3 = i + 1, ref4 = EIG_N; ref3 <= ref4 ? l1 < ref4 : l1 > ref4; j = ref3 <= ref4 ? ++l1 : --l1) {
7156 if (Math.abs(p1.tensor.elem[EIG_N * i + j].d - p1.tensor.elem[EIG_N * j + i].d) > 1e-10) {
7157 stop("eigen: matrix is not symmetrical");
7158 }
7159 }
7160 }
7161 return 1;
7162 };
7163
7164 eigen = function(op) {
7165 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;
7166 i = 0;
7167 j = 0;
7168 for (i = o = 0, ref = EIG_N * EIG_N; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
7169 EIG_yydd[i] = 0.0;
7170 }
7171 for (i = i1 = 0, ref1 = EIG_N * EIG_N; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
7172 EIG_yyqq[i] = 0.0;
7173 }
7174 for (i = j1 = 0, ref2 = EIG_N; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
7175 EIG_yydd[EIG_N * i + i] = p1.tensor.elem[EIG_N * i + i].d;
7176 for (j = l1 = ref3 = i + 1, ref4 = EIG_N; ref3 <= ref4 ? l1 < ref4 : l1 > ref4; j = ref3 <= ref4 ? ++l1 : --l1) {
7177 EIG_yydd[EIG_N * i + j] = p1.tensor.elem[EIG_N * i + j].d;
7178 EIG_yydd[EIG_N * j + i] = p1.tensor.elem[EIG_N * i + j].d;
7179 }
7180 }
7181 for (i = m1 = 0, ref5 = EIG_N; 0 <= ref5 ? m1 < ref5 : m1 > ref5; i = 0 <= ref5 ? ++m1 : --m1) {
7182 EIG_yyqq[EIG_N * i + i] = 1.0;
7183 for (j = n1 = ref6 = i + 1, ref7 = EIG_N; ref6 <= ref7 ? n1 < ref7 : n1 > ref7; j = ref6 <= ref7 ? ++n1 : --n1) {
7184 EIG_yyqq[EIG_N * i + j] = 0.0;
7185 EIG_yyqq[EIG_N * j + i] = 0.0;
7186 }
7187 }
7188 for (i = o1 = 0; o1 < 100; i = ++o1) {
7189 if (step() === 0) {
7190 break;
7191 }
7192 }
7193 if (i === 100) {
7194 printstr("\nnote: eigen did not converge\n");
7195 }
7196 if (op === EIGEN || op === EIGENVAL) {
7197 push(p1);
7198 copy_tensor();
7199 p2 = pop();
7200 for (i = q1 = 0, ref8 = EIG_N; 0 <= ref8 ? q1 < ref8 : q1 > ref8; i = 0 <= ref8 ? ++q1 : --q1) {
7201 for (j = r1 = 0, ref9 = EIG_N; 0 <= ref9 ? r1 < ref9 : r1 > ref9; j = 0 <= ref9 ? ++r1 : --r1) {
7202 push_double(EIG_yydd[EIG_N * i + j]);
7203 p2.tensor.elem[EIG_N * i + j] = pop();
7204 }
7205 }
7206 }
7207 if (op === EIGEN || op === EIGENVEC) {
7208 push(p1);
7209 copy_tensor();
7210 p3 = pop();
7211 results = [];
7212 for (i = s1 = 0, ref10 = EIG_N; 0 <= ref10 ? s1 < ref10 : s1 > ref10; i = 0 <= ref10 ? ++s1 : --s1) {
7213 results.push((function() {
7214 var ref11, results1, t1;
7215 results1 = [];
7216 for (j = t1 = 0, ref11 = EIG_N; 0 <= ref11 ? t1 < ref11 : t1 > ref11; j = 0 <= ref11 ? ++t1 : --t1) {
7217 push_double(EIG_yyqq[EIG_N * i + j]);
7218 results1.push(p3.tensor.elem[EIG_N * i + j] = pop());
7219 }
7220 return results1;
7221 })());
7222 }
7223 return results;
7224 }
7225 };
7226
7227 step = function() {
7228 var count, i, i1, j, o, ref, ref1, ref2;
7229 i = 0;
7230 j = 0;
7231 count = 0;
7232 for (i = o = 0, ref = EIG_N - 1; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
7233 for (j = i1 = ref1 = i + 1, ref2 = EIG_N; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; j = ref1 <= ref2 ? ++i1 : --i1) {
7234 if (EIG_yydd[EIG_N * i + j] !== 0.0) {
7235 step2(i, j);
7236 count++;
7237 }
7238 }
7239 }
7240 return count;
7241 };
7242
7243 step2 = function(p, q) {
7244 var c, cc, i1, j1, k, o, ref, ref1, ref2, s, ss, t, theta;
7245 k = 0;
7246 t = 0.0;
7247 theta = 0.0;
7248 c = 0.0;
7249 cc = 0.0;
7250 s = 0.0;
7251 ss = 0.0;
7252 theta = 0.5 * (EIG_yydd[EIG_N * p + p] - EIG_yydd[EIG_N * q + q]) / EIG_yydd[EIG_N * p + q];
7253 t = 1.0 / (Math.abs(theta) + Math.sqrt(theta * theta + 1.0));
7254 if (theta < 0.0) {
7255 t = -t;
7256 }
7257 c = 1.0 / Math.sqrt(t * t + 1.0);
7258 s = t * c;
7259 for (k = o = 0, ref = EIG_N; 0 <= ref ? o < ref : o > ref; k = 0 <= ref ? ++o : --o) {
7260 cc = EIG_yydd[EIG_N * p + k];
7261 ss = EIG_yydd[EIG_N * q + k];
7262 EIG_yydd[EIG_N * p + k] = c * cc + s * ss;
7263 EIG_yydd[EIG_N * q + k] = c * ss - s * cc;
7264 }
7265 for (k = i1 = 0, ref1 = EIG_N; 0 <= ref1 ? i1 < ref1 : i1 > ref1; k = 0 <= ref1 ? ++i1 : --i1) {
7266 cc = EIG_yydd[EIG_N * k + p];
7267 ss = EIG_yydd[EIG_N * k + q];
7268 EIG_yydd[EIG_N * k + p] = c * cc + s * ss;
7269 EIG_yydd[EIG_N * k + q] = c * ss - s * cc;
7270 }
7271 for (k = j1 = 0, ref2 = EIG_N; 0 <= ref2 ? j1 < ref2 : j1 > ref2; k = 0 <= ref2 ? ++j1 : --j1) {
7272 cc = EIG_yyqq[EIG_N * p + k];
7273 ss = EIG_yyqq[EIG_N * q + k];
7274 EIG_yyqq[EIG_N * p + k] = c * cc + s * ss;
7275 EIG_yyqq[EIG_N * q + k] = c * ss - s * cc;
7276 }
7277 EIG_yydd[EIG_N * p + q] = 0.0;
7278 return EIG_yydd[EIG_N * q + p] = 0.0;
7279 };
7280
7281
7282 /* erf =====================================================================
7283
7284 Tags
7285 ----
7286 scripting, JS, internal, treenode, general concept
7287
7288 Authors
7289 -------
7290 philippe.billet@noos.fr
7291
7292 Parameters
7293 ----------
7294 x
7295
7296 General description
7297 -------------------
7298 Error function erf(x).
7299 erf(-x)=erf(x)
7300 */
7301
7302 Eval_erf = function() {
7303 push(cadr(p1));
7304 Eval();
7305 return yerf();
7306 };
7307
7308 yerf = function() {
7309 save();
7310 yyerf();
7311 return restore();
7312 };
7313
7314 yyerf = function() {
7315 var d;
7316 d = 0.0;
7317 p1 = pop();
7318 if (isdouble(p1)) {
7319 d = 1.0 - erfc(p1.d);
7320 push_double(d);
7321 return;
7322 }
7323 if (isnegativeterm(p1)) {
7324 push_symbol(ERF);
7325 push(p1);
7326 negate();
7327 list(2);
7328 negate();
7329 return;
7330 }
7331 push_symbol(ERF);
7332 push(p1);
7333 list(2);
7334 };
7335
7336 Eval_erfc = function() {
7337 push(cadr(p1));
7338 Eval();
7339 return yerfc();
7340 };
7341
7342 yerfc = function() {
7343 save();
7344 yyerfc();
7345 return restore();
7346 };
7347
7348 yyerfc = function() {
7349 var d;
7350 d = 0.0;
7351 p1 = pop();
7352 if (isdouble(p1)) {
7353 d = erfc(p1.d);
7354 push_double(d);
7355 return;
7356 }
7357 push_symbol(ERFC);
7358 push(p1);
7359 list(2);
7360 };
7361
7362 erfc = function(x) {
7363 var ans, t, z;
7364 t = 0.0;
7365 z = 0.0;
7366 ans = 0.0;
7367 z = Math.abs(x);
7368 t = 1.0 / (1.0 + 0.5 * z);
7369 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)))))))));
7370 if (x >= 0.0) {
7371 return ans;
7372 } else {
7373 return 2.0 - ans;
7374 }
7375 };
7376
7377
7378 /*
7379 * commented-out test
7380 "float(erfc(1))",
7381 "0.157299",
7382 */
7383
7384 Eval = function() {
7385 var willEvaluateAsFloats;
7386 check_esc_flag();
7387 save();
7388 p1 = pop();
7389 if (p1 == null) {
7390 debugger;
7391 }
7392 if (!evaluatingAsFloats && isfloating(p1)) {
7393 willEvaluateAsFloats = true;
7394 evaluatingAsFloats++;
7395 }
7396 switch (p1.k) {
7397 case CONS:
7398 Eval_cons();
7399 break;
7400 case NUM:
7401 if (evaluatingAsFloats) {
7402 push_double(convert_rational_to_double(p1));
7403 } else {
7404 push(p1);
7405 }
7406 break;
7407 case DOUBLE:
7408 case STR:
7409 push(p1);
7410 break;
7411 case TENSOR:
7412 Eval_tensor();
7413 break;
7414 case SYM:
7415 Eval_sym();
7416 break;
7417 default:
7418 stop("atom?");
7419 }
7420 if (willEvaluateAsFloats) {
7421 evaluatingAsFloats--;
7422 }
7423 return restore();
7424 };
7425
7426 Eval_sym = function() {
7427 var cycleString, i, o, positionIfSymbolAlreadyBeingEvaluated, ref, ref1;
7428 if (iskeyword(p1)) {
7429 push(p1);
7430 push(symbol(LAST));
7431 list(2);
7432 Eval();
7433 return;
7434 } else if (p1 === symbol(PI) && evaluatingAsFloats) {
7435 push_double(Math.PI);
7436 return;
7437 }
7438 p2 = get_binding(p1);
7439 if (DEBUG) {
7440 console.log("looked up: " + p1 + " which contains: " + p2);
7441 }
7442 push(p2);
7443 if (p1 !== p2) {
7444 positionIfSymbolAlreadyBeingEvaluated = chainOfUserSymbolsNotFunctionsBeingEvaluated.indexOf(p1);
7445 if (positionIfSymbolAlreadyBeingEvaluated !== -1) {
7446 cycleString = "";
7447 for (i = o = ref = positionIfSymbolAlreadyBeingEvaluated, ref1 = chainOfUserSymbolsNotFunctionsBeingEvaluated.length; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
7448 cycleString += chainOfUserSymbolsNotFunctionsBeingEvaluated[i].printname + " -> ";
7449 }
7450 cycleString += p1.printname;
7451 stop("recursive evaluation of symbols: " + cycleString);
7452 return;
7453 }
7454 chainOfUserSymbolsNotFunctionsBeingEvaluated.push(p1);
7455 Eval();
7456 return chainOfUserSymbolsNotFunctionsBeingEvaluated.pop();
7457 }
7458 };
7459
7460 Eval_cons = function() {
7461 var cons_head;
7462 cons_head = car(p1);
7463 if (car(cons_head) === symbol(EVAL)) {
7464 Eval_user_function();
7465 return;
7466 }
7467 if (!issymbol(cons_head)) {
7468 stop("cons?");
7469 }
7470 switch (symnum(cons_head)) {
7471 case ABS:
7472 return Eval_abs();
7473 case ADD:
7474 return Eval_add();
7475 case ADJ:
7476 return Eval_adj();
7477 case AND:
7478 return Eval_and();
7479 case ARCCOS:
7480 return Eval_arccos();
7481 case ARCCOSH:
7482 return Eval_arccosh();
7483 case ARCSIN:
7484 return Eval_arcsin();
7485 case ARCSINH:
7486 return Eval_arcsinh();
7487 case ARCTAN:
7488 return Eval_arctan();
7489 case ARCTANH:
7490 return Eval_arctanh();
7491 case ARG:
7492 return Eval_arg();
7493 case ATOMIZE:
7494 return Eval_atomize();
7495 case BESSELJ:
7496 return Eval_besselj();
7497 case BESSELY:
7498 return Eval_bessely();
7499 case BINDING:
7500 return Eval_binding();
7501 case BINOMIAL:
7502 return Eval_binomial();
7503 case CEILING:
7504 return Eval_ceiling();
7505 case CHECK:
7506 return Eval_check();
7507 case CHOOSE:
7508 return Eval_choose();
7509 case CIRCEXP:
7510 return Eval_circexp();
7511 case CLEAR:
7512 return Eval_clear();
7513 case CLEARALL:
7514 return Eval_clearall();
7515 case CLEARPATTERNS:
7516 return Eval_clearpatterns();
7517 case CLOCK:
7518 return Eval_clock();
7519 case COEFF:
7520 return Eval_coeff();
7521 case COFACTOR:
7522 return Eval_cofactor();
7523 case CONDENSE:
7524 return Eval_condense();
7525 case CONJ:
7526 return Eval_conj();
7527 case CONTRACT:
7528 return Eval_contract();
7529 case COS:
7530 return Eval_cos();
7531 case COSH:
7532 return Eval_cosh();
7533 case DECOMP:
7534 return Eval_decomp();
7535 case DEGREE:
7536 return Eval_degree();
7537 case DEFINT:
7538 return Eval_defint();
7539 case DENOMINATOR:
7540 return Eval_denominator();
7541 case DERIVATIVE:
7542 return Eval_derivative();
7543 case DET:
7544 return Eval_det();
7545 case DIM:
7546 return Eval_dim();
7547 case DIRAC:
7548 return Eval_dirac();
7549 case DIVISORS:
7550 return Eval_divisors();
7551 case DO:
7552 return Eval_do();
7553 case DOT:
7554 return Eval_inner();
7555 case DRAW:
7556 return Eval_draw();
7557 case DSOLVE:
7558 return Eval_dsolve();
7559 case EIGEN:
7560 return Eval_eigen();
7561 case EIGENVAL:
7562 return Eval_eigenval();
7563 case EIGENVEC:
7564 return Eval_eigenvec();
7565 case ERF:
7566 return Eval_erf();
7567 case ERFC:
7568 return Eval_erfc();
7569 case EVAL:
7570 return Eval_Eval();
7571 case EXP:
7572 return Eval_exp();
7573 case EXPAND:
7574 return Eval_expand();
7575 case EXPCOS:
7576 return Eval_expcos();
7577 case EXPSIN:
7578 return Eval_expsin();
7579 case FACTOR:
7580 return Eval_factor();
7581 case FACTORIAL:
7582 return Eval_factorial();
7583 case FACTORPOLY:
7584 return Eval_factorpoly();
7585 case FILTER:
7586 return Eval_filter();
7587 case FLOATF:
7588 return Eval_float();
7589 case APPROXRATIO:
7590 return Eval_approxratio();
7591 case FLOOR:
7592 return Eval_floor();
7593 case FOR:
7594 return Eval_for();
7595 case FUNCTION:
7596 return Eval_function_reference();
7597 case GAMMA:
7598 return Eval_gamma();
7599 case GCD:
7600 return Eval_gcd();
7601 case HERMITE:
7602 return Eval_hermite();
7603 case HILBERT:
7604 return Eval_hilbert();
7605 case IMAG:
7606 return Eval_imag();
7607 case INDEX:
7608 return Eval_index();
7609 case INNER:
7610 return Eval_inner();
7611 case INTEGRAL:
7612 return Eval_integral();
7613 case INV:
7614 return Eval_inv();
7615 case INVG:
7616 return Eval_invg();
7617 case ISINTEGER:
7618 return Eval_isinteger();
7619 case ISPRIME:
7620 return Eval_isprime();
7621 case LAGUERRE:
7622 return Eval_laguerre();
7623 case LCM:
7624 return Eval_lcm();
7625 case LEADING:
7626 return Eval_leading();
7627 case LEGENDRE:
7628 return Eval_legendre();
7629 case LOG:
7630 return Eval_log();
7631 case LOOKUP:
7632 return Eval_lookup();
7633 case MOD:
7634 return Eval_mod();
7635 case MULTIPLY:
7636 return Eval_multiply();
7637 case NOT:
7638 return Eval_not();
7639 case NROOTS:
7640 return Eval_nroots();
7641 case NUMBER:
7642 return Eval_number();
7643 case NUMERATOR:
7644 return Eval_numerator();
7645 case OPERATOR:
7646 return Eval_operator();
7647 case OR:
7648 return Eval_or();
7649 case OUTER:
7650 return Eval_outer();
7651 case PATTERN:
7652 return Eval_pattern();
7653 case PATTERNSINFO:
7654 return Eval_patternsinfo();
7655 case POLAR:
7656 return Eval_polar();
7657 case POWER:
7658 return Eval_power();
7659 case PRIME:
7660 return Eval_prime();
7661 case PRINT:
7662 return Eval_print();
7663 case PRINT2DASCII:
7664 return Eval_print2dascii();
7665 case PRINTFULL:
7666 return Eval_printfull();
7667 case PRINTLATEX:
7668 return Eval_printlatex();
7669 case PRINTLIST:
7670 return Eval_printlist();
7671 case PRINTPLAIN:
7672 return Eval_printplain();
7673 case PRODUCT:
7674 return Eval_product();
7675 case QUOTE:
7676 return Eval_quote();
7677 case QUOTIENT:
7678 return Eval_quotient();
7679 case RANK:
7680 return Eval_rank();
7681 case RATIONALIZE:
7682 return Eval_rationalize();
7683 case REAL:
7684 return Eval_real();
7685 case ROUND:
7686 return Eval_round();
7687 case YYRECT:
7688 return Eval_rect();
7689 case ROOTS:
7690 return Eval_roots();
7691 case SETQ:
7692 return Eval_setq();
7693 case SGN:
7694 return Eval_sgn();
7695 case SILENTPATTERN:
7696 return Eval_silentpattern();
7697 case SIMPLIFY:
7698 return Eval_simplify();
7699 case SIN:
7700 return Eval_sin();
7701 case SINH:
7702 return Eval_sinh();
7703 case SHAPE:
7704 return Eval_shape();
7705 case SQRT:
7706 return Eval_sqrt();
7707 case STOP:
7708 return Eval_stop();
7709 case SUBST:
7710 return Eval_subst();
7711 case SUM:
7712 return Eval_sum();
7713 case SYMBOLSINFO:
7714 return Eval_symbolsinfo();
7715 case TAN:
7716 return Eval_tan();
7717 case TANH:
7718 return Eval_tanh();
7719 case TAYLOR:
7720 return Eval_taylor();
7721 case TEST:
7722 return Eval_test();
7723 case TESTEQ:
7724 return Eval_testeq();
7725 case TESTGE:
7726 return Eval_testge();
7727 case TESTGT:
7728 return Eval_testgt();
7729 case TESTLE:
7730 return Eval_testle();
7731 case TESTLT:
7732 return Eval_testlt();
7733 case TRANSPOSE:
7734 return Eval_transpose();
7735 case UNIT:
7736 return Eval_unit();
7737 case ZERO:
7738 return Eval_zero();
7739 default:
7740 return Eval_user_function();
7741 }
7742 };
7743
7744 Eval_binding = function() {
7745 return push(get_binding(cadr(p1)));
7746 };
7747
7748
7749 /* check =====================================================================
7750
7751 Tags
7752 ----
7753 scripting, JS, internal, treenode, general concept
7754
7755 Parameters
7756 ----------
7757 p
7758
7759 General description
7760 -------------------
7761 Checks the predicate p, e.g. check(a = b)
7762 Note how "check" can turn what normally would be an assignment into a test,
7763 so in the case above "a" is not assigned anything.
7764 */
7765
7766 Eval_check = function() {
7767 push(cadr(p1));
7768 Eval_predicate();
7769 p1 = pop();
7770 return push(p1);
7771 };
7772
7773 Eval_det = function() {
7774 push(cadr(p1));
7775 Eval();
7776 return det();
7777 };
7778
7779
7780 /* dim =====================================================================
7781
7782 Tags
7783 ----
7784 scripting, JS, internal, treenode, general concept
7785
7786 Parameters
7787 ----------
7788 m,n
7789
7790 General description
7791 -------------------
7792 Returns the cardinality of the nth index of tensor "m".
7793 */
7794
7795 Eval_dim = function() {
7796 var n;
7797 push(cadr(p1));
7798 Eval();
7799 p2 = pop();
7800 if (iscons(cddr(p1))) {
7801 push(caddr(p1));
7802 Eval();
7803 n = pop_integer();
7804 } else {
7805 n = 1;
7806 }
7807 if (!istensor(p2)) {
7808 return push_integer(1);
7809 } else if (n < 1 || n > p2.tensor.ndim) {
7810 return push(p1);
7811 } else {
7812 return push_integer(p2.tensor.dim[n - 1]);
7813 }
7814 };
7815
7816 Eval_divisors = function() {
7817 push(cadr(p1));
7818 Eval();
7819 return divisors();
7820 };
7821
7822
7823 /* do =====================================================================
7824
7825 Tags
7826 ----
7827 scripting, JS, internal, treenode, general concept
7828
7829 Parameters
7830 ----------
7831 a,b,...
7832
7833 General description
7834 -------------------
7835 Evaluates each argument from left to right. Returns the result of the last argument.
7836 */
7837
7838 Eval_do = function() {
7839 var results;
7840 push(car(p1));
7841 p1 = cdr(p1);
7842 results = [];
7843 while (iscons(p1)) {
7844 pop();
7845 push(car(p1));
7846 Eval();
7847 results.push(p1 = cdr(p1));
7848 }
7849 return results;
7850 };
7851
7852 Eval_dsolve = function() {
7853 push(cadr(p1));
7854 Eval();
7855 push(caddr(p1));
7856 Eval();
7857 push(cadddr(p1));
7858 Eval();
7859 return dsolve();
7860 };
7861
7862 Eval_Eval = function() {
7863 push(cadr(p1));
7864 Eval();
7865 p1 = cddr(p1);
7866 while (iscons(p1)) {
7867 push(car(p1));
7868 Eval();
7869 push(cadr(p1));
7870 Eval();
7871 subst();
7872 p1 = cddr(p1);
7873 }
7874 return Eval();
7875 };
7876
7877 Eval_exp = function() {
7878 push(cadr(p1));
7879 Eval();
7880 return exponential();
7881 };
7882
7883 Eval_factorial = function() {
7884 push(cadr(p1));
7885 Eval();
7886 return factorial();
7887 };
7888
7889 Eval_factorpoly = function() {
7890 var results;
7891 p1 = cdr(p1);
7892 push(car(p1));
7893 Eval();
7894 p1 = cdr(p1);
7895 push(car(p1));
7896 Eval();
7897 factorpoly();
7898 p1 = cdr(p1);
7899 results = [];
7900 while (iscons(p1)) {
7901 push(car(p1));
7902 Eval();
7903 factorpoly();
7904 results.push(p1 = cdr(p1));
7905 }
7906 return results;
7907 };
7908
7909 Eval_hermite = function() {
7910 push(cadr(p1));
7911 Eval();
7912 push(caddr(p1));
7913 Eval();
7914 return hermite();
7915 };
7916
7917 Eval_hilbert = function() {
7918 push(cadr(p1));
7919 Eval();
7920 return hilbert();
7921 };
7922
7923 Eval_index = function() {
7924 var h, orig, theTensor;
7925 h = tos;
7926 orig = p1;
7927 p1 = cdr(p1);
7928 push(car(p1));
7929 Eval();
7930 theTensor = stack[tos - 1];
7931 if (isnum(theTensor)) {
7932 stop("trying to access a scalar as a tensor");
7933 }
7934 if (!istensor(theTensor)) {
7935 moveTos(h);
7936 push(orig);
7937 return;
7938 }
7939 p1 = cdr(p1);
7940 while (iscons(p1)) {
7941 push(car(p1));
7942 Eval();
7943 if (!isintegerorintegerfloat(stack[tos - 1])) {
7944 moveTos(h);
7945 push(orig);
7946 return;
7947 }
7948 p1 = cdr(p1);
7949 }
7950 return index_function(tos - h);
7951 };
7952
7953 Eval_inv = function() {
7954 push(cadr(p1));
7955 Eval();
7956 return inv();
7957 };
7958
7959 Eval_invg = function() {
7960 push(cadr(p1));
7961 Eval();
7962 return invg();
7963 };
7964
7965 Eval_isinteger = function() {
7966 var n;
7967 push(cadr(p1));
7968 Eval();
7969 p1 = pop();
7970 if (isrational(p1)) {
7971 if (isinteger(p1)) {
7972 push(one);
7973 } else {
7974 push(zero);
7975 }
7976 return;
7977 }
7978 if (isdouble(p1)) {
7979 n = Math.floor(p1.d);
7980 if (n === p1.d) {
7981 push(one);
7982 } else {
7983 push(zero);
7984 }
7985 return;
7986 }
7987 push_symbol(ISINTEGER);
7988 push(p1);
7989 return list(2);
7990 };
7991
7992 Eval_number = function() {
7993 push(cadr(p1));
7994 Eval();
7995 p1 = pop();
7996 if (p1.k === NUM || p1.k === DOUBLE) {
7997 return push_integer(1);
7998 } else {
7999 return push_integer(0);
8000 }
8001 };
8002
8003 Eval_operator = function() {
8004 var h;
8005 h = tos;
8006 push_symbol(OPERATOR);
8007 p1 = cdr(p1);
8008 while (iscons(p1)) {
8009 push(car(p1));
8010 Eval();
8011 p1 = cdr(p1);
8012 }
8013 return list(tos - h);
8014 };
8015
8016 Eval_quote = function() {
8017 return push(cadr(p1));
8018 };
8019
8020 Eval_rank = function() {
8021 push(cadr(p1));
8022 Eval();
8023 p1 = pop();
8024 if (istensor(p1)) {
8025 return push_integer(p1.tensor.ndim);
8026 } else {
8027 return push(zero);
8028 }
8029 };
8030
8031 Eval_setq = function() {
8032 if (caadr(p1) === symbol(INDEX)) {
8033 setq_indexed();
8034 return;
8035 }
8036 if (iscons(cadr(p1))) {
8037 define_user_function();
8038 return;
8039 }
8040 if (!issymbol(cadr(p1))) {
8041 stop("symbol assignment: error in symbol");
8042 }
8043 push(caddr(p1));
8044 Eval();
8045 p2 = pop();
8046 set_binding(cadr(p1), p2);
8047 return push(symbol(NIL));
8048 };
8049
8050 setq_indexed = function() {
8051 var h;
8052 p4 = cadadr(p1);
8053 if (!issymbol(p4)) {
8054 stop("indexed assignment: error in symbol");
8055 }
8056 h = tos;
8057 push(caddr(p1));
8058 Eval();
8059 p2 = cdadr(p1);
8060 while (iscons(p2)) {
8061 push(car(p2));
8062 Eval();
8063 p2 = cdr(p2);
8064 }
8065 set_component(tos - h);
8066 p3 = pop();
8067 set_binding(p4, p3);
8068 return push(symbol(NIL));
8069 };
8070
8071 Eval_sqrt = function() {
8072 push(cadr(p1));
8073 Eval();
8074 push_rational(1, 2);
8075 return power();
8076 };
8077
8078 Eval_stop = function() {
8079 return stop("user stop");
8080 };
8081
8082 Eval_subst = function() {
8083 push(cadddr(p1));
8084 Eval();
8085 push(caddr(p1));
8086 Eval();
8087 push(cadr(p1));
8088 Eval();
8089 subst();
8090 return Eval();
8091 };
8092
8093 Eval_unit = function() {
8094 var i, n, o, ref;
8095 i = 0;
8096 n = 0;
8097 push(cadr(p1));
8098 Eval();
8099 n = pop_integer();
8100 if (isNaN(n)) {
8101 push(p1);
8102 return;
8103 }
8104 if (n < 1) {
8105 push(p1);
8106 return;
8107 }
8108 p1 = alloc_tensor(n * n);
8109 p1.tensor.ndim = 2;
8110 p1.tensor.dim[0] = n;
8111 p1.tensor.dim[1] = n;
8112 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8113 p1.tensor.elem[n * i + i] = one;
8114 }
8115 check_tensor_dimensions(p1);
8116 return push(p1);
8117 };
8118
8119 Eval_noexpand = function() {
8120 var prev_expanding;
8121 prev_expanding = expanding;
8122 expanding = 0;
8123 Eval();
8124 return expanding = prev_expanding;
8125 };
8126
8127 Eval_predicate = function() {
8128 save();
8129 p1 = top();
8130 if (car(p1) === symbol(SETQ)) {
8131 pop();
8132 push_symbol(TESTEQ);
8133 push(cadr(p1));
8134 push(caddr(p1));
8135 list(3);
8136 }
8137 Eval();
8138 return restore();
8139 };
8140
8141 Eval_expand = function() {
8142 push(cadr(p1));
8143 Eval();
8144 push(caddr(p1));
8145 Eval();
8146 p2 = pop();
8147 if (p2 === symbol(NIL)) {
8148 guess();
8149 } else {
8150 push(p2);
8151 }
8152 return expand();
8153 };
8154
8155 expand = function() {
8156 var prev_expanding;
8157 save();
8158 p9 = pop();
8159 p5 = pop();
8160 if (istensor(p5)) {
8161 expand_tensor();
8162 restore();
8163 return;
8164 }
8165 if (car(p5) === symbol(ADD)) {
8166 push_integer(0);
8167 p1 = cdr(p5);
8168 while (iscons(p1)) {
8169 push(car(p1));
8170 push(p9);
8171 expand();
8172 add();
8173 p1 = cdr(p1);
8174 }
8175 restore();
8176 return;
8177 }
8178 push(p5);
8179 numerator();
8180 p3 = pop();
8181 push(p5);
8182 denominator();
8183 p2 = pop();
8184 remove_negative_exponents();
8185 push(p3);
8186 push(p2);
8187 push(p9);
8188 if (isone(p3) || isone(p2)) {
8189 if (!ispoly(p2, p9) || isone(p2)) {
8190 pop();
8191 pop();
8192 pop();
8193 push(p5);
8194 restore();
8195 return;
8196 }
8197 }
8198 divpoly();
8199 p7 = pop();
8200 push(p3);
8201 push(p2);
8202 push(p7);
8203 multiply();
8204 subtract();
8205 p3 = pop();
8206 if (iszero(p3)) {
8207 push(p7);
8208 restore();
8209 return;
8210 }
8211 push(p2);
8212 push(p9);
8213 factorpoly();
8214 p2 = pop();
8215 expand_get_C();
8216 expand_get_B();
8217 expand_get_A();
8218 if (istensor(p4)) {
8219 push(p4);
8220 prev_expanding = expanding;
8221 expanding = 1;
8222 inv();
8223 expanding = prev_expanding;
8224 push(p3);
8225 inner();
8226 push(p2);
8227 inner();
8228 } else {
8229 push(p3);
8230 push(p4);
8231 prev_expanding = expanding;
8232 expanding = 1;
8233 divide();
8234 expanding = prev_expanding;
8235 push(p2);
8236 multiply();
8237 }
8238 push(p7);
8239 add();
8240 return restore();
8241 };
8242
8243 expand_tensor = function() {
8244 var i, o, ref;
8245 i = 0;
8246 push(p5);
8247 copy_tensor();
8248 p5 = pop();
8249 for (i = o = 0, ref = p5.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8250 push(p5.tensor.elem[i]);
8251 push(p9);
8252 expand();
8253 p5.tensor.elem[i] = pop();
8254 }
8255 return push(p5);
8256 };
8257
8258 remove_negative_exponents = function() {
8259 var h, i, j, k, n, o, ref;
8260 h = 0;
8261 i = 0;
8262 j = 0;
8263 k = 0;
8264 n = 0;
8265 h = tos;
8266 factors(p2);
8267 factors(p3);
8268 n = tos - h;
8269 j = 0;
8270 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8271 p1 = stack[h + i];
8272 if (car(p1) !== symbol(POWER)) {
8273 continue;
8274 }
8275 if (cadr(p1) !== p9) {
8276 continue;
8277 }
8278 push(caddr(p1));
8279 k = pop_integer();
8280 if (isNaN(k)) {
8281 continue;
8282 }
8283 if (k < j) {
8284 j = k;
8285 }
8286 }
8287 moveTos(h);
8288 if (j === 0) {
8289 return;
8290 }
8291 push(p2);
8292 push(p9);
8293 push_integer(-j);
8294 power();
8295 multiply();
8296 p2 = pop();
8297 push(p3);
8298 push(p9);
8299 push_integer(-j);
8300 power();
8301 multiply();
8302 return p3 = pop();
8303 };
8304
8305 expand_get_C = function() {
8306 var a, h, i, i1, j, n, o, prev_expanding, ref, ref1;
8307 h = 0;
8308 i = 0;
8309 j = 0;
8310 n = 0;
8311 h = tos;
8312 if (car(p2) === symbol(MULTIPLY)) {
8313 p1 = cdr(p2);
8314 while (iscons(p1)) {
8315 p5 = car(p1);
8316 expand_get_CF();
8317 p1 = cdr(p1);
8318 }
8319 } else {
8320 p5 = p2;
8321 expand_get_CF();
8322 }
8323 n = tos - h;
8324 if (n === 1) {
8325 p4 = pop();
8326 return;
8327 }
8328 p4 = alloc_tensor(n * n);
8329 p4.tensor.ndim = 2;
8330 p4.tensor.dim[0] = n;
8331 p4.tensor.dim[1] = n;
8332 a = h;
8333 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8334 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
8335 push(stack[a + j]);
8336 push(p9);
8337 push_integer(i);
8338 power();
8339 prev_expanding = expanding;
8340 expanding = 1;
8341 divide();
8342 expanding = prev_expanding;
8343 push(p9);
8344 filter();
8345 p4.tensor.elem[n * i + j] = pop();
8346 }
8347 }
8348 return moveTos(tos - n);
8349 };
8350
8351 expand_get_CF = function() {
8352 var d, i, j, n, o, prev_expanding, ref, results;
8353 d = 0;
8354 i = 0;
8355 j = 0;
8356 n = 0;
8357 if (!Find(p5, p9)) {
8358 return;
8359 }
8360 prev_expanding = expanding;
8361 expanding = 1;
8362 trivial_divide();
8363 expanding = prev_expanding;
8364 if (car(p5) === symbol(POWER)) {
8365 push(caddr(p5));
8366 n = pop_integer();
8367 p6 = cadr(p5);
8368 } else {
8369 n = 1;
8370 p6 = p5;
8371 }
8372 push(p6);
8373 push(p9);
8374 degree();
8375 d = pop_integer();
8376 results = [];
8377 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8378 results.push((function() {
8379 var i1, ref1, results1;
8380 results1 = [];
8381 for (j = i1 = 0, ref1 = d; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
8382 push(p8);
8383 push(p6);
8384 push_integer(i);
8385 power();
8386 prev_expanding = expanding;
8387 expanding = 1;
8388 multiply();
8389 expanding = prev_expanding;
8390 push(p9);
8391 push_integer(j);
8392 power();
8393 prev_expanding = expanding;
8394 expanding = 1;
8395 multiply();
8396 results1.push(expanding = prev_expanding);
8397 }
8398 return results1;
8399 })());
8400 }
8401 return results;
8402 };
8403
8404 trivial_divide = function() {
8405 var h;
8406 h = 0;
8407 if (car(p2) === symbol(MULTIPLY)) {
8408 h = tos;
8409 p0 = cdr(p2);
8410 while (iscons(p0)) {
8411 if (!equal(car(p0), p5)) {
8412 push(car(p0));
8413 Eval();
8414 }
8415 p0 = cdr(p0);
8416 }
8417 multiply_all(tos - h);
8418 } else {
8419 push_integer(1);
8420 }
8421 return p8 = pop();
8422 };
8423
8424 expand_get_B = function() {
8425 var i, n, o, prev_expanding, ref;
8426 i = 0;
8427 n = 0;
8428 if (!istensor(p4)) {
8429 return;
8430 }
8431 n = p4.tensor.dim[0];
8432 p8 = alloc_tensor(n);
8433 p8.tensor.ndim = 1;
8434 p8.tensor.dim[0] = n;
8435 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8436 push(p3);
8437 push(p9);
8438 push_integer(i);
8439 power();
8440 prev_expanding = expanding;
8441 expanding = 1;
8442 divide();
8443 expanding = prev_expanding;
8444 push(p9);
8445 filter();
8446 p8.tensor.elem[i] = pop();
8447 }
8448 return p3 = p8;
8449 };
8450
8451 expand_get_A = function() {
8452 var h, i, n, o, ref;
8453 h = 0;
8454 i = 0;
8455 n = 0;
8456 if (!istensor(p4)) {
8457 push(p2);
8458 reciprocate();
8459 p2 = pop();
8460 return;
8461 }
8462 h = tos;
8463 if (car(p2) === symbol(MULTIPLY)) {
8464 p8 = cdr(p2);
8465 while (iscons(p8)) {
8466 p5 = car(p8);
8467 expand_get_AF();
8468 p8 = cdr(p8);
8469 }
8470 } else {
8471 p5 = p2;
8472 expand_get_AF();
8473 }
8474 n = tos - h;
8475 p8 = alloc_tensor(n);
8476 p8.tensor.ndim = 1;
8477 p8.tensor.dim[0] = n;
8478 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8479 p8.tensor.elem[i] = stack[h + i];
8480 }
8481 moveTos(h);
8482 return p2 = p8;
8483 };
8484
8485 expand_get_AF = function() {
8486 var d, i, j, n, o, ref, results;
8487 d = 0;
8488 i = 0;
8489 j = 0;
8490 n = 1;
8491 if (!Find(p5, p9)) {
8492 return;
8493 }
8494 if (car(p5) === symbol(POWER)) {
8495 push(caddr(p5));
8496 n = pop_integer();
8497 p5 = cadr(p5);
8498 }
8499 push(p5);
8500 push(p9);
8501 degree();
8502 d = pop_integer();
8503 results = [];
8504 for (i = o = ref = n; ref <= 0 ? o < 0 : o > 0; i = ref <= 0 ? ++o : --o) {
8505 results.push((function() {
8506 var i1, ref1, results1;
8507 results1 = [];
8508 for (j = i1 = 0, ref1 = d; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
8509 push(p5);
8510 push_integer(i);
8511 power();
8512 reciprocate();
8513 push(p9);
8514 push_integer(j);
8515 power();
8516 results1.push(multiply());
8517 }
8518 return results1;
8519 })());
8520 }
8521 return results;
8522 };
8523
8524 Eval_expcos = function() {
8525 push(cadr(p1));
8526 Eval();
8527 return expcos();
8528 };
8529
8530 expcos = function() {
8531 save();
8532 p1 = pop();
8533 push(imaginaryunit);
8534 push(p1);
8535 multiply();
8536 exponential();
8537 push_rational(1, 2);
8538 multiply();
8539 push(imaginaryunit);
8540 negate();
8541 push(p1);
8542 multiply();
8543 exponential();
8544 push_rational(1, 2);
8545 multiply();
8546 add();
8547 return restore();
8548 };
8549
8550 Eval_expsin = function() {
8551 push(cadr(p1));
8552 Eval();
8553 return expsin();
8554 };
8555
8556 expsin = function() {
8557 save();
8558 p1 = pop();
8559 push(imaginaryunit);
8560 push(p1);
8561 multiply();
8562 exponential();
8563 push(imaginaryunit);
8564 divide();
8565 push_rational(1, 2);
8566 multiply();
8567 push(imaginaryunit);
8568 negate();
8569 push(p1);
8570 multiply();
8571 exponential();
8572 push(imaginaryunit);
8573 divide();
8574 push_rational(1, 2);
8575 multiply();
8576 subtract();
8577 return restore();
8578 };
8579
8580 Eval_factor = function() {
8581 var results;
8582 push(cadr(p1));
8583 Eval();
8584 push(caddr(p1));
8585 Eval();
8586 p2 = pop();
8587 if (p2 === symbol(NIL)) {
8588 guess();
8589 } else {
8590 push(p2);
8591 }
8592 factor();
8593 p1 = cdddr(p1);
8594 results = [];
8595 while (iscons(p1)) {
8596 push(car(p1));
8597 Eval();
8598 factor_again();
8599 results.push(p1 = cdr(p1));
8600 }
8601 return results;
8602 };
8603
8604 factor_again = function() {
8605 var h, n;
8606 save();
8607 p2 = pop();
8608 p1 = pop();
8609 h = tos;
8610 if (car(p1) === symbol(MULTIPLY)) {
8611 p1 = cdr(p1);
8612 while (iscons(p1)) {
8613 push(car(p1));
8614 push(p2);
8615 factor_term();
8616 p1 = cdr(p1);
8617 }
8618 } else {
8619 push(p1);
8620 push(p2);
8621 factor_term();
8622 }
8623 n = tos - h;
8624 if (n > 1) {
8625 multiply_all_noexpand(n);
8626 }
8627 return restore();
8628 };
8629
8630 factor_term = function() {
8631 save();
8632 factorpoly();
8633 p1 = pop();
8634 if (car(p1) === symbol(MULTIPLY)) {
8635 p1 = cdr(p1);
8636 while (iscons(p1)) {
8637 push(car(p1));
8638 p1 = cdr(p1);
8639 }
8640 } else {
8641 push(p1);
8642 }
8643 return restore();
8644 };
8645
8646 factor = function() {
8647 save();
8648 p2 = pop();
8649 p1 = pop();
8650 if (isinteger(p1)) {
8651 push(p1);
8652 factor_number();
8653 } else {
8654 push(p1);
8655 push(p2);
8656 factorpoly();
8657 }
8658 return restore();
8659 };
8660
8661 factor_small_number = function() {
8662 var d, expo, i, n, o, ref;
8663 i = 0;
8664 save();
8665 n = pop_integer();
8666 if (isNaN(n)) {
8667 stop("number too big to factor");
8668 }
8669 if (n < 0) {
8670 n = -n;
8671 }
8672 for (i = o = 0, ref = MAXPRIMETAB; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8673 d = primetab[i];
8674 if (d > n / d) {
8675 break;
8676 }
8677 expo = 0;
8678 while (n % d === 0) {
8679 n /= d;
8680 expo++;
8681 }
8682 if (expo) {
8683 push_integer(d);
8684 push_integer(expo);
8685 }
8686 }
8687 if (n > 1) {
8688 push_integer(n);
8689 push_integer(1);
8690 }
8691 return restore();
8692 };
8693
8694 factorial = function() {
8695 var n;
8696 n = 0;
8697 save();
8698 p1 = pop();
8699 push(p1);
8700 n = pop_integer();
8701 if (n < 0 || isNaN(n)) {
8702 push_symbol(FACTORIAL);
8703 push(p1);
8704 list(2);
8705 restore();
8706 return;
8707 }
8708 bignum_factorial(n);
8709 return restore();
8710 };
8711
8712 simplifyfactorials = function() {
8713 var x;
8714 x = 0;
8715 save();
8716 x = expanding;
8717 expanding = 0;
8718 p1 = pop();
8719 if (car(p1) === symbol(ADD)) {
8720 push(zero);
8721 p1 = cdr(p1);
8722 while (iscons(p1)) {
8723 push(car(p1));
8724 simplifyfactorials();
8725 add();
8726 p1 = cdr(p1);
8727 }
8728 expanding = x;
8729 restore();
8730 return;
8731 }
8732 if (car(p1) === symbol(MULTIPLY)) {
8733 sfac_product();
8734 expanding = x;
8735 restore();
8736 return;
8737 }
8738 push(p1);
8739 expanding = x;
8740 return restore();
8741 };
8742
8743 sfac_product = function() {
8744 var i, i1, j, j1, n, o, ref, ref1, ref2, ref3, s;
8745 i = 0;
8746 j = 0;
8747 n = 0;
8748 s = tos;
8749 p1 = cdr(p1);
8750 n = 0;
8751 while (iscons(p1)) {
8752 push(car(p1));
8753 p1 = cdr(p1);
8754 n++;
8755 }
8756 for (i = o = 0, ref = n - 1; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
8757 if (stack[s + i] === symbol(NIL)) {
8758 continue;
8759 }
8760 for (j = i1 = ref1 = i + 1, ref2 = n; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; j = ref1 <= ref2 ? ++i1 : --i1) {
8761 if (stack[s + j] === symbol(NIL)) {
8762 continue;
8763 }
8764 sfac_product_f(s, i, j);
8765 }
8766 }
8767 push(one);
8768 for (i = j1 = 0, ref3 = n; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
8769 if (stack[s + i] === symbol(NIL)) {
8770 continue;
8771 }
8772 push(stack[s + i]);
8773 multiply();
8774 }
8775 p1 = pop();
8776 moveTos(tos - n);
8777 return push(p1);
8778 };
8779
8780 sfac_product_f = function(s, a, b) {
8781 var i, n, o, ref;
8782 i = 0;
8783 n = 0;
8784 p1 = stack[s + a];
8785 p2 = stack[s + b];
8786 if (ispower(p1)) {
8787 p3 = caddr(p1);
8788 p1 = cadr(p1);
8789 } else {
8790 p3 = one;
8791 }
8792 if (ispower(p2)) {
8793 p4 = caddr(p2);
8794 p2 = cadr(p2);
8795 } else {
8796 p4 = one;
8797 }
8798 if (isfactorial(p1) && isfactorial(p2)) {
8799 push(p3);
8800 push(p4);
8801 add();
8802 yyexpand();
8803 n = pop_integer();
8804 if (n !== 0) {
8805 return;
8806 }
8807 push(cadr(p1));
8808 push(cadr(p2));
8809 subtract();
8810 yyexpand();
8811 n = pop_integer();
8812 if (n === 0 || isNaN(n)) {
8813 return;
8814 }
8815 if (n < 0) {
8816 n = -n;
8817 p5 = p1;
8818 p1 = p2;
8819 p2 = p5;
8820 p5 = p3;
8821 p3 = p4;
8822 p4 = p5;
8823 }
8824 push(one);
8825 for (i = o = 1, ref = n; 1 <= ref ? o <= ref : o >= ref; i = 1 <= ref ? ++o : --o) {
8826 push(cadr(p2));
8827 push_integer(i);
8828 add();
8829 push(p3);
8830 power();
8831 multiply();
8832 }
8833 stack[s + a] = pop();
8834 return stack[s + b] = symbol(NIL);
8835 }
8836 };
8837
8838 polycoeff = 0;
8839
8840 factpoly_expo = 0;
8841
8842 factorpoly = function() {
8843 save();
8844 p2 = pop();
8845 p1 = pop();
8846 if (!Find(p1, p2)) {
8847 push(p1);
8848 restore();
8849 return;
8850 }
8851 if (!ispoly(p1, p2)) {
8852 push(p1);
8853 restore();
8854 return;
8855 }
8856 if (!issymbol(p2)) {
8857 push(p1);
8858 restore();
8859 return;
8860 }
8861 push(p1);
8862 push(p2);
8863 yyfactorpoly();
8864 return restore();
8865 };
8866
8867 yyfactorpoly = function() {
8868 var checkingTheDivision, dividend, foundComplexRoot, foundRealRoot, h, i, i1, j1, l1, o, prev_expanding, previousFactorisation, ref, ref1, ref2, ref3, remainingPoly, whichRootsAreWeFinding;
8869 h = 0;
8870 i = 0;
8871 save();
8872 p2 = pop();
8873 p1 = pop();
8874 h = tos;
8875 if (isfloating(p1)) {
8876 stop("floating point numbers in polynomial");
8877 }
8878 polycoeff = tos;
8879 push(p1);
8880 push(p2);
8881 factpoly_expo = coeff() - 1;
8882 rationalize_coefficients(h);
8883 whichRootsAreWeFinding = "real";
8884 remainingPoly = null;
8885 while (factpoly_expo > 0) {
8886 if (iszero(stack[polycoeff + 0])) {
8887 push_integer(1);
8888 p4 = pop();
8889 push_integer(0);
8890 p5 = pop();
8891 } else {
8892 if (whichRootsAreWeFinding === "real") {
8893 foundRealRoot = get_factor_from_real_root();
8894 } else if (whichRootsAreWeFinding === "complex") {
8895 foundComplexRoot = get_factor_from_complex_root(remainingPoly);
8896 }
8897 }
8898 if (whichRootsAreWeFinding === "real") {
8899 if (foundRealRoot === 0) {
8900 whichRootsAreWeFinding = "complex";
8901 continue;
8902 } else {
8903 push(p4);
8904 push(p2);
8905 multiply();
8906 push(p5);
8907 add();
8908 p8 = pop();
8909 if (DEBUG) {
8910 console.log("success\nFACTOR=" + p8);
8911 }
8912
8913 /*
8914 if (isnegativeterm(p4))
8915 push(p8)
8916 negate()
8917 p8 = pop()
8918 push(p7)
8919 negate_noexpand()
8920 p7 = pop()
8921 */
8922 push(p7);
8923 push(p8);
8924 multiply_noexpand();
8925 p7 = pop();
8926 yydivpoly();
8927 while (factpoly_expo && iszero(stack[polycoeff + factpoly_expo])) {
8928 factpoly_expo--;
8929 }
8930 push(zero);
8931 for (i = o = 0, ref = factpoly_expo; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) {
8932 push(stack[polycoeff + i]);
8933 push(p2);
8934 push_integer(i);
8935 power();
8936 multiply();
8937 add();
8938 }
8939 remainingPoly = pop();
8940 }
8941 } else if (whichRootsAreWeFinding === "complex") {
8942 if (foundComplexRoot === 0) {
8943 break;
8944 } else {
8945 push(p4);
8946 push(p2);
8947 subtract();
8948 push(p4);
8949 conjugate();
8950 push(p2);
8951 subtract();
8952 multiply();
8953 p8 = pop();
8954 if (DEBUG) {
8955 console.log("success\nFACTOR=" + p8);
8956 }
8957
8958 /*
8959 if (isnegativeterm(p4))
8960 push(p8)
8961 negate()
8962 p8 = pop()
8963 push(p7)
8964 negate_noexpand()
8965 p7 = pop()
8966 */
8967 push(p7);
8968 previousFactorisation = pop();
8969 push(p7);
8970 push(p8);
8971 multiply_noexpand();
8972 p7 = pop();
8973 if (remainingPoly == null) {
8974 push(zero);
8975 for (i = i1 = 0, ref1 = factpoly_expo; 0 <= ref1 ? i1 <= ref1 : i1 >= ref1; i = 0 <= ref1 ? ++i1 : --i1) {
8976 push(stack[polycoeff + i]);
8977 push(p2);
8978 push_integer(i);
8979 power();
8980 multiply();
8981 add();
8982 }
8983 remainingPoly = pop();
8984 }
8985 dividend = remainingPoly;
8986 push(dividend);
8987 push(p8);
8988 push(p2);
8989 divpoly();
8990 remainingPoly = pop();
8991 push(remainingPoly);
8992 push(p8);
8993 multiply();
8994 checkingTheDivision = pop();
8995 if (!equal(checkingTheDivision, dividend)) {
8996 if (DEBUG) {
8997 console.log("we found a polynomial based on complex root and its conj but it doesn't divide the poly, quitting");
8998 }
8999 if (DEBUG) {
9000 console.log("so just returning previousFactorisation times dividend: " + previousFactorisation + " * " + dividend);
9001 }
9002 push(previousFactorisation);
9003 push(dividend);
9004 prev_expanding = expanding;
9005 expanding = 0;
9006 yycondense();
9007 expanding = prev_expanding;
9008 multiply_noexpand();
9009 p7 = pop();
9010 stack[h] = p7;
9011 moveTos(h + 1);
9012 restore();
9013 return;
9014 }
9015
9016 /*
9017 if compare_numbers(startingDegree, remainingDegree)
9018 * ok even if we found a complex root that
9019 * together with the conjugate generates a poly in Z,
9020 * that doesn't mean that the division would end up in Z.
9021 * Example: 1+x^2+x^4+x^6 has +i and -i as one of its roots
9022 * so a factor is 1+x^2 ( = (x+i)*(x-i))
9023 * BUT
9024 */
9025 for (i = j1 = 0, ref2 = factpoly_expo; 0 <= ref2 ? j1 <= ref2 : j1 >= ref2; i = 0 <= ref2 ? ++j1 : --j1) {
9026 pop();
9027 }
9028 push(remainingPoly);
9029 push(p2);
9030 coeff();
9031 factpoly_expo -= 2;
9032 }
9033 }
9034 }
9035 push(zero);
9036 for (i = l1 = 0, ref3 = factpoly_expo; 0 <= ref3 ? l1 <= ref3 : l1 >= ref3; i = 0 <= ref3 ? ++l1 : --l1) {
9037 push(stack[polycoeff + i]);
9038 push(p2);
9039 push_integer(i);
9040 power();
9041 multiply();
9042 add();
9043 }
9044 p1 = pop();
9045 if (DEBUG) {
9046 console.log("POLY=" + p1);
9047 }
9048 push(p1);
9049 prev_expanding = expanding;
9050 expanding = 0;
9051 yycondense();
9052 expanding = prev_expanding;
9053 p1 = pop();
9054 if (factpoly_expo > 0 && isnegativeterm(stack[polycoeff + factpoly_expo])) {
9055 push(p1);
9056 negate();
9057 p1 = pop();
9058 push(p7);
9059 negate_noexpand();
9060 p7 = pop();
9061 }
9062 push(p7);
9063 push(p1);
9064 multiply_noexpand();
9065 p7 = pop();
9066 if (DEBUG) {
9067 console.log("RESULT=" + p7);
9068 }
9069 stack[h] = p7;
9070 moveTos(h + 1);
9071 return restore();
9072 };
9073
9074 rationalize_coefficients = function(h) {
9075 var i, i1, o, ref, ref1, ref2, ref3;
9076 i = 0;
9077 p7 = one;
9078 for (i = o = ref = h, ref1 = tos; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
9079 push(stack[i]);
9080 denominator();
9081 push(p7);
9082 lcm();
9083 p7 = pop();
9084 }
9085 for (i = i1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? i1 < ref3 : i1 > ref3; i = ref2 <= ref3 ? ++i1 : --i1) {
9086 push(p7);
9087 push(stack[i]);
9088 multiply();
9089 stack[i] = pop();
9090 }
9091 push(p7);
9092 reciprocate();
9093 p7 = pop();
9094 if (DEBUG) {
9095 return console.log("rationalize_coefficients result");
9096 }
9097 };
9098
9099 get_factor_from_real_root = function() {
9100 var a0, an, h, i, i1, j, j1, l1, m1, na0, nan, o, ref, ref1, ref2, ref3, ref4, rootsTries_i, rootsTries_j;
9101 i = 0;
9102 j = 0;
9103 h = 0;
9104 a0 = 0;
9105 an = 0;
9106 na0 = 0;
9107 nan = 0;
9108 if (DEBUG) {
9109 push(zero);
9110 for (i = o = 0, ref = factpoly_expo; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) {
9111 push(stack[polycoeff + i]);
9112 push(p2);
9113 push_integer(i);
9114 power();
9115 multiply();
9116 add();
9117 }
9118 p1 = pop();
9119 console.log("POLY=" + p1);
9120 }
9121 h = tos;
9122 an = tos;
9123 push(stack[polycoeff + factpoly_expo]);
9124 divisors_onstack();
9125 nan = tos - an;
9126 a0 = tos;
9127 push(stack[polycoeff + 0]);
9128 divisors_onstack();
9129 na0 = tos - a0;
9130 if (DEBUG) {
9131 console.log("divisors of base term");
9132 for (i = i1 = 0, ref1 = na0; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
9133 console.log(", " + stack[a0 + i]);
9134 }
9135 console.log("divisors of leading term");
9136 for (i = j1 = 0, ref2 = nan; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
9137 console.log(", " + stack[an + i]);
9138 }
9139 }
9140 for (rootsTries_i = l1 = 0, ref3 = nan; 0 <= ref3 ? l1 < ref3 : l1 > ref3; rootsTries_i = 0 <= ref3 ? ++l1 : --l1) {
9141 for (rootsTries_j = m1 = 0, ref4 = na0; 0 <= ref4 ? m1 < ref4 : m1 > ref4; rootsTries_j = 0 <= ref4 ? ++m1 : --m1) {
9142 p4 = stack[an + rootsTries_i];
9143 p5 = stack[a0 + rootsTries_j];
9144 push(p5);
9145 push(p4);
9146 divide();
9147 negate();
9148 p3 = pop();
9149 Evalpoly();
9150 if (DEBUG) {
9151 console.log("try A=" + p4);
9152 console.log(", B=" + p5);
9153 console.log(", root " + p2);
9154 console.log("=-B/A=" + p3);
9155 console.log(", POLY(" + p3);
9156 console.log(")=" + p6);
9157 }
9158 if (iszero(p6)) {
9159 moveTos(h);
9160 if (DEBUG) {
9161 console.log("get_factor_from_real_root returning 1");
9162 }
9163 return 1;
9164 }
9165 push(p5);
9166 negate();
9167 p5 = pop();
9168 push(p3);
9169 negate();
9170 p3 = pop();
9171 Evalpoly();
9172 if (DEBUG) {
9173 console.log("try A=" + p4);
9174 console.log(", B=" + p5);
9175 console.log(", root " + p2);
9176 console.log("=-B/A=" + p3);
9177 console.log(", POLY(" + p3);
9178 console.log(")=" + p6);
9179 }
9180 if (iszero(p6)) {
9181 moveTos(h);
9182 if (DEBUG) {
9183 console.log("get_factor_from_real_root returning 1");
9184 }
9185 return 1;
9186 }
9187 }
9188 }
9189 moveTos(h);
9190 if (DEBUG) {
9191 console.log("get_factor_from_real_root returning 0");
9192 }
9193 return 0;
9194 };
9195
9196 get_factor_from_complex_root = function(remainingPoly) {
9197 var a0, an, h, i, i1, j, na0, nan, o, rootsTries_i, rootsTries_j;
9198 i = 0;
9199 j = 0;
9200 h = 0;
9201 a0 = 0;
9202 an = 0;
9203 na0 = 0;
9204 nan = 0;
9205 if (factpoly_expo <= 2) {
9206 if (DEBUG) {
9207 console.log("no more factoring via complex roots to be found in polynomial of degree <= 2");
9208 }
9209 return 0;
9210 }
9211 p1 = remainingPoly;
9212 if (DEBUG) {
9213 console.log("complex root finding for POLY=" + p1);
9214 }
9215 h = tos;
9216 an = tos;
9217 push_integer(-1);
9218 push_rational(2, 3);
9219 power();
9220 rect();
9221 p4 = pop();
9222 if (DEBUG) {
9223 console.log("complex root finding: trying with " + p4);
9224 }
9225 push(p4);
9226 p3 = pop();
9227 push(p3);
9228 Evalpoly();
9229 if (DEBUG) {
9230 console.log("complex root finding result: " + p6);
9231 }
9232 if (iszero(p6)) {
9233 moveTos(h);
9234 if (DEBUG) {
9235 console.log("get_factor_from_complex_root returning 1");
9236 }
9237 return 1;
9238 }
9239 push_integer(1);
9240 push_rational(2, 3);
9241 power();
9242 rect();
9243 p4 = pop();
9244 if (DEBUG) {
9245 console.log("complex root finding: trying with " + p4);
9246 }
9247 push(p4);
9248 p3 = pop();
9249 push(p3);
9250 Evalpoly();
9251 if (DEBUG) {
9252 console.log("complex root finding result: " + p6);
9253 }
9254 if (iszero(p6)) {
9255 moveTos(h);
9256 if (DEBUG) {
9257 console.log("get_factor_from_complex_root returning 1");
9258 }
9259 return 1;
9260 }
9261 for (rootsTries_i = o = -10; o <= 10; rootsTries_i = ++o) {
9262 for (rootsTries_j = i1 = 1; i1 <= 5; rootsTries_j = ++i1) {
9263 push_integer(rootsTries_i);
9264 push_integer(rootsTries_j);
9265 push(imaginaryunit);
9266 multiply();
9267 add();
9268 rect();
9269 p4 = pop();
9270 push(p4);
9271 p3 = pop();
9272 push(p3);
9273 Evalpoly();
9274 if (iszero(p6)) {
9275 moveTos(h);
9276 if (DEBUG) {
9277 console.log("found complex root: " + p6);
9278 }
9279 return 1;
9280 }
9281 }
9282 }
9283 moveTos(h);
9284 if (DEBUG) {
9285 console.log("get_factor_from_complex_root returning 0");
9286 }
9287 return 0;
9288 };
9289
9290 yydivpoly = function() {
9291 var i, o, ref;
9292 i = 0;
9293 p6 = zero;
9294 for (i = o = ref = factpoly_expo; ref <= 0 ? o < 0 : o > 0; i = ref <= 0 ? ++o : --o) {
9295 push(stack[polycoeff + i]);
9296 stack[polycoeff + i] = p6;
9297 push(p4);
9298 divide();
9299 p6 = pop();
9300 push(stack[polycoeff + i - 1]);
9301 push(p6);
9302 push(p5);
9303 multiply();
9304 subtract();
9305 stack[polycoeff + i - 1] = pop();
9306 }
9307 stack[polycoeff + 0] = p6;
9308 if (DEBUG) {
9309 return console.log("yydivpoly Q:");
9310 }
9311 };
9312
9313 Evalpoly = function() {
9314 var i, o, ref;
9315 i = 0;
9316 push(zero);
9317 for (i = o = ref = factpoly_expo; ref <= 0 ? o <= 0 : o >= 0; i = ref <= 0 ? ++o : --o) {
9318 push(p3);
9319 multiply();
9320 push(stack[polycoeff + i]);
9321 if (DEBUG) {
9322 console.log("Evalpoly top of stack:");
9323 console.log(print_list(stack[tos - i]));
9324 }
9325 add();
9326 }
9327 return p6 = pop();
9328 };
9329
9330 factors = function(p) {
9331 var h;
9332 h = tos;
9333 if (car(p) === symbol(ADD)) {
9334 p = cdr(p);
9335 while (iscons(p)) {
9336 push_term_factors(car(p));
9337 p = cdr(p);
9338 }
9339 } else {
9340 push_term_factors(p);
9341 }
9342 return tos - h;
9343 };
9344
9345 push_term_factors = function(p) {
9346 var results;
9347 if (car(p) === symbol(MULTIPLY)) {
9348 p = cdr(p);
9349 results = [];
9350 while (iscons(p)) {
9351 push(car(p));
9352 results.push(p = cdr(p));
9353 }
9354 return results;
9355 } else {
9356 return push(p);
9357 }
9358 };
9359
9360
9361 /*
9362 Remove terms that involve a given symbol or expression. For example...
9363
9364 filter(x^2 + x + 1, x) => 1
9365
9366 filter(x^2 + x + 1, x^2) => x + 1
9367 */
9368
9369 Eval_filter = function() {
9370 var results;
9371 p1 = cdr(p1);
9372 push(car(p1));
9373 Eval();
9374 p1 = cdr(p1);
9375 results = [];
9376 while (iscons(p1)) {
9377 push(car(p1));
9378 Eval();
9379 filter();
9380 results.push(p1 = cdr(p1));
9381 }
9382 return results;
9383 };
9384
9385
9386 /*
9387 For example...
9388
9389 push(F)
9390 push(X)
9391 filter()
9392 F = pop()
9393 */
9394
9395 filter = function() {
9396 save();
9397 p2 = pop();
9398 p1 = pop();
9399 filter_main();
9400 return restore();
9401 };
9402
9403 filter_main = function() {
9404 if (car(p1) === symbol(ADD)) {
9405 return filter_sum();
9406 } else if (istensor(p1)) {
9407 return filter_tensor();
9408 } else if (Find(p1, p2)) {
9409 return push_integer(0);
9410 } else {
9411 return push(p1);
9412 }
9413 };
9414
9415 filter_sum = function() {
9416 var results;
9417 push_integer(0);
9418 p1 = cdr(p1);
9419 results = [];
9420 while (iscons(p1)) {
9421 push(car(p1));
9422 push(p2);
9423 filter();
9424 add();
9425 results.push(p1 = cdr(p1));
9426 }
9427 return results;
9428 };
9429
9430 filter_tensor = function() {
9431 var i, i1, n, o, ref, ref1;
9432 i = 0;
9433 n = 0;
9434 n = p1.tensor.nelem;
9435 p3 = alloc_tensor(n);
9436 p3.tensor.ndim = p1.tensor.ndim;
9437 for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
9438 p3.tensor.dim[i] = p1.tensor.dim[i];
9439 }
9440 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
9441 push(p1.tensor.elem[i]);
9442 push(p2);
9443 filter();
9444 p3.tensor.elem[i] = pop();
9445 }
9446 return push(p3);
9447 };
9448
9449 Eval_float = function() {
9450 evaluatingAsFloats++;
9451 push(cadr(p1));
9452 Eval();
9453 yyfloat();
9454 Eval();
9455 return evaluatingAsFloats--;
9456 };
9457
9458 checkFloatHasWorkedOutCompletely = function(nodeToCheck) {
9459 var numberOfEs, numberOfMults, numberOfPIs, numberOfPowers, numberOfSums;
9460 numberOfPowers = countOccurrencesOfSymbol(symbol(POWER), nodeToCheck);
9461 numberOfPIs = countOccurrencesOfSymbol(symbol(PI), nodeToCheck);
9462 numberOfEs = countOccurrencesOfSymbol(symbol(E), nodeToCheck);
9463 numberOfMults = countOccurrencesOfSymbol(symbol(MULTIPLY), nodeToCheck);
9464 numberOfSums = countOccurrencesOfSymbol(symbol(ADD), nodeToCheck);
9465 if (DEBUG) {
9466 console.log(" ... numberOfPowers: " + numberOfPowers);
9467 console.log(" ... numberOfPIs: " + numberOfPIs);
9468 console.log(" ... numberOfEs: " + numberOfEs);
9469 console.log(" ... numberOfMults: " + numberOfMults);
9470 console.log(" ... numberOfSums: " + numberOfSums);
9471 }
9472 if (numberOfPowers > 1 || numberOfPIs > 0 || numberOfEs > 0 || numberOfMults > 1 || numberOfSums > 1) {
9473 return stop("float: some unevalued parts in " + nodeToCheck);
9474 }
9475 };
9476
9477 zzfloat = function() {
9478 save();
9479 evaluatingAsFloats++;
9480 Eval();
9481 yyfloat();
9482 Eval();
9483 evaluatingAsFloats--;
9484 return restore();
9485 };
9486
9487 yyfloat = function() {
9488 var h, i, o, ref;
9489 i = 0;
9490 h = 0;
9491 evaluatingAsFloats++;
9492 save();
9493 p1 = pop();
9494 if (iscons(p1)) {
9495 h = tos;
9496 while (iscons(p1)) {
9497 push(car(p1));
9498 yyfloat();
9499 p1 = cdr(p1);
9500 }
9501 list(tos - h);
9502 } else if (p1.k === TENSOR) {
9503 push(p1);
9504 copy_tensor();
9505 p1 = pop();
9506 for (i = o = 0, ref = p1.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
9507 push(p1.tensor.elem[i]);
9508 yyfloat();
9509 p1.tensor.elem[i] = pop();
9510 }
9511 push(p1);
9512 } else if (p1.k === NUM) {
9513 push(p1);
9514 bignum_float();
9515 } else if (p1 === symbol(PI)) {
9516 push_double(Math.PI);
9517 } else if (p1 === symbol(E)) {
9518 push_double(Math.E);
9519 } else {
9520 push(p1);
9521 }
9522 restore();
9523 return evaluatingAsFloats--;
9524 };
9525
9526 Eval_floor = function() {
9527 push(cadr(p1));
9528 Eval();
9529 return yfloor();
9530 };
9531
9532 yfloor = function() {
9533 save();
9534 yyfloor();
9535 return restore();
9536 };
9537
9538 yyfloor = function() {
9539 var d;
9540 d = 0.0;
9541 p1 = pop();
9542 if (!isnum(p1)) {
9543 push_symbol(FLOOR);
9544 push(p1);
9545 list(2);
9546 return;
9547 }
9548 if (isdouble(p1)) {
9549 d = Math.floor(p1.d);
9550 push_double(d);
9551 return;
9552 }
9553 if (isinteger(p1)) {
9554 push(p1);
9555 return;
9556 }
9557 p3 = new U();
9558 p3.k = NUM;
9559 p3.q.a = mdiv(p1.q.a, p1.q.b);
9560 p3.q.b = mint(1);
9561 push(p3);
9562 if (isnegativenumber(p1)) {
9563 push_integer(-1);
9564 return add();
9565 }
9566 };
9567
9568
9569 /*
9570 x=0
9571 y=2
9572 for(do(x=sqrt(2+x),y=2*y/x),k,1,9)
9573 float(y)
9574
9575 X: k
9576 B: 1...9
9577
9578 1st parameter is the body
9579 2nd parameter is the variable to loop with
9580 3rd and 4th are the limits
9581 */
9582
9583 Eval_for = function() {
9584 var i, j, k, loopingVariable, o, ref, ref1;
9585 i = 0;
9586 j = 0;
9587 k = 0;
9588 loopingVariable = caddr(p1);
9589 if (!issymbol(loopingVariable)) {
9590 stop("for: 2nd arg should be the variable to loop over");
9591 }
9592 push(cadddr(p1));
9593 Eval();
9594 j = pop_integer();
9595 if (isNaN(j)) {
9596 push(p1);
9597 return;
9598 }
9599 push(caddddr(p1));
9600 Eval();
9601 k = pop_integer();
9602 if (isNaN(k)) {
9603 push(p1);
9604 return;
9605 }
9606 p4 = get_binding(loopingVariable);
9607 for (i = o = ref = j, ref1 = k; ref <= ref1 ? o <= ref1 : o >= ref1; i = ref <= ref1 ? ++o : --o) {
9608 push_integer(i);
9609 p5 = pop();
9610 set_binding(loopingVariable, p5);
9611 push(cadr(p1));
9612 Eval();
9613 pop();
9614 }
9615 set_binding(loopingVariable, p4);
9616 return push_symbol(NIL);
9617 };
9618
9619 Eval_gamma = function() {
9620 push(cadr(p1));
9621 Eval();
9622 return gamma();
9623 };
9624
9625 gamma = function() {
9626 save();
9627 gammaf();
9628 return restore();
9629 };
9630
9631 gammaf = function() {
9632 p1 = pop();
9633 if (isrational(p1) && MEQUAL(p1.q.a, 1) && MEQUAL(p1.q.b, 2)) {
9634 if (evaluatingAsFloats) {
9635 push_double(Math.PI);
9636 } else {
9637 push_symbol(PI);
9638 }
9639 push_rational(1, 2);
9640 power();
9641 return;
9642 }
9643 if (isrational(p1) && MEQUAL(p1.q.a, 3) && MEQUAL(p1.q.b, 2)) {
9644 if (evaluatingAsFloats) {
9645 push_double(Math.PI);
9646 } else {
9647 push_symbol(PI);
9648 }
9649 push_rational(1, 2);
9650 power();
9651 push_rational(1, 2);
9652 multiply();
9653 return;
9654 }
9655 if (isnegativeterm(p1)) {
9656 if (evaluatingAsFloats) {
9657 push_double(Math.PI);
9658 } else {
9659 push_symbol(PI);
9660 }
9661 push_integer(-1);
9662 multiply();
9663 if (evaluatingAsFloats) {
9664 push_double(Math.PI);
9665 } else {
9666 push_symbol(PI);
9667 }
9668 push(p1);
9669 multiply();
9670 sine();
9671 push(p1);
9672 multiply();
9673 push(p1);
9674 negate();
9675 gamma();
9676 multiply();
9677 divide();
9678 return;
9679 }
9680 if (car(p1) === symbol(ADD)) {
9681 gamma_of_sum();
9682 return;
9683 }
9684 push_symbol(GAMMA);
9685 push(p1);
9686 list(2);
9687 };
9688
9689 gamma_of_sum = function() {
9690 p3 = cdr(p1);
9691 if (isrational(car(p3)) && MEQUAL(car(p3).q.a, 1) && MEQUAL(car(p3).q.b, 1)) {
9692 push(cadr(p3));
9693 push(cadr(p3));
9694 gamma();
9695 return multiply();
9696 } else {
9697 if (isrational(car(p3)) && MEQUAL(car(p3).q.a, -1) && MEQUAL(car(p3).q.b, 1)) {
9698 push(cadr(p3));
9699 gamma();
9700 push(cadr(p3));
9701 push_integer(-1);
9702 add();
9703 return divide();
9704 } else {
9705 push_symbol(GAMMA);
9706 push(p1);
9707 list(2);
9708 }
9709 }
9710 };
9711
9712 Eval_gcd = function() {
9713 var results;
9714 p1 = cdr(p1);
9715 push(car(p1));
9716 Eval();
9717 p1 = cdr(p1);
9718 results = [];
9719 while (iscons(p1)) {
9720 push(car(p1));
9721 Eval();
9722 gcd();
9723 results.push(p1 = cdr(p1));
9724 }
9725 return results;
9726 };
9727
9728 gcd = function() {
9729 var prev_expanding;
9730 prev_expanding = expanding;
9731 save();
9732 gcd_main();
9733 restore();
9734 return expanding = prev_expanding;
9735 };
9736
9737 gcd_main = function() {
9738 expanding = 1;
9739 p2 = pop();
9740 p1 = pop();
9741 if (equal(p1, p2)) {
9742 push(p1);
9743 return;
9744 }
9745 if (isrational(p1) && isrational(p2)) {
9746 push(p1);
9747 push(p2);
9748 gcd_numbers();
9749 return;
9750 }
9751 if (car(p1) === symbol(ADD) && car(p2) === symbol(ADD)) {
9752 gcd_expr_expr();
9753 return;
9754 }
9755 if (car(p1) === symbol(ADD)) {
9756 gcd_expr(p1);
9757 p1 = pop();
9758 }
9759 if (car(p2) === symbol(ADD)) {
9760 gcd_expr(p2);
9761 p2 = pop();
9762 }
9763 if (car(p1) === symbol(MULTIPLY) && car(p2) === symbol(MULTIPLY)) {
9764 gcd_term_term();
9765 return;
9766 }
9767 if (car(p1) === symbol(MULTIPLY)) {
9768 gcd_term_factor();
9769 return;
9770 }
9771 if (car(p2) === symbol(MULTIPLY)) {
9772 gcd_factor_term();
9773 return;
9774 }
9775 if (car(p1) === symbol(POWER)) {
9776 p3 = caddr(p1);
9777 p1 = cadr(p1);
9778 } else {
9779 p3 = one;
9780 }
9781 if (car(p2) === symbol(POWER)) {
9782 p4 = caddr(p2);
9783 p2 = cadr(p2);
9784 } else {
9785 p4 = one;
9786 }
9787 if (!equal(p1, p2)) {
9788 push(one);
9789 return;
9790 }
9791 if (isnum(p3) && isnum(p4)) {
9792 push(p1);
9793 if (lessp(p3, p4)) {
9794 push(p3);
9795 } else {
9796 push(p4);
9797 }
9798 power();
9799 return;
9800 }
9801 push(p3);
9802 push(p4);
9803 divide();
9804 p5 = pop();
9805 if (isnum(p5)) {
9806 push(p1);
9807 if (car(p3) === symbol(MULTIPLY) && isnum(cadr(p3))) {
9808 p5 = cadr(p3);
9809 } else {
9810 p5 = one;
9811 }
9812 if (car(p4) === symbol(MULTIPLY) && isnum(cadr(p4))) {
9813 p6 = cadr(p4);
9814 } else {
9815 p6 = one;
9816 }
9817 if (lessp(p5, p6)) {
9818 push(p3);
9819 } else {
9820 push(p4);
9821 }
9822 power();
9823 return;
9824 }
9825 push(p3);
9826 push(p4);
9827 subtract();
9828 p5 = pop();
9829 if (!isnum(p5)) {
9830 push(one);
9831 return;
9832 }
9833 push(p1);
9834 if (isnegativenumber(p5)) {
9835 push(p3);
9836 } else {
9837 push(p4);
9838 }
9839 return power();
9840 };
9841
9842 gcd_expr_expr = function() {
9843 if (length(p1) !== length(p2)) {
9844 push(one);
9845 return;
9846 }
9847 p3 = cdr(p1);
9848 push(car(p3));
9849 p3 = cdr(p3);
9850 while (iscons(p3)) {
9851 push(car(p3));
9852 gcd();
9853 p3 = cdr(p3);
9854 }
9855 p3 = pop();
9856 p4 = cdr(p2);
9857 push(car(p4));
9858 p4 = cdr(p4);
9859 while (iscons(p4)) {
9860 push(car(p4));
9861 gcd();
9862 p4 = cdr(p4);
9863 }
9864 p4 = pop();
9865 push(p1);
9866 push(p3);
9867 divide();
9868 p5 = pop();
9869 push(p2);
9870 push(p4);
9871 divide();
9872 p6 = pop();
9873 if (equal(p5, p6)) {
9874 push(p5);
9875 push(p3);
9876 push(p4);
9877 gcd();
9878 return multiply();
9879 } else {
9880 return push(one);
9881 }
9882 };
9883
9884 gcd_expr = function(p) {
9885 var results;
9886 p = cdr(p);
9887 push(car(p));
9888 p = cdr(p);
9889 results = [];
9890 while (iscons(p)) {
9891 push(car(p));
9892 gcd();
9893 results.push(p = cdr(p));
9894 }
9895 return results;
9896 };
9897
9898 gcd_term_term = function() {
9899 var results;
9900 push(one);
9901 p3 = cdr(p1);
9902 results = [];
9903 while (iscons(p3)) {
9904 p4 = cdr(p2);
9905 while (iscons(p4)) {
9906 push(car(p3));
9907 push(car(p4));
9908 gcd();
9909 multiply();
9910 p4 = cdr(p4);
9911 }
9912 results.push(p3 = cdr(p3));
9913 }
9914 return results;
9915 };
9916
9917 gcd_term_factor = function() {
9918 var results;
9919 push(one);
9920 p3 = cdr(p1);
9921 results = [];
9922 while (iscons(p3)) {
9923 push(car(p3));
9924 push(p2);
9925 gcd();
9926 multiply();
9927 results.push(p3 = cdr(p3));
9928 }
9929 return results;
9930 };
9931
9932 gcd_factor_term = function() {
9933 var results;
9934 push(one);
9935 p4 = cdr(p2);
9936 results = [];
9937 while (iscons(p4)) {
9938 push(p1);
9939 push(car(p4));
9940 gcd();
9941 multiply();
9942 results.push(p4 = cdr(p4));
9943 }
9944 return results;
9945 };
9946
9947 guess = function() {
9948 var p;
9949 p = pop();
9950 push(p);
9951 if (Find(p, symbol(SYMBOL_X))) {
9952 return push_symbol(SYMBOL_X);
9953 } else if (Find(p, symbol(SYMBOL_Y))) {
9954 return push_symbol(SYMBOL_Y);
9955 } else if (Find(p, symbol(SYMBOL_Z))) {
9956 return push_symbol(SYMBOL_Z);
9957 } else if (Find(p, symbol(SYMBOL_T))) {
9958 return push_symbol(SYMBOL_T);
9959 } else if (Find(p, symbol(SYMBOL_S))) {
9960 return push_symbol(SYMBOL_S);
9961 } else {
9962 return push_symbol(SYMBOL_X);
9963 }
9964 };
9965
9966 hermite = function() {
9967 save();
9968 yyhermite();
9969 return restore();
9970 };
9971
9972 yyhermite = function() {
9973 var n;
9974 n = 0;
9975 p2 = pop();
9976 p1 = pop();
9977 push(p2);
9978 n = pop_integer();
9979 if (n < 0 || isNaN(n)) {
9980 push_symbol(HERMITE);
9981 push(p1);
9982 push(p2);
9983 list(3);
9984 return;
9985 }
9986 if (issymbol(p1)) {
9987 return yyhermite2(n);
9988 } else {
9989 p3 = p1;
9990 p1 = symbol(SECRETX);
9991 yyhermite2(n);
9992 p1 = p3;
9993 push(symbol(SECRETX));
9994 push(p1);
9995 subst();
9996 return Eval();
9997 }
9998 };
9999
10000 yyhermite2 = function(n) {
10001 var i, o, ref, results;
10002 i = 0;
10003 push_integer(1);
10004 push_integer(0);
10005 p4 = pop();
10006 results = [];
10007 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10008 p5 = p4;
10009 p4 = pop();
10010 push(p1);
10011 push(p4);
10012 multiply();
10013 push_integer(i);
10014 push(p5);
10015 multiply();
10016 subtract();
10017 push_integer(2);
10018 results.push(multiply());
10019 }
10020 return results;
10021 };
10022
10023 hilbert = function() {
10024 var i, i1, j, n, o, ref, ref1;
10025 i = 0;
10026 j = 0;
10027 n = 0;
10028 save();
10029 p2 = pop();
10030 push(p2);
10031 n = pop_integer();
10032 if (n < 2) {
10033 push_symbol(HILBERT);
10034 push(p2);
10035 list(2);
10036 restore();
10037 return;
10038 }
10039 push_zero_matrix(n, n);
10040 p1 = pop();
10041 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10042 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
10043 push_integer(i + j + 1);
10044 inverse();
10045 p1.tensor.elem[i * n + j] = pop();
10046 }
10047 }
10048 push(p1);
10049 return restore();
10050 };
10051
10052
10053 /*
10054 Returns the coefficient of the imaginary part of complex z
10055
10056 z imag(z)
10057 - -------
10058
10059 a + i b b
10060
10061 exp(i a) sin(a)
10062 */
10063
10064 DEBUG_IMAG = false;
10065
10066 Eval_imag = function() {
10067 push(cadr(p1));
10068 Eval();
10069 return imag();
10070 };
10071
10072 imag = function() {
10073 save();
10074 rect();
10075 p1 = pop();
10076 if (DEBUG_IMAG) {
10077 console.log("IMAGE of " + p1);
10078 }
10079 push(p1);
10080 push(p1);
10081 conjugate();
10082 if (DEBUG_IMAG) {
10083 console.log(" image: conjugate result: " + stack[tos - 1]);
10084 }
10085 subtract();
10086 push_integer(2);
10087 divide();
10088 if (DEBUG_IMAG) {
10089 console.log(" image: 1st divide result: " + stack[tos - 1]);
10090 }
10091 push(imaginaryunit);
10092 divide();
10093 if (DEBUG_IMAG) {
10094 console.log(" image: 2nd divide result: " + stack[tos - 1]);
10095 }
10096 return restore();
10097 };
10098
10099 index_function = function(n) {
10100 var i, i1, j1, k, l1, m, m1, ndim, nelem, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, s, t;
10101 i = 0;
10102 k = 0;
10103 m = 0;
10104 ndim = 0;
10105 nelem = 0;
10106 t = 0;
10107 save();
10108 s = tos - n;
10109 p1 = stack[s];
10110 ndim = p1.tensor.ndim;
10111 m = n - 1;
10112 if (m > ndim) {
10113 stop("too many indices for tensor");
10114 }
10115 k = 0;
10116 for (i = o = 0, ref = m; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10117 push(stack[s + i + 1]);
10118 t = pop_integer();
10119 if (t < 1 || t > p1.tensor.dim[i]) {
10120 stop("index out of range");
10121 }
10122 k = k * p1.tensor.dim[i] + t - 1;
10123 }
10124 if (ndim === m) {
10125 moveTos(tos - n);
10126 push(p1.tensor.elem[k]);
10127 restore();
10128 return;
10129 }
10130 for (i = i1 = ref1 = m, ref2 = ndim; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
10131 k = k * p1.tensor.dim[i] + 0;
10132 }
10133 nelem = 1;
10134 for (i = j1 = ref3 = m, ref4 = ndim; ref3 <= ref4 ? j1 < ref4 : j1 > ref4; i = ref3 <= ref4 ? ++j1 : --j1) {
10135 nelem *= p1.tensor.dim[i];
10136 }
10137 p2 = alloc_tensor(nelem);
10138 p2.tensor.ndim = ndim - m;
10139 for (i = l1 = ref5 = m, ref6 = ndim; ref5 <= ref6 ? l1 < ref6 : l1 > ref6; i = ref5 <= ref6 ? ++l1 : --l1) {
10140 p2.tensor.dim[i - m] = p1.tensor.dim[i];
10141 }
10142 for (i = m1 = 0, ref7 = nelem; 0 <= ref7 ? m1 < ref7 : m1 > ref7; i = 0 <= ref7 ? ++m1 : --m1) {
10143 p2.tensor.elem[i] = p1.tensor.elem[k + i];
10144 }
10145 check_tensor_dimensions(p1);
10146 check_tensor_dimensions(p2);
10147 moveTos(tos - n);
10148 push(p2);
10149 return restore();
10150 };
10151
10152 set_component = function(n) {
10153 var i, i1, j1, k, l1, m, m1, n1, ndim, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, s, t;
10154 i = 0;
10155 k = 0;
10156 m = 0;
10157 ndim = 0;
10158 t = 0;
10159 save();
10160 if (n < 3) {
10161 stop("error in indexed assign");
10162 }
10163 s = tos - n;
10164 p2 = stack[s];
10165 p1 = stack[s + 1];
10166 if (!istensor(p1)) {
10167 stop("error in indexed assign");
10168 }
10169 ndim = p1.tensor.ndim;
10170 m = n - 2;
10171 if (m > ndim) {
10172 stop("error in indexed assign");
10173 }
10174 k = 0;
10175 for (i = o = 0, ref = m; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10176 push(stack[s + i + 2]);
10177 t = pop_integer();
10178 if (t < 1 || t > p1.tensor.dim[i]) {
10179 stop("error in indexed assign\n");
10180 }
10181 k = k * p1.tensor.dim[i] + t - 1;
10182 }
10183 for (i = i1 = ref1 = m, ref2 = ndim; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
10184 k = k * p1.tensor.dim[i] + 0;
10185 }
10186 p3 = alloc_tensor(p1.tensor.nelem);
10187 p3.tensor.ndim = p1.tensor.ndim;
10188 for (i = j1 = 0, ref3 = p1.tensor.ndim; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
10189 p3.tensor.dim[i] = p1.tensor.dim[i];
10190 }
10191 for (i = l1 = 0, ref4 = p1.tensor.nelem; 0 <= ref4 ? l1 < ref4 : l1 > ref4; i = 0 <= ref4 ? ++l1 : --l1) {
10192 p3.tensor.elem[i] = p1.tensor.elem[i];
10193 }
10194 check_tensor_dimensions(p1);
10195 check_tensor_dimensions(p3);
10196 p1 = p3;
10197 if (ndim === m) {
10198 if (istensor(p2)) {
10199 stop("error in indexed assign");
10200 }
10201 p1.tensor.elem[k] = p2;
10202 check_tensor_dimensions(p1);
10203 moveTos(tos - n);
10204 push(p1);
10205 restore();
10206 return;
10207 }
10208 if (!istensor(p2)) {
10209 stop("error in indexed assign");
10210 }
10211 if (ndim - m !== p2.tensor.ndim) {
10212 stop("error in indexed assign");
10213 }
10214 for (i = m1 = 0, ref5 = p2.tensor.ndim; 0 <= ref5 ? m1 < ref5 : m1 > ref5; i = 0 <= ref5 ? ++m1 : --m1) {
10215 if (p1.tensor.dim[m + i] !== p2.tensor.dim[i]) {
10216 stop("error in indexed assign");
10217 }
10218 }
10219 for (i = n1 = 0, ref6 = p2.tensor.nelem; 0 <= ref6 ? n1 < ref6 : n1 > ref6; i = 0 <= ref6 ? ++n1 : --n1) {
10220 p1.tensor.elem[k + i] = p2.tensor.elem[i];
10221 }
10222 check_tensor_dimensions(p1);
10223 check_tensor_dimensions(p2);
10224 moveTos(tos - n);
10225 push(p1);
10226 return restore();
10227 };
10228
10229
10230 /* dot =====================================================================
10231
10232 Tags
10233 ----
10234 scripting, JS, internal, treenode, general concept
10235
10236 Parameters
10237 ----------
10238 a,b,...
10239
10240 General description
10241 -------------------
10242
10243 The inner (or dot) operator gives products of vectors,
10244 matrices, and tensors.
10245
10246 Note that for Algebrite, the elements of a vector/matrix
10247 can only be scalars. This allows for example to flesh out
10248 matrix multiplication using the usual multiplication.
10249 So for example block-representations are not allowed.
10250
10251 There is an aweful lot of confusion between sw packages on
10252 what dot and inner do.
10253
10254 First off, the "dot" operator is different from the
10255 mathematical notion of dot product, which can be
10256 slightly confusing.
10257
10258 The mathematical notion of dot product is here:
10259 http://mathworld.wolfram.com/DotProduct.html
10260
10261 However, "dot" does that and a bunch of other things,
10262 i.e. in Algebrite
10263 dot/inner does what the dot of Mathematica does, i.e.:
10264
10265 scalar product of vectors:
10266
10267 inner((a, b, c), (x, y, z))
10268 > a x + b y + c z
10269
10270 products of matrices and vectors:
10271
10272 inner(((a, b), (c,d)), (x, y))
10273 > (a x + b y,c x + d y)
10274
10275 inner((x, y), ((a, b), (c,d)))
10276 > (a x + c y,b x + d y)
10277
10278 inner((x, y), ((a, b), (c,d)), (r, s))
10279 > a r x + b s x + c r y + d s y
10280
10281 matrix product:
10282
10283 inner(((a,b),(c,d)),((r,s),(t,u)))
10284 > ((a r + b t,a s + b u),(c r + d t,c s + d u))
10285
10286 the "dot/inner" operator is associative and
10287 distributive but not commutative.
10288
10289 In Mathematica, Inner is a generalisation of Dot where
10290 the user can specify the multiplication and the addition
10291 operators.
10292 But here in Algebrite they do the same thing.
10293
10294 https://reference.wolfram.com/language/ref/Dot.html
10295 https://reference.wolfram.com/language/ref/Inner.html
10296
10297 http://uk.mathworks.com/help/matlab/ref/dot.html
10298 http://uk.mathworks.com/help/matlab/ref/mtimes.html
10299 */
10300
10301 Eval_inner = function() {
10302 var difference, i, i1, j1, l1, moretheArguments, o, operands, ref, ref1, ref2, ref3, refinedOperands, results, secondArgument, shift, theArguments;
10303 theArguments = [];
10304 theArguments.push(car(cdr(p1)));
10305 secondArgument = car(cdr(cdr(p1)));
10306 if (secondArgument === symbol(NIL)) {
10307 stop("pattern needs at least a template and a transformed version");
10308 }
10309 moretheArguments = cdr(cdr(p1));
10310 while (moretheArguments !== symbol(NIL)) {
10311 theArguments.push(car(moretheArguments));
10312 moretheArguments = cdr(moretheArguments);
10313 }
10314 if (theArguments.length > 2) {
10315 push_symbol(INNER);
10316 push(theArguments[theArguments.length - 2]);
10317 push(theArguments[theArguments.length - 1]);
10318 list(3);
10319 for (i = o = 2, ref = theArguments.length; 2 <= ref ? o < ref : o > ref; i = 2 <= ref ? ++o : --o) {
10320 push_symbol(INNER);
10321 swap();
10322 push(theArguments[theArguments.length - i - 1]);
10323 swap();
10324 list(3);
10325 }
10326 p1 = pop();
10327 Eval_inner();
10328 return;
10329 }
10330 operands = [];
10331 get_innerprod_factors(p1, operands);
10332 refinedOperands = [];
10333 for (i = i1 = 0, ref1 = operands.length; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
10334 if (operands[i] === symbol(SYMBOL_IDENTITY_MATRIX)) {
10335 continue;
10336 } else {
10337 refinedOperands.push(operands[i]);
10338 }
10339 }
10340 operands = refinedOperands;
10341 refinedOperands = [];
10342 if (operands.length > 1) {
10343 shift = 0;
10344 for (i = j1 = 0, ref2 = operands.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
10345 if ((i + shift + 1) <= (operands.length - 1)) {
10346 if (!(isnumerictensor(operands[i + shift]) || isnumerictensor(operands[i + shift + 1]))) {
10347 push(operands[i + shift]);
10348 Eval();
10349 inv();
10350 push(operands[i + shift + 1]);
10351 Eval();
10352 subtract();
10353 difference = pop();
10354 if (iszero(difference)) {
10355 shift += 1;
10356 } else {
10357 refinedOperands.push(operands[i + shift]);
10358 }
10359 } else {
10360 refinedOperands.push(operands[i + shift]);
10361 }
10362 } else {
10363 break;
10364 }
10365 if (i + shift === operands.length - 2) {
10366 refinedOperands.push(operands[operands.length - 1]);
10367 }
10368 if (i + shift >= operands.length - 1) {
10369 break;
10370 }
10371 }
10372 operands = refinedOperands;
10373 }
10374 push(symbol(INNER));
10375 if (operands.length > 0) {
10376 for (i = l1 = 0, ref3 = operands.length; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
10377 push(operands[i]);
10378 }
10379 } else {
10380 pop();
10381 push(symbol(SYMBOL_IDENTITY_MATRIX));
10382 return;
10383 }
10384 list(operands.length + 1);
10385 p1 = pop();
10386 p1 = cdr(p1);
10387 push(car(p1));
10388 Eval();
10389 p1 = cdr(p1);
10390 results = [];
10391 while (iscons(p1)) {
10392 push(car(p1));
10393 Eval();
10394 inner();
10395 results.push(p1 = cdr(p1));
10396 }
10397 return results;
10398 };
10399
10400 inner = function() {
10401 var arg1, arg2, arg3, subtractionResult;
10402 save();
10403 p2 = pop();
10404 p1 = pop();
10405 if (isnegativeterm(p2) && isnegativeterm(p1)) {
10406 push(p2);
10407 negate();
10408 p2 = pop();
10409 push(p1);
10410 negate();
10411 p1 = pop();
10412 }
10413 if (isinnerordot(p1)) {
10414 arg1 = car(cdr(p1));
10415 arg2 = car(cdr(cdr(p1)));
10416 arg3 = p2;
10417 p1 = arg1;
10418 push(arg2);
10419 push(arg3);
10420 inner();
10421 p2 = pop();
10422 }
10423 if (p1 === symbol(SYMBOL_IDENTITY_MATRIX)) {
10424 push(p2);
10425 restore();
10426 return;
10427 } else if (p2 === symbol(SYMBOL_IDENTITY_MATRIX)) {
10428 push(p1);
10429 restore();
10430 return;
10431 }
10432 if (istensor(p1) && istensor(p2)) {
10433 inner_f();
10434 } else {
10435 if (!(isnumerictensor(p1) || isnumerictensor(p2))) {
10436 push(p1);
10437 push(p2);
10438 inv();
10439 subtract();
10440 subtractionResult = pop();
10441 if (iszero(subtractionResult)) {
10442 push_symbol(SYMBOL_IDENTITY_MATRIX);
10443 restore();
10444 return;
10445 }
10446 }
10447 if (expanding && isadd(p1)) {
10448 p1 = cdr(p1);
10449 push(zero);
10450 while (iscons(p1)) {
10451 push(car(p1));
10452 push(p2);
10453 inner();
10454 add();
10455 p1 = cdr(p1);
10456 }
10457 restore();
10458 return;
10459 }
10460 if (expanding && isadd(p2)) {
10461 p2 = cdr(p2);
10462 push(zero);
10463 while (iscons(p2)) {
10464 push(p1);
10465 push(car(p2));
10466 inner();
10467 add();
10468 p2 = cdr(p2);
10469 }
10470 restore();
10471 return;
10472 }
10473 push(p1);
10474 push(p2);
10475 if (istensor(p1) && isnum(p2)) {
10476 tensor_times_scalar();
10477 } else if (isnum(p1) && istensor(p2)) {
10478 scalar_times_tensor();
10479 } else {
10480 if (isnum(p1) || isnum(p2)) {
10481 multiply();
10482 } else {
10483 pop();
10484 pop();
10485 push_symbol(INNER);
10486 push(p1);
10487 push(p2);
10488 list(3);
10489 restore();
10490 return;
10491 }
10492 }
10493 }
10494 return restore();
10495 };
10496
10497 inner_f = function() {
10498 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;
10499 i = 0;
10500 n = p1.tensor.dim[p1.tensor.ndim - 1];
10501 if (n !== p2.tensor.dim[0]) {
10502 debugger;
10503 stop("inner: tensor dimension check");
10504 }
10505 ndim = p1.tensor.ndim + p2.tensor.ndim - 2;
10506 if (ndim > MAXDIM) {
10507 stop("inner: rank of result exceeds maximum");
10508 }
10509 a = p1.tensor.elem;
10510 b = p2.tensor.elem;
10511 ak = 1;
10512 for (i = o = 0, ref = p1.tensor.ndim - 1; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10513 ak *= p1.tensor.dim[i];
10514 }
10515 bk = 1;
10516 for (i = i1 = 1, ref1 = p2.tensor.ndim; 1 <= ref1 ? i1 < ref1 : i1 > ref1; i = 1 <= ref1 ? ++i1 : --i1) {
10517 bk *= p2.tensor.dim[i];
10518 }
10519 p3 = alloc_tensor(ak * bk);
10520 c = p3.tensor.elem;
10521 for (i = j1 = 0, ref2 = ak; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
10522 for (j = l1 = 0, ref3 = n; 0 <= ref3 ? l1 < ref3 : l1 > ref3; j = 0 <= ref3 ? ++l1 : --l1) {
10523 if (iszero(a[i * n + j])) {
10524 continue;
10525 }
10526 for (k = m1 = 0, ref4 = bk; 0 <= ref4 ? m1 < ref4 : m1 > ref4; k = 0 <= ref4 ? ++m1 : --m1) {
10527 push(a[i * n + j]);
10528 push(b[j * bk + k]);
10529 multiply();
10530 push(c[i * bk + k]);
10531 add();
10532 c[i * bk + k] = pop();
10533 }
10534 }
10535 }
10536 if (ndim === 0) {
10537 return push(p3.tensor.elem[0]);
10538 } else {
10539 p3.tensor.ndim = ndim;
10540 j = 0;
10541 for (i = n1 = 0, ref5 = p1.tensor.ndim - 1; 0 <= ref5 ? n1 < ref5 : n1 > ref5; i = 0 <= ref5 ? ++n1 : --n1) {
10542 p3.tensor.dim[i] = p1.tensor.dim[i];
10543 }
10544 j = p1.tensor.ndim - 1;
10545 for (i = o1 = 0, ref6 = p2.tensor.ndim - 1; 0 <= ref6 ? o1 < ref6 : o1 > ref6; i = 0 <= ref6 ? ++o1 : --o1) {
10546 p3.tensor.dim[j + i] = p2.tensor.dim[i + 1];
10547 }
10548 return push(p3);
10549 }
10550 };
10551
10552 get_innerprod_factors = function(tree, factors_accumulator) {
10553 if (!iscons(tree)) {
10554 add_factor_to_accumulator(tree, factors_accumulator);
10555 return;
10556 }
10557 if (cdr(tree) === symbol(NIL)) {
10558 tree = get_innerprod_factors(car(tree), factors_accumulator);
10559 return;
10560 }
10561 if (isinnerordot(tree)) {
10562 get_innerprod_factors(car(cdr(tree)), factors_accumulator);
10563 get_innerprod_factors(cdr(cdr(tree)), factors_accumulator);
10564 return;
10565 }
10566 return add_factor_to_accumulator(tree, factors_accumulator);
10567 };
10568
10569 add_factor_to_accumulator = function(tree, factors_accumulator) {
10570 if (tree !== symbol(NIL)) {
10571 return factors_accumulator.push(tree);
10572 }
10573 };
10574
10575
10576 /*
10577 Table of integrals
10578
10579 The symbol f is just a dummy symbol for creating a list f(A,B,C,C,...) where
10580
10581 A is the template expression
10582
10583 B is the result expression
10584
10585 C is an optional list of conditional expressions
10586 */
10587
10588 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];
10589
10590 Eval_integral = function() {
10591 var doNothing, i, i1, n, o, ref, ref1;
10592 i = 0;
10593 n = 0;
10594 p1 = cdr(p1);
10595 push(car(p1));
10596 Eval();
10597 p1 = cdr(p1);
10598 push(car(p1));
10599 Eval();
10600 p2 = pop();
10601 if (p2 === symbol(NIL)) {
10602 guess();
10603 push(symbol(NIL));
10604 } else if (isnum(p2)) {
10605 guess();
10606 push(p2);
10607 } else {
10608 push(p2);
10609 p1 = cdr(p1);
10610 push(car(p1));
10611 Eval();
10612 }
10613 p5 = pop();
10614 p4 = pop();
10615 p3 = pop();
10616 while (1) {
10617 if (isnum(p5)) {
10618 push(p5);
10619 n = pop_integer();
10620 if (isNaN(n)) {
10621 stop("nth integral: check n");
10622 }
10623 } else {
10624 n = 1;
10625 }
10626 push(p3);
10627 if (n >= 0) {
10628 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10629 push(p4);
10630 integral();
10631 }
10632 } else {
10633 n = -n;
10634 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
10635 push(p4);
10636 derivative();
10637 }
10638 }
10639 p3 = pop();
10640 if (p5 === symbol(NIL)) {
10641 break;
10642 }
10643 if (isnum(p5)) {
10644 p1 = cdr(p1);
10645 push(car(p1));
10646 Eval();
10647 p5 = pop();
10648 if (p5 === symbol(NIL)) {
10649 break;
10650 }
10651 if (isnum(p5)) {
10652 doNothing = 1;
10653 } else {
10654 p4 = p5;
10655 p1 = cdr(p1);
10656 push(car(p1));
10657 Eval();
10658 p5 = pop();
10659 }
10660 } else {
10661 p4 = p5;
10662 p1 = cdr(p1);
10663 push(car(p1));
10664 Eval();
10665 p5 = pop();
10666 }
10667 }
10668 return push(p3);
10669 };
10670
10671 integral = function() {
10672 save();
10673 p2 = pop();
10674 p1 = pop();
10675 if (car(p1) === symbol(ADD)) {
10676 integral_of_sum();
10677 } else if (car(p1) === symbol(MULTIPLY)) {
10678 integral_of_product();
10679 } else {
10680 integral_of_form();
10681 }
10682 p1 = pop();
10683 if (Find(p1, symbol(INTEGRAL))) {
10684 stop("integral: sorry, could not find a solution");
10685 }
10686 push(p1);
10687 simplify();
10688 Eval();
10689 return restore();
10690 };
10691
10692 integral_of_sum = function() {
10693 var results;
10694 p1 = cdr(p1);
10695 push(car(p1));
10696 push(p2);
10697 integral();
10698 p1 = cdr(p1);
10699 results = [];
10700 while (iscons(p1)) {
10701 push(car(p1));
10702 push(p2);
10703 integral();
10704 add();
10705 results.push(p1 = cdr(p1));
10706 }
10707 return results;
10708 };
10709
10710 integral_of_product = function() {
10711 push(p1);
10712 push(p2);
10713 partition();
10714 p1 = pop();
10715 integral_of_form();
10716 return multiply();
10717 };
10718
10719 integral_of_form = function() {
10720 push(p1);
10721 push(p2);
10722 transform(itab, false);
10723 p3 = pop();
10724 if (p3 === symbol(NIL)) {
10725 push_symbol(INTEGRAL);
10726 push(p1);
10727 push(p2);
10728 return list(3);
10729 } else {
10730 return push(p3);
10731 }
10732 };
10733
10734 INV_check_arg = function() {
10735 if (!istensor(p1)) {
10736 return 0;
10737 } else if (p1.tensor.ndim !== 2) {
10738 return 0;
10739 } else if (p1.tensor.dim[0] !== p1.tensor.dim[1]) {
10740 return 0;
10741 } else {
10742 return 1;
10743 }
10744 };
10745
10746 inv = function() {
10747 var accumulator, eachEntry, i, n, o, ref;
10748 i = 0;
10749 n = 0;
10750 save();
10751 p1 = pop();
10752 if (isinv(p1)) {
10753 push(car(cdr(p1)));
10754 restore();
10755 return;
10756 }
10757 if (isidentitymatrix(p1)) {
10758 push(p1);
10759 restore();
10760 return;
10761 }
10762 if (expanding && isinnerordot(p1)) {
10763 p1 = cdr(p1);
10764 accumulator = [];
10765 while (iscons(p1)) {
10766 accumulator.push(car(p1));
10767 p1 = cdr(p1);
10768 }
10769 for (eachEntry = o = ref = accumulator.length - 1; ref <= 0 ? o <= 0 : o >= 0; eachEntry = ref <= 0 ? ++o : --o) {
10770 push(accumulator[eachEntry]);
10771 inv();
10772 if (eachEntry !== accumulator.length - 1) {
10773 inner();
10774 }
10775 }
10776 restore();
10777 return;
10778 }
10779 if (INV_check_arg() === 0) {
10780 push_symbol(INV);
10781 push(p1);
10782 list(2);
10783 restore();
10784 return;
10785 }
10786 if (isnumerictensor(p1)) {
10787 yyinvg();
10788 } else {
10789 push(p1);
10790 adj();
10791 push(p1);
10792 det();
10793 p2 = pop();
10794 if (iszero(p2)) {
10795 stop("inverse of singular matrix");
10796 }
10797 push(p2);
10798 divide();
10799 }
10800 return restore();
10801 };
10802
10803 invg = function() {
10804 save();
10805 p1 = pop();
10806 if (INV_check_arg() === 0) {
10807 push_symbol(INVG);
10808 push(p1);
10809 list(2);
10810 restore();
10811 return;
10812 }
10813 yyinvg();
10814 return restore();
10815 };
10816
10817 yyinvg = function() {
10818 var h, i, i1, j, j1, l1, n, o, ref, ref1, ref2, ref3;
10819 h = 0;
10820 i = 0;
10821 j = 0;
10822 n = 0;
10823 n = p1.tensor.dim[0];
10824 h = tos;
10825 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10826 for (j = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; j = 0 <= ref1 ? ++i1 : --i1) {
10827 if (i === j) {
10828 push(one);
10829 } else {
10830 push(zero);
10831 }
10832 }
10833 }
10834 for (i = j1 = 0, ref2 = n * n; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
10835 push(p1.tensor.elem[i]);
10836 }
10837 INV_decomp(n);
10838 p1 = alloc_tensor(n * n);
10839 p1.tensor.ndim = 2;
10840 p1.tensor.dim[0] = n;
10841 p1.tensor.dim[1] = n;
10842 for (i = l1 = 0, ref3 = n * n; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
10843 p1.tensor.elem[i] = stack[h + i];
10844 }
10845 moveTos(tos - 2 * n * n);
10846 return push(p1);
10847 };
10848
10849 INV_decomp = function(n) {
10850 var a, d, i, i1, j, j1, l1, o, ref, ref1, ref2, ref3, ref4, results, u;
10851 a = 0;
10852 d = 0;
10853 i = 0;
10854 j = 0;
10855 u = 0;
10856 a = tos - n * n;
10857 u = a - n * n;
10858 results = [];
10859 for (d = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; d = 0 <= ref ? ++o : --o) {
10860 if (equal(stack[a + n * d + d], zero)) {
10861 for (i = i1 = ref1 = d + 1, ref2 = n; ref1 <= ref2 ? i1 < ref2 : i1 > ref2; i = ref1 <= ref2 ? ++i1 : --i1) {
10862 if (!equal(stack[a + n * i + d], zero)) {
10863 break;
10864 }
10865 }
10866 if (i === n) {
10867 stop("inverse of singular matrix");
10868 }
10869 for (j = j1 = 0, ref3 = n; 0 <= ref3 ? j1 < ref3 : j1 > ref3; j = 0 <= ref3 ? ++j1 : --j1) {
10870 p2 = stack[a + n * d + j];
10871 stack[a + n * d + j] = stack[a + n * i + j];
10872 stack[a + n * i + j] = p2;
10873 p2 = stack[u + n * d + j];
10874 stack[u + n * d + j] = stack[u + n * i + j];
10875 stack[u + n * i + j] = p2;
10876 }
10877 }
10878 p2 = stack[a + n * d + d];
10879 for (j = l1 = 0, ref4 = n; 0 <= ref4 ? l1 < ref4 : l1 > ref4; j = 0 <= ref4 ? ++l1 : --l1) {
10880 if (j > d) {
10881 push(stack[a + n * d + j]);
10882 push(p2);
10883 divide();
10884 stack[a + n * d + j] = pop();
10885 }
10886 push(stack[u + n * d + j]);
10887 push(p2);
10888 divide();
10889 stack[u + n * d + j] = pop();
10890 }
10891 results.push((function() {
10892 var m1, ref5, results1;
10893 results1 = [];
10894 for (i = m1 = 0, ref5 = n; 0 <= ref5 ? m1 < ref5 : m1 > ref5; i = 0 <= ref5 ? ++m1 : --m1) {
10895 if (i === d) {
10896 continue;
10897 }
10898 p2 = stack[a + n * i + d];
10899 results1.push((function() {
10900 var n1, ref6, results2;
10901 results2 = [];
10902 for (j = n1 = 0, ref6 = n; 0 <= ref6 ? n1 < ref6 : n1 > ref6; j = 0 <= ref6 ? ++n1 : --n1) {
10903 if (j > d) {
10904 push(stack[a + n * i + j]);
10905 push(stack[a + n * d + j]);
10906 push(p2);
10907 multiply();
10908 subtract();
10909 stack[a + n * i + j] = pop();
10910 }
10911 push(stack[u + n * i + j]);
10912 push(stack[u + n * d + j]);
10913 push(p2);
10914 multiply();
10915 subtract();
10916 results2.push(stack[u + n * i + j] = pop());
10917 }
10918 return results2;
10919 })());
10920 }
10921 return results1;
10922 })());
10923 }
10924 return results;
10925 };
10926
10927 DEBUG_IS = false;
10928
10929 iszero = function(p) {
10930 var i, o, ref;
10931 i = 0;
10932 switch (p.k) {
10933 case NUM:
10934 if (MZERO(p.q.a)) {
10935 return 1;
10936 }
10937 break;
10938 case DOUBLE:
10939 if (p.d === 0.0) {
10940 return 1;
10941 }
10942 break;
10943 case TENSOR:
10944 for (i = o = 0, ref = p.tensor.nelem; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
10945 if (!iszero(p.tensor.elem[i])) {
10946 return 0;
10947 }
10948 }
10949 return 1;
10950 }
10951 return 0;
10952 };
10953
10954 isnegativenumber = function(p) {
10955 switch (p.k) {
10956 case NUM:
10957 if (MSIGN(p.q.a) === -1) {
10958 return 1;
10959 }
10960 break;
10961 case DOUBLE:
10962 if (p.d < 0.0) {
10963 return 1;
10964 }
10965 }
10966 return 0;
10967 };
10968
10969 ispositivenumber = function(p) {
10970 switch (p.k) {
10971 case NUM:
10972 if (MSIGN(p.q.a) === 1) {
10973 return 1;
10974 }
10975 break;
10976 case DOUBLE:
10977 if (p.d > 0.0) {
10978 return 1;
10979 }
10980 }
10981 return 0;
10982 };
10983
10984 isplustwo = function(p) {
10985 switch (p.k) {
10986 case NUM:
10987 if (MEQUAL(p.q.a, 2) && MEQUAL(p.q.b, 1)) {
10988 return 1;
10989 }
10990 break;
10991 case DOUBLE:
10992 if (p.d === 2.0) {
10993 return 1;
10994 }
10995 }
10996 return 0;
10997 };
10998
10999 isplusone = function(p) {
11000 switch (p.k) {
11001 case NUM:
11002 if (MEQUAL(p.q.a, 1) && MEQUAL(p.q.b, 1)) {
11003 return 1;
11004 }
11005 break;
11006 case DOUBLE:
11007 if (p.d === 1.0) {
11008 return 1;
11009 }
11010 }
11011 return 0;
11012 };
11013
11014 isminusone = function(p) {
11015 switch (p.k) {
11016 case NUM:
11017 if (MEQUAL(p.q.a, -1) && MEQUAL(p.q.b, 1)) {
11018 return 1;
11019 }
11020 break;
11021 case DOUBLE:
11022 if (p.d === -1.0) {
11023 return 1;
11024 }
11025 }
11026 return 0;
11027 };
11028
11029 isone = function(p) {
11030 return isplusone(p) || isminusone(p);
11031 };
11032
11033 isinteger = function(p) {
11034 if (p.k === NUM && MEQUAL(p.q.b, 1)) {
11035 return 1;
11036 } else {
11037 return 0;
11038 }
11039 };
11040
11041 isintegerorintegerfloat = function(p) {
11042 if (p.k === DOUBLE) {
11043 if (p.d === Math.round(p.d)) {
11044 return 1;
11045 }
11046 return 0;
11047 }
11048 return isinteger(p);
11049 };
11050
11051 isnonnegativeinteger = function(p) {
11052 if (isrational(p) && MEQUAL(p.q.b, 1) && MSIGN(p.q.a) === 1) {
11053 return 1;
11054 } else {
11055 return 0;
11056 }
11057 };
11058
11059 isposint = function(p) {
11060 if (isinteger(p) && MSIGN(p.q.a) === 1) {
11061 return 1;
11062 } else {
11063 return 0;
11064 }
11065 };
11066
11067 ispoly = function(p, x) {
11068 if (Find(p, x)) {
11069 return ispoly_expr(p, x);
11070 } else {
11071 return 0;
11072 }
11073 };
11074
11075 ispoly_expr = function(p, x) {
11076 if (car(p) === symbol(ADD)) {
11077 p = cdr(p);
11078 while (iscons(p)) {
11079 if (!ispoly_term(car(p), x)) {
11080 return 0;
11081 }
11082 p = cdr(p);
11083 }
11084 return 1;
11085 } else {
11086 return ispoly_term(p, x);
11087 }
11088 };
11089
11090 ispoly_term = function(p, x) {
11091 if (car(p) === symbol(MULTIPLY)) {
11092 p = cdr(p);
11093 while (iscons(p)) {
11094 if (!ispoly_factor(car(p), x)) {
11095 return 0;
11096 }
11097 p = cdr(p);
11098 }
11099 return 1;
11100 } else {
11101 return ispoly_factor(p, x);
11102 }
11103 };
11104
11105 ispoly_factor = function(p, x) {
11106 if (equal(p, x)) {
11107 return 1;
11108 }
11109 if (car(p) === symbol(POWER) && equal(cadr(p), x)) {
11110 if (isposint(caddr(p))) {
11111 return 1;
11112 } else {
11113 return 0;
11114 }
11115 }
11116 if (Find(p, x)) {
11117 return 0;
11118 } else {
11119 return 1;
11120 }
11121 };
11122
11123 isnegativeterm = function(p) {
11124 if (isnegativenumber(p)) {
11125 return 1;
11126 } else if (car(p) === symbol(MULTIPLY) && isnegativenumber(cadr(p))) {
11127 return 1;
11128 } else {
11129 return 0;
11130 }
11131 };
11132
11133 hasNegativeRationalExponent = function(p) {
11134 if (car(p) === symbol(POWER) && isrational(car(cdr(cdr(p)))) && isnegativenumber(car(cdr(p)))) {
11135 if (DEBUG_IS) {
11136 console.log("hasNegativeRationalExponent: " + p.toString() + " has imaginary component");
11137 }
11138 return 1;
11139 } else {
11140 if (DEBUG_IS) {
11141 console.log("hasNegativeRationalExponent: " + p.toString() + " has NO imaginary component");
11142 }
11143 return 0;
11144 }
11145 };
11146
11147 isimaginarynumberdouble = function(p) {
11148 if ((car(p) === symbol(MULTIPLY) && length(p) === 3 && isdouble(cadr(p)) && hasNegativeRationalExponent(caddr(p))) || equal(p, imaginaryunit)) {
11149 return 1;
11150 } else {
11151 return 0;
11152 }
11153 };
11154
11155 isimaginarynumber = function(p) {
11156 if ((car(p) === symbol(MULTIPLY) && length(p) === 3 && isnum(cadr(p)) && equal(caddr(p), imaginaryunit)) || equal(p, imaginaryunit) || hasNegativeRationalExponent(caddr(p))) {
11157 if (DEBUG_IS) {
11158 console.log("isimaginarynumber: " + p.toString() + " is imaginary number");
11159 }
11160 return 1;
11161 } else {
11162 if (DEBUG_IS) {
11163 console.log("isimaginarynumber: " + p.toString() + " isn't an imaginary number");
11164 }
11165 return 0;
11166 }
11167 };
11168
11169 iscomplexnumberdouble = function(p) {
11170 if ((car(p) === symbol(ADD) && length(p) === 3 && isdouble(cadr(p)) && isimaginarynumberdouble(caddr(p))) || isimaginarynumberdouble(p)) {
11171 return 1;
11172 } else {
11173 return 0;
11174 }
11175 };
11176
11177 iscomplexnumber = function(p) {
11178 if (DEBUG_IS) {
11179 debugger;
11180 }
11181 if ((car(p) === symbol(ADD) && length(p) === 3 && isnum(cadr(p)) && isimaginarynumber(caddr(p))) || isimaginarynumber(p)) {
11182 if (DEBUG) {
11183 console.log("iscomplexnumber: " + p.toString() + " is imaginary number");
11184 }
11185 return 1;
11186 } else {
11187 if (DEBUG) {
11188 console.log("iscomplexnumber: " + p.toString() + " is imaginary number");
11189 }
11190 return 0;
11191 }
11192 };
11193
11194 iseveninteger = function(p) {
11195 if (isinteger(p) && p.q.a.isEven()) {
11196 return 1;
11197 } else {
11198 return 0;
11199 }
11200 };
11201
11202 isnegative = function(p) {
11203 if (car(p) === symbol(ADD) && isnegativeterm(cadr(p))) {
11204 return 1;
11205 } else if (isnegativeterm(p)) {
11206 return 1;
11207 } else {
11208 return 0;
11209 }
11210 };
11211
11212 issymbolic = function(p) {
11213 if (issymbol(p)) {
11214 return 1;
11215 } else {
11216 while (iscons(p)) {
11217 if (issymbolic(car(p))) {
11218 return 1;
11219 }
11220 p = cdr(p);
11221 }
11222 return 0;
11223 }
11224 };
11225
11226 isintegerfactor = function(p) {
11227 if (isinteger(p) || car(p) === symbol(POWER) && isinteger(cadr(p)) && isinteger(caddr(p))) {
11228 return 1;
11229 } else {
11230 return 0;
11231 }
11232 };
11233
11234 isnumberoneoversomething = function(p) {
11235 if (isfraction(p) && Math.abs(p.q.a.value) === 1) {
11236 return 1;
11237 } else {
11238 return 0;
11239 }
11240 };
11241
11242 isoneover = function(p) {
11243 if (car(p) === symbol(POWER) && isminusone(caddr(p))) {
11244 return 1;
11245 } else {
11246 return 0;
11247 }
11248 };
11249
11250 isfraction = function(p) {
11251 if (p.k === NUM && !MEQUAL(p.q.b, 1)) {
11252 return 1;
11253 } else {
11254 return 0;
11255 }
11256 };
11257
11258 equaln = function(p, n) {
11259 switch (p.k) {
11260 case NUM:
11261 if (MEQUAL(p.q.a, n) && MEQUAL(p.q.b, 1)) {
11262 return 1;
11263 }
11264 break;
11265 case DOUBLE:
11266 if (p.d === n) {
11267 return 1;
11268 }
11269 }
11270 return 0;
11271 };
11272
11273 equalq = function(p, a, b) {
11274 switch (p.k) {
11275 case NUM:
11276 if (MEQUAL(p.q.a, a) && MEQUAL(p.q.b, b)) {
11277 return 1;
11278 }
11279 break;
11280 case DOUBLE:
11281 if (p.d === a / b) {
11282 return 1;
11283 }
11284 }
11285 return 0;
11286 };
11287
11288 isoneovertwo = function(p) {
11289 if (equalq(p, 1, 2)) {
11290 return 1;
11291 } else {
11292 return 0;
11293 }
11294 };
11295
11296 isminusoneovertwo = function(p) {
11297 if (equalq(p, -1, 2)) {
11298 return 1;
11299 } else {
11300 return 0;
11301 }
11302 };
11303
11304 isoneoversqrttwo = function(p) {
11305 if (car(p) === symbol(POWER) && equaln(cadr(p), 2) && equalq(caddr(p), -1, 2)) {
11306 return 1;
11307 } else {
11308 return 0;
11309 }
11310 };
11311
11312 isminusoneoversqrttwo = function(p) {
11313 if (car(p) === symbol(MULTIPLY) && equaln(cadr(p), -1) && isoneoversqrttwo(caddr(p)) && length(p) === 3) {
11314 return 1;
11315 } else {
11316 return 0;
11317 }
11318 };
11319
11320 isfloating = function(p) {
11321 if (p.k === DOUBLE || p === symbol(FLOATF)) {
11322 return 1;
11323 }
11324 while (iscons(p)) {
11325 if (isfloating(car(p))) {
11326 return 1;
11327 }
11328 p = cdr(p);
11329 }
11330 return 0;
11331 };
11332
11333 isimaginaryunit = function(p) {
11334 if (equal(p, imaginaryunit)) {
11335 return 1;
11336 } else {
11337 return 0;
11338 }
11339 };
11340
11341 isquarterturn = function(p) {
11342 var minussign, n;
11343 n = 0;
11344 minussign = 0;
11345 if (car(p) !== symbol(MULTIPLY)) {
11346 return 0;
11347 }
11348 if (equal(cadr(p), imaginaryunit)) {
11349 if (caddr(p) !== symbol(PI)) {
11350 return 0;
11351 }
11352 if (length(p) !== 3) {
11353 return 0;
11354 }
11355 return 2;
11356 }
11357 if (!isnum(cadr(p))) {
11358 return 0;
11359 }
11360 if (!equal(caddr(p), imaginaryunit)) {
11361 return 0;
11362 }
11363 if (cadddr(p) !== symbol(PI)) {
11364 return 0;
11365 }
11366 if (length(p) !== 4) {
11367 return 0;
11368 }
11369 push(cadr(p));
11370 push_integer(2);
11371 multiply();
11372 n = pop_integer();
11373 if (isNaN(n)) {
11374 return 0;
11375 }
11376 if (n < 1) {
11377 minussign = 1;
11378 n = -n;
11379 }
11380 switch (n % 4) {
11381 case 0:
11382 n = 1;
11383 break;
11384 case 1:
11385 if (minussign) {
11386 n = 4;
11387 } else {
11388 n = 3;
11389 }
11390 break;
11391 case 2:
11392 n = 2;
11393 break;
11394 case 3:
11395 if (minussign) {
11396 n = 3;
11397 } else {
11398 n = 4;
11399 }
11400 }
11401 return n;
11402 };
11403
11404 isnpi = function(p) {
11405 var doNothing, n;
11406 n = 0;
11407 if (p === symbol(PI)) {
11408 return 2;
11409 }
11410 if (car(p) === symbol(MULTIPLY) && isnum(cadr(p)) && caddr(p) === symbol(PI) && length(p) === 3) {
11411 doNothing = 0;
11412 } else {
11413 return 0;
11414 }
11415 push(cadr(p));
11416 push_integer(2);
11417 multiply();
11418 n = pop_integer();
11419 if (isNaN(n)) {
11420 return 0;
11421 }
11422 if (n < 0) {
11423 n = 4 - (-n) % 4;
11424 } else {
11425 n = 1 + (n - 1) % 4;
11426 }
11427 return n;
11428 };
11429
11430 $.iszero = iszero;
11431
11432 $.isnegativenumber = isnegativenumber;
11433
11434 $.isplusone = isplusone;
11435
11436 $.isminusone = isminusone;
11437
11438 $.isinteger = isinteger;
11439
11440 $.isnonnegativeinteger = isnonnegativeinteger;
11441
11442 $.isposint = isposint;
11443
11444 $.isnegativeterm = isnegativeterm;
11445
11446 $.isimaginarynumber = isimaginarynumber;
11447
11448 $.iscomplexnumber = iscomplexnumber;
11449
11450 $.iseveninteger = iseveninteger;
11451
11452 $.isnegative = isnegative;
11453
11454 $.issymbolic = issymbolic;
11455
11456 $.isintegerfactor = isintegerfactor;
11457
11458 $.isoneover = isoneover;
11459
11460 $.isfraction = isfraction;
11461
11462 $.isoneoversqrttwo = isoneoversqrttwo;
11463
11464 $.isminusoneoversqrttwo = isminusoneoversqrttwo;
11465
11466 $.isfloating = isfloating;
11467
11468 $.isimaginaryunit = isimaginaryunit;
11469
11470 $.isquarterturn = isquarterturn;
11471
11472 $.isnpi = isnpi;
11473
11474 Eval_isprime = function() {
11475 push(cadr(p1));
11476 Eval();
11477 p1 = pop();
11478 if (isnonnegativeinteger(p1) && mprime(p1.q.a)) {
11479 return push_integer(1);
11480 } else {
11481 return push_integer(0);
11482 }
11483 };
11484
11485
11486 /*
11487 Laguerre function
11488
11489 Example
11490
11491 laguerre(x,3)
11492
11493 Result
11494
11495 1 3 3 2
11496 - --- x + --- x - 3 x + 1
11497 6 2
11498
11499 The computation uses the following recurrence relation.
11500
11501 L(x,0,k) = 1
11502
11503 L(x,1,k) = -x + k + 1
11504
11505 n*L(x,n,k) = (2*(n-1)+1-x+k)*L(x,n-1,k) - (n-1+k)*L(x,n-2,k)
11506
11507 In the "for" loop i = n-1 so the recurrence relation becomes
11508
11509 (i+1)*L(x,n,k) = (2*i+1-x+k)*L(x,n-1,k) - (i+k)*L(x,n-2,k)
11510 */
11511
11512 Eval_laguerre = function() {
11513 push(cadr(p1));
11514 Eval();
11515 push(caddr(p1));
11516 Eval();
11517 push(cadddr(p1));
11518 Eval();
11519 p2 = pop();
11520 if (p2 === symbol(NIL)) {
11521 push_integer(0);
11522 } else {
11523 push(p2);
11524 }
11525 return laguerre();
11526 };
11527
11528 laguerre = function() {
11529 var n;
11530 n = 0;
11531 save();
11532 p3 = pop();
11533 p2 = pop();
11534 p1 = pop();
11535 push(p2);
11536 n = pop_integer();
11537 if (n < 0 || isNaN(n)) {
11538 push_symbol(LAGUERRE);
11539 push(p1);
11540 push(p2);
11541 push(p3);
11542 list(4);
11543 restore();
11544 return;
11545 }
11546 if (issymbol(p1)) {
11547 laguerre2(n);
11548 } else {
11549 p4 = p1;
11550 p1 = symbol(SECRETX);
11551 laguerre2(n);
11552 p1 = p4;
11553 push(symbol(SECRETX));
11554 push(p1);
11555 subst();
11556 Eval();
11557 }
11558 return restore();
11559 };
11560
11561 laguerre2 = function(n) {
11562 var i, o, ref, results;
11563 i = 0;
11564 push_integer(1);
11565 push_integer(0);
11566 p6 = pop();
11567 results = [];
11568 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
11569 p5 = p6;
11570 p6 = pop();
11571 push_integer(2 * i + 1);
11572 push(p1);
11573 subtract();
11574 push(p3);
11575 add();
11576 push(p6);
11577 multiply();
11578 push_integer(i);
11579 push(p3);
11580 add();
11581 push(p5);
11582 multiply();
11583 subtract();
11584 push_integer(i + 1);
11585 results.push(divide());
11586 }
11587 return results;
11588 };
11589
11590 Eval_lcm = function() {
11591 var results;
11592 p1 = cdr(p1);
11593 push(car(p1));
11594 Eval();
11595 p1 = cdr(p1);
11596 results = [];
11597 while (iscons(p1)) {
11598 push(car(p1));
11599 Eval();
11600 lcm();
11601 results.push(p1 = cdr(p1));
11602 }
11603 return results;
11604 };
11605
11606 lcm = function() {
11607 var prev_expanding;
11608 prev_expanding = expanding;
11609 save();
11610 yylcm();
11611 restore();
11612 return expanding = prev_expanding;
11613 };
11614
11615 yylcm = function() {
11616 expanding = 1;
11617 p2 = pop();
11618 p1 = pop();
11619 push(p1);
11620 push(p2);
11621 gcd();
11622 push(p1);
11623 divide();
11624 push(p2);
11625 divide();
11626 return inverse();
11627 };
11628
11629
11630 /*
11631 Return the leading coefficient of a polynomial.
11632
11633 Example
11634
11635 leading(5x^2+x+1,x)
11636
11637 Result
11638
11639 5
11640
11641 The result is undefined if P is not a polynomial.
11642 */
11643
11644 Eval_leading = function() {
11645 push(cadr(p1));
11646 Eval();
11647 push(caddr(p1));
11648 Eval();
11649 p1 = pop();
11650 if (p1 === symbol(NIL)) {
11651 guess();
11652 } else {
11653 push(p1);
11654 }
11655 return leading();
11656 };
11657
11658 leading = function() {
11659 save();
11660 p2 = pop();
11661 p1 = pop();
11662 push(p1);
11663 push(p2);
11664 degree();
11665 p3 = pop();
11666 push(p1);
11667 push(p2);
11668 push(p3);
11669 power();
11670 divide();
11671 push(p2);
11672 filter();
11673 return restore();
11674 };
11675
11676
11677 /*
11678 Legendre function
11679
11680 Example
11681
11682 legendre(x,3,0)
11683
11684 Result
11685
11686 5 3 3
11687 --- x - --- x
11688 2 2
11689
11690 The computation uses the following recurrence relation.
11691
11692 P(x,0) = 1
11693
11694 P(x,1) = x
11695
11696 n*P(x,n) = (2*(n-1)+1)*x*P(x,n-1) - (n-1)*P(x,n-2)
11697
11698 In the "for" loop we have i = n-1 so the recurrence relation becomes
11699
11700 (i+1)*P(x,n) = (2*i+1)*x*P(x,n-1) - i*P(x,n-2)
11701
11702 For m > 0
11703
11704 P(x,n,m) = (-1)^m * (1-x^2)^(m/2) * d^m/dx^m P(x,n)
11705 */
11706
11707 Eval_legendre = function() {
11708 push(cadr(p1));
11709 Eval();
11710 push(caddr(p1));
11711 Eval();
11712 push(cadddr(p1));
11713 Eval();
11714 p2 = pop();
11715 if (p2 === symbol(NIL)) {
11716 push_integer(0);
11717 } else {
11718 push(p2);
11719 }
11720 return legendre();
11721 };
11722
11723 legendre = function() {
11724 save();
11725 __legendre();
11726 return restore();
11727 };
11728
11729 __legendre = function() {
11730 var m, n;
11731 m = 0;
11732 n = 0;
11733 p3 = pop();
11734 p2 = pop();
11735 p1 = pop();
11736 push(p2);
11737 n = pop_integer();
11738 push(p3);
11739 m = pop_integer();
11740 if (n < 0 || isNaN(n) || m < 0 || isNaN(m)) {
11741 push_symbol(LEGENDRE);
11742 push(p1);
11743 push(p2);
11744 push(p3);
11745 list(4);
11746 return;
11747 }
11748 if (issymbol(p1)) {
11749 __legendre2(n, m);
11750 } else {
11751 p4 = p1;
11752 p1 = symbol(SECRETX);
11753 __legendre2(n, m);
11754 p1 = p4;
11755 push(symbol(SECRETX));
11756 push(p1);
11757 subst();
11758 Eval();
11759 }
11760 return __legendre3(m);
11761 };
11762
11763 __legendre2 = function(n, m) {
11764 var i, i1, o, ref, ref1, results;
11765 i = 0;
11766 push_integer(1);
11767 push_integer(0);
11768 p6 = pop();
11769 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
11770 p5 = p6;
11771 p6 = pop();
11772 push_integer(2 * i + 1);
11773 push(p1);
11774 multiply();
11775 push(p6);
11776 multiply();
11777 push_integer(i);
11778 push(p5);
11779 multiply();
11780 subtract();
11781 push_integer(i + 1);
11782 divide();
11783 }
11784 results = [];
11785 for (i = i1 = 0, ref1 = m; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
11786 push(p1);
11787 results.push(derivative());
11788 }
11789 return results;
11790 };
11791
11792 __legendre3 = function(m) {
11793 if (m === 0) {
11794 return;
11795 }
11796 if (car(p1) === symbol(COS)) {
11797 push(cadr(p1));
11798 sine();
11799 square();
11800 } else if (car(p1) === symbol(SIN)) {
11801 push(cadr(p1));
11802 cosine();
11803 square();
11804 } else {
11805 push_integer(1);
11806 push(p1);
11807 square();
11808 subtract();
11809 }
11810 push_integer(m);
11811 push_rational(1, 2);
11812 multiply();
11813 power();
11814 multiply();
11815 if (m % 2) {
11816 return negate();
11817 }
11818 };
11819
11820 list = function(n) {
11821 var listIterator, o, ref, results;
11822 listIterator = 0;
11823 push(symbol(NIL));
11824 results = [];
11825 for (listIterator = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; listIterator = 0 <= ref ? ++o : --o) {
11826 results.push(cons());
11827 }
11828 return results;
11829 };
11830
11831 Eval_log = function() {
11832 push(cadr(p1));
11833 Eval();
11834 return logarithm();
11835 };
11836
11837 logarithm = function() {
11838 save();
11839 yylog();
11840 return restore();
11841 };
11842
11843 yylog = function() {
11844 var d;
11845 d = 0.0;
11846 p1 = pop();
11847 if (p1 === symbol(E)) {
11848 push_integer(1);
11849 return;
11850 }
11851 if (equaln(p1, 1)) {
11852 push_integer(0);
11853 return;
11854 }
11855 if (isnegativenumber(p1)) {
11856 push(p1);
11857 negate();
11858 logarithm();
11859 push(imaginaryunit);
11860 if (evaluatingAsFloats) {
11861 push_double(Math.PI);
11862 } else {
11863 push_symbol(PI);
11864 }
11865 multiply();
11866 add();
11867 return;
11868 }
11869 if (isdouble(p1)) {
11870 d = Math.log(p1.d);
11871 push_double(d);
11872 return;
11873 }
11874 if (isfraction(p1)) {
11875 push(p1);
11876 numerator();
11877 logarithm();
11878 push(p1);
11879 denominator();
11880 logarithm();
11881 subtract();
11882 return;
11883 }
11884 if (car(p1) === symbol(POWER)) {
11885 push(caddr(p1));
11886 push(cadr(p1));
11887 logarithm();
11888 multiply();
11889 return;
11890 }
11891 if (car(p1) === symbol(MULTIPLY)) {
11892 push_integer(0);
11893 p1 = cdr(p1);
11894 while (iscons(p1)) {
11895 push(car(p1));
11896 logarithm();
11897 add();
11898 p1 = cdr(p1);
11899 }
11900 return;
11901 }
11902 push_symbol(LOG);
11903 push(p1);
11904 return list(2);
11905 };
11906
11907 Eval_lookup = function() {
11908 p1 = cadr(p1);
11909 if (!iscons(p1) && cadr(p1).k === SYM) {
11910 p1 = get_binding(p1);
11911 }
11912 return push(p1);
11913 };
11914
11915 madd = function(a, b) {
11916 return a.add(b);
11917 };
11918
11919 msub = function(a, b) {
11920 return a.subtract(b);
11921 };
11922
11923 addf = function(a, b) {
11924 return a.add(b);
11925 };
11926
11927 subf = function(a, b) {
11928 return a.subtract(b);
11929 };
11930
11931 ucmp = function(a, b) {
11932 return a.compareAbs(b);
11933 };
11934
11935 mgcd = function(u, v) {
11936 return bigInt.gcd(u, v);
11937 };
11938
11939 new_string = function(s) {
11940 save();
11941 p1 = new U();
11942 p1.k = STR;
11943 p1.str = s;
11944 push(p1);
11945 return restore();
11946 };
11947
11948 out_of_memory = function() {
11949 return stop("out of memory");
11950 };
11951
11952 push_zero_matrix = function(i, j) {
11953 push(alloc_tensor(i * j));
11954 stack[tos - 1].tensor.ndim = 2;
11955 stack[tos - 1].tensor.dim[0] = i;
11956 return stack[tos - 1].tensor.dim[1] = j;
11957 };
11958
11959 push_identity_matrix = function(n) {
11960 var i, o, ref;
11961 push_zero_matrix(n, n);
11962 i = 0;
11963 for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
11964 stack[tos - 1].tensor.elem[i * n + i] = one;
11965 }
11966 return check_tensor_dimensions(stack[tos - 1]);
11967 };
11968
11969 push_cars = function(p) {
11970 var results;
11971 results = [];
11972 while (iscons(p)) {
11973 push(car(p));
11974 results.push(p = cdr(p));
11975 }
11976 return results;
11977 };
11978
11979 peek = function() {
11980 save();
11981 p1 = pop();
11982 push(p1);
11983 return restore();
11984 };
11985
11986 equal = function(p1, p2) {
11987 if (cmp_expr(p1, p2) === 0) {
11988 return 1;
11989 } else {
11990 return 0;
11991 }
11992 };
11993
11994 lessp = function(p1, p2) {
11995 if (cmp_expr(p1, p2) < 0) {
11996 return 1;
11997 } else {
11998 return 0;
11999 }
12000 };
12001
12002 sign = function(n) {
12003 if (n < 0) {
12004 return -1;
12005 } else if (n > 0) {
12006 return 1;
12007 } else {
12008 return 0;
12009 }
12010 };
12011
12012 cmp_expr = function(p1, p2) {
12013 var n;
12014 n = 0;
12015 if (p1 === p2) {
12016 return 0;
12017 }
12018 if (p1 === symbol(NIL)) {
12019 return -1;
12020 }
12021 if (p2 === symbol(NIL)) {
12022 return 1;
12023 }
12024 if (isnum(p1) && isnum(p2)) {
12025 return sign(compare_numbers(p1, p2));
12026 }
12027 if (isnum(p1)) {
12028 return -1;
12029 }
12030 if (isnum(p2)) {
12031 return 1;
12032 }
12033 if (isstr(p1) && isstr(p2)) {
12034 return sign(strcmp(p1.str, p2.str));
12035 }
12036 if (isstr(p1)) {
12037 return -1;
12038 }
12039 if (isstr(p2)) {
12040 return 1;
12041 }
12042 if (issymbol(p1) && issymbol(p2)) {
12043 return sign(strcmp(get_printname(p1), get_printname(p2)));
12044 }
12045 if (issymbol(p1)) {
12046 return -1;
12047 }
12048 if (issymbol(p2)) {
12049 return 1;
12050 }
12051 if (istensor(p1) && istensor(p2)) {
12052 return compare_tensors(p1, p2);
12053 }
12054 if (istensor(p1)) {
12055 return -1;
12056 }
12057 if (istensor(p2)) {
12058 return 1;
12059 }
12060 while (iscons(p1) && iscons(p2)) {
12061 n = cmp_expr(car(p1), car(p2));
12062 if (n !== 0) {
12063 return n;
12064 }
12065 p1 = cdr(p1);
12066 p2 = cdr(p2);
12067 }
12068 if (iscons(p2)) {
12069 return -1;
12070 }
12071 if (iscons(p1)) {
12072 return 1;
12073 }
12074 return 0;
12075 };
12076
12077 length = function(p) {
12078 var n;
12079 n = 0;
12080 while (iscons(p)) {
12081 p = cdr(p);
12082 n++;
12083 }
12084 return n;
12085 };
12086
12087 unique = function(p) {
12088 save();
12089 p1 = symbol(NIL);
12090 p2 = symbol(NIL);
12091 unique_f(p);
12092 if (p2 !== symbol(NIL)) {
12093 p1 = symbol(NIL);
12094 }
12095 p = p1;
12096 restore();
12097 return p;
12098 };
12099
12100 unique_f = function(p) {
12101 if (isstr(p)) {
12102 if (p1 === symbol(NIL)) {
12103 p1 = p;
12104 } else if (p !== p1) {
12105 p2 = p;
12106 }
12107 return;
12108 }
12109 while (iscons(p)) {
12110 unique_f(car(p));
12111 if (p2 !== symbol(NIL)) {
12112 return;
12113 }
12114 p = cdr(p);
12115 }
12116 };
12117
12118 ssqrt = function() {
12119 push_rational(1, 2);
12120 return power();
12121 };
12122
12123 yyexpand = function() {
12124 var prev_expanding;
12125 prev_expanding = expanding;
12126 expanding = 1;
12127 Eval();
12128 return expanding = prev_expanding;
12129 };
12130
12131 exponential = function() {
12132 push_symbol(E);
12133 swap();
12134 return power();
12135 };
12136
12137 square = function() {
12138 push_integer(2);
12139 return power();
12140 };
12141
12142 sort_stack = function(n) {
12143 var h, subsetOfStack;
12144 h = tos - n;
12145 subsetOfStack = stack.slice(h, h + n);
12146 subsetOfStack.sort(cmp_expr);
12147 return stack = stack.slice(0, h).concat(subsetOfStack).concat(stack.slice(h + n));
12148 };
12149
12150 $.equal = equal;
12151
12152 $.length = length;
12153
12154 mmul = function(a, b) {
12155 return a.multiply(b);
12156 };
12157
12158 mdiv = function(a, b) {
12159 return a.divide(b);
12160 };
12161
12162
12163 /*
12164 static void
12165 addf(unsigned int *a, unsigned int *b, int len)
12166 {
12167 int i
12168 long long t = 0; # can be signed or unsigned
12169 for (i = 0; i < len; i++) {
12170 t += (long long) a[i] + b[i]
12171 a[i] = (unsigned int) t
12172 t >>= 32
12173 }
12174 }
12175
12176 // a = a - b
12177
12178 static void
12179 subf(unsigned int *a, unsigned int *b, int len)
12180 {
12181 int i
12182 long long t = 0; # must be signed
12183 for (i = 0; i < len; i++) {
12184 t += (long long) a[i] - b[i]
12185 a[i] = (unsigned int) t
12186 t >>= 32
12187 }
12188 }
12189
12190 // a = b * c
12191
12192 // 0xffffffff + 0xffffffff * 0xffffffff == 0xffffffff00000000
12193
12194 static void
12195 mulf(unsigned int *a, unsigned int *b, int len, unsigned int c)
12196 {
12197 int i
12198 unsigned long long t = 0; # must be unsigned
12199 for (i = 0; i < len; i++) {
12200 t += (unsigned long long) b[i] * c
12201 a[i] = (unsigned int) t
12202 t >>= 32
12203 }
12204 a[i] = (unsigned int) t
12205 }
12206 */
12207
12208 mmod = function(a, b) {
12209 return a.mod(b);
12210 };
12211
12212 mdivrem = function(a, b) {
12213 var toReturn;
12214 toReturn = a.divmod(b);
12215 return [toReturn.quotient, toReturn.remainder];
12216 };
12217
12218 Eval_mod = function() {
12219 push(cadr(p1));
12220 Eval();
12221 push(caddr(p1));
12222 Eval();
12223 return mod();
12224 };
12225
12226 mod = function() {
12227 var n;
12228 n = 0;
12229 save();
12230 p2 = pop();
12231 p1 = pop();
12232 if (iszero(p2)) {
12233 stop("mod function: divide by zero");
12234 }
12235 if (!isnum(p1) || !isnum(p2)) {
12236 push_symbol(MOD);
12237 push(p1);
12238 push(p2);
12239 list(3);
12240 restore();
12241 return;
12242 }
12243 if (isdouble(p1)) {
12244 push(p1);
12245 n = pop_integer();
12246 if (isNaN(n)) {
12247 stop("mod function: cannot convert float value to integer");
12248 }
12249 push_integer(n);
12250 p1 = pop();
12251 }
12252 if (isdouble(p2)) {
12253 push(p2);
12254 n = pop_integer();
12255 if (isNaN(n)) {
12256 stop("mod function: cannot convert float value to integer");
12257 }
12258 push_integer(n);
12259 p2 = pop();
12260 }
12261 if (!isinteger(p1) || !isinteger(p2)) {
12262 stop("mod function: integer arguments expected");
12263 }
12264 p3 = new U();
12265 p3.k = NUM;
12266 p3.q.a = mmod(p1.q.a, p2.q.a);
12267 p3.q.b = mint(1);
12268 push(p3);
12269 return restore();
12270 };
12271
12272 mpow = function(a, n) {
12273 return a.pow(n);
12274 };
12275
12276 mprime = function(n) {
12277 return n.isProbablePrime();
12278 };
12279
12280 mroot = function(n, index) {
12281 var i, j, k, o, ref, x, y;
12282 n = n.abs();
12283 i = 0;
12284 j = 0;
12285 k = 0;
12286 if (index === 0) {
12287 stop("root index is zero");
12288 }
12289 k = 0;
12290 while (n.shiftRight(k) > 0) {
12291 k++;
12292 }
12293 if (k === 0) {
12294 return mint(0);
12295 }
12296 k = Math.floor((k - 1) / index);
12297 j = Math.floor(k / 32 + 1);
12298 x = bigInt(j);
12299 for (i = o = 0, ref = j; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
12300 x = x.and(bigInt(1).shiftLeft(i).not());
12301 }
12302 while (k >= 0) {
12303 x = x.or(bigInt(1).shiftLeft(k));
12304 y = mpow(x, index);
12305 switch (mcmp(y, n)) {
12306 case 0:
12307 return x;
12308 case 1:
12309 x = x.and(bigInt(1).shiftLeft(k).not());
12310 }
12311 k--;
12312 }
12313 return 0;
12314 };
12315
12316 Eval_multiply = function() {
12317 var results;
12318 push(cadr(p1));
12319 Eval();
12320 p1 = cddr(p1);
12321 results = [];
12322 while (iscons(p1)) {
12323 push(car(p1));
12324 Eval();
12325 multiply();
12326 results.push(p1 = cdr(p1));
12327 }
12328 return results;
12329 };
12330
12331 multiply = function() {
12332 if (esc_flag) {
12333 stop("escape key stop");
12334 }
12335 if (isnum(stack[tos - 2]) && isnum(stack[tos - 1])) {
12336 return multiply_numbers();
12337 } else {
12338 save();
12339 yymultiply();
12340 return restore();
12341 }
12342 };
12343
12344 yymultiply = function() {
12345 var h, i, n, o, ref, ref1;
12346 h = 0;
12347 i = 0;
12348 n = 0;
12349 p2 = pop();
12350 p1 = pop();
12351 h = tos;
12352 if (iszero(p1) || iszero(p2)) {
12353 if (evaluatingAsFloats) {
12354 push_double(0.0);
12355 } else {
12356 push(zero);
12357 }
12358 return;
12359 }
12360 if (expanding && isadd(p1)) {
12361 p1 = cdr(p1);
12362 if (evaluatingAsFloats) {
12363 push_double(0.0);
12364 } else {
12365 push(zero);
12366 }
12367 while (iscons(p1)) {
12368 push(car(p1));
12369 push(p2);
12370 multiply();
12371 add();
12372 p1 = cdr(p1);
12373 }
12374 return;
12375 }
12376 if (expanding && isadd(p2)) {
12377 p2 = cdr(p2);
12378 if (evaluatingAsFloats) {
12379 push_double(0.0);
12380 } else {
12381 push(zero);
12382 }
12383 while (iscons(p2)) {
12384 push(p1);
12385 push(car(p2));
12386 multiply();
12387 add();
12388 p2 = cdr(p2);
12389 }
12390 return;
12391 }
12392 if (!istensor(p1) && istensor(p2)) {
12393 push(p1);
12394 push(p2);
12395 scalar_times_tensor();
12396 return;
12397 }
12398 if (istensor(p1) && !istensor(p2)) {
12399 push(p1);
12400 push(p2);
12401 tensor_times_scalar();
12402 return;
12403 }
12404 if (car(p1) === symbol(MULTIPLY)) {
12405 p1 = cdr(p1);
12406 } else {
12407 push(p1);
12408 list(1);
12409 p1 = pop();
12410 }
12411 if (car(p2) === symbol(MULTIPLY)) {
12412 p2 = cdr(p2);
12413 } else {
12414 push(p2);
12415 list(1);
12416 p2 = pop();
12417 }
12418 if (isnum(car(p1)) && isnum(car(p2))) {
12419 push(car(p1));
12420 push(car(p2));
12421 multiply_numbers();
12422 p1 = cdr(p1);
12423 p2 = cdr(p2);
12424 } else if (isnum(car(p1))) {
12425 push(car(p1));
12426 p1 = cdr(p1);
12427 } else if (isnum(car(p2))) {
12428 push(car(p2));
12429 p2 = cdr(p2);
12430 } else {
12431 if (evaluatingAsFloats) {
12432 push_double(1.0);
12433 } else {
12434 push(one);
12435 }
12436 }
12437 parse_p1();
12438 parse_p2();
12439 while (iscons(p1) && iscons(p2)) {
12440 if (caar(p1) === symbol(OPERATOR) && caar(p2) === symbol(OPERATOR)) {
12441 push_symbol(OPERATOR);
12442 push(cdar(p1));
12443 push(cdar(p2));
12444 append();
12445 cons();
12446 p1 = cdr(p1);
12447 p2 = cdr(p2);
12448 parse_p1();
12449 parse_p2();
12450 continue;
12451 }
12452 switch (cmp_expr(p3, p4)) {
12453 case -1:
12454 push(car(p1));
12455 p1 = cdr(p1);
12456 parse_p1();
12457 break;
12458 case 1:
12459 push(car(p2));
12460 p2 = cdr(p2);
12461 parse_p2();
12462 break;
12463 case 0:
12464 combine_factors(h);
12465 p1 = cdr(p1);
12466 p2 = cdr(p2);
12467 parse_p1();
12468 parse_p2();
12469 break;
12470 default:
12471 stop("internal error 2");
12472 }
12473 }
12474 while (iscons(p1)) {
12475 push(car(p1));
12476 p1 = cdr(p1);
12477 }
12478 while (iscons(p2)) {
12479 push(car(p2));
12480 p2 = cdr(p2);
12481 }
12482 __normalize_radical_factors(h);
12483 if (expanding) {
12484 for (i = o = ref = h, ref1 = tos; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
12485 if (isadd(stack[i])) {
12486 multiply_all(tos - h);
12487 return;
12488 }
12489 }
12490 }
12491 n = tos - h;
12492 if (n === 1) {
12493 return;
12494 }
12495 if (isrational(stack[h]) && equaln(stack[h], 1)) {
12496 if (n === 2) {
12497 p7 = pop();
12498 pop();
12499 push(p7);
12500 } else {
12501 stack[h] = symbol(MULTIPLY);
12502 list(n);
12503 }
12504 return;
12505 }
12506 list(n);
12507 p7 = pop();
12508 push_symbol(MULTIPLY);
12509 push(p7);
12510 return cons();
12511 };
12512
12513 parse_p1 = function() {
12514 p3 = car(p1);
12515 p5 = evaluatingAsFloats ? one_as_double : one;
12516 if (car(p3) === symbol(POWER)) {
12517 p5 = caddr(p3);
12518 return p3 = cadr(p3);
12519 }
12520 };
12521
12522 parse_p2 = function() {
12523 p4 = car(p2);
12524 p6 = evaluatingAsFloats ? one_as_double : one;
12525 if (car(p4) === symbol(POWER)) {
12526 p6 = caddr(p4);
12527 return p4 = cadr(p4);
12528 }
12529 };
12530
12531 combine_factors = function(h) {
12532 push(p4);
12533 push(p5);
12534 push(p6);
12535 add();
12536 power();
12537 p7 = pop();
12538 if (isnum(p7)) {
12539 push(stack[h]);
12540 push(p7);
12541 multiply_numbers();
12542 return stack[h] = pop();
12543 } else if (car(p7) === symbol(MULTIPLY)) {
12544 if (isnum(cadr(p7)) && cdddr(p7) === symbol(NIL)) {
12545 push(stack[h]);
12546 push(cadr(p7));
12547 multiply_numbers();
12548 stack[h] = pop();
12549 return push(caddr(p7));
12550 } else {
12551 return push(p7);
12552 }
12553 } else {
12554 return push(p7);
12555 }
12556 };
12557
12558 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]];
12559
12560 combine_gammas = function(h) {
12561 var n;
12562 n = gp[Math.floor(p1.gamma)][Math.floor(p2.gamma)];
12563 if (n < 0) {
12564 n = -n;
12565 push(stack[h]);
12566 negate();
12567 stack[h] = pop();
12568 }
12569 if (n > 1) {
12570 return push(_gamma[n]);
12571 }
12572 };
12573
12574 multiply_noexpand = function() {
12575 var prev_expanding;
12576 prev_expanding = expanding;
12577 expanding = 0;
12578 multiply();
12579 return expanding = prev_expanding;
12580 };
12581
12582 multiply_all = function(n) {
12583 var h, i, o, ref;
12584 i = 0;
12585 if (n === 1) {
12586 return;
12587 }
12588 if (n === 0) {
12589 push(evaluatingAsFloats ? one_as_double : one);
12590 return;
12591 }
12592 h = tos - n;
12593 push(stack[h]);
12594 for (i = o = 1, ref = n; 1 <= ref ? o < ref : o > ref; i = 1 <= ref ? ++o : --o) {
12595 push(stack[h + i]);
12596 multiply();
12597 }
12598 stack[h] = pop();
12599 return moveTos(h + 1);
12600 };
12601
12602 multiply_all_noexpand = function(n) {
12603 var prev_expanding;
12604 prev_expanding = expanding;
12605 expanding = 0;
12606 multiply_all(n);
12607 return expanding = prev_expanding;
12608 };
12609
12610 divide = function() {
12611 if (isnum(stack[tos - 2]) && isnum(stack[tos - 1])) {
12612 return divide_numbers();
12613 } else {
12614 inverse();
12615 return multiply();
12616 }
12617 };
12618
12619 inverse = function() {
12620 if (isnum(stack[tos - 1])) {
12621 return invert_number();
12622 } else {
12623 push_integer(-1);
12624 return power();
12625 }
12626 };
12627
12628 reciprocate = function() {
12629 return inverse();
12630 };
12631
12632 negate = function() {
12633 if (isnum(stack[tos - 1])) {
12634 return negate_number();
12635 } else {
12636 if (evaluatingAsFloats) {
12637 push_double(-1.0);
12638 } else {
12639 push_integer(-1);
12640 }
12641 return multiply();
12642 }
12643 };
12644
12645 negate_expand = function() {
12646 var prev_expanding;
12647 prev_expanding = expanding;
12648 expanding = 1;
12649 negate();
12650 return expanding = prev_expanding;
12651 };
12652
12653 negate_noexpand = function() {
12654 var prev_expanding;
12655 prev_expanding = expanding;
12656 expanding = 0;
12657 negate();
12658 return expanding = prev_expanding;
12659 };
12660
12661 __normalize_radical_factors = function(h) {
12662 var i, i1, j1, o, ref, ref1, ref2, ref3, ref4, ref5;
12663 i = 0;
12664 if (isplusone(stack[h]) || isminusone(stack[h]) || isdouble(stack[h])) {
12665 return;
12666 }
12667 for (i = o = ref = h + 1, ref1 = tos; ref <= ref1 ? o < ref1 : o > ref1; i = ref <= ref1 ? ++o : --o) {
12668 if (__is_radical_number(stack[i])) {
12669 break;
12670 }
12671 }
12672 if (i === tos) {
12673 return;
12674 }
12675 save();
12676 push(stack[h]);
12677 mp_numerator();
12678 p1 = pop();
12679 for (i = i1 = ref2 = h + 1, ref3 = tos; ref2 <= ref3 ? i1 < ref3 : i1 > ref3; i = ref2 <= ref3 ? ++i1 : --i1) {
12680 if (isplusone(p1) || isminusone(p1)) {
12681 break;
12682 }
12683 if (!__is_radical_number(stack[i])) {
12684 continue;
12685 }
12686 p3 = cadr(stack[i]);
12687 p4 = caddr(stack[i]);
12688 if (!isnegativenumber(p4)) {
12689 continue;
12690 }
12691 push(p1);
12692 push(p3);
12693 divide();
12694 p5 = pop();
12695 if (!isinteger(p5)) {
12696 continue;
12697 }
12698 p1 = p5;
12699 push_symbol(POWER);
12700 push(p3);
12701 push(evaluatingAsFloats ? one_as_double : one);
12702 push(p4);
12703 add();
12704 list(3);
12705 stack[i] = pop();
12706 }
12707 push(stack[h]);
12708 mp_denominator();
12709 p2 = pop();
12710 for (i = j1 = ref4 = h + 1, ref5 = tos; ref4 <= ref5 ? j1 < ref5 : j1 > ref5; i = ref4 <= ref5 ? ++j1 : --j1) {
12711 if (isplusone(p2)) {
12712 break;
12713 }
12714 if (!__is_radical_number(stack[i])) {
12715 continue;
12716 }
12717 p3 = cadr(stack[i]);
12718 p4 = caddr(stack[i]);
12719 if (isnegativenumber(p4)) {
12720 continue;
12721 }
12722 push(p2);
12723 push(p3);
12724 divide();
12725 p5 = pop();
12726 if (!isinteger(p5)) {
12727 continue;
12728 }
12729 p2 = p5;
12730 push_symbol(POWER);
12731 push(p3);
12732 push(p4);
12733 push(one);
12734 subtract();
12735 if (dontCreateNewRadicalsInDenominatorWhenEvalingMultiplication) {
12736 if (isinteger(p3) && !isinteger(stack[tos - 1]) && isnegativenumber(stack[tos - 1])) {
12737 pop();
12738 pop();
12739 pop();
12740 push(p1);
12741 push(p3);
12742 divide();
12743 p1 = pop();
12744 break;
12745 }
12746 }
12747 list(3);
12748 stack[i] = pop();
12749 }
12750 push(p1);
12751 push(p2);
12752 divide();
12753 stack[h] = pop();
12754 return restore();
12755 };
12756
12757 __is_radical_number = function(p) {
12758 if (car(p) === symbol(POWER) && isnum(cadr(p)) && isnum(caddr(p)) && !isminusone(cadr(p))) {
12759 return 1;
12760 } else {
12761 return 0;
12762 }
12763 };
12764
12765 NROOTS_YMAX = 101;
12766
12767 NROOTS_DELTA = 1.0e-6;
12768
12769 NROOTS_EPSILON = 1.0e-9;
12770
12771 NROOTS_ABS = function(z) {
12772 return Math.sqrt(z.r * z.r + z.i * z.i);
12773 };
12774
12775 theRandom = 0.0;
12776
12777 NROOTS_RANDOM = function() {
12778 return 4.0 * Math.random() - 2.0;
12779 };
12780
12781 numericRootOfPolynomial = (function() {
12782 function numericRootOfPolynomial() {}
12783
12784 numericRootOfPolynomial.prototype.r = 0.0;
12785
12786 numericRootOfPolynomial.prototype.i = 0.0;
12787
12788 return numericRootOfPolynomial;
12789
12790 })();
12791
12792 nroots_a = new numericRootOfPolynomial();
12793
12794 nroots_b = new numericRootOfPolynomial();
12795
12796 nroots_x = new numericRootOfPolynomial();
12797
12798 nroots_y = new numericRootOfPolynomial();
12799
12800 nroots_fa = new numericRootOfPolynomial();
12801
12802 nroots_fb = new numericRootOfPolynomial();
12803
12804 nroots_dx = new numericRootOfPolynomial();
12805
12806 nroots_df = new numericRootOfPolynomial();
12807
12808 nroots_c = [];
12809
12810 for (initNRoots = o = 0, ref = NROOTS_YMAX; 0 <= ref ? o < ref : o > ref; initNRoots = 0 <= ref ? ++o : --o) {
12811 nroots_c[initNRoots] = new numericRootOfPolynomial();
12812 }
12813
12814 Eval_nroots = function() {
12815 var h, i, i1, j1, k, l1, n, ref1, ref2, ref3;
12816 h = 0;
12817 i = 0;
12818 k = 0;
12819 n = 0;
12820 push(cadr(p1));
12821 Eval();
12822 push(caddr(p1));
12823 Eval();
12824 p2 = pop();
12825 if (p2 === symbol(NIL)) {
12826 guess();
12827 } else {
12828 push(p2);
12829 }
12830 p2 = pop();
12831 p1 = pop();
12832 if (!ispoly(p1, p2)) {
12833 stop("nroots: polynomial?");
12834 }
12835 h = tos;
12836 push(p1);
12837 push(p2);
12838 n = coeff();
12839 if (n > NROOTS_YMAX) {
12840 stop("nroots: degree?");
12841 }
12842 for (i = i1 = 0, ref1 = n; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
12843 push(stack[h + i]);
12844 real();
12845 yyfloat();
12846 Eval();
12847 p1 = pop();
12848 push(stack[h + i]);
12849 imag();
12850 yyfloat();
12851 Eval();
12852 p2 = pop();
12853 if (!isdouble(p1) || !isdouble(p2)) {
12854 stop("nroots: coefficients?");
12855 }
12856 nroots_c[i].r = p1.d;
12857 nroots_c[i].i = p2.d;
12858 }
12859 moveTos(h);
12860 monic(n);
12861 for (k = j1 = ref2 = n; j1 > 1; k = j1 += -1) {
12862 findroot(k);
12863 if (Math.abs(nroots_a.r) < NROOTS_DELTA) {
12864 nroots_a.r = 0.0;
12865 }
12866 if (Math.abs(nroots_a.i) < NROOTS_DELTA) {
12867 nroots_a.i = 0.0;
12868 }
12869 push_double(nroots_a.r);
12870 push_double(nroots_a.i);
12871 push(imaginaryunit);
12872 multiply();
12873 add();
12874 NROOTS_divpoly(k);
12875 }
12876 n = tos - h;
12877 if (n > 1) {
12878 sort_stack(n);
12879 p1 = alloc_tensor(n);
12880 p1.tensor.ndim = 1;
12881 p1.tensor.dim[0] = n;
12882 for (i = l1 = 0, ref3 = n; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
12883 p1.tensor.elem[i] = stack[h + i];
12884 }
12885 moveTos(h);
12886 return push(p1);
12887 }
12888 };
12889
12890 monic = function(n) {
12891 var i1, k, ref1, t;
12892 k = 0;
12893 t = 0.0;
12894 nroots_y.r = nroots_c[n - 1].r;
12895 nroots_y.i = nroots_c[n - 1].i;
12896 t = nroots_y.r * nroots_y.r + nroots_y.i * nroots_y.i;
12897 for (k = i1 = 0, ref1 = n - 1; 0 <= ref1 ? i1 < ref1 : i1 > ref1; k = 0 <= ref1 ? ++i1 : --i1) {
12898 nroots_c[k].r = (nroots_c[k].r * nroots_y.r + nroots_c[k].i * nroots_y.i) / t;
12899 nroots_c[k].i = (nroots_c[k].i * nroots_y.r - nroots_c[k].r * nroots_y.i) / t;
12900 }
12901 nroots_c[n - 1].r = 1.0;
12902 return nroots_c[n - 1].i = 0.0;
12903 };
12904
12905 findroot = function(n) {
12906 var i1, j, j1, k, nrabs, t;
12907 j = 0;
12908 k = 0;
12909 t = 0.0;
12910 if (NROOTS_ABS(nroots_c[0]) < NROOTS_DELTA) {
12911 nroots_a.r = 0.0;
12912 nroots_a.i = 0.0;
12913 return;
12914 }
12915 for (j = i1 = 0; i1 < 100; j = ++i1) {
12916 nroots_a.r = NROOTS_RANDOM();
12917 nroots_a.i = NROOTS_RANDOM();
12918 compute_fa(n);
12919 nroots_b.r = nroots_a.r;
12920 nroots_b.i = nroots_a.i;
12921 nroots_fb.r = nroots_fa.r;
12922 nroots_fb.i = nroots_fa.i;
12923 nroots_a.r = NROOTS_RANDOM();
12924 nroots_a.i = NROOTS_RANDOM();
12925 for (k = j1 = 0; j1 < 1000; k = ++j1) {
12926 compute_fa(n);
12927 nrabs = NROOTS_ABS(nroots_fa);
12928 if (DEBUG) {
12929 console.log("nrabs: " + nrabs);
12930 }
12931 if (nrabs < NROOTS_EPSILON) {
12932 return;
12933 }
12934 if (NROOTS_ABS(nroots_fa) < NROOTS_ABS(nroots_fb)) {
12935 nroots_x.r = nroots_a.r;
12936 nroots_x.i = nroots_a.i;
12937 nroots_a.r = nroots_b.r;
12938 nroots_a.i = nroots_b.i;
12939 nroots_b.r = nroots_x.r;
12940 nroots_b.i = nroots_x.i;
12941 nroots_x.r = nroots_fa.r;
12942 nroots_x.i = nroots_fa.i;
12943 nroots_fa.r = nroots_fb.r;
12944 nroots_fa.i = nroots_fb.i;
12945 nroots_fb.r = nroots_x.r;
12946 nroots_fb.i = nroots_x.i;
12947 }
12948 nroots_dx.r = nroots_b.r - nroots_a.r;
12949 nroots_dx.i = nroots_b.i - nroots_a.i;
12950 nroots_df.r = nroots_fb.r - nroots_fa.r;
12951 nroots_df.i = nroots_fb.i - nroots_fa.i;
12952 t = nroots_df.r * nroots_df.r + nroots_df.i * nroots_df.i;
12953 if (t === 0.0) {
12954 break;
12955 }
12956 nroots_y.r = (nroots_dx.r * nroots_df.r + nroots_dx.i * nroots_df.i) / t;
12957 nroots_y.i = (nroots_dx.i * nroots_df.r - nroots_dx.r * nroots_df.i) / t;
12958 nroots_a.r = nroots_b.r - (nroots_y.r * nroots_fb.r - nroots_y.i * nroots_fb.i);
12959 nroots_a.i = nroots_b.i - (nroots_y.r * nroots_fb.i + nroots_y.i * nroots_fb.r);
12960 }
12961 }
12962 return stop("nroots: convergence error");
12963 };
12964
12965 compute_fa = function(n) {
12966 var i1, k, ref1, results, t;
12967 k = 0;
12968 t = 0.0;
12969 nroots_x.r = nroots_a.r;
12970 nroots_x.i = nroots_a.i;
12971 nroots_fa.r = nroots_c[0].r + nroots_c[1].r * nroots_x.r - nroots_c[1].i * nroots_x.i;
12972 nroots_fa.i = nroots_c[0].i + nroots_c[1].r * nroots_x.i + nroots_c[1].i * nroots_x.r;
12973 results = [];
12974 for (k = i1 = 2, ref1 = n; 2 <= ref1 ? i1 < ref1 : i1 > ref1; k = 2 <= ref1 ? ++i1 : --i1) {
12975 t = nroots_a.r * nroots_x.r - nroots_a.i * nroots_x.i;
12976 nroots_x.i = nroots_a.r * nroots_x.i + nroots_a.i * nroots_x.r;
12977 nroots_x.r = t;
12978 nroots_fa.r += nroots_c[k].r * nroots_x.r - nroots_c[k].i * nroots_x.i;
12979 results.push(nroots_fa.i += nroots_c[k].r * nroots_x.i + nroots_c[k].i * nroots_x.r);
12980 }
12981 return results;
12982 };
12983
12984 NROOTS_divpoly = function(n) {
12985 var i1, j1, k, ref1, ref2, results;
12986 k = 0;
12987 for (k = i1 = ref1 = n - 1; ref1 <= 0 ? i1 < 0 : i1 > 0; k = ref1 <= 0 ? ++i1 : --i1) {
12988 nroots_c[k - 1].r += nroots_c[k].r * nroots_a.r - nroots_c[k].i * nroots_a.i;
12989 nroots_c[k - 1].i += nroots_c[k].i * nroots_a.r + nroots_c[k].r * nroots_a.i;
12990 }
12991 if (NROOTS_ABS(nroots_c[0]) > NROOTS_DELTA) {
12992 stop("nroots: residual error");
12993 }
12994 results = [];
12995 for (k = j1 = 0, ref2 = n - 1; 0 <= ref2 ? j1 < ref2 : j1 > ref2; k = 0 <= ref2 ? ++j1 : --j1) {
12996 nroots_c[k].r = nroots_c[k + 1].r;
12997 results.push(nroots_c[k].i = nroots_c[k + 1].i);
12998 }
12999 return results;
13000 };
13001
13002 Eval_numerator = function() {
13003 push(cadr(p1));
13004 Eval();
13005 return numerator();
13006 };
13007
13008 numerator = function() {
13009 var h;
13010 h = 0;
13011 save();
13012 p1 = pop();
13013 if (car(p1) === symbol(ADD)) {
13014 push(p1);
13015 rationalize();
13016 p1 = pop();
13017 }
13018 if (car(p1) === symbol(MULTIPLY)) {
13019 h = tos;
13020 p1 = cdr(p1);
13021 while (iscons(p1)) {
13022 push(car(p1));
13023 numerator();
13024 p1 = cdr(p1);
13025 }
13026 multiply_all(tos - h);
13027 } else if (isrational(p1)) {
13028 push(p1);
13029 mp_numerator();
13030 } else if (car(p1) === symbol(POWER) && isnegativeterm(caddr(p1))) {
13031 push(one);
13032 } else {
13033 push(p1);
13034 }
13035 return restore();
13036 };
13037
13038 Eval_outer = function() {
13039 var results;
13040 p1 = cdr(p1);
13041 push(car(p1));
13042 Eval();
13043 p1 = cdr(p1);
13044 results = [];
13045 while (iscons(p1)) {
13046 push(car(p1));
13047 Eval();
13048 outer();
13049 results.push(p1 = cdr(p1));
13050 }
13051 return results;
13052 };
13053
13054 outer = function() {
13055 save();
13056 p2 = pop();
13057 p1 = pop();
13058 if (istensor(p1) && istensor(p2)) {
13059 yyouter();
13060 } else {
13061 push(p1);
13062 push(p2);
13063 if (istensor(p1)) {
13064 tensor_times_scalar();
13065 } else if (istensor(p2)) {
13066 scalar_times_tensor();
13067 } else {
13068 multiply();
13069 }
13070 }
13071 return restore();
13072 };
13073
13074 yyouter = function() {
13075 var i, i1, j, j1, k, l1, m1, ndim, nelem, ref1, ref2, ref3, ref4;
13076 i = 0;
13077 j = 0;
13078 k = 0;
13079 ndim = 0;
13080 nelem = 0;
13081 ndim = p1.tensor.ndim + p2.tensor.ndim;
13082 if (ndim > MAXDIM) {
13083 stop("outer: rank of result exceeds maximum");
13084 }
13085 nelem = p1.tensor.nelem * p2.tensor.nelem;
13086 p3 = alloc_tensor(nelem);
13087 p3.tensor.ndim = ndim;
13088 for (i = i1 = 0, ref1 = p1.tensor.ndim; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
13089 p3.tensor.dim[i] = p1.tensor.dim[i];
13090 }
13091 j = i;
13092 for (i = j1 = 0, ref2 = p2.tensor.ndim; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
13093 p3.tensor.dim[j + i] = p2.tensor.dim[i];
13094 }
13095 k = 0;
13096 for (i = l1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
13097 for (j = m1 = 0, ref4 = p2.tensor.nelem; 0 <= ref4 ? m1 < ref4 : m1 > ref4; j = 0 <= ref4 ? ++m1 : --m1) {
13098 push(p1.tensor.elem[i]);
13099 push(p2.tensor.elem[j]);
13100 multiply();
13101 p3.tensor.elem[k++] = pop();
13102 }
13103 }
13104 return push(p3);
13105 };
13106
13107
13108 /*
13109 Partition a term
13110
13111 Input stack:
13112
13113 term (factor or product of factors)
13114
13115 free variable
13116
13117 Output stack:
13118
13119 constant expression
13120
13121 variable expression
13122 */
13123
13124 partition = function() {
13125 save();
13126 p2 = pop();
13127 p1 = pop();
13128 push_integer(1);
13129 p3 = pop();
13130 p4 = p3;
13131 p1 = cdr(p1);
13132 while (iscons(p1)) {
13133 if (Find(car(p1), p2)) {
13134 push(p4);
13135 push(car(p1));
13136 multiply();
13137 p4 = pop();
13138 } else {
13139 push(p3);
13140 push(car(p1));
13141 multiply();
13142 p3 = pop();
13143 }
13144 p1 = cdr(p1);
13145 }
13146 push(p3);
13147 push(p4);
13148 return restore();
13149 };
13150
13151
13152 /*
13153 Add a pattern i.e. a substitution rule.
13154 Substitution rule needs a template as first argument
13155 and what to transform it to as second argument.
13156 Optional third argument is a boolean test which
13157 adds conditions to when the rule is applied.
13158 */
13159
13160 Eval_silentpattern = function() {
13161 Eval_pattern();
13162 pop();
13163 return push_symbol(NIL);
13164 };
13165
13166 Eval_pattern = function() {
13167 var firstArgument, patternPosition, secondArgument, stringKey, thirdArgument;
13168 if (!iscons(cdr(p1))) {
13169 stop("pattern needs at least a template and a transformed version");
13170 }
13171 firstArgument = car(cdr(p1));
13172 secondArgument = car(cdr(cdr(p1)));
13173 if (secondArgument === symbol(NIL)) {
13174 stop("pattern needs at least a template and a transformed version");
13175 }
13176 if (!iscons(cdr(cdr(p1)))) {
13177 thirdArgument = symbol(NIL);
13178 } else {
13179 thirdArgument = car(cdr(cdr(cdr(p1))));
13180 }
13181 if (equal(firstArgument, secondArgument)) {
13182 stop("recursive pattern");
13183 }
13184 stringKey = "template: " + print_list(firstArgument);
13185 stringKey += " tests: " + print_list(thirdArgument);
13186 if (DEBUG) {
13187 console.log("pattern stringkey: " + stringKey);
13188 }
13189 patternPosition = userSimplificationsInStringForm.indexOf(stringKey);
13190 if (patternPosition === -1) {
13191 userSimplificationsInStringForm.push(stringKey);
13192 userSimplificationsInListForm.push(cdr(p1));
13193 } else {
13194 if (DEBUG) {
13195 console.log("pattern already exists, replacing. " + cdr(p1));
13196 }
13197 userSimplificationsInStringForm[patternPosition] = stringKey;
13198 userSimplificationsInListForm[patternPosition] = cdr(p1);
13199 }
13200 push_symbol(PATTERN);
13201 push(cdr(p1));
13202 return list(2);
13203 };
13204
13205
13206 /*
13207 Clear all patterns
13208 */
13209
13210 do_clearPatterns = function() {
13211 userSimplificationsInListForm = [];
13212 return userSimplificationsInStringForm = [];
13213 };
13214
13215 Eval_clearpatterns = function() {
13216 do_clearPatterns();
13217 return push_symbol(NIL);
13218 };
13219
13220 Eval_patternsinfo = function() {
13221 var patternsinfoToBePrinted;
13222 patternsinfoToBePrinted = patternsinfo();
13223 if (patternsinfoToBePrinted !== "") {
13224 return new_string(patternsinfoToBePrinted);
13225 } else {
13226 return push_symbol(NIL);
13227 }
13228 };
13229
13230 patternsinfo = function() {
13231 var i, i1, len, patternsinfoToBePrinted;
13232 patternsinfoToBePrinted = "";
13233 for (i1 = 0, len = userSimplificationsInListForm.length; i1 < len; i1++) {
13234 i = userSimplificationsInListForm[i1];
13235 patternsinfoToBePrinted += userSimplificationsInListForm + "\n";
13236 }
13237 return patternsinfoToBePrinted;
13238 };
13239
13240
13241 /*
13242 Convert complex z to polar form
13243
13244 Input: push z
13245
13246 Output: Result on stack
13247
13248 polar(z) = abs(z) * exp(i * arg(z))
13249 */
13250
13251 Eval_polar = function() {
13252 push(cadr(p1));
13253 Eval();
13254 return polar();
13255 };
13256
13257 polar = function() {
13258 evaluatingPolar++;
13259 save();
13260 p1 = pop();
13261 push(p1);
13262 abs();
13263 push(imaginaryunit);
13264 push(p1);
13265 arg();
13266 multiply();
13267 exponential();
13268 multiply();
13269 evaluatingPolar--;
13270 return restore();
13271 };
13272
13273 n_factor_number = 0;
13274
13275 factor_number = function() {
13276 var h;
13277 h = 0;
13278 save();
13279 p1 = pop();
13280 if (equaln(p1, 0) || equaln(p1, 1) || equaln(p1, -1)) {
13281 push(p1);
13282 restore();
13283 return;
13284 }
13285 n_factor_number = p1.q.a;
13286 h = tos;
13287 factor_a();
13288 if (tos - h > 1) {
13289 list(tos - h);
13290 push_symbol(MULTIPLY);
13291 swap();
13292 cons();
13293 }
13294 return restore();
13295 };
13296
13297 factor_a = function() {
13298 var i1, k;
13299 k = 0;
13300 if (n_factor_number.isNegative()) {
13301 n_factor_number = setSignTo(n_factor_number, 1);
13302 push_integer(-1);
13303 }
13304 for (k = i1 = 0; i1 < 10000; k = ++i1) {
13305 try_kth_prime(k);
13306 if (n_factor_number.compare(1) === 0) {
13307 return;
13308 }
13309 }
13310 return factor_b();
13311 };
13312
13313 try_kth_prime = function(k) {
13314 var count, d, q, r, ref1;
13315 count = 0;
13316 d = mint(primetab[k]);
13317 count = 0;
13318 while (1) {
13319 if (n_factor_number.compare(1) === 0) {
13320 if (count) {
13321 push_factor(d, count);
13322 }
13323 return;
13324 }
13325 ref1 = mdivrem(n_factor_number, d), q = ref1[0], r = ref1[1];
13326 if (r.isZero()) {
13327 count++;
13328 n_factor_number = q;
13329 } else {
13330 break;
13331 }
13332 }
13333 if (count) {
13334 push_factor(d, count);
13335 }
13336 if (mcmp(q, d) === -1) {
13337 push_factor(n_factor_number, 1);
13338 return n_factor_number = mint(1);
13339 }
13340 };
13341
13342 factor_b = function() {
13343 var bigint_one, g, k, l, t, x, xprime;
13344 k = 0;
13345 l = 0;
13346 bigint_one = mint(1);
13347 x = mint(5);
13348 xprime = mint(2);
13349 k = 1;
13350 l = 1;
13351 while (1) {
13352 if (mprime(n_factor_number)) {
13353 push_factor(n_factor_number, 1);
13354 return 0;
13355 }
13356 while (1) {
13357 if (esc_flag) {
13358 stop("esc");
13359 }
13360 t = msub(xprime, x);
13361 t = setSignTo(t, 1);
13362 g = mgcd(t, n_factor_number);
13363 if (MEQUAL(g, 1)) {
13364 if (--k === 0) {
13365 xprime = x;
13366 l *= 2;
13367 k = l;
13368 }
13369 t = mmul(x, x);
13370 x = madd(t, bigint_one);
13371 t = mmod(x, n_factor_number);
13372 x = t;
13373 continue;
13374 }
13375 push_factor(g, 1);
13376 if (mcmp(g, n_factor_number) === 0) {
13377 return -1;
13378 }
13379 t = mdiv(n_factor_number, g);
13380 n_factor_number = t;
13381 t = mmod(x, n_factor_number);
13382 x = t;
13383 t = mmod(xprime, n_factor_number);
13384 xprime = t;
13385 break;
13386 }
13387 }
13388 };
13389
13390 push_factor = function(d, count) {
13391 p1 = new U();
13392 p1.k = NUM;
13393 p1.q.a = d;
13394 p1.q.b = mint(1);
13395 push(p1);
13396 if (count > 1) {
13397 push_symbol(POWER);
13398 swap();
13399 p1 = new U();
13400 p1.k = NUM;
13401 p1.q.a = mint(count);
13402 p1.q.b = mint(1);
13403 push(p1);
13404 return list(3);
13405 }
13406 };
13407
13408
13409 /* Power function
13410
13411 Input: push Base
13412
13413 push Exponent
13414
13415 Output: Result on stack
13416 */
13417
13418 DEBUG_POWER = false;
13419
13420 Eval_power = function() {
13421 if (DEBUG_POWER) {
13422 debugger;
13423 }
13424 push(cadr(p1));
13425 Eval();
13426 push(caddr(p1));
13427 Eval();
13428 return power();
13429 };
13430
13431 power = function() {
13432 save();
13433 yypower();
13434 return restore();
13435 };
13436
13437 yypower = function() {
13438 var b_isEven_and_c_isItsInverse, hopefullySimplified, inputBase, inputExp, isThisOne, is_a_moreThanZero, n;
13439 if (DEBUG_POWER) {
13440 debugger;
13441 }
13442 n = 0;
13443 p2 = pop();
13444 p1 = pop();
13445 inputExp = p2;
13446 inputBase = p1;
13447 if (DEBUG_POWER) {
13448 console.log("POWER: " + p1 + " ^ " + p2);
13449 }
13450 if (equal(p1, one) || iszero(p2)) {
13451 if (evaluatingAsFloats) {
13452 push_double(1.0);
13453 } else {
13454 push(one);
13455 }
13456 if (DEBUG_POWER) {
13457 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13458 }
13459 return;
13460 }
13461 if (equal(p2, one)) {
13462 push(p1);
13463 if (DEBUG_POWER) {
13464 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13465 }
13466 return;
13467 }
13468 if (isminusone(p1) && isminusone(p2)) {
13469 if (evaluatingAsFloats) {
13470 push_double(1.0);
13471 } else {
13472 push(one);
13473 }
13474 negate();
13475 if (DEBUG_POWER) {
13476 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13477 }
13478 return;
13479 }
13480 if (isminusone(p1) && (isoneovertwo(p2))) {
13481 push(imaginaryunit);
13482 if (DEBUG_POWER) {
13483 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13484 }
13485 return;
13486 }
13487 if (isminusone(p1) && isminusoneovertwo(p2)) {
13488 push(imaginaryunit);
13489 negate();
13490 if (DEBUG_POWER) {
13491 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13492 }
13493 return;
13494 }
13495 if (isminusone(p1) && !isdouble(p1) && isrational(p2) && !isinteger(p2) && ispositivenumber(p2) && !evaluatingAsFloats) {
13496 if (DEBUG_POWER) {
13497 console.log(" power: -1 ^ rational");
13498 }
13499 if (DEBUG_POWER) {
13500 console.log(" trick: p2.q.a , p2.q.b " + p2.q.a + " , " + p2.q.b);
13501 }
13502 if (p2.q.a < p2.q.b) {
13503 push_symbol(POWER);
13504 push(p1);
13505 push(p2);
13506 list(3);
13507 } else {
13508 push_symbol(MULTIPLY);
13509 push(p1);
13510 push_symbol(POWER);
13511 push(p1);
13512 push_rational(p2.q.a.mod(p2.q.b), p2.q.b);
13513 list(3);
13514 list(3);
13515 if (DEBUG_POWER) {
13516 console.log(" trick applied : " + stack[tos - 1]);
13517 }
13518 }
13519 rect();
13520 if (DEBUG_POWER) {
13521 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13522 }
13523 return;
13524 }
13525 if (isrational(p1) && isrational(p2)) {
13526 if (DEBUG_POWER) {
13527 console.log(" power: isrational(p1) && isrational(p2)");
13528 }
13529 push(p1);
13530 push(p2);
13531 qpow();
13532 if (DEBUG_POWER) {
13533 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13534 }
13535 return;
13536 }
13537 if (isnum(p1) && isnum(p2)) {
13538 if (DEBUG_POWER) {
13539 console.log(" power: both base and exponent are either rational or double ");
13540 }
13541 if (DEBUG_POWER) {
13542 console.log("POWER - isnum(p1) && isnum(p2)");
13543 }
13544 push(p1);
13545 push(p2);
13546 dpow();
13547 if (DEBUG_POWER) {
13548 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13549 }
13550 return;
13551 }
13552 if (istensor(p1)) {
13553 if (DEBUG_POWER) {
13554 console.log(" power: istensor(p1) ");
13555 }
13556 power_tensor();
13557 if (DEBUG_POWER) {
13558 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13559 }
13560 return;
13561 }
13562 if (car(p1) === symbol(ABS) && iseveninteger(p2) && !iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
13563 if (DEBUG_POWER) {
13564 console.log(" power: even power of absolute of real value ");
13565 }
13566 push(cadr(p1));
13567 push(p2);
13568 power();
13569 if (DEBUG_POWER) {
13570 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13571 }
13572 return;
13573 }
13574 if (p1 === symbol(E) && car(p2) === symbol(LOG)) {
13575 push(cadr(p2));
13576 if (DEBUG_POWER) {
13577 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13578 }
13579 return;
13580 }
13581 if (p1 === symbol(E) && isdouble(p2)) {
13582 if (DEBUG_POWER) {
13583 console.log(" power: p1 == symbol(E) && isdouble(p2) ");
13584 }
13585 push_double(Math.exp(p2.d));
13586 if (DEBUG_POWER) {
13587 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13588 }
13589 return;
13590 }
13591 if (p1 === symbol(E) && Find(p2, imaginaryunit) !== 0 && Find(p2, symbol(PI)) !== 0 && !evaluatingPolar) {
13592 push_symbol(POWER);
13593 push(p1);
13594 push(p2);
13595 list(3);
13596 if (DEBUG_POWER) {
13597 console.log(" power: turning complex exponential to rect: " + stack[tos - 1]);
13598 }
13599 rect();
13600 hopefullySimplified = pop();
13601 if (Find(hopefullySimplified, symbol(PI)) === 0) {
13602 if (DEBUG_POWER) {
13603 console.log(" power: turned complex exponential to rect: " + hopefullySimplified);
13604 }
13605 push(hopefullySimplified);
13606 return;
13607 }
13608 }
13609 if (car(p1) === symbol(MULTIPLY) && isinteger(p2)) {
13610 if (DEBUG_POWER) {
13611 console.log(" power: (a * b) ^ c -> (a ^ c) * (b ^ c) ");
13612 }
13613 p1 = cdr(p1);
13614 push(car(p1));
13615 push(p2);
13616 power();
13617 p1 = cdr(p1);
13618 while (iscons(p1)) {
13619 push(car(p1));
13620 push(p2);
13621 power();
13622 multiply();
13623 p1 = cdr(p1);
13624 }
13625 if (DEBUG_POWER) {
13626 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13627 }
13628 return;
13629 }
13630 is_a_moreThanZero = false;
13631 if (isnum(cadr(p1))) {
13632 is_a_moreThanZero = sign(compare_numbers(cadr(p1), zero));
13633 }
13634 if (car(p1) === symbol(POWER) && (isinteger(p2) || is_a_moreThanZero)) {
13635 push(cadr(p1));
13636 push(caddr(p1));
13637 push(p2);
13638 multiply();
13639 power();
13640 if (DEBUG_POWER) {
13641 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13642 }
13643 return;
13644 }
13645 b_isEven_and_c_isItsInverse = false;
13646 if (iseveninteger(caddr(p1))) {
13647 push(caddr(p1));
13648 push(p2);
13649 multiply();
13650 isThisOne = pop();
13651 if (isone(isThisOne)) {
13652 b_isEven_and_c_isItsInverse = true;
13653 }
13654 }
13655 if (car(p1) === symbol(POWER) && b_isEven_and_c_isItsInverse) {
13656 if (DEBUG_POWER) {
13657 console.log(" power: car(p1) == symbol(POWER) && b_isEven_and_c_isItsInverse ");
13658 }
13659 push(cadr(p1));
13660 abs();
13661 if (DEBUG_POWER) {
13662 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13663 }
13664 return;
13665 }
13666 if (expanding && isadd(p1) && isnum(p2)) {
13667 push(p2);
13668 n = pop_integer();
13669 if (n > 1 && !isNaN(n)) {
13670 if (DEBUG_POWER) {
13671 console.log(" power: expanding && isadd(p1) && isnum(p2) ");
13672 }
13673 power_sum(n);
13674 if (DEBUG_POWER) {
13675 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13676 }
13677 return;
13678 }
13679 }
13680 if (trigmode === 1 && car(p1) === symbol(SIN) && iseveninteger(p2)) {
13681 if (DEBUG_POWER) {
13682 console.log(" power: trigmode == 1 && car(p1) == symbol(SIN) && iseveninteger(p2) ");
13683 }
13684 push_integer(1);
13685 push(cadr(p1));
13686 cosine();
13687 push_integer(2);
13688 power();
13689 subtract();
13690 push(p2);
13691 push_rational(1, 2);
13692 multiply();
13693 power();
13694 if (DEBUG_POWER) {
13695 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13696 }
13697 return;
13698 }
13699 if (trigmode === 2 && car(p1) === symbol(COS) && iseveninteger(p2)) {
13700 if (DEBUG_POWER) {
13701 console.log(" power: trigmode == 2 && car(p1) == symbol(COS) && iseveninteger(p2) ");
13702 }
13703 push_integer(1);
13704 push(cadr(p1));
13705 sine();
13706 push_integer(2);
13707 power();
13708 subtract();
13709 push(p2);
13710 push_rational(1, 2);
13711 multiply();
13712 power();
13713 if (DEBUG_POWER) {
13714 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13715 }
13716 return;
13717 }
13718 if (iscomplexnumber(p1)) {
13719 if (DEBUG_POWER) {
13720 console.log(" power - handling the case (a + ib) ^ n");
13721 }
13722 if (isinteger(p2)) {
13723 push(p1);
13724 conjugate();
13725 p3 = pop();
13726 push(p3);
13727 push(p3);
13728 push(p1);
13729 multiply();
13730 divide();
13731 if (!isone(p2)) {
13732 push(p2);
13733 negate();
13734 power();
13735 }
13736 if (DEBUG_POWER) {
13737 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13738 }
13739 return;
13740 }
13741 if (isnum(p2)) {
13742 push(p1);
13743 abs();
13744 push(p2);
13745 power();
13746 push_integer(-1);
13747 push(p1);
13748 arg();
13749 push(p2);
13750 multiply();
13751 if (evaluatingAsFloats || (iscomplexnumberdouble(p1) && isdouble(p2))) {
13752 push_double(Math.PI);
13753 } else {
13754 push(symbol(PI));
13755 }
13756 divide();
13757 power();
13758 multiply();
13759 if (avoidCalculatingPowersIntoArctans) {
13760 if (Find(stack[tos - 1], symbol(ARCTAN))) {
13761 pop();
13762 push_symbol(POWER);
13763 push(p1);
13764 push(p2);
13765 list(3);
13766 }
13767 }
13768 if (DEBUG_POWER) {
13769 console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13770 }
13771 return;
13772 }
13773 }
13774 if (simplify_polar()) {
13775 if (DEBUG_POWER) {
13776 console.log(" power: using simplify_polar");
13777 }
13778 return;
13779 }
13780 if (DEBUG_POWER) {
13781 console.log(" power: nothing can be done ");
13782 }
13783 push_symbol(POWER);
13784 push(p1);
13785 push(p2);
13786 list(3);
13787 if (DEBUG_POWER) {
13788 return console.log(" power of " + inputBase + " ^ " + inputExp + ": " + stack[tos - 1]);
13789 }
13790 };
13791
13792 power_sum = function(n) {
13793 var a, i, i1, j, j1, k, l1, ref1, ref2, ref3;
13794 a = [];
13795 i = 0;
13796 j = 0;
13797 k = 0;
13798 k = length(p1) - 1;
13799 push_frame(k * (n + 1));
13800 p1 = cdr(p1);
13801 for (i = i1 = 0, ref1 = k; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
13802 for (j = j1 = 0, ref2 = n; 0 <= ref2 ? j1 <= ref2 : j1 >= ref2; j = 0 <= ref2 ? ++j1 : --j1) {
13803 push(car(p1));
13804 push_integer(j);
13805 power();
13806 stack[frame + i * (n + 1) + j] = pop();
13807 }
13808 p1 = cdr(p1);
13809 }
13810 push_integer(n);
13811 factorial();
13812 p1 = pop();
13813 for (i = l1 = 0, ref3 = k; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
13814 a[i] = 0;
13815 }
13816 push(zero);
13817 multinomial_sum(k, n, a, 0, n);
13818 return pop_frame(k * (n + 1));
13819 };
13820
13821 multinomial_sum = function(k, n, a, i, m) {
13822 var i1, j, j1, l1, ref1, ref2, ref3;
13823 j = 0;
13824 if (i < k - 1) {
13825 for (j = i1 = 0, ref1 = m; 0 <= ref1 ? i1 <= ref1 : i1 >= ref1; j = 0 <= ref1 ? ++i1 : --i1) {
13826 a[i] = j;
13827 multinomial_sum(k, n, a, i + 1, m - j);
13828 }
13829 return;
13830 }
13831 a[i] = m;
13832 push(p1);
13833 for (j = j1 = 0, ref2 = k; 0 <= ref2 ? j1 < ref2 : j1 > ref2; j = 0 <= ref2 ? ++j1 : --j1) {
13834 push_integer(a[j]);
13835 factorial();
13836 divide();
13837 }
13838 for (j = l1 = 0, ref3 = k; 0 <= ref3 ? l1 < ref3 : l1 > ref3; j = 0 <= ref3 ? ++l1 : --l1) {
13839 push(stack[frame + j * (n + 1) + a[j]]);
13840 multiply();
13841 }
13842 return add();
13843 };
13844
13845 simplify_polar = function() {
13846 var doNothing, n;
13847 n = 0;
13848 n = isquarterturn(p2);
13849 switch (n) {
13850 case 0:
13851 doNothing = 1;
13852 break;
13853 case 1:
13854 push_integer(1);
13855 return 1;
13856 case 2:
13857 push_integer(-1);
13858 return 1;
13859 case 3:
13860 push(imaginaryunit);
13861 return 1;
13862 case 4:
13863 push(imaginaryunit);
13864 negate();
13865 return 1;
13866 }
13867 if (car(p2) === symbol(ADD)) {
13868 p3 = cdr(p2);
13869 while (iscons(p3)) {
13870 n = isquarterturn(car(p3));
13871 if (n) {
13872 break;
13873 }
13874 p3 = cdr(p3);
13875 }
13876 switch (n) {
13877 case 0:
13878 return 0;
13879 case 1:
13880 push_integer(1);
13881 break;
13882 case 2:
13883 push_integer(-1);
13884 break;
13885 case 3:
13886 push(imaginaryunit);
13887 break;
13888 case 4:
13889 push(imaginaryunit);
13890 negate();
13891 }
13892 push(p2);
13893 push(car(p3));
13894 subtract();
13895 exponential();
13896 multiply();
13897 return 1;
13898 }
13899 return 0;
13900 };
13901
13902 Eval_prime = function() {
13903 push(cadr(p1));
13904 Eval();
13905 return prime();
13906 };
13907
13908 prime = function() {
13909 var n;
13910 n = 0;
13911 n = pop_integer();
13912 if (n < 1 || n > MAXPRIMETAB) {
13913 stop("prime: Argument out of range.");
13914 }
13915 n = primetab[n - 1];
13916 return push_integer(n);
13917 };
13918
13919 power_str = "^";
13920
13921 codeGen = false;
13922
13923 Eval_print = function() {
13924 stringsEmittedByUserPrintouts += _print(cdr(p1), environment_printmode);
13925 return push(symbol(NIL));
13926 };
13927
13928 Eval_print2dascii = function() {
13929 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_2DASCII);
13930 return push(symbol(NIL));
13931 };
13932
13933 Eval_printfull = function() {
13934 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_FULL);
13935 return push(symbol(NIL));
13936 };
13937
13938 Eval_printlatex = function() {
13939 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_LATEX);
13940 return push(symbol(NIL));
13941 };
13942
13943 Eval_printplain = function() {
13944 var original_test_flag;
13945 original_test_flag = test_flag;
13946 test_flag = 0;
13947 stringsEmittedByUserPrintouts += _print(cdr(p1), PRINTMODE_PLAIN);
13948 test_flag = original_test_flag;
13949 return push(symbol(NIL));
13950 };
13951
13952 Eval_printlist = function() {
13953 var beenPrinted;
13954 beenPrinted = _print(cdr(p1), PRINTMODE_LIST);
13955 stringsEmittedByUserPrintouts += beenPrinted;
13956 return push(symbol(NIL));
13957 };
13958
13959 _print = function(p, passedPrintMode) {
13960 var accumulator, origPrintMode;
13961 accumulator = "";
13962 while (iscons(p)) {
13963 push(car(p));
13964 Eval();
13965 p2 = pop();
13966
13967 /*
13968 if (issymbol(car(p)) && car(p) != p2)
13969 push_symbol(SETQ);
13970 push(car(p));
13971 push(p2);
13972 list(3);
13973 p2 = pop();
13974 */
13975 origPrintMode = printMode;
13976 if (passedPrintMode === PRINTMODE_FULL) {
13977 printMode = PRINTMODE_FULL;
13978 accumulator = printline(p2);
13979 rememberPrint(accumulator, LAST_FULL_PRINT);
13980 } else if (passedPrintMode === PRINTMODE_PLAIN) {
13981 printMode = PRINTMODE_PLAIN;
13982 accumulator = printline(p2);
13983 rememberPrint(accumulator, LAST_PLAIN_PRINT);
13984 } else if (passedPrintMode === PRINTMODE_2DASCII) {
13985 printMode = PRINTMODE_2DASCII;
13986 accumulator = print2dascii(p2);
13987 rememberPrint(accumulator, LAST_2DASCII_PRINT);
13988 } else if (passedPrintMode === PRINTMODE_LATEX) {
13989 printMode = PRINTMODE_LATEX;
13990 accumulator = printline(p2);
13991 rememberPrint(accumulator, LAST_LATEX_PRINT);
13992 } else if (passedPrintMode === PRINTMODE_LIST) {
13993 printMode = PRINTMODE_LIST;
13994 accumulator = print_list(p2);
13995 rememberPrint(accumulator, LAST_LIST_PRINT);
13996 }
13997 printMode = origPrintMode;
13998 p = cdr(p);
13999 }
14000 if (DEBUG) {
14001 console.log("emttedString from display: " + stringsEmittedByUserPrintouts);
14002 }
14003 return accumulator;
14004 };
14005
14006 rememberPrint = function(theString, theTypeOfPrint) {
14007 var parsedString;
14008 scan('"' + theString + '"');
14009 parsedString = pop();
14010 return set_binding(symbol(theTypeOfPrint), parsedString);
14011 };
14012
14013 print_str = function(s) {
14014 if (DEBUG) {
14015 console.log("emttedString from print_str: " + stringsEmittedByUserPrintouts);
14016 }
14017 return s;
14018 };
14019
14020 print_char = function(c) {
14021 return c;
14022 };
14023
14024 collectLatexStringFromReturnValue = function(p) {
14025 var origPrintMode, originalCodeGen, returnedString;
14026 origPrintMode = printMode;
14027 printMode = PRINTMODE_LATEX;
14028 originalCodeGen = codeGen;
14029 codeGen = false;
14030 returnedString = print_expr(p);
14031 returnedString = returnedString.replace(/_/g, "\\_");
14032 printMode = origPrintMode;
14033 codeGen = originalCodeGen;
14034 if (DEBUG) {
14035 console.log("emttedString from collectLatexStringFromReturnValue: " + stringsEmittedByUserPrintouts);
14036 }
14037 return returnedString;
14038 };
14039
14040 printline = function(p) {
14041 var accumulator;
14042 accumulator = "";
14043 accumulator += print_expr(p);
14044 return accumulator;
14045 };
14046
14047 print_base_of_denom = function(p1) {
14048 var accumulator;
14049 accumulator = "";
14050 if (isfraction(p1) || car(p1) === symbol(ADD) || car(p1) === symbol(MULTIPLY) || car(p1) === symbol(POWER) || lessp(p1, zero)) {
14051 accumulator += print_char('(');
14052 accumulator += print_expr(p1);
14053 accumulator += print_char(')');
14054 } else {
14055 accumulator += print_expr(p1);
14056 }
14057 return accumulator;
14058 };
14059
14060 print_expo_of_denom = function(p2) {
14061 var accumulator;
14062 accumulator = "";
14063 if (isfraction(p2) || car(p2) === symbol(ADD) || car(p2) === symbol(MULTIPLY) || car(p2) === symbol(POWER)) {
14064 accumulator += print_char('(');
14065 accumulator += print_expr(p2);
14066 accumulator += print_char(')');
14067 } else {
14068 accumulator += print_expr(p2);
14069 }
14070 return accumulator;
14071 };
14072
14073 print_denom = function(p, d) {
14074 var accumulator;
14075 accumulator = "";
14076 save();
14077 p1 = cadr(p);
14078 p2 = caddr(p);
14079 if (isminusone(p2)) {
14080 accumulator += print_base_of_denom(p1);
14081 restore();
14082 return accumulator;
14083 }
14084 if (d === 1) {
14085 accumulator += print_char('(');
14086 }
14087 push(p2);
14088 negate();
14089 p2 = pop();
14090 accumulator += print_power(p1, p2);
14091 if (d === 1) {
14092 accumulator += print_char(')');
14093 }
14094 restore();
14095 return accumulator;
14096 };
14097
14098 print_a_over_b = function(p) {
14099 var accumulator, d, doNothing, n;
14100 accumulator = "";
14101 flag = 0;
14102 n = 0;
14103 d = 0;
14104 save();
14105 n = 0;
14106 d = 0;
14107 p1 = cdr(p);
14108 p2 = car(p1);
14109 if (isrational(p2)) {
14110 push(p2);
14111 mp_numerator();
14112 absval();
14113 p3 = pop();
14114 push(p2);
14115 mp_denominator();
14116 p4 = pop();
14117 if (!isplusone(p3)) {
14118 n++;
14119 }
14120 if (!isplusone(p4)) {
14121 d++;
14122 }
14123 p1 = cdr(p1);
14124 } else {
14125 p3 = one;
14126 p4 = one;
14127 }
14128 while (iscons(p1)) {
14129 p2 = car(p1);
14130 if (is_denominator(p2)) {
14131 d++;
14132 } else {
14133 n++;
14134 }
14135 p1 = cdr(p1);
14136 }
14137 if (printMode === PRINTMODE_LATEX) {
14138 accumulator += print_str('\\frac{');
14139 }
14140 if (n === 0) {
14141 accumulator += print_char('1');
14142 } else {
14143 flag = 0;
14144 p1 = cdr(p);
14145 if (isrational(car(p1))) {
14146 p1 = cdr(p1);
14147 }
14148 if (!isplusone(p3)) {
14149 accumulator += print_factor(p3);
14150 flag = 1;
14151 }
14152 while (iscons(p1)) {
14153 p2 = car(p1);
14154 if (is_denominator(p2)) {
14155 doNothing = 1;
14156 } else {
14157 if (flag) {
14158 accumulator += print_multiply_sign();
14159 }
14160 accumulator += print_factor(p2);
14161 flag = 1;
14162 }
14163 p1 = cdr(p1);
14164 }
14165 }
14166 if (printMode === PRINTMODE_LATEX) {
14167 accumulator += print_str('}{');
14168 } else if (printMode === PRINTMODE_PLAIN && !test_flag) {
14169 accumulator += print_str(" / ");
14170 } else {
14171 accumulator += print_str("/");
14172 }
14173 if (d > 1 && printMode !== PRINTMODE_LATEX) {
14174 accumulator += print_char('(');
14175 }
14176 flag = 0;
14177 p1 = cdr(p);
14178 if (isrational(car(p1))) {
14179 p1 = cdr(p1);
14180 }
14181 if (!isplusone(p4)) {
14182 accumulator += print_factor(p4);
14183 flag = 1;
14184 }
14185 while (iscons(p1)) {
14186 p2 = car(p1);
14187 if (is_denominator(p2)) {
14188 if (flag) {
14189 accumulator += print_multiply_sign();
14190 }
14191 accumulator += print_denom(p2, d);
14192 flag = 1;
14193 }
14194 p1 = cdr(p1);
14195 }
14196 if (d > 1 && printMode !== PRINTMODE_LATEX) {
14197 accumulator += print_char(')');
14198 }
14199 if (printMode === PRINTMODE_LATEX) {
14200 accumulator += print_str('}');
14201 }
14202 restore();
14203 return accumulator;
14204 };
14205
14206 print_expr = function(p) {
14207 var accumulator;
14208 accumulator = "";
14209 if (isadd(p)) {
14210 p = cdr(p);
14211 if (sign_of_term(car(p)) === '-') {
14212 accumulator += print_str("-");
14213 }
14214 accumulator += print_term(car(p));
14215 p = cdr(p);
14216 while (iscons(p)) {
14217 if (sign_of_term(car(p)) === '+') {
14218 if (printMode === PRINTMODE_PLAIN && !test_flag) {
14219 accumulator += print_str(" + ");
14220 } else {
14221 accumulator += print_str("+");
14222 }
14223 } else {
14224 if (printMode === PRINTMODE_PLAIN && !test_flag) {
14225 accumulator += print_str(" - ");
14226 } else {
14227 accumulator += print_str("-");
14228 }
14229 }
14230 accumulator += print_term(car(p));
14231 p = cdr(p);
14232 }
14233 } else {
14234 if (sign_of_term(p) === '-') {
14235 accumulator += print_str("-");
14236 }
14237 accumulator += print_term(p);
14238 }
14239 return accumulator;
14240 };
14241
14242 sign_of_term = function(p) {
14243 var accumulator;
14244 accumulator = "";
14245 if (car(p) === symbol(MULTIPLY) && isnum(cadr(p)) && lessp(cadr(p), zero)) {
14246 accumulator += '-';
14247 } else if (isnum(p) && lessp(p, zero)) {
14248 accumulator += '-';
14249 } else {
14250 accumulator += '+';
14251 }
14252 return accumulator;
14253 };
14254
14255 print_term = function(p) {
14256 var accumulator, denom, numberOneOverSomething, origAccumulator, previousFactorWasANumber;
14257 accumulator = "";
14258 if (car(p) === symbol(MULTIPLY) && any_denominators(p)) {
14259 accumulator += print_a_over_b(p);
14260 return accumulator;
14261 }
14262 if (car(p) === symbol(MULTIPLY)) {
14263 p = cdr(p);
14264 if (isminusone(car(p))) {
14265 p = cdr(p);
14266 }
14267 previousFactorWasANumber = false;
14268 if (isnum(car(p))) {
14269 previousFactorWasANumber = true;
14270 }
14271 numberOneOverSomething = false;
14272 if (printMode === PRINTMODE_LATEX && iscons(cdr(p)) && isnumberoneoversomething(car(p))) {
14273 numberOneOverSomething = true;
14274 denom = car(p).q.b.toString();
14275 }
14276 if (numberOneOverSomething) {
14277 origAccumulator = accumulator;
14278 accumulator = "";
14279 } else {
14280 accumulator += print_factor(car(p));
14281 }
14282 p = cdr(p);
14283 while (iscons(p)) {
14284 if (printMode === PRINTMODE_LATEX) {
14285 if (previousFactorWasANumber) {
14286 if (caar(p) === symbol(POWER)) {
14287 if (isnum(car(cdr(car(p))))) {
14288 if (!isfraction(car(cdr(cdr(car(p)))))) {
14289 accumulator += " \\cdot ";
14290 }
14291 }
14292 }
14293 }
14294 }
14295 accumulator += print_multiply_sign();
14296 accumulator += print_factor(car(p));
14297 previousFactorWasANumber = false;
14298 if (isnum(car(p))) {
14299 previousFactorWasANumber = true;
14300 }
14301 p = cdr(p);
14302 }
14303 if (numberOneOverSomething) {
14304 accumulator = origAccumulator + "\\frac{" + accumulator + "}{" + denom + "}";
14305 }
14306 } else {
14307 accumulator += print_factor(p);
14308 }
14309 return accumulator;
14310 };
14311
14312 print_subexpr = function(p) {
14313 var accumulator;
14314 accumulator = "";
14315 accumulator += print_char('(');
14316 accumulator += print_expr(p);
14317 accumulator += print_char(')');
14318 return accumulator;
14319 };
14320
14321 print_factorial_function = function(p) {
14322 var accumulator;
14323 accumulator = "";
14324 p = cadr(p);
14325 if (car(p) === symbol(ADD) || car(p) === symbol(MULTIPLY) || car(p) === symbol(POWER) || car(p) === symbol(FACTORIAL)) {
14326 accumulator += print_subexpr(p);
14327 } else {
14328 accumulator += print_expr(p);
14329 }
14330 accumulator += print_char('!');
14331 return accumulator;
14332 };
14333
14334 print_ABS_latex = function(p) {
14335 var accumulator;
14336 accumulator = "";
14337 accumulator += print_str("\\left |");
14338 accumulator += print_expr(cadr(p));
14339 accumulator += print_str(" \\right |");
14340 return accumulator;
14341 };
14342
14343 print_BINOMIAL_latex = function(p) {
14344 var accumulator;
14345 accumulator = "";
14346 accumulator += print_str("\\binom{");
14347 accumulator += print_expr(cadr(p));
14348 accumulator += print_str("}{");
14349 accumulator += print_expr(caddr(p));
14350 accumulator += print_str("} ");
14351 return accumulator;
14352 };
14353
14354 print_DOT_latex = function(p) {
14355 var accumulator;
14356 accumulator = "";
14357 accumulator += print_expr(cadr(p));
14358 accumulator += print_str(" \\cdot ");
14359 accumulator += print_expr(caddr(p));
14360 return accumulator;
14361 };
14362
14363 print_DOT_codegen = function(p) {
14364 var accumulator;
14365 accumulator = "dot(";
14366 accumulator += print_expr(cadr(p));
14367 accumulator += ", ";
14368 accumulator += print_expr(caddr(p));
14369 accumulator += ")";
14370 return accumulator;
14371 };
14372
14373 print_SIN_codegen = function(p) {
14374 var accumulator;
14375 accumulator = "Math.sin(";
14376 accumulator += print_expr(cadr(p));
14377 accumulator += ")";
14378 return accumulator;
14379 };
14380
14381 print_COS_codegen = function(p) {
14382 var accumulator;
14383 accumulator = "Math.cos(";
14384 accumulator += print_expr(cadr(p));
14385 accumulator += ")";
14386 return accumulator;
14387 };
14388
14389 print_TAN_codegen = function(p) {
14390 var accumulator;
14391 accumulator = "Math.tan(";
14392 accumulator += print_expr(cadr(p));
14393 accumulator += ")";
14394 return accumulator;
14395 };
14396
14397 print_ARCSIN_codegen = function(p) {
14398 var accumulator;
14399 accumulator = "Math.asin(";
14400 accumulator += print_expr(cadr(p));
14401 accumulator += ")";
14402 return accumulator;
14403 };
14404
14405 print_ARCCOS_codegen = function(p) {
14406 var accumulator;
14407 accumulator = "Math.acos(";
14408 accumulator += print_expr(cadr(p));
14409 accumulator += ")";
14410 return accumulator;
14411 };
14412
14413 print_ARCTAN_codegen = function(p) {
14414 var accumulator;
14415 accumulator = "Math.atan(";
14416 accumulator += print_expr(cadr(p));
14417 accumulator += ")";
14418 return accumulator;
14419 };
14420
14421 print_SQRT_latex = function(p) {
14422 var accumulator;
14423 accumulator = "";
14424 accumulator += print_str("\\sqrt{");
14425 accumulator += print_expr(cadr(p));
14426 accumulator += print_str("} ");
14427 return accumulator;
14428 };
14429
14430 print_TRANSPOSE_latex = function(p) {
14431 var accumulator;
14432 accumulator = "";
14433 accumulator += print_str("{");
14434 if (iscons(cadr(p))) {
14435 accumulator += print_str('(');
14436 }
14437 accumulator += print_expr(cadr(p));
14438 if (iscons(cadr(p))) {
14439 accumulator += print_str(')');
14440 }
14441 accumulator += print_str("}");
14442 accumulator += print_str("^T");
14443 return accumulator;
14444 };
14445
14446 print_TRANSPOSE_codegen = function(p) {
14447 var accumulator;
14448 accumulator = "";
14449 accumulator += print_str("transpose(");
14450 accumulator += print_expr(cadr(p));
14451 accumulator += print_str(')');
14452 return accumulator;
14453 };
14454
14455 print_UNIT_codegen = function(p) {
14456 var accumulator;
14457 accumulator = "";
14458 accumulator += print_str("identity(");
14459 accumulator += print_expr(cadr(p));
14460 accumulator += print_str(')');
14461 return accumulator;
14462 };
14463
14464 print_INV_latex = function(p) {
14465 var accumulator;
14466 accumulator = "";
14467 accumulator += print_str("{");
14468 if (iscons(cadr(p))) {
14469 accumulator += print_str('(');
14470 }
14471 accumulator += print_expr(cadr(p));
14472 if (iscons(cadr(p))) {
14473 accumulator += print_str(')');
14474 }
14475 accumulator += print_str("}");
14476 accumulator += print_str("^{-1}");
14477 return accumulator;
14478 };
14479
14480 print_INV_codegen = function(p) {
14481 var accumulator;
14482 accumulator = "";
14483 accumulator += print_str("inv(");
14484 accumulator += print_expr(cadr(p));
14485 accumulator += print_str(')');
14486 return accumulator;
14487 };
14488
14489 print_DEFINT_latex = function(p) {
14490 var accumulator, functionBody, i, i1, numberOfIntegrals, originalIntegral, ref1, theIntegral, theVariable;
14491 accumulator = "";
14492 functionBody = car(cdr(p));
14493 p = cdr(p);
14494 originalIntegral = p;
14495 numberOfIntegrals = 0;
14496 while (iscons(cdr(cdr(p)))) {
14497 numberOfIntegrals++;
14498 theIntegral = cdr(cdr(p));
14499 accumulator += print_str("\\int^{");
14500 accumulator += print_expr(car(cdr(theIntegral)));
14501 accumulator += print_str("}_{");
14502 accumulator += print_expr(car(theIntegral));
14503 accumulator += print_str("} \\! ");
14504 p = cdr(theIntegral);
14505 }
14506 accumulator += print_expr(functionBody);
14507 accumulator += print_str(" \\,");
14508 p = originalIntegral;
14509 for (i = i1 = 1, ref1 = numberOfIntegrals; 1 <= ref1 ? i1 <= ref1 : i1 >= ref1; i = 1 <= ref1 ? ++i1 : --i1) {
14510 theVariable = cdr(p);
14511 accumulator += print_str(" \\mathrm{d} ");
14512 accumulator += print_expr(car(theVariable));
14513 if (i < numberOfIntegrals) {
14514 accumulator += print_str(" \\, ");
14515 }
14516 p = cdr(cdr(theVariable));
14517 }
14518 return accumulator;
14519 };
14520
14521 print_tensor = function(p) {
14522 var accumulator;
14523 accumulator = "";
14524 accumulator += print_tensor_inner(p, 0, 0)[1];
14525 return accumulator;
14526 };
14527
14528 print_tensor_inner = function(p, j, k) {
14529 var accumulator, i, i1, j1, ref1, ref2, ref3, retString;
14530 accumulator = "";
14531 accumulator += print_str("[");
14532 if (j < p.tensor.ndim - 1) {
14533 for (i = i1 = 0, ref1 = p.tensor.dim[j]; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
14534 ref2 = print_tensor_inner(p, j + 1, k), k = ref2[0], retString = ref2[1];
14535 accumulator += retString;
14536 if (i !== p.tensor.dim[j] - 1) {
14537 accumulator += print_str(",");
14538 }
14539 }
14540 } else {
14541 for (i = j1 = 0, ref3 = p.tensor.dim[j]; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
14542 accumulator += print_expr(p.tensor.elem[k]);
14543 if (i !== p.tensor.dim[j] - 1) {
14544 accumulator += print_str(",");
14545 }
14546 k++;
14547 }
14548 }
14549 accumulator += print_str("]");
14550 return [k, accumulator];
14551 };
14552
14553 print_tensor_latex = function(p) {
14554 var accumulator;
14555 accumulator = "";
14556 if (p.tensor.ndim <= 2) {
14557 accumulator += print_tensor_inner_latex(true, p, 0, 0)[1];
14558 }
14559 return accumulator;
14560 };
14561
14562 print_tensor_inner_latex = function(firstLevel, p, j, k) {
14563 var accumulator, i, i1, j1, ref1, ref2, ref3, retString;
14564 accumulator = "";
14565 if (firstLevel) {
14566 accumulator += "\\begin{bmatrix} ";
14567 }
14568 if (j < p.tensor.ndim - 1) {
14569 for (i = i1 = 0, ref1 = p.tensor.dim[j]; 0 <= ref1 ? i1 < ref1 : i1 > ref1; i = 0 <= ref1 ? ++i1 : --i1) {
14570 ref2 = print_tensor_inner_latex(0, p, j + 1, k), k = ref2[0], retString = ref2[1];
14571 accumulator += retString;
14572 if (i !== p.tensor.dim[j] - 1) {
14573 accumulator += print_str(" \\\\ ");
14574 }
14575 }
14576 } else {
14577 for (i = j1 = 0, ref3 = p.tensor.dim[j]; 0 <= ref3 ? j1 < ref3 : j1 > ref3; i = 0 <= ref3 ? ++j1 : --j1) {
14578 accumulator += print_expr(p.tensor.elem[k]);
14579 if (i !== p.tensor.dim[j] - 1) {
14580 accumulator += print_str(" & ");
14581 }
14582 k++;
14583 }
14584 }
14585 if (firstLevel) {
14586 accumulator += " \\end{bmatrix}";
14587 }
14588 return [k, accumulator];
14589 };
14590
14591 print_SUM_latex = function(p) {
14592 var accumulator;
14593 accumulator = "\\sum_{";
14594 accumulator += print_expr(caddr(p));
14595 accumulator += "=";
14596 accumulator += print_expr(cadddr(p));
14597 accumulator += "}^{";
14598 accumulator += print_expr(caddddr(p));
14599 accumulator += "}{";
14600 accumulator += print_expr(cadr(p));
14601 accumulator += "}";
14602 return accumulator;
14603 };
14604
14605 print_SUM_codegen = function(p) {
14606 var accumulator, body, lowerlimit, upperlimit, variable;
14607 body = cadr(p);
14608 variable = caddr(p);
14609 lowerlimit = cadddr(p);
14610 upperlimit = caddddr(p);
14611 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;" + "})()";
14612 return accumulator;
14613 };
14614
14615 print_TEST_latex = function(p) {
14616 var accumulator;
14617 accumulator = "\\left\\{ \\begin{array}{ll}";
14618 p = cdr(p);
14619 while (iscons(p)) {
14620 if (cdr(p) === symbol(NIL)) {
14621 accumulator += "{";
14622 accumulator += print_expr(car(p));
14623 accumulator += "} & otherwise ";
14624 accumulator += " \\\\\\\\";
14625 break;
14626 }
14627 accumulator += "{";
14628 accumulator += print_expr(cadr(p));
14629 accumulator += "} & if & ";
14630 accumulator += print_expr(car(p));
14631 accumulator += " \\\\\\\\";
14632 p = cddr(p);
14633 }
14634 accumulator = accumulator.substring(0, accumulator.length - 4);
14635 return accumulator += "\\end{array} \\right.";
14636 };
14637
14638 print_TEST_codegen = function(p) {
14639 var accumulator, howManyIfs;
14640 accumulator = "(function(){";
14641 p = cdr(p);
14642 howManyIfs = 0;
14643 while (iscons(p)) {
14644 if (cdr(p) === symbol(NIL)) {
14645 accumulator += "else {";
14646 accumulator += "return (" + print_expr(car(p)) + ");";
14647 accumulator += "}";
14648 break;
14649 }
14650 if (howManyIfs) {
14651 accumulator += " else ";
14652 }
14653 accumulator += "if (" + print_expr(car(p)) + "){";
14654 accumulator += "return (" + print_expr(cadr(p)) + ");";
14655 accumulator += "}";
14656 howManyIfs++;
14657 p = cddr(p);
14658 }
14659 accumulator += "})()";
14660 return accumulator;
14661 };
14662
14663 print_TESTLT_latex = function(p) {
14664 var accumulator;
14665 accumulator = "{";
14666 accumulator += print_expr(cadr(p));
14667 accumulator += "}";
14668 accumulator += " < ";
14669 accumulator += "{";
14670 accumulator += print_expr(caddr(p));
14671 return accumulator += "}";
14672 };
14673
14674 print_TESTLE_latex = function(p) {
14675 var accumulator;
14676 accumulator = "{";
14677 accumulator += print_expr(cadr(p));
14678 accumulator += "}";
14679 accumulator += " \\leq ";
14680 accumulator += "{";
14681 accumulator += print_expr(caddr(p));
14682 return accumulator += "}";
14683 };
14684
14685 print_TESTGT_latex = function(p) {
14686 var accumulator;
14687 accumulator = "{";
14688 accumulator += print_expr(cadr(p));
14689 accumulator += "}";
14690 accumulator += " > ";
14691 accumulator += "{";
14692 accumulator += print_expr(caddr(p));
14693 return accumulator += "}";
14694 };
14695
14696 print_TESTGE_latex = function(p) {
14697 var accumulator;
14698 accumulator = "{";
14699 accumulator += print_expr(cadr(p));
14700 accumulator += "}";
14701 accumulator += " \\geq ";
14702 accumulator += "{";
14703 accumulator += print_expr(caddr(p));
14704 return accumulator += "}";
14705 };
14706
14707 print_TESTEQ_latex = function(p) {
14708 var accumulator;
14709 accumulator = "{";
14710 accumulator += print_expr(cadr(p));
14711 accumulator += "}";
14712 accumulator += " = ";
14713 accumulator += "{";
14714 accumulator += print_expr(caddr(p));
14715 return accumulator += "}";
14716 };
14717
14718 print_FOR_codegen = function(p) {
14719 var accumulator, body, lowerlimit, upperlimit, variable;
14720 body = cadr(p);
14721 variable = caddr(p);
14722 lowerlimit = cadddr(p);
14723 upperlimit = caddddr(p);
14724 accumulator = "(function(){" + " var " + variable + "; " + " var lowerlimit = " + print_expr(lowerlimit) + "; " + " var upperlimit = " + print_expr(upperlimit) + "; " + " for (" + variable + " = lowerlimit; " + variable + " < upperlimit; " + variable + "++) { " + " " + print_expr(body) + " } " + "})()";
14725 return accumulator;
14726 };
14727
14728 print_DO_codegen = function(p) {
14729 var accumulator;
14730 accumulator = "";
14731 p = cdr(p);
14732 while (iscons(p)) {
14733 accumulator += print_expr(car(p));
14734 p = cdr(p);
14735 }
14736 return accumulator;
14737 };
14738
14739 print_SETQ_codegen = function(p) {
14740 var accumulator;
14741 accumulator = "";
14742 accumulator += print_expr(cadr(p));
14743 accumulator += " = ";
14744 accumulator += print_expr(caddr(p));
14745 accumulator += "; ";
14746 return accumulator;
14747 };
14748
14749 print_PRODUCT_latex = function(p) {
14750 var accumulator;
14751 accumulator = "\\prod_{";
14752 accumulator += print_expr(caddr(p));
14753 accumulator += "=";
14754 accumulator += print_expr(cadddr(p));
14755 accumulator += "}^{";
14756 accumulator += print_expr(caddddr(p));
14757 accumulator += "}{";
14758 accumulator += print_expr(cadr(p));
14759 accumulator += "}";
14760 return accumulator;
14761 };
14762
14763 print_PRODUCT_codegen = function(p) {
14764 var accumulator, body, lowerlimit, upperlimit, variable;
14765 body = cadr(p);
14766 variable = caddr(p);
14767 lowerlimit = cadddr(p);
14768 upperlimit = caddddr(p);
14769 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;" + "})()";
14770 return accumulator;
14771 };
14772
14773 print_base = function(p) {
14774 var accumulator;
14775 accumulator = "";
14776 if (isadd(cadr(p)) || caadr(p) === symbol(MULTIPLY) || caadr(p) === symbol(POWER) || isnegativenumber(cadr(p))) {
14777 accumulator += print_str('(');
14778 accumulator += print_expr(cadr(p));
14779 accumulator += print_str(')');
14780 } else if (isnum(cadr(p)) && (lessp(cadr(p), zero) || isfraction(cadr(p)))) {
14781 accumulator += print_str('(');
14782 accumulator += print_factor(cadr(p));
14783 accumulator += print_str(')');
14784 } else {
14785 accumulator += print_factor(cadr(p));
14786 }
14787 return accumulator;
14788 };
14789
14790 print_exponent = function(p) {
14791 var accumulator;
14792 accumulator = "";
14793 if (iscons(caddr(p)) || isfraction(caddr(p)) || (isnum(caddr(p)) && lessp(caddr(p), zero))) {
14794 accumulator += print_str('(');
14795 accumulator += print_expr(caddr(p));
14796 accumulator += print_str(')');
14797 } else {
14798 accumulator += print_factor(caddr(p));
14799 }
14800 return accumulator;
14801 };
14802
14803 print_power = function(base, exponent) {
14804 var accumulator, denomExponent, newExponent, numExponent;
14805 accumulator = "";
14806 if (DEBUG) {
14807 console.log("power base: " + base + " " + " exponent: " + exponent);
14808 }
14809 if (isoneovertwo(exponent)) {
14810 if (equaln(base, 2)) {
14811 if (codeGen) {
14812 accumulator += print_str("Math.SQRT2");
14813 return accumulator;
14814 }
14815 } else {
14816 if (printMode === PRINTMODE_LATEX) {
14817 accumulator += print_str("\\sqrt{");
14818 accumulator += print_expr(base);
14819 accumulator += print_str("}");
14820 return accumulator;
14821 } else if (codeGen) {
14822 accumulator += print_str("Math.sqrt(");
14823 accumulator += print_expr(base);
14824 accumulator += print_str(')');
14825 return accumulator;
14826 }
14827 }
14828 }
14829 if ((equaln(get_binding(symbol(PRINT_LEAVE_E_ALONE)), 1)) && base === symbol(E)) {
14830 if (codeGen) {
14831 accumulator += print_str("Math.exp(");
14832 accumulator += print_expo_of_denom(exponent);
14833 accumulator += print_str(')');
14834 return accumulator;
14835 }
14836 if (printMode === PRINTMODE_LATEX) {
14837 accumulator += print_str("e^{");
14838 accumulator += print_expr(exponent);
14839 accumulator += print_str("}");
14840 } else {
14841 accumulator += print_str("exp(");
14842 accumulator += print_expr(exponent);
14843 accumulator += print_str(')');
14844 }
14845 return accumulator;
14846 }
14847 if (codeGen) {
14848 accumulator += print_str("Math.pow(");
14849 accumulator += print_base_of_denom(base);
14850 accumulator += print_str(", ");
14851 accumulator += print_expo_of_denom(exponent);
14852 accumulator += print_str(')');
14853 return accumulator;
14854 }
14855 if ((equaln(get_binding(symbol(PRINT_LEAVE_X_ALONE)), 0)) || base.printname !== "x") {
14856 if (base !== symbol(E)) {
14857 if (isminusone(exponent)) {
14858 if (printMode === PRINTMODE_LATEX) {
14859 accumulator += print_str("\\frac{1}{");
14860 } else if (printMode === PRINTMODE_PLAIN && !test_flag) {
14861 accumulator += print_str("1 / ");
14862 } else {
14863 accumulator += print_str("1/");
14864 }
14865 if (iscons(base) && printMode !== PRINTMODE_LATEX) {
14866 accumulator += print_str('(');
14867 accumulator += print_expr(base);
14868 accumulator += print_str(')');
14869 } else {
14870 accumulator += print_expr(base);
14871 }
14872 if (printMode === PRINTMODE_LATEX) {
14873 accumulator += print_str("}");
14874 }
14875 return accumulator;
14876 }
14877 if (isnegativeterm(exponent)) {
14878 if (printMode === PRINTMODE_LATEX) {
14879 accumulator += print_str("\\frac{1}{");
14880 } else if (printMode === PRINTMODE_PLAIN && !test_flag) {
14881 accumulator += print_str("1 / ");
14882 } else {
14883 accumulator += print_str("1/");
14884 }
14885 push(exponent);
14886 push_integer(-1);
14887 multiply();
14888 newExponent = pop();
14889 if (iscons(base) && printMode !== PRINTMODE_LATEX) {
14890 accumulator += print_str('(');
14891 accumulator += print_power(base, newExponent);
14892 accumulator += print_str(')');
14893 } else {
14894 accumulator += print_power(base, newExponent);
14895 }
14896 if (printMode === PRINTMODE_LATEX) {
14897 accumulator += print_str("}");
14898 }
14899 return accumulator;
14900 }
14901 }
14902 if (isfraction(exponent) && printMode === PRINTMODE_LATEX) {
14903 accumulator += print_str("\\sqrt");
14904 push(exponent);
14905 denominator();
14906 denomExponent = pop();
14907 if (!isplustwo(denomExponent)) {
14908 accumulator += print_str("[");
14909 accumulator += print_expr(denomExponent);
14910 accumulator += print_str("]");
14911 }
14912 accumulator += print_str("{");
14913 push(exponent);
14914 numerator();
14915 numExponent = pop();
14916 exponent = numExponent;
14917 accumulator += print_power(base, exponent);
14918 accumulator += print_str("}");
14919 return accumulator;
14920 }
14921 }
14922 if (printMode === PRINTMODE_LATEX && isplusone(exponent)) {
14923 accumulator += print_expr(base);
14924 } else {
14925 if (isadd(base) || isnegativenumber(base)) {
14926 accumulator += print_str('(');
14927 accumulator += print_expr(base);
14928 accumulator += print_str(')');
14929 } else if (car(base) === symbol(MULTIPLY) || car(base) === symbol(POWER)) {
14930 if (printMode !== PRINTMODE_LATEX) {
14931 accumulator += print_str('(');
14932 }
14933 accumulator += print_factor(base, true);
14934 if (printMode !== PRINTMODE_LATEX) {
14935 accumulator += print_str(')');
14936 }
14937 } else if (isnum(base) && (lessp(base, zero) || isfraction(base))) {
14938 accumulator += print_str('(');
14939 accumulator += print_factor(base);
14940 accumulator += print_str(')');
14941 } else {
14942 accumulator += print_factor(base);
14943 }
14944 if (printMode === PRINTMODE_PLAIN && !test_flag) {
14945 accumulator += print_str(power_str);
14946 } else {
14947 accumulator += print_str("^");
14948 }
14949 if (printMode === PRINTMODE_LATEX) {
14950 if (print_expr(exponent).length > 1) {
14951 accumulator += print_str("{");
14952 accumulator += print_expr(exponent);
14953 accumulator += print_str("}");
14954 } else {
14955 accumulator += print_expr(exponent);
14956 }
14957 } else if (iscons(exponent) || isfraction(exponent) || (isnum(exponent) && lessp(exponent, zero))) {
14958 accumulator += print_str('(');
14959 accumulator += print_expr(exponent);
14960 accumulator += print_str(')');
14961 } else {
14962 accumulator += print_factor(exponent);
14963 }
14964 }
14965 return accumulator;
14966 };
14967
14968 print_index_function = function(p) {
14969 var accumulator;
14970 accumulator = "";
14971 p = cdr(p);
14972 if (caar(p) === symbol(ADD) || caar(p) === symbol(MULTIPLY) || caar(p) === symbol(POWER) || caar(p) === symbol(FACTORIAL)) {
14973 accumulator += print_subexpr(car(p));
14974 } else {
14975 accumulator += print_expr(car(p));
14976 }
14977 accumulator += print_str('[');
14978 p = cdr(p);
14979 if (iscons(p)) {
14980 accumulator += print_expr(car(p));
14981 p = cdr(p);
14982 while (iscons(p)) {
14983 accumulator += print_str(',');
14984 accumulator += print_expr(car(p));
14985 p = cdr(p);
14986 }
14987 }
14988 accumulator += print_str(']');
14989 return accumulator;
14990 };
14991
14992 print_factor = function(p, omitParens) {
14993 var accumulator, base, exponent, fbody, parameters, returned;
14994 accumulator = "";
14995 if (isnum(p)) {
14996 accumulator += print_number(p, false);
14997 return accumulator;
14998 }
14999 if (isstr(p)) {
15000 accumulator += print_str("\"");
15001 accumulator += print_str(p.str);
15002 accumulator += print_str("\"");
15003 return accumulator;
15004 }
15005 if (istensor(p)) {
15006 if (printMode === PRINTMODE_LATEX) {
15007 accumulator += print_tensor_latex(p);
15008 } else {
15009 accumulator += print_tensor(p);
15010 }
15011 return accumulator;
15012 }
15013 if (car(p) === symbol(MULTIPLY)) {
15014 if (!omitParens) {
15015 if (sign_of_term(p) === '-' || printMode !== PRINTMODE_LATEX) {
15016 if (printMode === PRINTMODE_LATEX) {
15017 accumulator += print_str(" \\left (");
15018 } else {
15019 accumulator += print_str('(');
15020 }
15021 }
15022 }
15023 accumulator += print_expr(p);
15024 if (!omitParens) {
15025 if (sign_of_term(p) === '-' || printMode !== PRINTMODE_LATEX) {
15026 if (printMode === PRINTMODE_LATEX) {
15027 accumulator += print_str(" \\right ) ");
15028 } else {
15029 accumulator += print_str(')');
15030 }
15031 }
15032 }
15033 return accumulator;
15034 } else if (isadd(p)) {
15035 if (!omitParens) {
15036 accumulator += print_str('(');
15037 }
15038 accumulator += print_expr(p);
15039 if (!omitParens) {
15040 accumulator += print_str(')');
15041 }
15042 return accumulator;
15043 }
15044 if (car(p) === symbol(POWER)) {
15045 base = cadr(p);
15046 exponent = caddr(p);
15047 accumulator += print_power(base, exponent);
15048 return accumulator;
15049 }
15050 if (car(p) === symbol(FUNCTION)) {
15051 fbody = cadr(p);
15052 if (!codeGen) {
15053 parameters = caddr(p);
15054 accumulator += print_str("function ");
15055 if (DEBUG) {
15056 console.log("emittedString from print_factor " + stringsEmittedByUserPrintouts);
15057 }
15058 returned = print_list(parameters);
15059 accumulator += returned;
15060 accumulator += print_str(" -> ");
15061 }
15062 accumulator += print_expr(fbody);
15063 return accumulator;
15064 }
15065 if (car(p) === symbol(PATTERN)) {
15066 accumulator += print_expr(caadr(p));
15067 if (printMode === PRINTMODE_LATEX) {
15068 accumulator += print_str(" \\rightarrow ");
15069 } else {
15070 if (printMode === PRINTMODE_PLAIN && !test_flag) {
15071 accumulator += print_str(" -> ");
15072 } else {
15073 accumulator += print_str("->");
15074 }
15075 }
15076 accumulator += print_expr(car(cdr(cadr(p))));
15077 return accumulator;
15078 }
15079 if (car(p) === symbol(INDEX) && issymbol(cadr(p))) {
15080 accumulator += print_index_function(p);
15081 return accumulator;
15082 }
15083 if (car(p) === symbol(FACTORIAL)) {
15084 accumulator += print_factorial_function(p);
15085 return accumulator;
15086 } else if (car(p) === symbol(ABS) && printMode === PRINTMODE_LATEX) {
15087 accumulator += print_ABS_latex(p);
15088 return accumulator;
15089 } else if (car(p) === symbol(SQRT) && printMode === PRINTMODE_LATEX) {
15090 accumulator += print_SQRT_latex(p);
15091 return accumulator;
15092 } else if (car(p) === symbol(TRANSPOSE)) {
15093 if (printMode === PRINTMODE_LATEX) {
15094 accumulator += print_TRANSPOSE_latex(p);
15095 return accumulator;
15096 } else if (codeGen) {
15097 accumulator += print_TRANSPOSE_codegen(p);
15098 return accumulator;
15099 }
15100 } else if (car(p) === symbol(UNIT)) {
15101 if (codeGen) {
15102 accumulator += print_UNIT_codegen(p);
15103 return accumulator;
15104 }
15105 } else if (car(p) === symbol(INV)) {
15106 if (printMode === PRINTMODE_LATEX) {
15107 accumulator += print_INV_latex(p);
15108 return accumulator;
15109 } else if (codeGen) {
15110 accumulator += print_INV_codegen(p);
15111 return accumulator;
15112 }
15113 } else if (car(p) === symbol(BINOMIAL) && printMode === PRINTMODE_LATEX) {
15114 accumulator += print_BINOMIAL_latex(p);
15115 return accumulator;
15116 } else if (car(p) === symbol(DEFINT) && printMode === PRINTMODE_LATEX) {
15117 accumulator += print_DEFINT_latex(p);
15118 return accumulator;
15119 } else if (isinnerordot(p)) {
15120 if (printMode === PRINTMODE_LATEX) {
15121 accumulator += print_DOT_latex(p);
15122 return accumulator;
15123 } else if (codeGen) {
15124 accumulator += print_DOT_codegen(p);
15125 return accumulator;
15126 }
15127 } else if (car(p) === symbol(SIN)) {
15128 if (codeGen) {
15129 accumulator += print_SIN_codegen(p);
15130 return accumulator;
15131 }
15132 } else if (car(p) === symbol(COS)) {
15133 if (codeGen) {
15134 accumulator += print_COS_codegen(p);
15135 return accumulator;
15136 }
15137 } else if (car(p) === symbol(TAN)) {
15138 if (codeGen) {
15139 accumulator += print_TAN_codegen(p);
15140 return accumulator;
15141 }
15142 } else if (car(p) === symbol(ARCSIN)) {
15143 if (codeGen) {
15144 accumulator += print_ARCSIN_codegen(p);
15145 return accumulator;
15146 }
15147 } else if (car(p) === symbol(ARCCOS)) {
15148 if (codeGen) {
15149 accumulator += print_ARCCOS_codegen(p);
15150 return accumulator;
15151 }
15152 } else if (car(p) === symbol(ARCTAN)) {
15153 if (codeGen) {
15154 accumulator += print_ARCTAN_codegen(p);
15155 return accumulator;
15156 }
15157 } else if (car(p) === symbol(SUM)) {
15158 if (printMode === PRINTMODE_LATEX) {
15159 accumulator += print_SUM_latex(p);
15160 return accumulator;
15161 } else if (codeGen) {
15162 accumulator += print_SUM_codegen(p);
15163 return accumulator;
15164 }
15165 } else if (car(p) === symbol(PRODUCT)) {
15166 if (printMode === PRINTMODE_LATEX) {
15167 accumulator += print_PRODUCT_latex(p);
15168 return accumulator;
15169 } else if (codeGen) {
15170 accumulator += print_PRODUCT_codegen(p);
15171 return accumulator;
15172 }
15173 } else if (car(p) === symbol(FOR)) {
15174 if (codeGen) {
15175 accumulator += print_FOR_codegen(p);
15176 return accumulator;
15177 }
15178 } else if (car(p) === symbol(DO)) {
15179 if (codeGen) {
15180 accumulator += print_DO_codegen(p);
15181 return accumulator;
15182 }
15183 } else if (car(p) === symbol(TEST)) {
15184 if (codeGen) {
15185 accumulator += print_TEST_codegen(p);
15186 return accumulator;
15187 }
15188 if (printMode === PRINTMODE_LATEX) {
15189 accumulator += print_TEST_latex(p);
15190 return accumulator;
15191 }
15192 } else if (car(p) === symbol(TESTLT)) {
15193 if (codeGen) {
15194 accumulator += "((" + print_expr(cadr(p)) + ") < (" + print_expr(caddr(p)) + "))";
15195 return accumulator;
15196 }
15197 if (printMode === PRINTMODE_LATEX) {
15198 accumulator += print_TESTLT_latex(p);
15199 return accumulator;
15200 }
15201 } else if (car(p) === symbol(TESTLE)) {
15202 if (codeGen) {
15203 accumulator += "((" + print_expr(cadr(p)) + ") <= (" + print_expr(caddr(p)) + "))";
15204 return accumulator;
15205 }
15206 if (printMode === PRINTMODE_LATEX) {
15207 accumulator += print_TESTLE_latex(p);
15208 return accumulator;
15209 }
15210 } else if (car(p) === symbol(TESTGT)) {
15211 if (codeGen) {
15212 accumulator += "((" + print_expr(cadr(p)) + ") > (" + print_expr(caddr(p)) + "))";
15213 return accumulator;
15214 }
15215 if (printMode === PRINTMODE_LATEX) {
15216 accumulator += print_TESTGT_latex(p);
15217 return accumulator;
15218 }
15219 } else if (car(p) === symbol(TESTGE)) {
15220 if (codeGen) {
15221 accumulator += "((" + print_expr(cadr(p)) + ") >= (" + print_expr(caddr(p)) + "))";
15222 return accumulator;
15223 }
15224 if (printMode === PRINTMODE_LATEX) {
15225 accumulator += print_TESTGE_latex(p);
15226 return accumulator;
15227 }
15228 } else if (car(p) === symbol(TESTEQ)) {
15229 if (codeGen) {
15230 accumulator += "((" + print_expr(cadr(p)) + ") === (" + print_expr(caddr(p)) + "))";
15231 return accumulator;
15232 }
15233 if (printMode === PRINTMODE_LATEX) {
15234 accumulator += print_TESTEQ_latex(p);
15235 return accumulator;
15236 }
15237 } else if (car(p) === symbol(FLOOR)) {
15238 if (codeGen) {
15239 accumulator += "Math.floor(" + print_expr(cadr(p)) + ")";
15240 return accumulator;
15241 }
15242 if (printMode === PRINTMODE_LATEX) {
15243 accumulator += " \\lfloor {" + print_expr(cadr(p)) + "} \\rfloor ";
15244 return accumulator;
15245 }
15246 } else if (car(p) === symbol(CEILING)) {
15247 debugger;
15248 if (codeGen) {
15249 accumulator += "Math.ceiling(" + print_expr(cadr(p)) + ")";
15250 return accumulator;
15251 }
15252 if (printMode === PRINTMODE_LATEX) {
15253 accumulator += " \\lceil {" + print_expr(cadr(p)) + "} \\rceil ";
15254 return accumulator;
15255 }
15256 } else if (car(p) === symbol(ROUND)) {
15257 if (codeGen) {
15258 accumulator += "Math.round(" + print_expr(cadr(p)) + ")";
15259 return accumulator;
15260 }
15261 } else if (car(p) === symbol(SETQ)) {
15262 if (codeGen) {
15263 accumulator += print_SETQ_codegen(p);
15264 return accumulator;
15265 } else {
15266 accumulator += print_expr(cadr(p));
15267 accumulator += print_str("=");
15268 accumulator += print_expr(caddr(p));
15269 return accumulator;
15270 }
15271 }
15272 if (iscons(p)) {
15273 accumulator += print_factor(car(p));
15274 p = cdr(p);
15275 if (!omitParens) {
15276 accumulator += print_str('(');
15277 }
15278 if (iscons(p)) {
15279 accumulator += print_expr(car(p));
15280 p = cdr(p);
15281 while (iscons(p)) {
15282 accumulator += print_str(",");
15283 accumulator += print_expr(car(p));
15284 p = cdr(p);
15285 }
15286 }
15287 if (!omitParens) {
15288 accumulator += print_str(')');
15289 }
15290 return accumulator;
15291 }
15292 if (p === symbol(DERIVATIVE)) {
15293 accumulator += print_char('d');
15294 } else if (p === symbol(E)) {
15295 if (codeGen) {
15296 accumulator += print_str("Math.E");
15297 } else {
15298 accumulator += print_str("e");
15299 }
15300 } else if (p === symbol(PI)) {
15301 if (printMode === PRINTMODE_LATEX) {
15302 accumulator += print_str("\\pi");
15303 } else {
15304 accumulator += print_str("pi");
15305 }
15306 } else {
15307 accumulator += print_str(get_printname(p));
15308 }
15309 return accumulator;
15310 };
15311
15312 print_list = function(p) {
15313 var accumulator;
15314 accumulator = "";
15315 switch (p.k) {
15316 case CONS:
15317 accumulator += '(';
15318 accumulator += print_list(car(p));
15319 if (p === cdr(p) && p !== symbol(NIL)) {
15320 console.log("oh no recursive!");
15321 debugger;
15322 }
15323 p = cdr(p);
15324 while (iscons(p)) {
15325 accumulator += " ";
15326 accumulator += print_list(car(p));
15327 p = cdr(p);
15328 if (p === cdr(p) && p !== symbol(NIL)) {
15329 console.log("oh no recursive!");
15330 debugger;
15331 }
15332 }
15333 if (p !== symbol(NIL)) {
15334 accumulator += " . ";
15335 accumulator += print_list(p);
15336 }
15337 accumulator += ')';
15338 break;
15339 case STR:
15340 accumulator += p.str;
15341 break;
15342 case NUM:
15343 case DOUBLE:
15344 accumulator += print_number(p, true);
15345 break;
15346 case SYM:
15347 accumulator += get_printname(p);
15348 break;
15349 default:
15350 accumulator += "<tensor>";
15351 }
15352 return accumulator;
15353 };
15354
15355 print_multiply_sign = function() {
15356 var accumulator;
15357 accumulator = "";
15358 if (printMode === PRINTMODE_LATEX) {
15359 if (printMode === PRINTMODE_PLAIN && !test_flag) {
15360 accumulator += print_str(" ");
15361 } else {
15362 return accumulator;
15363 }
15364 }
15365 if (printMode === PRINTMODE_PLAIN && !test_flag && !codeGen) {
15366 accumulator += print_str(" ");
15367 } else {
15368 accumulator += print_str("*");
15369 }
15370 return accumulator;
15371 };
15372
15373 is_denominator = function(p) {
15374 if (car(p) === symbol(POWER) && cadr(p) !== symbol(E) && isnegativeterm(caddr(p))) {
15375 return 1;
15376 } else {
15377 return 0;
15378 }
15379 };
15380
15381 any_denominators = function(p) {
15382 var q;
15383 p = cdr(p);
15384 while (iscons(p)) {
15385 q = car(p);
15386 if (is_denominator(q)) {
15387 return 1;
15388 }
15389 p = cdr(p);
15390 }
15391 return 0;
15392 };
15393
15394
15395 /*
15396
15397 Prints in "2d", e.g. instead of 1/(x+1)^2 :
15398
15399 1
15400 ----------
15401 2
15402 (1 + x)
15403
15404 Note that although this looks more natural, a) it's not parsable and
15405 b) it can be occasionally be ambiguous, such as:
15406
15407 1
15408 ----
15409 2
15410 x
15411
15412 is 1/x^2 but it also looks a little like x^(1/2)
15413 */
15414
15415 YMAX = 10000;
15416
15417 glyph = (function() {
15418 function glyph() {}
15419
15420 glyph.prototype.c = 0;
15421
15422 glyph.prototype.x = 0;
15423
15424 glyph.prototype.y = 0;
15425
15426 return glyph;
15427
15428 })();
15429
15430 chartab = [];
15431
15432 for (charTabIndex = i1 = 0, ref1 = YMAX; 0 <= ref1 ? i1 < ref1 : i1 > ref1; charTabIndex = 0 <= ref1 ? ++i1 : --i1) {
15433 chartab[charTabIndex] = new glyph();
15434 }
15435
15436 yindex = 0;
15437
15438 level = 0;
15439
15440 emit_x = 0;
15441
15442 expr_level = 0;
15443
15444 display_flag = 0;
15445
15446 printchar_nowrap = function(character) {
15447 var accumulator;
15448 accumulator = "";
15449 accumulator += character;
15450 return accumulator;
15451 };
15452
15453 printchar = function(character) {
15454 return printchar_nowrap(character);
15455 };
15456
15457 print2dascii = function(p) {
15458 var beenPrinted, h, ref2, w, y;
15459 h = 0;
15460 w = 0;
15461 y = 0;
15462 save();
15463 yindex = 0;
15464 level = 0;
15465 emit_x = 0;
15466 emit_top_expr(p);
15467 ref2 = get_size(0, yindex), h = ref2[0], w = ref2[1], y = ref2[2];
15468 if (w > 100) {
15469 printline(p);
15470 restore();
15471 return;
15472 }
15473 beenPrinted = print_glyphs();
15474 restore();
15475 return beenPrinted;
15476 };
15477
15478 emit_top_expr = function(p) {
15479 if (car(p) === symbol(SETQ)) {
15480 emit_expr(cadr(p));
15481 __emit_str(" = ");
15482 emit_expr(caddr(p));
15483 return;
15484 }
15485 if (istensor(p)) {
15486 return emit_tensor(p);
15487 } else {
15488 return emit_expr(p);
15489 }
15490 };
15491
15492 will_be_displayed_as_fraction = function(p) {
15493 if (level > 0) {
15494 return 0;
15495 }
15496 if (isfraction(p)) {
15497 return 1;
15498 }
15499 if (car(p) !== symbol(MULTIPLY)) {
15500 return 0;
15501 }
15502 if (isfraction(cadr(p))) {
15503 return 1;
15504 }
15505 while (iscons(p)) {
15506 if (isdenominator(car(p))) {
15507 return 1;
15508 }
15509 p = cdr(p);
15510 }
15511 return 0;
15512 };
15513
15514 emit_expr = function(p) {
15515 expr_level++;
15516 if (car(p) === symbol(ADD)) {
15517 p = cdr(p);
15518 if (__is_negative(car(p))) {
15519 __emit_char('-');
15520 if (will_be_displayed_as_fraction(car(p))) {
15521 __emit_char(' ');
15522 }
15523 }
15524 emit_term(car(p));
15525 p = cdr(p);
15526 while (iscons(p)) {
15527 if (__is_negative(car(p))) {
15528 __emit_char(' ');
15529 __emit_char('-');
15530 __emit_char(' ');
15531 } else {
15532 __emit_char(' ');
15533 __emit_char('+');
15534 __emit_char(' ');
15535 }
15536 emit_term(car(p));
15537 p = cdr(p);
15538 }
15539 } else {
15540 if (__is_negative(p)) {
15541 __emit_char('-');
15542 if (will_be_displayed_as_fraction(p)) {
15543 __emit_char(' ');
15544 }
15545 }
15546 emit_term(p);
15547 }
15548 return expr_level--;
15549 };
15550
15551 emit_unsigned_expr = function(p) {
15552 var results;
15553 if (car(p) === symbol(ADD)) {
15554 p = cdr(p);
15555 emit_term(car(p));
15556 p = cdr(p);
15557 results = [];
15558 while (iscons(p)) {
15559 if (__is_negative(car(p))) {
15560 __emit_char(' ');
15561 __emit_char('-');
15562 __emit_char(' ');
15563 } else {
15564 __emit_char(' ');
15565 __emit_char('+');
15566 __emit_char(' ');
15567 }
15568 emit_term(car(p));
15569 results.push(p = cdr(p));
15570 }
15571 return results;
15572 } else {
15573 return emit_term(p);
15574 }
15575 };
15576
15577 __is_negative = function(p) {
15578 if (isnegativenumber(p)) {
15579 return 1;
15580 }
15581 if (car(p) === symbol(MULTIPLY) && isnegativenumber(cadr(p))) {
15582 return 1;
15583 }
15584 return 0;
15585 };
15586
15587 emit_term = function(p) {
15588 var n;
15589 if (car(p) === symbol(MULTIPLY)) {
15590 n = count_denominators(p);
15591 if (n && level === 0) {
15592 return emit_fraction(p, n);
15593 } else {
15594 return emit_multiply(p, n);
15595 }
15596 } else {
15597 return emit_factor(p);
15598 }
15599 };
15600
15601 isdenominator = function(p) {
15602 if (car(p) === symbol(POWER) && cadr(p) !== symbol(E) && __is_negative(caddr(p))) {
15603 return 1;
15604 } else {
15605 return 0;
15606 }
15607 };
15608
15609 count_denominators = function(p) {
15610 var count, q;
15611 count = 0;
15612 p = cdr(p);
15613 while (iscons(p)) {
15614 q = car(p);
15615 if (isdenominator(q)) {
15616 count++;
15617 }
15618 p = cdr(p);
15619 }
15620 return count;
15621 };
15622
15623 emit_multiply = function(p, n) {
15624 var results;
15625 if (n === 0) {
15626 p = cdr(p);
15627 if (isplusone(car(p)) || isminusone(car(p))) {
15628 p = cdr(p);
15629 }
15630 emit_factor(car(p));
15631 p = cdr(p);
15632 results = [];
15633 while (iscons(p)) {
15634 __emit_char(' ');
15635 emit_factor(car(p));
15636 results.push(p = cdr(p));
15637 }
15638 return results;
15639 } else {
15640 emit_numerators(p);
15641 __emit_char('/');
15642 if (n > 1 || isfraction(cadr(p))) {
15643 __emit_char('(');
15644 emit_denominators(p);
15645 return __emit_char(')');
15646 } else {
15647 return emit_denominators(p);
15648 }
15649 }
15650 };
15651
15652 emit_fraction = function(p, d) {
15653 var count, doNothing, k1, k2, n, x;
15654 count = 0;
15655 k1 = 0;
15656 k2 = 0;
15657 n = 0;
15658 x = 0;
15659 save();
15660 p3 = one;
15661 p4 = one;
15662 if (isrational(cadr(p))) {
15663 push(cadr(p));
15664 mp_numerator();
15665 absval();
15666 p3 = pop();
15667 push(cadr(p));
15668 mp_denominator();
15669 p4 = pop();
15670 }
15671 if (isdouble(cadr(p))) {
15672 push(cadr(p));
15673 absval();
15674 p3 = pop();
15675 }
15676 if (isplusone(p3)) {
15677 n = 0;
15678 } else {
15679 n = 1;
15680 }
15681 p1 = cdr(p);
15682 if (isnum(car(p1))) {
15683 p1 = cdr(p1);
15684 }
15685 while (iscons(p1)) {
15686 p2 = car(p1);
15687 if (isdenominator(p2)) {
15688 doNothing = 1;
15689 } else {
15690 n++;
15691 }
15692 p1 = cdr(p1);
15693 }
15694 x = emit_x;
15695 k1 = yindex;
15696 count = 0;
15697 if (!isplusone(p3)) {
15698 emit_number(p3, 0);
15699 count++;
15700 }
15701 p1 = cdr(p);
15702 if (isnum(car(p1))) {
15703 p1 = cdr(p1);
15704 }
15705 while (iscons(p1)) {
15706 p2 = car(p1);
15707 if (isdenominator(p2)) {
15708 doNothing = 1;
15709 } else {
15710 if (count > 0) {
15711 __emit_char(' ');
15712 }
15713 if (n === 1) {
15714 emit_expr(p2);
15715 } else {
15716 emit_factor(p2);
15717 }
15718 count++;
15719 }
15720 p1 = cdr(p1);
15721 }
15722 if (count === 0) {
15723 __emit_char('1');
15724 }
15725 k2 = yindex;
15726 count = 0;
15727 if (!isplusone(p4)) {
15728 emit_number(p4, 0);
15729 count++;
15730 d++;
15731 }
15732 p1 = cdr(p);
15733 if (isrational(car(p1))) {
15734 p1 = cdr(p1);
15735 }
15736 while (iscons(p1)) {
15737 p2 = car(p1);
15738 if (isdenominator(p2)) {
15739 if (count > 0) {
15740 __emit_char(' ');
15741 }
15742 emit_denominator(p2, d);
15743 count++;
15744 }
15745 p1 = cdr(p1);
15746 }
15747 fixup_fraction(x, k1, k2);
15748 return restore();
15749 };
15750
15751 emit_numerators = function(p) {
15752 var doNothing, n;
15753 save();
15754 n = 0;
15755 p1 = one;
15756 p = cdr(p);
15757 if (isrational(car(p))) {
15758 push(car(p));
15759 mp_numerator();
15760 absval();
15761 p1 = pop();
15762 p = cdr(p);
15763 } else if (isdouble(car(p))) {
15764 push(car(p));
15765 absval();
15766 p1 = pop();
15767 p = cdr(p);
15768 }
15769 n = 0;
15770 if (!isplusone(p1)) {
15771 emit_number(p1, 0);
15772 n++;
15773 }
15774 while (iscons(p)) {
15775 if (isdenominator(car(p))) {
15776 doNothing = 1;
15777 } else {
15778 if (n > 0) {
15779 __emit_char(' ');
15780 }
15781 emit_factor(car(p));
15782 n++;
15783 }
15784 p = cdr(p);
15785 }
15786 if (n === 0) {
15787 __emit_char('1');
15788 }
15789 return restore();
15790 };
15791
15792 emit_denominators = function(p) {
15793 var n;
15794 save();
15795 n = 0;
15796 p = cdr(p);
15797 if (isfraction(car(p))) {
15798 push(car(p));
15799 mp_denominator();
15800 p1 = pop();
15801 emit_number(p1, 0);
15802 n++;
15803 p = cdr(p);
15804 }
15805 while (iscons(p)) {
15806 if (isdenominator(car(p))) {
15807 if (n > 0) {
15808 __emit_char(' ');
15809 }
15810 emit_denominator(car(p), 0);
15811 n++;
15812 }
15813 p = cdr(p);
15814 }
15815 return restore();
15816 };
15817
15818 emit_factor = function(p) {
15819 if (istensor(p)) {
15820 if (level === 0) {
15821 emit_flat_tensor(p);
15822 } else {
15823 emit_flat_tensor(p);
15824 }
15825 return;
15826 }
15827 if (isdouble(p)) {
15828 emit_number(p, 0);
15829 return;
15830 }
15831 if (car(p) === symbol(ADD) || car(p) === symbol(MULTIPLY)) {
15832 emit_subexpr(p);
15833 return;
15834 }
15835 if (car(p) === symbol(POWER)) {
15836 emit_power(p);
15837 return;
15838 }
15839 if (iscons(p)) {
15840 emit_function(p);
15841 return;
15842 }
15843 if (isnum(p)) {
15844 if (level === 0) {
15845 emit_numerical_fraction(p);
15846 } else {
15847 emit_number(p, 0);
15848 }
15849 return;
15850 }
15851 if (issymbol(p)) {
15852 emit_symbol(p);
15853 return;
15854 }
15855 if (isstr(p)) {
15856 emit_string(p);
15857 }
15858 };
15859
15860 emit_numerical_fraction = function(p) {
15861 var k1, k2, x;
15862 k1 = 0;
15863 k2 = 0;
15864 x = 0;
15865 save();
15866 push(p);
15867 mp_numerator();
15868 absval();
15869 p3 = pop();
15870 push(p);
15871 mp_denominator();
15872 p4 = pop();
15873 if (isplusone(p4)) {
15874 emit_number(p3, 0);
15875 restore();
15876 return;
15877 }
15878 x = emit_x;
15879 k1 = yindex;
15880 emit_number(p3, 0);
15881 k2 = yindex;
15882 emit_number(p4, 0);
15883 fixup_fraction(x, k1, k2);
15884 return restore();
15885 };
15886
15887 isfactor = function(p) {
15888 if (iscons(p) && car(p) !== symbol(ADD) && car(p) !== symbol(MULTIPLY) && car(p) !== symbol(POWER)) {
15889 return 1;
15890 }
15891 if (issymbol(p)) {
15892 return 1;
15893 }
15894 if (isfraction(p)) {
15895 return 0;
15896 }
15897 if (isnegativenumber(p)) {
15898 return 0;
15899 }
15900 if (isnum(p)) {
15901 return 1;
15902 }
15903 return 0;
15904 };
15905
15906 emit_power = function(p) {
15907 var k1, k2, x;
15908 k1 = 0;
15909 k2 = 0;
15910 x = 0;
15911 if (cadr(p) === symbol(E)) {
15912 __emit_str("exp(");
15913 emit_expr(caddr(p));
15914 __emit_char(')');
15915 return;
15916 }
15917 if (level > 0) {
15918 if (isminusone(caddr(p))) {
15919 __emit_char('1');
15920 __emit_char('/');
15921 if (isfactor(cadr(p))) {
15922 emit_factor(cadr(p));
15923 } else {
15924 emit_subexpr(cadr(p));
15925 }
15926 } else {
15927 if (isfactor(cadr(p))) {
15928 emit_factor(cadr(p));
15929 } else {
15930 emit_subexpr(cadr(p));
15931 }
15932 __emit_char('^');
15933 if (isfactor(caddr(p))) {
15934 emit_factor(caddr(p));
15935 } else {
15936 emit_subexpr(caddr(p));
15937 }
15938 }
15939 return;
15940 }
15941 if (__is_negative(caddr(p))) {
15942 x = emit_x;
15943 k1 = yindex;
15944 __emit_char('1');
15945 k2 = yindex;
15946 emit_denominator(p, 1);
15947 fixup_fraction(x, k1, k2);
15948 return;
15949 }
15950 k1 = yindex;
15951 if (isfactor(cadr(p))) {
15952 emit_factor(cadr(p));
15953 } else {
15954 emit_subexpr(cadr(p));
15955 }
15956 k2 = yindex;
15957 level++;
15958 emit_expr(caddr(p));
15959 level--;
15960 return fixup_power(k1, k2);
15961 };
15962
15963 emit_denominator = function(p, n) {
15964 var k1, k2;
15965 k1 = 0;
15966 k2 = 0;
15967 if (isminusone(caddr(p))) {
15968 if (n === 1) {
15969 emit_expr(cadr(p));
15970 } else {
15971 emit_factor(cadr(p));
15972 }
15973 return;
15974 }
15975 k1 = yindex;
15976 if (isfactor(cadr(p))) {
15977 emit_factor(cadr(p));
15978 } else {
15979 emit_subexpr(cadr(p));
15980 }
15981 k2 = yindex;
15982 level++;
15983 emit_unsigned_expr(caddr(p));
15984 level--;
15985 return fixup_power(k1, k2);
15986 };
15987
15988 emit_function = function(p) {
15989 if (car(p) === symbol(INDEX) && issymbol(cadr(p))) {
15990 emit_index_function(p);
15991 return;
15992 }
15993 if (car(p) === symbol(FACTORIAL)) {
15994 emit_factorial_function(p);
15995 return;
15996 }
15997 if (car(p) === symbol(DERIVATIVE)) {
15998 __emit_char('d');
15999 } else {
16000 emit_symbol(car(p));
16001 }
16002 __emit_char('(');
16003 p = cdr(p);
16004 if (iscons(p)) {
16005 emit_expr(car(p));
16006 p = cdr(p);
16007 while (iscons(p)) {
16008 __emit_char(',');
16009 emit_expr(car(p));
16010 p = cdr(p);
16011 }
16012 }
16013 return __emit_char(')');
16014 };
16015
16016 emit_index_function = function(p) {
16017 p = cdr(p);
16018 if (caar(p) === symbol(ADD) || caar(p) === symbol(MULTIPLY) || caar(p) === symbol(POWER) || caar(p) === symbol(FACTORIAL)) {
16019 emit_subexpr(car(p));
16020 } else {
16021 emit_expr(car(p));
16022 }
16023 __emit_char('[');
16024 p = cdr(p);
16025 if (iscons(p)) {
16026 emit_expr(car(p));
16027 p = cdr(p);
16028 while (iscons(p)) {
16029 __emit_char(',');
16030 emit_expr(car(p));
16031 p = cdr(p);
16032 }
16033 }
16034 return __emit_char(']');
16035 };
16036
16037 emit_factorial_function = function(p) {
16038 p = cadr(p);
16039 if (car(p) === symbol(ADD) || car(p) === symbol(MULTIPLY) || car(p) === symbol(POWER) || car(p) === symbol(FACTORIAL)) {
16040 emit_subexpr(p);
16041 } else {
16042 emit_expr(p);
16043 }
16044 return __emit_char('!');
16045 };
16046
16047 emit_subexpr = function(p) {
16048 __emit_char('(');
16049 emit_expr(p);
16050 return __emit_char(')');
16051 };
16052
16053 emit_symbol = function(p) {
16054 var i, j1, pPrintName, ref2, results;
16055 i = 0;
16056 if (p === symbol(E)) {
16057 __emit_str("exp(1)");
16058 return;
16059 }
16060 pPrintName = get_printname(p);
16061 results = [];
16062 for (i = j1 = 0, ref2 = pPrintName.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16063 results.push(__emit_char(pPrintName[i]));
16064 }
16065 return results;
16066 };
16067
16068 emit_string = function(p) {
16069 var i, j1, pString, ref2;
16070 i = 0;
16071 pString = p.str;
16072 __emit_char('"');
16073 for (i = j1 = 0, ref2 = pString.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16074 __emit_char(pString[i]);
16075 }
16076 return __emit_char('"');
16077 };
16078
16079 fixup_fraction = function(x, k1, k2) {
16080 var dx, dy, h1, h2, i, j1, ref2, ref3, ref4, results, w, w1, w2, y, y1, y2;
16081 dx = 0;
16082 dy = 0;
16083 i = 0;
16084 w = 0;
16085 y = 0;
16086 h1 = 0;
16087 w1 = 0;
16088 y1 = 0;
16089 h2 = 0;
16090 w2 = 0;
16091 y2 = 0;
16092 ref2 = get_size(k1, k2), h1 = ref2[0], w1 = ref2[1], y1 = ref2[2];
16093 ref3 = get_size(k2, yindex), h2 = ref3[0], w2 = ref3[1], y2 = ref3[2];
16094 if (w2 > w1) {
16095 dx = (w2 - w1) / 2;
16096 } else {
16097 dx = 0;
16098 }
16099 dx++;
16100 y = y1 + h1 - 1;
16101 dy = -y - 1;
16102 move(k1, k2, dx, dy);
16103 if (w2 > w1) {
16104 dx = -w1;
16105 } else {
16106 dx = -w1 + (w1 - w2) / 2;
16107 }
16108 dx++;
16109 dy = -y2 + 1;
16110 move(k2, yindex, dx, dy);
16111 if (w2 > w1) {
16112 w = w2;
16113 } else {
16114 w = w1;
16115 }
16116 w += 2;
16117 emit_x = x;
16118 results = [];
16119 for (i = j1 = 0, ref4 = w; 0 <= ref4 ? j1 < ref4 : j1 > ref4; i = 0 <= ref4 ? ++j1 : --j1) {
16120 results.push(__emit_char('-'));
16121 }
16122 return results;
16123 };
16124
16125 fixup_power = function(k1, k2) {
16126 var dy, h1, h2, ref2, ref3, w1, w2, y1, y2;
16127 dy = 0;
16128 h1 = 0;
16129 w1 = 0;
16130 y1 = 0;
16131 h2 = 0;
16132 w2 = 0;
16133 y2 = 0;
16134 ref2 = get_size(k1, k2), h1 = ref2[0], w1 = ref2[1], y1 = ref2[2];
16135 ref3 = get_size(k2, yindex), h2 = ref3[0], w2 = ref3[1], y2 = ref3[2];
16136 dy = -y2 - h2 + 1;
16137 dy += y1 - 1;
16138 return move(k2, yindex, 0, dy);
16139 };
16140
16141 move = function(j, k, dx, dy) {
16142 var i, j1, ref2, ref3, results;
16143 i = 0;
16144 results = [];
16145 for (i = j1 = ref2 = j, ref3 = k; ref2 <= ref3 ? j1 < ref3 : j1 > ref3; i = ref2 <= ref3 ? ++j1 : --j1) {
16146 chartab[i].x += dx;
16147 results.push(chartab[i].y += dy);
16148 }
16149 return results;
16150 };
16151
16152 get_size = function(j, k) {
16153 var h, i, j1, max_x, max_y, min_x, min_y, ref2, ref3, w, y;
16154 i = 0;
16155 min_x = chartab[j].x;
16156 max_x = chartab[j].x;
16157 min_y = chartab[j].y;
16158 max_y = chartab[j].y;
16159 for (i = j1 = ref2 = j + 1, ref3 = k; ref2 <= ref3 ? j1 < ref3 : j1 > ref3; i = ref2 <= ref3 ? ++j1 : --j1) {
16160 if (chartab[i].x < min_x) {
16161 min_x = chartab[i].x;
16162 }
16163 if (chartab[i].x > max_x) {
16164 max_x = chartab[i].x;
16165 }
16166 if (chartab[i].y < min_y) {
16167 min_y = chartab[i].y;
16168 }
16169 if (chartab[i].y > max_y) {
16170 max_y = chartab[i].y;
16171 }
16172 }
16173 h = max_y - min_y + 1;
16174 w = max_x - min_x + 1;
16175 y = min_y;
16176 return [h, w, y];
16177 };
16178
16179 displaychar = function(c) {
16180 return __emit_char(c);
16181 };
16182
16183 __emit_char = function(c) {
16184 if (yindex === YMAX) {
16185 return;
16186 }
16187 if (chartab[yindex] == null) {
16188 debugger;
16189 }
16190 chartab[yindex].c = c;
16191 chartab[yindex].x = emit_x;
16192 chartab[yindex].y = 0;
16193 yindex++;
16194 return emit_x++;
16195 };
16196
16197 __emit_str = function(s) {
16198 var i, j1, ref2, results;
16199 i = 0;
16200 results = [];
16201 for (i = j1 = 0, ref2 = s.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16202 results.push(__emit_char(s[i]));
16203 }
16204 return results;
16205 };
16206
16207 emit_number = function(p, emit_sign) {
16208 var i, j1, l1, m1, ref2, ref3, ref4, results, results1, tmpString;
16209 tmpString = "";
16210 i = 0;
16211 switch (p.k) {
16212 case NUM:
16213 tmpString = p.q.a.toString();
16214 if (tmpString[0] === '-' && emit_sign === 0) {
16215 tmpString = tmpString.substring(1);
16216 }
16217 for (i = j1 = 0, ref2 = tmpString.length; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16218 __emit_char(tmpString[i]);
16219 }
16220 tmpString = p.q.b.toString();
16221 if (tmpString === "1") {
16222 break;
16223 }
16224 __emit_char('/');
16225 results = [];
16226 for (i = l1 = 0, ref3 = tmpString.length; 0 <= ref3 ? l1 < ref3 : l1 > ref3; i = 0 <= ref3 ? ++l1 : --l1) {
16227 results.push(__emit_char(tmpString[i]));
16228 }
16229 return results;
16230 break;
16231 case DOUBLE:
16232 tmpString = doubleToReasonableString(p.d);
16233 if (tmpString[0] === '-' && emit_sign === 0) {
16234 tmpString = tmpString.substring(1);
16235 }
16236 results1 = [];
16237 for (i = m1 = 0, ref4 = tmpString.length; 0 <= ref4 ? m1 < ref4 : m1 > ref4; i = 0 <= ref4 ? ++m1 : --m1) {
16238 results1.push(__emit_char(tmpString[i]));
16239 }
16240 return results1;
16241 }
16242 };
16243
16244 cmpGlyphs = function(a, b) {
16245 if (a.y < b.y) {
16246 return -1;
16247 }
16248 if (a.y > b.y) {
16249 return 1;
16250 }
16251 if (a.x < b.x) {
16252 return -1;
16253 }
16254 if (a.x > b.x) {
16255 return 1;
16256 }
16257 return 0;
16258 };
16259
16260 print_glyphs = function() {
16261 var accumulator, i, j1, ref2, subsetOfStack, x, y;
16262 i = 0;
16263 accumulator = "";
16264 subsetOfStack = chartab.slice(0, yindex);
16265 subsetOfStack.sort(cmpGlyphs);
16266 chartab = [].concat(subsetOfStack).concat(chartab.slice(yindex));
16267 x = 0;
16268 y = chartab[0].y;
16269 for (i = j1 = 0, ref2 = yindex; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16270 while (chartab[i].y > y) {
16271 accumulator += printchar('\n');
16272 x = 0;
16273 y++;
16274 }
16275 while (chartab[i].x > x) {
16276 accumulator += printchar_nowrap(' ');
16277 x++;
16278 }
16279 accumulator += printchar_nowrap(chartab[i].c);
16280 x++;
16281 }
16282 return accumulator;
16283 };
16284
16285 buffer = "";
16286
16287 getdisplaystr = function() {
16288 yindex = 0;
16289 level = 0;
16290 emit_x = 0;
16291 emit_expr(pop());
16292 fill_buf();
16293 return buffer;
16294 };
16295
16296 fill_buf = function() {
16297 var i, j1, ref2, sIndex, subsetOfStack, tmpBuffer, x, y;
16298 tmpBuffer = buffer;
16299 sIndex = 0;
16300 i = 0;
16301 subsetOfStack = chartab.slice(0, yindex);
16302 subsetOfStack.sort(cmpGlyphs);
16303 chartab = [].concat(subsetOfStack).concat(chartab.slice(yindex));
16304 x = 0;
16305 y = chartab[0].y;
16306 for (i = j1 = 0, ref2 = yindex; 0 <= ref2 ? j1 < ref2 : j1 > ref2; i = 0 <= ref2 ? ++j1 : --j1) {
16307 while (chartab[i].y > y) {
16308 tmpBuffer[sIndex++] = '\n';
16309 x = 0;
16310 y++;
16311 }
16312 while (chartab[i].x > x) {
16313 tmpBuffer[sIndex++] = ' ';
16314 x++;
16315 }
16316 tmpBuffer[sIndex++] = chartab[i].c;
16317 x++;
16318 }
16319 return tmpBuffer[sIndex++] = '\n';
16320 };
16321
16322 N = 100;
16323
16324 oneElement = (function() {
16325 function oneElement() {}
16326
16327 oneElement.prototype.x = 0;
16328
16329 oneElement.prototype.y = 0;
16330
16331 oneElement.prototype.h = 0;
16332
16333 oneElement.prototype.w = 0;
16334
16335 oneElement.prototype.index = 0;
16336
16337 oneElement.prototype.count = 0;
16338
16339 return oneElement;
16340
16341 })();
16342
16343 elem = [];
16344
16345 for (elelmIndex = j1 = 0; j1 < 10000; elelmIndex = ++j1) {
16346 elem[elelmIndex] = new oneElement;
16347 }
16348
16349 SPACE_BETWEEN_COLUMNS = 3;
16350
16351 SPACE_BETWEEN_ROWS = 1;
16352
16353 emit_tensor = function(p) {
16354 var col, dx, dy, eh, ew, h, i, l1, m1, n, n1, ncol, nrow, o1, ref2, ref3, ref4, ref5, ref6, row, w, x, y;
16355 i = 0;
16356 n = 0;
16357 nrow = 0;
16358 ncol = 0;
16359 x = 0;
16360 y = 0;
16361 h = 0;
16362 w = 0;
16363 dx = 0;
16364 dy = 0;
16365 eh = 0;
16366 ew = 0;
16367 row = 0;
16368 col = 0;
16369 if (p.tensor.ndim > 2) {
16370 emit_flat_tensor(p);
16371 return;
16372 }
16373 nrow = p.tensor.dim[0];
16374 if (p.tensor.ndim === 2) {
16375 ncol = p.tensor.dim[1];
16376 } else {
16377 ncol = 1;
16378 }
16379 n = nrow * ncol;
16380 if (n > N) {
16381 emit_flat_tensor(p);
16382 return;
16383 }
16384 x = emit_x;
16385 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
16386 elem[i].index = yindex;
16387 elem[i].x = emit_x;
16388 emit_expr(p.tensor.elem[i]);
16389 elem[i].count = yindex - elem[i].index;
16390 ref3 = get_size(elem[i].index, yindex), elem[i].h = ref3[0], elem[i].w = ref3[1], elem[i].y = ref3[2];
16391 }
16392 eh = 0;
16393 ew = 0;
16394 for (i = m1 = 0, ref4 = n; 0 <= ref4 ? m1 < ref4 : m1 > ref4; i = 0 <= ref4 ? ++m1 : --m1) {
16395 if (elem[i].h > eh) {
16396 eh = elem[i].h;
16397 }
16398 if (elem[i].w > ew) {
16399 ew = elem[i].w;
16400 }
16401 }
16402 h = nrow * eh + (nrow - 1) * SPACE_BETWEEN_ROWS;
16403 w = ncol * ew + (ncol - 1) * SPACE_BETWEEN_COLUMNS;
16404 y = -(h / 2);
16405 for (row = n1 = 0, ref5 = nrow; 0 <= ref5 ? n1 < ref5 : n1 > ref5; row = 0 <= ref5 ? ++n1 : --n1) {
16406 for (col = o1 = 0, ref6 = ncol; 0 <= ref6 ? o1 < ref6 : o1 > ref6; col = 0 <= ref6 ? ++o1 : --o1) {
16407 i = row * ncol + col;
16408 dx = x - elem[i].x;
16409 dy = y - elem[i].y;
16410 move(elem[i].index, elem[i].index + elem[i].count, dx, dy);
16411 dx = 0;
16412 if (col > 0) {
16413 dx = col * (ew + SPACE_BETWEEN_COLUMNS);
16414 }
16415 dy = 0;
16416 if (row > 0) {
16417 dy = row * (eh + SPACE_BETWEEN_ROWS);
16418 }
16419 dx += (ew - elem[i].w) / 2;
16420 dy += (eh - elem[i].h) / 2;
16421 move(elem[i].index, elem[i].index + elem[i].count, dx, dy);
16422 }
16423 }
16424 return emit_x = x + w;
16425
16426 /*
16427 if 0
16428
16429 * left brace
16430
16431 for (i = 0; i < h; i++) {
16432 if (yindex == YMAX)
16433 break
16434 chartab[yindex].c = '|'
16435 chartab[yindex].x = x - 2
16436 chartab[yindex].y = y + i
16437 yindex++
16438 }
16439
16440 * right brace
16441
16442 emit_x++
16443
16444 for (i = 0; i < h; i++) {
16445 if (yindex == YMAX)
16446 break
16447 chartab[yindex].c = '|'
16448 chartab[yindex].x = emit_x
16449 chartab[yindex].y = y + i
16450 yindex++
16451 }
16452
16453 emit_x++
16454
16455 endif
16456 */
16457 };
16458
16459 emit_flat_tensor = function(p) {
16460 return emit_tensor_inner(p, 0, 0);
16461 };
16462
16463 emit_tensor_inner = function(p, j, k) {
16464 var i, l1, ref2;
16465 i = 0;
16466 __emit_char('(');
16467 for (i = l1 = 0, ref2 = p.tensor.dim[j]; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
16468 if (j + 1 === p.tensor.ndim) {
16469 emit_expr(p.tensor.elem[k]);
16470 k = k + 1;
16471 } else {
16472 k = emit_tensor_inner(p, j + 1, k);
16473 }
16474 if (i + 1 < p.tensor.dim[j]) {
16475 __emit_char(',');
16476 }
16477 }
16478 __emit_char(')');
16479 return k;
16480 };
16481
16482 Eval_product = function() {
16483 var body, i, indexVariable, j, k, l1, oldIndexVariableValue, ref2, ref3;
16484 i = 0;
16485 j = 0;
16486 k = 0;
16487 body = cadr(p1);
16488 indexVariable = caddr(p1);
16489 if (!issymbol(p6)) {
16490 stop("sum: 1st arg?");
16491 }
16492 push(cadddr(p1));
16493 Eval();
16494 j = pop_integer();
16495 if (isNaN(j)) {
16496 push(p1);
16497 return;
16498 }
16499 push(caddddr(p1));
16500 Eval();
16501 k = pop_integer();
16502 if (isNaN(k)) {
16503 push(p1);
16504 return;
16505 }
16506 oldIndexVariableValue = get_binding(indexVariable);
16507 push_integer(1);
16508 for (i = l1 = ref2 = j, ref3 = k; ref2 <= ref3 ? l1 <= ref3 : l1 >= ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
16509 push_integer(i);
16510 p5 = pop();
16511 set_binding(indexVariable, p5);
16512 push(body);
16513 Eval();
16514 if (DEBUG) {
16515 console.log("product - factor 1: " + stack[tos - 1].toString());
16516 console.log("product - factor 2: " + stack[tos - 2].toString());
16517 }
16518 multiply();
16519 if (DEBUG) {
16520 console.log("product - result: " + stack[tos - 1].toString());
16521 }
16522 }
16523 return set_binding(indexVariable, oldIndexVariableValue);
16524 };
16525
16526 qadd = function() {
16527 var a, ab, b, ba, c;
16528 save();
16529 p2 = pop();
16530 p1 = pop();
16531 ab = mmul(p1.q.a, p2.q.b);
16532 ba = mmul(p1.q.b, p2.q.a);
16533 a = madd(ab, ba);
16534 if (MZERO(a)) {
16535 push(zero);
16536 restore();
16537 return;
16538 }
16539 b = mmul(p1.q.b, p2.q.b);
16540 c = mgcd(a, b);
16541 c = makeSignSameAs(c, b);
16542 p1 = new U();
16543 p1.k = NUM;
16544 p1.q.a = mdiv(a, c);
16545 p1.q.b = mdiv(b, c);
16546 push(p1);
16547 return restore();
16548 };
16549
16550 qdiv = function() {
16551 var aa, bb, c;
16552 save();
16553 p2 = pop();
16554 p1 = pop();
16555 if (MZERO(p2.q.a)) {
16556 stop("divide by zero");
16557 }
16558 if (MZERO(p1.q.a)) {
16559 push(zero);
16560 restore();
16561 return;
16562 }
16563 aa = mmul(p1.q.a, p2.q.b);
16564 bb = mmul(p1.q.b, p2.q.a);
16565 c = mgcd(aa, bb);
16566 c = makeSignSameAs(c, bb);
16567 p1 = new U();
16568 p1.k = NUM;
16569 p1.q.a = mdiv(aa, c);
16570 p1.q.b = mdiv(bb, c);
16571 push(p1);
16572 return restore();
16573 };
16574
16575 qmul = function() {
16576 var aa, bb, c;
16577 save();
16578 p2 = pop();
16579 p1 = pop();
16580 if (MZERO(p1.q.a) || MZERO(p2.q.a)) {
16581 push(zero);
16582 restore();
16583 return;
16584 }
16585 aa = mmul(p1.q.a, p2.q.a);
16586 bb = mmul(p1.q.b, p2.q.b);
16587 c = mgcd(aa, bb);
16588 c = makeSignSameAs(c, bb);
16589 p1 = new U();
16590 p1.k = NUM;
16591 p1.q.a = mdiv(aa, c);
16592 p1.q.b = mdiv(bb, c);
16593 push(p1);
16594 return restore();
16595 };
16596
16597 qpow = function() {
16598 save();
16599 qpowf();
16600 return restore();
16601 };
16602
16603 qpowf = function() {
16604 var a, b, expo, t, x, y;
16605 expo = 0;
16606 p2 = pop();
16607 p1 = pop();
16608 if (isplusone(p1) || iszero(p2)) {
16609 push_integer(1);
16610 return;
16611 }
16612 if (isminusone(p1) && isoneovertwo(p2)) {
16613 push(imaginaryunit);
16614 return;
16615 }
16616 if (iszero(p1)) {
16617 if (isnegativenumber(p2)) {
16618 stop("divide by zero");
16619 }
16620 push(zero);
16621 return;
16622 }
16623 if (isplusone(p2)) {
16624 push(p1);
16625 return;
16626 }
16627 if (isinteger(p2)) {
16628 push(p2);
16629 expo = pop_integer();
16630 if (isNaN(expo)) {
16631 push_symbol(POWER);
16632 push(p1);
16633 push(p2);
16634 list(3);
16635 return;
16636 }
16637 x = mpow(p1.q.a, Math.abs(expo));
16638 y = mpow(p1.q.b, Math.abs(expo));
16639 if (expo < 0) {
16640 t = x;
16641 x = y;
16642 y = t;
16643 x = makeSignSameAs(x, y);
16644 y = makePositive(y);
16645 }
16646 p3 = new U();
16647 p3.k = NUM;
16648 p3.q.a = x;
16649 p3.q.b = y;
16650 push(p3);
16651 return;
16652 }
16653 if (isminusone(p1)) {
16654 push(p2);
16655 normalize_angle();
16656 return;
16657 }
16658 if (isnegativenumber(p1)) {
16659 push(p1);
16660 negate();
16661 push(p2);
16662 qpow();
16663 push_integer(-1);
16664 push(p2);
16665 qpow();
16666 multiply();
16667 return;
16668 }
16669 if (!isinteger(p1)) {
16670 push(p1);
16671 mp_numerator();
16672 push(p2);
16673 qpow();
16674 push(p1);
16675 mp_denominator();
16676 push(p2);
16677 negate();
16678 qpow();
16679 multiply();
16680 return;
16681 }
16682 if (is_small_integer(p1)) {
16683 push(p1);
16684 push(p2);
16685 quickfactor();
16686 return;
16687 }
16688 if (!p2.q.a.isSmall || !p2.q.b.isSmall) {
16689 push_symbol(POWER);
16690 push(p1);
16691 push(p2);
16692 list(3);
16693 return;
16694 }
16695 a = p2.q.a;
16696 b = p2.q.b;
16697 x = mroot(p1.q.a, b);
16698 if (x === 0) {
16699 push_symbol(POWER);
16700 push(p1);
16701 push(p2);
16702 list(3);
16703 return;
16704 }
16705 y = mpow(x, a);
16706 p3 = new U();
16707 p3.k = NUM;
16708 if (p2.q.a.isNegative()) {
16709 p3.q.a = bigInt(1);
16710 p3.q.b = y;
16711 } else {
16712 p3.q.a = y;
16713 p3.q.b = bigInt(1);
16714 }
16715 return push(p3);
16716 };
16717
16718 normalize_angle = function() {
16719 save();
16720 p1 = pop();
16721 if (isinteger(p1)) {
16722 if (p1.q.a.isOdd()) {
16723 push_integer(-1);
16724 } else {
16725 push_integer(1);
16726 }
16727 restore();
16728 return;
16729 }
16730 push(p1);
16731 bignum_truncate();
16732 p2 = pop();
16733 if (isnegativenumber(p1)) {
16734 push(p2);
16735 push_integer(-1);
16736 add();
16737 p2 = pop();
16738 }
16739 push(p1);
16740 push(p2);
16741 subtract();
16742 p3 = pop();
16743 push_symbol(POWER);
16744 push_integer(-1);
16745 push(p3);
16746 list(3);
16747 if (p2.q.a.isOdd()) {
16748 negate();
16749 }
16750 return restore();
16751 };
16752
16753 is_small_integer = function(p) {
16754 return p.q.a.isSmall;
16755 };
16756
16757 quickfactor = function() {
16758 var h, i, l1, n, ref2, stackIndex;
16759 i = 0;
16760 save();
16761 p2 = pop();
16762 p1 = pop();
16763 h = tos;
16764 push(p1);
16765 factor_small_number();
16766 n = tos - h;
16767 stackIndex = h;
16768 for (i = l1 = 0, ref2 = n; l1 < ref2; i = l1 += 2) {
16769 push(stack[stackIndex + i]);
16770 push(stack[stackIndex + i + 1]);
16771 push(p2);
16772 multiply();
16773 quickpower();
16774 }
16775 multiply_all(tos - h - n);
16776 p1 = pop();
16777 moveTos(h);
16778 push(p1);
16779 return restore();
16780 };
16781
16782 quickpower = function() {
16783 var expo;
16784 expo = 0;
16785 save();
16786 p2 = pop();
16787 p1 = pop();
16788 push(p2);
16789 bignum_truncate();
16790 p3 = pop();
16791 push(p2);
16792 push(p3);
16793 subtract();
16794 p4 = pop();
16795 if (!iszero(p4)) {
16796 push_symbol(POWER);
16797 push(p1);
16798 push(p4);
16799 list(3);
16800 }
16801 push(p3);
16802 expo = pop_integer();
16803 if (isNaN(expo)) {
16804 push_symbol(POWER);
16805 push(p1);
16806 push(p3);
16807 list(3);
16808 restore();
16809 return;
16810 }
16811 if (expo === 0) {
16812 restore();
16813 return;
16814 }
16815 push(p1);
16816 bignum_power_number(expo);
16817 return restore();
16818 };
16819
16820 Eval_quotient = function() {
16821 push(cadr(p1));
16822 Eval();
16823 push(caddr(p1));
16824 Eval();
16825 push(cadddr(p1));
16826 Eval();
16827 p1 = pop();
16828 if (p1 === symbol(NIL)) {
16829 p1 = symbol(SYMBOL_X);
16830 }
16831 push(p1);
16832 return divpoly();
16833 };
16834
16835 divpoly = function() {
16836 var dividend, divisor, h, i, l1, m, n, ref2, x;
16837 h = 0;
16838 i = 0;
16839 m = 0;
16840 n = 0;
16841 x = 0;
16842 save();
16843 p3 = pop();
16844 p2 = pop();
16845 p1 = pop();
16846 h = tos;
16847 dividend = tos;
16848 push(p1);
16849 push(p3);
16850 m = coeff() - 1;
16851 divisor = tos;
16852 push(p2);
16853 push(p3);
16854 n = coeff() - 1;
16855 x = m - n;
16856 push_integer(0);
16857 p5 = pop();
16858 while (x >= 0) {
16859 push(stack[dividend + m]);
16860 push(stack[divisor + n]);
16861 divide();
16862 p4 = pop();
16863 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 0 <= ref2 ? ++l1 : --l1) {
16864 push(stack[dividend + x + i]);
16865 push(stack[divisor + i]);
16866 push(p4);
16867 multiply();
16868 subtract();
16869 stack[dividend + x + i] = pop();
16870 }
16871 push(p5);
16872 push(p4);
16873 push(p3);
16874 push_integer(x);
16875 power();
16876 multiply();
16877 add();
16878 p5 = pop();
16879 m--;
16880 x--;
16881 }
16882 moveTos(h);
16883 push(p5);
16884 return restore();
16885 };
16886
16887 Eval_rationalize = function() {
16888 push(cadr(p1));
16889 Eval();
16890 return rationalize();
16891 };
16892
16893 rationalize = function() {
16894 var x;
16895 x = expanding;
16896 save();
16897 yyrationalize();
16898 restore();
16899 return expanding = x;
16900 };
16901
16902 yyrationalize = function() {
16903 p1 = pop();
16904 if (istensor(p1)) {
16905 __rationalize_tensor();
16906 return;
16907 }
16908 expanding = 0;
16909 if (car(p1) !== symbol(ADD)) {
16910 push(p1);
16911 return;
16912 }
16913 if (DEBUG) {
16914 printf("rationalize: this is the input expr:\n");
16915 printline(p1);
16916 }
16917 push(one);
16918 multiply_denominators(p1);
16919 p2 = pop();
16920 if (DEBUG) {
16921 printf("rationalize: this is the common denominator:\n");
16922 printline(p2);
16923 }
16924 push(zero);
16925 p3 = cdr(p1);
16926 while (iscons(p3)) {
16927 push(p2);
16928 push(car(p3));
16929 multiply();
16930 add();
16931 p3 = cdr(p3);
16932 }
16933 if (DEBUG) {
16934 printf("rationalize: original expr times common denominator:\n");
16935 printline(stack[tos - 1]);
16936 }
16937 Condense();
16938 if (DEBUG) {
16939 printf("rationalize: after factoring:\n");
16940 printline(stack[tos - 1]);
16941 }
16942 push(p2);
16943 divide();
16944 if (DEBUG) {
16945 printf("rationalize: after dividing by common denom. (and we're done):\n");
16946 return printline(stack[tos - 1]);
16947 }
16948 };
16949
16950 multiply_denominators = function(p) {
16951 var results;
16952 if (car(p) === symbol(ADD)) {
16953 p = cdr(p);
16954 results = [];
16955 while (iscons(p)) {
16956 multiply_denominators_term(car(p));
16957 results.push(p = cdr(p));
16958 }
16959 return results;
16960 } else {
16961 return multiply_denominators_term(p);
16962 }
16963 };
16964
16965 multiply_denominators_term = function(p) {
16966 var results;
16967 if (car(p) === symbol(MULTIPLY)) {
16968 p = cdr(p);
16969 results = [];
16970 while (iscons(p)) {
16971 multiply_denominators_factor(car(p));
16972 results.push(p = cdr(p));
16973 }
16974 return results;
16975 } else {
16976 return multiply_denominators_factor(p);
16977 }
16978 };
16979
16980 multiply_denominators_factor = function(p) {
16981 if (car(p) !== symbol(POWER)) {
16982 return;
16983 }
16984 push(p);
16985 p = caddr(p);
16986 if (isnegativenumber(p)) {
16987 inverse();
16988 __lcm();
16989 return;
16990 }
16991 if (car(p) === symbol(MULTIPLY) && isnegativenumber(cadr(p))) {
16992 inverse();
16993 __lcm();
16994 return;
16995 }
16996 return pop();
16997 };
16998
16999 __rationalize_tensor = function() {
17000 var i, l1, n, ref2;
17001 i = 0;
17002 push(p1);
17003 Eval();
17004 p1 = pop();
17005 if (!istensor(p1)) {
17006 push(p1);
17007 return;
17008 }
17009 n = p1.tensor.nelem;
17010 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
17011 push(p1.tensor.elem[i]);
17012 rationalize();
17013 p1.tensor.elem[i] = pop();
17014 }
17015 check_tensor_dimensions(p1);
17016 return push(p1);
17017 };
17018
17019 __lcm = function() {
17020 save();
17021 p1 = pop();
17022 p2 = pop();
17023 push(p1);
17024 push(p2);
17025 multiply();
17026 push(p1);
17027 push(p2);
17028 gcd();
17029 divide();
17030 return restore();
17031 };
17032
17033
17034 /*
17035 Returns the real part of complex z
17036
17037 z real(z)
17038 - -------
17039
17040 a + i b a
17041
17042 exp(i a) cos(a)
17043 */
17044
17045 Eval_real = function() {
17046 push(cadr(p1));
17047 Eval();
17048 return real();
17049 };
17050
17051 real = function() {
17052 save();
17053 rect();
17054 p1 = pop();
17055 push(p1);
17056 push(p1);
17057 conjugate();
17058 add();
17059 push_integer(2);
17060 divide();
17061 return restore();
17062 };
17063
17064
17065 /*
17066 Convert complex z to rectangular form
17067
17068 Input: push z
17069
17070 Output: Result on stack
17071 */
17072
17073 DEBUG_RECT = false;
17074
17075 Eval_rect = function() {
17076 push(cadr(p1));
17077 Eval();
17078 return rect();
17079 };
17080
17081 rect = function() {
17082 var input;
17083 save();
17084 p1 = pop();
17085 input = p1;
17086 if (DEBUG_RECT) {
17087 console.log("RECT of " + input);
17088 }
17089 if (DEBUG_RECT) {
17090 console.log("any clock forms in : " + input + " ? " + findPossibleClockForm(input));
17091 }
17092 if (issymbol(p1)) {
17093 if (DEBUG_RECT) {
17094 console.log(" rect: simple symbol: " + input);
17095 }
17096 if (!iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
17097 push(p1);
17098 } else {
17099 push_symbol(YYRECT);
17100 push(p1);
17101 list(2);
17102 }
17103 } else if (!iszero(get_binding(symbol(ASSUME_REAL_VARIABLES))) && !findPossibleExponentialForm(p1) && !findPossibleClockForm(p1) && !(Find(p1, symbol(SIN)) && Find(p1, symbol(COS)) && Find(p1, imaginaryunit))) {
17104 if (DEBUG_RECT) {
17105 console.log(" rect: simple symbol: " + input);
17106 }
17107 push(p1);
17108 } else if (car(p1) === symbol(MULTIPLY) && isimaginaryunit(cadr(p1)) && !iszero(get_binding(symbol(ASSUME_REAL_VARIABLES)))) {
17109 push(p1);
17110 } else if (car(p1) === symbol(ADD)) {
17111 if (DEBUG_RECT) {
17112 console.log(" rect - " + input + " is a sum ");
17113 }
17114 push_integer(0);
17115 p1 = cdr(p1);
17116 while (iscons(p1)) {
17117 push(car(p1));
17118 rect();
17119 add();
17120 p1 = cdr(p1);
17121 }
17122 } else {
17123 if (DEBUG_RECT) {
17124 console.log(" rect - " + input + " is NOT a sum ");
17125 }
17126 push(p1);
17127 abs();
17128 if (DEBUG_RECT) {
17129 console.log(" rect - " + input + " abs: " + stack[tos - 1].toString());
17130 }
17131 push(p1);
17132 arg();
17133 if (DEBUG_RECT) {
17134 console.log(" rect - " + input + " arg of " + p1 + " : " + stack[tos - 1].toString());
17135 }
17136 p1 = pop();
17137 push(p1);
17138 cosine();
17139 if (DEBUG_RECT) {
17140 console.log(" rect - " + input + " cosine: " + stack[tos - 1].toString());
17141 }
17142 push(imaginaryunit);
17143 push(p1);
17144 sine();
17145 if (DEBUG_RECT) {
17146 console.log(" rect - " + input + " sine: " + stack[tos - 1].toString());
17147 }
17148 multiply();
17149 if (DEBUG_RECT) {
17150 console.log(" rect - " + input + " i * sine: " + stack[tos - 1].toString());
17151 }
17152 add();
17153 if (DEBUG_RECT) {
17154 console.log(" rect - " + input + " cos + i * sine: " + stack[tos - 1].toString());
17155 }
17156 multiply();
17157 }
17158 restore();
17159 if (DEBUG_RECT) {
17160 return console.log("rect of " + input + " : " + stack[tos - 1]);
17161 }
17162 };
17163
17164 show_power_debug = false;
17165
17166 performing_roots = false;
17167
17168 Eval_roots = function() {
17169 p2 = cadr(p1);
17170 if (car(p2) === symbol(SETQ) || car(p2) === symbol(TESTEQ)) {
17171 push(cadr(p2));
17172 Eval();
17173 push(caddr(p2));
17174 Eval();
17175 subtract();
17176 } else {
17177 push(p2);
17178 Eval();
17179 p2 = pop();
17180 if (car(p2) === symbol(SETQ) || car(p2) === symbol(TESTEQ)) {
17181 push(cadr(p2));
17182 Eval();
17183 push(caddr(p2));
17184 Eval();
17185 subtract();
17186 } else {
17187 push(p2);
17188 }
17189 }
17190 push(caddr(p1));
17191 Eval();
17192 p2 = pop();
17193 if (p2 === symbol(NIL)) {
17194 guess();
17195 } else {
17196 push(p2);
17197 }
17198 p2 = pop();
17199 p1 = pop();
17200 if (!ispoly(p1, p2)) {
17201 stop("roots: 1st argument is not a polynomial");
17202 }
17203 push(p1);
17204 push(p2);
17205 return roots();
17206 };
17207
17208 hasImaginaryCoeff = function(k) {
17209 var h, i, imaginaryCoefficients, l1, ref2;
17210 imaginaryCoefficients = false;
17211 h = tos;
17212 for (i = l1 = ref2 = k; l1 > 0; i = l1 += -1) {
17213 if (iscomplexnumber(stack[tos - i])) {
17214 imaginaryCoefficients = true;
17215 break;
17216 }
17217 }
17218 return imaginaryCoefficients;
17219 };
17220
17221 isSimpleRoot = function(k) {
17222 var h, i, isSimpleRootPolynomial, l1, ref2;
17223 if (k > 2) {
17224 isSimpleRootPolynomial = true;
17225 h = tos;
17226 if (iszero(stack[tos - k])) {
17227 isSimpleRootPolynomial = false;
17228 }
17229 for (i = l1 = ref2 = k - 1; l1 > 1; i = l1 += -1) {
17230 if (!iszero(stack[tos - i])) {
17231 isSimpleRootPolynomial = false;
17232 break;
17233 }
17234 }
17235 } else {
17236 isSimpleRootPolynomial = false;
17237 }
17238 return isSimpleRootPolynomial;
17239 };
17240
17241 normalisedCoeff = function() {
17242 var divideBy, i, k, l1, m1, miniStack, ref2, ref3;
17243 k = coeff();
17244 divideBy = stack[tos - 1];
17245 miniStack = [];
17246 for (i = l1 = 1, ref2 = k; 1 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 1 <= ref2 ? ++l1 : --l1) {
17247 miniStack.push(pop());
17248 }
17249 for (i = m1 = ref3 = k - 1; ref3 <= 0 ? m1 <= 0 : m1 >= 0; i = ref3 <= 0 ? ++m1 : --m1) {
17250 push(miniStack[i]);
17251 push(divideBy);
17252 divide();
17253 }
17254 return k;
17255 };
17256
17257 roots = function() {
17258 var h, i, k, l1, lastCoeff, leadingCoeff, n, ref2;
17259 h = 0;
17260 i = 0;
17261 n = 0;
17262 save();
17263 if (recursionLevelNestedRadicalsRemoval > 1) {
17264 pop();
17265 pop();
17266 push(symbol(NIL));
17267 restore();
17268 return;
17269 }
17270 performing_roots = true;
17271 h = tos - 2;
17272 if (DEBUG) {
17273 console.log("checking if " + stack[tos - 1].toString() + " is a case of simple roots");
17274 }
17275 p2 = pop();
17276 p1 = pop();
17277 push(p1);
17278 push(p2);
17279 push(p1);
17280 push(p2);
17281 k = normalisedCoeff();
17282 if (isSimpleRoot(k)) {
17283 if (DEBUG) {
17284 console.log("yes, " + stack[tos - 1].toString() + " is a case of simple roots");
17285 }
17286 lastCoeff = stack[tos - k];
17287 leadingCoeff = stack[tos - 1];
17288 moveTos(tos - k);
17289 pop();
17290 pop();
17291 getSimpleRoots(k, leadingCoeff, lastCoeff);
17292 } else {
17293 moveTos(tos - k);
17294 roots2();
17295 }
17296 n = tos - h;
17297 if (n === 0) {
17298 stop("roots: the polynomial is not factorable, try nroots");
17299 }
17300 if (n === 1) {
17301 performing_roots = false;
17302 restore();
17303 return;
17304 }
17305 sort_stack(n);
17306 p1 = alloc_tensor(n);
17307 p1.tensor.ndim = 1;
17308 p1.tensor.dim[0] = n;
17309 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
17310 p1.tensor.elem[i] = stack[h + i];
17311 }
17312 moveTos(h);
17313 push(p1);
17314 restore();
17315 return performing_roots = false;
17316 };
17317
17318 getSimpleRoots = function(n, leadingCoeff, lastCoeff) {
17319 var aSol, commonPart, l1, m1, ref2, ref3, rootsOfOne;
17320 if (DEBUG) {
17321 console.log("getSimpleRoots");
17322 }
17323 save();
17324 n = n - 1;
17325 push(lastCoeff);
17326 push_rational(1, n);
17327 power();
17328 push(leadingCoeff);
17329 push_rational(1, n);
17330 power();
17331 divide();
17332 commonPart = pop();
17333 if (n % 2 === 0) {
17334 for (rootsOfOne = l1 = 1, ref2 = n; l1 <= ref2; rootsOfOne = l1 += 2) {
17335 push(commonPart);
17336 push_integer(-1);
17337 push_rational(rootsOfOne, n);
17338 power();
17339 multiply();
17340 aSol = pop();
17341 push(aSol);
17342 push(aSol);
17343 negate();
17344 }
17345 } else {
17346 for (rootsOfOne = m1 = 1, ref3 = n; 1 <= ref3 ? m1 <= ref3 : m1 >= ref3; rootsOfOne = 1 <= ref3 ? ++m1 : --m1) {
17347 push(commonPart);
17348 push_integer(-1);
17349 push_rational(rootsOfOne, n);
17350 power();
17351 multiply();
17352 if (rootsOfOne % 2 === 0) {
17353 negate();
17354 }
17355 }
17356 }
17357 return restore();
17358 };
17359
17360 roots2 = function() {
17361 var k;
17362 save();
17363 p2 = pop();
17364 p1 = pop();
17365 push(p1);
17366 push(p2);
17367 push(p1);
17368 push(p2);
17369 k = normalisedCoeff();
17370 if (!hasImaginaryCoeff(k)) {
17371 moveTos(tos - k);
17372 factorpoly();
17373 p1 = pop();
17374 } else {
17375 moveTos(tos - k);
17376 pop();
17377 pop();
17378 }
17379 if (car(p1) === symbol(MULTIPLY)) {
17380 p1 = cdr(p1);
17381 while (iscons(p1)) {
17382 push(car(p1));
17383 push(p2);
17384 roots3();
17385 p1 = cdr(p1);
17386 }
17387 } else {
17388 push(p1);
17389 push(p2);
17390 roots3();
17391 }
17392 return restore();
17393 };
17394
17395 roots3 = function() {
17396 var n;
17397 save();
17398 p2 = pop();
17399 p1 = pop();
17400 if (car(p1) === symbol(POWER) && ispoly(cadr(p1), p2) && isposint(caddr(p1))) {
17401 push(cadr(p1));
17402 push(p2);
17403 n = normalisedCoeff();
17404 mini_solve(n);
17405 } else if (ispoly(p1, p2)) {
17406 push(p1);
17407 push(p2);
17408 n = normalisedCoeff();
17409 mini_solve(n);
17410 }
17411 return restore();
17412 };
17413
17414 mini_solve = function(n) {
17415 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;
17416 save();
17417 if (n === 2) {
17418 p3 = pop();
17419 p4 = pop();
17420 push(p4);
17421 push(p3);
17422 divide();
17423 negate();
17424 restore();
17425 return;
17426 }
17427 if (n === 3) {
17428 p3 = pop();
17429 p4 = pop();
17430 p5 = pop();
17431 push(p4);
17432 push_integer(2);
17433 power();
17434 push_integer(4);
17435 push(p3);
17436 multiply();
17437 push(p5);
17438 multiply();
17439 subtract();
17440 push_rational(1, 2);
17441 power();
17442 p6 = pop();
17443 push(p6);
17444 push(p4);
17445 subtract();
17446 push(p3);
17447 push_integer(2);
17448 multiply();
17449 divide();
17450 push(p6);
17451 push(p4);
17452 add();
17453 negate();
17454 push(p3);
17455 divide();
17456 push_rational(1, 2);
17457 multiply();
17458 restore();
17459 return;
17460 }
17461 if (n === 4 || n === 5) {
17462 p3 = pop();
17463 p4 = pop();
17464 p5 = pop();
17465 p6 = pop();
17466 push(p5);
17467 push(p5);
17468 multiply();
17469 R_c2 = pop();
17470 push(R_c2);
17471 push(p5);
17472 multiply();
17473 R_c3 = pop();
17474 push(p4);
17475 push(p4);
17476 multiply();
17477 R_b2 = pop();
17478 push(R_b2);
17479 push(p4);
17480 multiply();
17481 R_b3 = pop();
17482 push(R_b3);
17483 push(p6);
17484 multiply();
17485 R_b3_d = pop();
17486 push(R_b3_d);
17487 push_integer(-4);
17488 multiply();
17489 R_m4_b3_d = pop();
17490 push(R_b3);
17491 push_integer(2);
17492 multiply();
17493 R_2_b3 = pop();
17494 push(p3);
17495 push(p3);
17496 multiply();
17497 R_a2 = pop();
17498 push(R_a2);
17499 push(p3);
17500 multiply();
17501 R_a3 = pop();
17502 push_integer(3);
17503 push(p3);
17504 multiply();
17505 R_3_a = pop();
17506 push(R_a2);
17507 push(p6);
17508 multiply();
17509 R_a2_d = pop();
17510 push(R_a2_d);
17511 push(p6);
17512 multiply();
17513 R_a2_d2 = pop();
17514 push(R_a2_d);
17515 push_integer(27);
17516 multiply();
17517 R_27_a2_d = pop();
17518 push(R_a2_d2);
17519 push_integer(-27);
17520 multiply();
17521 R_m27_a2_d2 = pop();
17522 push(R_3_a);
17523 push_integer(2);
17524 multiply();
17525 R_6_a = pop();
17526 push(p3);
17527 push(p5);
17528 multiply();
17529 R_a_c = pop();
17530 push(R_a_c);
17531 push(p4);
17532 multiply();
17533 R_a_b_c = pop();
17534 push(R_a_b_c);
17535 push(p6);
17536 multiply();
17537 R_a_b_c_d = pop();
17538 push(R_a_c);
17539 push_integer(3);
17540 multiply();
17541 R_3_a_c = pop();
17542 push_integer(-4);
17543 push(p3);
17544 push(R_c3);
17545 multiply();
17546 multiply();
17547 R_m4_a_c3 = pop();
17548 push(R_a_b_c);
17549 push_integer(9);
17550 multiply();
17551 negate();
17552 R_m9_a_b_c = pop();
17553 push(R_a_b_c_d);
17554 push_integer(18);
17555 multiply();
17556 R_18_a_b_c_d = pop();
17557 push(R_b2);
17558 push(R_3_a_c);
17559 subtract();
17560 R_DELTA0 = pop();
17561 push(R_b2);
17562 push(R_c2);
17563 multiply();
17564 R_b2_c2 = pop();
17565 push(p4);
17566 negate();
17567 push(R_3_a);
17568 divide();
17569 R_m_b_over_3a = pop();
17570 if (n === 4) {
17571 if (DEBUG) {
17572 console.log(">>>>>>>>>>>>>>>> actually using cubic formula <<<<<<<<<<<<<<< ");
17573 }
17574 if (DEBUG) {
17575 console.log("cubic: D0: " + R_DELTA0.toString());
17576 }
17577 push(R_DELTA0);
17578 push_integer(3);
17579 power();
17580 push_integer(4);
17581 multiply();
17582 R_4_DELTA03 = pop();
17583 push(R_DELTA0);
17584 simplify();
17585 absValFloat();
17586 R_DELTA0_toBeCheckedIfZero = pop();
17587 if (DEBUG) {
17588 console.log("cubic: D0 as float: " + R_DELTA0_toBeCheckedIfZero.toString());
17589 }
17590 push(R_18_a_b_c_d);
17591 push(R_m4_b3_d);
17592 push(R_b2_c2);
17593 push(R_m4_a_c3);
17594 push(R_m27_a2_d2);
17595 add();
17596 add();
17597 add();
17598 add();
17599 simplify();
17600 absValFloat();
17601 R_determinant = pop();
17602 if (DEBUG) {
17603 console.log("cubic: DETERMINANT: " + R_determinant.toString());
17604 }
17605 push(R_2_b3);
17606 push(R_m9_a_b_c);
17607 push(R_27_a2_d);
17608 add();
17609 add();
17610 R_DELTA1 = pop();
17611 if (DEBUG) {
17612 console.log("cubic: D1: " + R_DELTA1.toString());
17613 }
17614 push(R_DELTA1);
17615 push_integer(2);
17616 power();
17617 push(R_4_DELTA03);
17618 subtract();
17619 push_rational(1, 2);
17620 power();
17621 simplify();
17622 R_Q = pop();
17623 if (iszero(R_determinant)) {
17624 if (iszero(R_DELTA0_toBeCheckedIfZero)) {
17625 if (DEBUG) {
17626 console.log(" cubic: DETERMINANT IS ZERO and delta0 is zero");
17627 }
17628 push(R_m_b_over_3a);
17629 restore();
17630 return;
17631 } else {
17632 if (DEBUG) {
17633 console.log(" cubic: DETERMINANT IS ZERO and delta0 is not zero");
17634 }
17635 push(p3);
17636 push(p6);
17637 push_integer(9);
17638 multiply();
17639 multiply();
17640 push(p4);
17641 push(p5);
17642 multiply();
17643 subtract();
17644 push(R_DELTA0);
17645 push_integer(2);
17646 multiply();
17647 divide();
17648 root_solution = pop();
17649 push(root_solution);
17650 push(root_solution);
17651 push(R_a_b_c);
17652 push_integer(4);
17653 multiply();
17654 push(p3);
17655 push(p3);
17656 push(p6);
17657 push_integer(9);
17658 multiply();
17659 multiply();
17660 multiply();
17661 negate();
17662 push(R_b3);
17663 negate();
17664 add();
17665 add();
17666 push(p3);
17667 push(R_DELTA0);
17668 multiply();
17669 divide();
17670 restore();
17671 return;
17672 }
17673 }
17674 C_CHECKED_AS_NOT_ZERO = false;
17675 flipSignOFQSoCIsNotZero = false;
17676 while (!C_CHECKED_AS_NOT_ZERO) {
17677 push(R_Q);
17678 if (flipSignOFQSoCIsNotZero) {
17679 negate();
17680 }
17681 push(R_DELTA1);
17682 add();
17683 push_rational(1, 2);
17684 multiply();
17685 push_rational(1, 3);
17686 power();
17687 simplify();
17688 R_C = pop();
17689 if (DEBUG) {
17690 console.log("cubic: C: " + R_C.toString());
17691 }
17692 push(R_C);
17693 simplify();
17694 absValFloat();
17695 R_C_simplified_toCheckIfZero = pop();
17696 if (DEBUG) {
17697 console.log("cubic: C as absval and float: " + R_C_simplified_toCheckIfZero.toString());
17698 }
17699 if (iszero(R_C_simplified_toCheckIfZero)) {
17700 if (DEBUG) {
17701 console.log(" cubic: C IS ZERO flipping the sign");
17702 }
17703 flipSignOFQSoCIsNotZero = true;
17704 } else {
17705 C_CHECKED_AS_NOT_ZERO = true;
17706 }
17707 }
17708 push(R_C);
17709 push(R_3_a);
17710 multiply();
17711 R_3_a_C = pop();
17712 push(R_3_a_C);
17713 push_integer(2);
17714 multiply();
17715 R_6_a_C = pop();
17716 push(imaginaryunit);
17717 push_integer(3);
17718 push_rational(1, 2);
17719 power();
17720 multiply();
17721 i_sqrt3 = pop();
17722 push_integer(1);
17723 push(i_sqrt3);
17724 add();
17725 one_plus_i_sqrt3 = pop();
17726 push_integer(1);
17727 push(i_sqrt3);
17728 subtract();
17729 one_minus_i_sqrt3 = pop();
17730 push(R_C);
17731 push(R_3_a);
17732 divide();
17733 R_C_over_3a = pop();
17734 push(R_m_b_over_3a);
17735 push(R_C_over_3a);
17736 negate();
17737 push(R_DELTA0);
17738 push(R_3_a_C);
17739 divide();
17740 negate();
17741 add();
17742 add();
17743 simplify();
17744 push(R_m_b_over_3a);
17745 push(R_C_over_3a);
17746 push(one_plus_i_sqrt3);
17747 multiply();
17748 push_integer(2);
17749 divide();
17750 push(one_minus_i_sqrt3);
17751 push(R_DELTA0);
17752 multiply();
17753 push(R_6_a_C);
17754 divide();
17755 add();
17756 add();
17757 simplify();
17758 push(R_m_b_over_3a);
17759 push(R_C_over_3a);
17760 push(one_minus_i_sqrt3);
17761 multiply();
17762 push_integer(2);
17763 divide();
17764 push(one_plus_i_sqrt3);
17765 push(R_DELTA0);
17766 multiply();
17767 push(R_6_a_C);
17768 divide();
17769 add();
17770 add();
17771 simplify();
17772 restore();
17773 return;
17774 }
17775 if (n === 5) {
17776 if (DEBUG) {
17777 console.log(">>>>>>>>>>>>>>>> actually using quartic formula <<<<<<<<<<<<<<< ");
17778 }
17779 p7 = pop();
17780 if (iszero(p4) && iszero(p6) && !iszero(p5) && !iszero(p7)) {
17781 if (DEBUG) {
17782 console.log("biquadratic case");
17783 }
17784 push(p3);
17785 push(symbol(SECRETX));
17786 push_integer(2);
17787 power();
17788 multiply();
17789 push(p5);
17790 push(symbol(SECRETX));
17791 multiply();
17792 push(p7);
17793 add();
17794 add();
17795 push(symbol(SECRETX));
17796 roots();
17797 biquadraticSolutions = pop();
17798 ref2 = biquadraticSolutions.tensor.elem;
17799 for (l1 = 0, len = ref2.length; l1 < len; l1++) {
17800 eachSolution = ref2[l1];
17801 push(eachSolution);
17802 push_rational(1, 2);
17803 power();
17804 simplify();
17805 push(eachSolution);
17806 push_rational(1, 2);
17807 power();
17808 negate();
17809 simplify();
17810 }
17811 restore();
17812 return;
17813 }
17814 push(p6);
17815 push(p6);
17816 multiply();
17817 R_d2 = pop();
17818 push(p7);
17819 push(p7);
17820 multiply();
17821 R_e2 = pop();
17822 push(R_e2);
17823 push(p7);
17824 multiply();
17825 R_e3 = pop();
17826 push_integer(256);
17827 push(R_a3);
17828 push(R_e3);
17829 multiply();
17830 multiply();
17831 push_integer(-192);
17832 push(R_a2_d);
17833 push(R_e2);
17834 push(p4);
17835 multiply();
17836 multiply();
17837 multiply();
17838 push_integer(-128);
17839 push(R_a2);
17840 push(R_c2);
17841 push(R_e2);
17842 multiply();
17843 multiply();
17844 multiply();
17845 push_integer(144);
17846 push(R_a2_d2);
17847 push(p5);
17848 push(p7);
17849 multiply();
17850 multiply();
17851 multiply();
17852 push(R_m27_a2_d2);
17853 push(R_d2);
17854 multiply();
17855 push_integer(144);
17856 push(R_a_b_c);
17857 push(p4);
17858 push(R_e2);
17859 multiply();
17860 multiply();
17861 multiply();
17862 push_integer(-6);
17863 push(p3);
17864 push(R_b2);
17865 push(R_d2);
17866 push(p7);
17867 multiply();
17868 multiply();
17869 multiply();
17870 multiply();
17871 push_integer(-80);
17872 push(R_a_b_c_d);
17873 push(p5);
17874 push(p7);
17875 multiply();
17876 multiply();
17877 multiply();
17878 push_integer(18);
17879 push(R_a_b_c_d);
17880 push(R_d2);
17881 multiply();
17882 multiply();
17883 push_integer(16);
17884 push(R_a_c);
17885 push(R_c3);
17886 push(p7);
17887 multiply();
17888 multiply();
17889 multiply();
17890 push_integer(-4);
17891 push(R_a_c);
17892 push(R_c2);
17893 push(R_d2);
17894 multiply();
17895 multiply();
17896 multiply();
17897 push_integer(-27);
17898 push(R_b3);
17899 push(p4);
17900 push(R_e2);
17901 multiply();
17902 multiply();
17903 multiply();
17904 push_integer(18);
17905 push(R_b3_d);
17906 push(p5);
17907 push(p7);
17908 multiply();
17909 multiply();
17910 multiply();
17911 push(R_m4_b3_d);
17912 push(R_d2);
17913 multiply();
17914 push_integer(-4);
17915 push(R_b2_c2);
17916 push(p5);
17917 push(p7);
17918 multiply();
17919 multiply();
17920 multiply();
17921 push(R_b2_c2);
17922 push(R_d2);
17923 multiply();
17924 add();
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 R_determinant = pop();
17940 if (DEBUG) {
17941 console.log("R_determinant: " + R_determinant.toString());
17942 }
17943 push(R_c2);
17944 push_integer(-3);
17945 push(p4);
17946 push(p6);
17947 multiply();
17948 multiply();
17949 push_integer(12);
17950 push(p3);
17951 push(p7);
17952 multiply();
17953 multiply();
17954 add();
17955 add();
17956 R_DELTA0 = pop();
17957 if (DEBUG) {
17958 console.log("R_DELTA0: " + R_DELTA0.toString());
17959 }
17960 push_integer(2);
17961 push(R_c3);
17962 multiply();
17963 push_integer(-9);
17964 push(p4);
17965 push(p5);
17966 push(p6);
17967 multiply();
17968 multiply();
17969 multiply();
17970 push_integer(27);
17971 push(R_b2);
17972 push(p7);
17973 multiply();
17974 multiply();
17975 push_integer(27);
17976 push(p3);
17977 push(R_d2);
17978 multiply();
17979 multiply();
17980 push_integer(-72);
17981 push(R_a_c);
17982 push(p7);
17983 multiply();
17984 multiply();
17985 add();
17986 add();
17987 add();
17988 add();
17989 R_DELTA1 = pop();
17990 if (DEBUG) {
17991 console.log("R_DELTA1: " + R_DELTA1.toString());
17992 }
17993 push_integer(8);
17994 push(R_a_c);
17995 multiply();
17996 push_integer(-3);
17997 push(R_b2);
17998 multiply();
17999 add();
18000 push_integer(8);
18001 push(R_a2);
18002 multiply();
18003 divide();
18004 R_p = pop();
18005 if (DEBUG) {
18006 console.log("p: " + R_p.toString());
18007 }
18008 push(R_b3);
18009 push_integer(-4);
18010 push(R_a_b_c);
18011 multiply();
18012 push_integer(8);
18013 push(R_a2_d);
18014 multiply();
18015 add();
18016 add();
18017 push_integer(8);
18018 push(R_a3);
18019 multiply();
18020 divide();
18021 R_q = pop();
18022 if (DEBUG) {
18023 console.log("q: " + R_q.toString());
18024 }
18025 if (DEBUG) {
18026 console.log("tos 1 " + tos);
18027 }
18028 if (!iszero(p4)) {
18029 if (DEBUG) {
18030 console.log("tos 2 " + tos);
18031 }
18032 push_integer(8);
18033 push(p5);
18034 push(p3);
18035 multiply();
18036 multiply();
18037 push_integer(-3);
18038 push(p4);
18039 push_integer(2);
18040 power();
18041 multiply();
18042 add();
18043 push_integer(8);
18044 push(p3);
18045 push_integer(2);
18046 power();
18047 multiply();
18048 divide();
18049 R_p = pop();
18050 if (DEBUG) {
18051 console.log("p for depressed quartic: " + R_p.toString());
18052 }
18053 push(p4);
18054 push_integer(3);
18055 power();
18056 push_integer(-4);
18057 push(p3);
18058 push(p4);
18059 push(p5);
18060 multiply();
18061 multiply();
18062 multiply();
18063 push_integer(8);
18064 push(p6);
18065 push(p3);
18066 push_integer(2);
18067 power();
18068 multiply();
18069 multiply();
18070 add();
18071 add();
18072 push_integer(8);
18073 push(p3);
18074 push_integer(3);
18075 power();
18076 multiply();
18077 divide();
18078 R_q = pop();
18079 if (DEBUG) {
18080 console.log("q for depressed quartic: " + R_q.toString());
18081 }
18082 push(p4);
18083 push_integer(4);
18084 power();
18085 push_integer(-3);
18086 multiply();
18087 push_integer(256);
18088 push(R_a3);
18089 push(p7);
18090 multiply();
18091 multiply();
18092 push_integer(-64);
18093 push(R_a2_d);
18094 push(p4);
18095 multiply();
18096 multiply();
18097 push_integer(16);
18098 push(R_b2);
18099 push(p3);
18100 push(p5);
18101 multiply();
18102 multiply();
18103 multiply();
18104 add();
18105 add();
18106 add();
18107 push_integer(256);
18108 push(p3);
18109 push_integer(4);
18110 power();
18111 multiply();
18112 divide();
18113 R_r = pop();
18114 if (DEBUG) {
18115 console.log("r for depressed quartic: " + R_r.toString());
18116 }
18117 if (DEBUG) {
18118 console.log("tos 4 " + tos);
18119 }
18120 push(symbol(SECRETX));
18121 push_integer(4);
18122 power();
18123 if (DEBUG) {
18124 console.log("4 * x^4: " + stack[tos - 1].toString());
18125 }
18126 push(R_p);
18127 push(symbol(SECRETX));
18128 push_integer(2);
18129 power();
18130 multiply();
18131 if (DEBUG) {
18132 console.log("R_p * x^2: " + stack[tos - 1].toString());
18133 }
18134 push(R_q);
18135 push(symbol(SECRETX));
18136 multiply();
18137 if (DEBUG) {
18138 console.log("R_q * x: " + stack[tos - 1].toString());
18139 }
18140 push(R_r);
18141 if (DEBUG) {
18142 console.log("R_r: " + stack[tos - 1].toString());
18143 }
18144 add();
18145 add();
18146 add();
18147 simplify();
18148 if (DEBUG) {
18149 console.log("solving depressed quartic: " + stack[tos - 1].toString());
18150 }
18151 push(symbol(SECRETX));
18152 roots();
18153 depressedSolutions = pop();
18154 if (DEBUG) {
18155 console.log("depressedSolutions: " + depressedSolutions);
18156 }
18157 ref3 = depressedSolutions.tensor.elem;
18158 for (m1 = 0, len1 = ref3.length; m1 < len1; m1++) {
18159 eachSolution = ref3[m1];
18160 push(eachSolution);
18161 push(p4);
18162 push_integer(4);
18163 push(p3);
18164 multiply();
18165 divide();
18166 subtract();
18167 simplify();
18168 if (DEBUG) {
18169 console.log("solution from depressed: " + stack[tos - 1].toString());
18170 }
18171 }
18172 restore();
18173 return;
18174 } else {
18175 R_p = p5;
18176 R_q = p6;
18177 R_r = p7;
18178
18179 /*
18180 * Descartes' solution
18181 * https://en.wikipedia.org/wiki/Quartic_function#Descartes.27_solution
18182 * finding the "u" in the depressed equation
18183
18184 push_integer(2)
18185 push(R_p)
18186 multiply()
18187 coeff2 = pop()
18188
18189 push_integer(-4)
18190 push(R_p)
18191 push_integer(2)
18192 power()
18193 multiply()
18194 push(R_r)
18195 multiply()
18196 coeff3 = pop()
18197
18198 push(R_q)
18199 push_integer(2)
18200 power()
18201 negate()
18202 coeff4 = pop()
18203
18204 * now build the polynomial
18205 push(symbol(SECRETX))
18206 push_integer(3)
18207 power()
18208
18209 push(coeff2)
18210 push(symbol(SECRETX))
18211 push_integer(2)
18212 power()
18213 multiply()
18214
18215 push(coeff3)
18216 push(symbol(SECRETX))
18217 multiply()
18218
18219 push(coeff4)
18220
18221 add()
18222 add()
18223 add()
18224
18225 console.log("Descarte's resolventCubic: " + stack[tos-1].toString())
18226 push(symbol(SECRETX))
18227
18228 roots()
18229
18230 resolventCubicSolutions = pop()
18231 console.log("Descarte's resolventCubic solutions: " + resolventCubicSolutions)
18232 console.log("tos: " + tos)
18233
18234 R_u = null
18235 #R_u = resolventCubicSolutions.tensor.elem[1]
18236 for eachSolution in resolventCubicSolutions.tensor.elem
18237 console.log("examining solution: " + eachSolution)
18238 push(eachSolution)
18239 push_integer(2)
18240 multiply()
18241 push(R_p)
18242 add()
18243
18244 absValFloat()
18245 toBeCheckedIFZero = pop()
18246 console.log("abs value is: " + eachSolution)
18247 if !iszero(toBeCheckedIFZero)
18248 R_u = eachSolution
18249 break
18250
18251 console.log("chosen solution: " + R_u)
18252
18253 push(R_u)
18254 negate()
18255 R_s = pop()
18256
18257 push(R_p)
18258 push(R_u)
18259 push_integer(2)
18260 power()
18261 push(R_q)
18262 push(R_u)
18263 divide()
18264 add()
18265 add()
18266 push_integer(2)
18267 divide()
18268 R_t = pop()
18269
18270 push(R_p)
18271 push(R_u)
18272 push_integer(2)
18273 power()
18274 push(R_q)
18275 push(R_u)
18276 divide()
18277 subtract()
18278 add()
18279 push_integer(2)
18280 divide()
18281 R_v = pop()
18282
18283 * factoring the quartic into two quadratics:
18284
18285 * now build the polynomial
18286 push(symbol(SECRETX))
18287 push_integer(2)
18288 power()
18289
18290 push(R_s)
18291 push(symbol(SECRETX))
18292 multiply()
18293
18294 push(R_t)
18295
18296 add()
18297 add()
18298
18299 console.log("factored quartic 1: " + stack[tos-1].toString())
18300
18301 push(symbol(SECRETX))
18302 push_integer(2)
18303 power()
18304
18305 push(R_u)
18306 push(symbol(SECRETX))
18307 multiply()
18308
18309 push(R_v)
18310
18311 add()
18312 add()
18313
18314 console.log("factored quartic 2: " + stack[tos-1].toString())
18315 pop()
18316
18317 restore()
18318 return
18319 */
18320 push_rational(5, 2);
18321 push(R_p);
18322 multiply();
18323 coeff2 = pop();
18324 push_integer(2);
18325 push(R_p);
18326 push_integer(2);
18327 power();
18328 multiply();
18329 push(R_r);
18330 subtract();
18331 coeff3 = pop();
18332 push(R_p);
18333 push_integer(3);
18334 power();
18335 push_integer(2);
18336 divide();
18337 push_rational(-1, 2);
18338 push(R_p);
18339 push(R_r);
18340 multiply();
18341 multiply();
18342 push_rational(-1, 8);
18343 push(R_q);
18344 push_integer(2);
18345 power();
18346 multiply();
18347 add();
18348 add();
18349 coeff4 = pop();
18350 push(symbol(SECRETX));
18351 push_integer(3);
18352 power();
18353 push(coeff2);
18354 push(symbol(SECRETX));
18355 push_integer(2);
18356 power();
18357 multiply();
18358 push(coeff3);
18359 push(symbol(SECRETX));
18360 multiply();
18361 push(coeff4);
18362 add();
18363 add();
18364 add();
18365 if (DEBUG) {
18366 console.log("resolventCubic: " + stack[tos - 1].toString());
18367 }
18368 push(symbol(SECRETX));
18369 roots();
18370 resolventCubicSolutions = pop();
18371 if (DEBUG) {
18372 console.log("resolventCubicSolutions: " + resolventCubicSolutions);
18373 }
18374 R_m = null;
18375 ref4 = resolventCubicSolutions.tensor.elem;
18376 for (n1 = 0, len2 = ref4.length; n1 < len2; n1++) {
18377 eachSolution = ref4[n1];
18378 if (DEBUG) {
18379 console.log("examining solution: " + eachSolution);
18380 }
18381 push(eachSolution);
18382 push_integer(2);
18383 multiply();
18384 push(R_p);
18385 add();
18386 absValFloat();
18387 toBeCheckedIFZero = pop();
18388 if (DEBUG) {
18389 console.log("abs value is: " + eachSolution);
18390 }
18391 if (!iszero(toBeCheckedIFZero)) {
18392 R_m = eachSolution;
18393 break;
18394 }
18395 }
18396 if (DEBUG) {
18397 console.log("chosen solution: " + R_m);
18398 }
18399 push(R_m);
18400 push_integer(2);
18401 multiply();
18402 push(R_p);
18403 add();
18404 push_rational(1, 2);
18405 power();
18406 simplify();
18407 sqrtPPlus2M = pop();
18408 push(R_q);
18409 push_integer(2);
18410 multiply();
18411 push(sqrtPPlus2M);
18412 divide();
18413 simplify();
18414 TwoQOversqrtPPlus2M = pop();
18415 push(R_p);
18416 push_integer(3);
18417 multiply();
18418 push(R_m);
18419 push_integer(2);
18420 multiply();
18421 add();
18422 ThreePPlus2M = pop();
18423 push(sqrtPPlus2M);
18424 push(ThreePPlus2M);
18425 push(TwoQOversqrtPPlus2M);
18426 add();
18427 negate();
18428 push_rational(1, 2);
18429 power();
18430 simplify();
18431 add();
18432 push_integer(2);
18433 divide();
18434 push(sqrtPPlus2M);
18435 push(ThreePPlus2M);
18436 push(TwoQOversqrtPPlus2M);
18437 add();
18438 negate();
18439 push_rational(1, 2);
18440 power();
18441 simplify();
18442 subtract();
18443 push_integer(2);
18444 divide();
18445 push(sqrtPPlus2M);
18446 negate();
18447 push(ThreePPlus2M);
18448 push(TwoQOversqrtPPlus2M);
18449 subtract();
18450 negate();
18451 push_rational(1, 2);
18452 power();
18453 simplify();
18454 add();
18455 push_integer(2);
18456 divide();
18457 push(sqrtPPlus2M);
18458 negate();
18459 push(ThreePPlus2M);
18460 push(TwoQOversqrtPPlus2M);
18461 subtract();
18462 negate();
18463 push_rational(1, 2);
18464 power();
18465 simplify();
18466 subtract();
18467 push_integer(2);
18468 divide();
18469 restore();
18470 return;
18471 }
18472 push(R_determinant);
18473 simplify();
18474 absValFloat();
18475 R_determinant_simplified_toCheckIfZero = pop();
18476 push(R_DELTA0);
18477 simplify();
18478 absValFloat();
18479 R_DELTA0_simplified_toCheckIfZero = pop();
18480 S_CHECKED_AS_NOT_ZERO = false;
18481 choiceOfRadicalInQSoSIsNotZero = 0;
18482 while (!S_CHECKED_AS_NOT_ZERO) {
18483 Q_CHECKED_AS_NOT_ZERO = false;
18484 flipSignOFRadicalSoQIsNotZero = false;
18485 while (!Q_CHECKED_AS_NOT_ZERO) {
18486 push(R_DELTA1);
18487 push(R_DELTA1);
18488 push_integer(2);
18489 power();
18490 push_integer(-4);
18491 push(R_DELTA0);
18492 push_integer(3);
18493 power();
18494 multiply();
18495 add();
18496 push_rational(1, 2);
18497 power();
18498 if (flipSignOFRadicalSoQIsNotZero) {
18499 negate();
18500 }
18501 add();
18502 push_integer(2);
18503 divide();
18504 if (DEBUG) {
18505 console.log("content of cubic root: " + stack[tos - 1].toString());
18506 }
18507 push_rational(1, 3);
18508 power();
18509 simplify();
18510 R_principalCubicRoot = pop();
18511 if (DEBUG) {
18512 console.log("principal cubic root: " + R_principalCubicRoot.toString());
18513 }
18514 if (DEBUG) {
18515 console.log("tos : " + tos);
18516 }
18517 if (choiceOfRadicalInQSoSIsNotZero === 0) {
18518 if (DEBUG) {
18519 console.log("chosing principal cubic root");
18520 }
18521 push(R_principalCubicRoot);
18522 } else if (choiceOfRadicalInQSoSIsNotZero === 1) {
18523 if (DEBUG) {
18524 console.log("chosing cubic root beyond principal");
18525 }
18526 push(R_principalCubicRoot);
18527 push_rational(-1, 2);
18528 multiply();
18529 push_integer(3);
18530 push_rational(1, 2);
18531 power();
18532 push(imaginaryunit);
18533 multiply();
18534 push_rational(-1, 2);
18535 multiply();
18536 push(R_principalCubicRoot);
18537 multiply();
18538 add();
18539 } else if (choiceOfRadicalInQSoSIsNotZero === 1) {
18540 if (DEBUG) {
18541 console.log("chosing cubic root beyond beyond principal");
18542 }
18543 push(R_principalCubicRoot);
18544 push_rational(-1, 2);
18545 multiply();
18546 push_integer(3);
18547 push_rational(1, 2);
18548 power();
18549 push(imaginaryunit);
18550 multiply();
18551 push_rational(1, 2);
18552 multiply();
18553 push(R_principalCubicRoot);
18554 multiply();
18555 add();
18556 }
18557 simplify();
18558 R_Q = pop();
18559 if (DEBUG) {
18560 console.log("Q " + R_Q.toString());
18561 }
18562 if (DEBUG) {
18563 console.log("tos: " + tos);
18564 }
18565 push(R_Q);
18566 simplify();
18567 absValFloat();
18568 R_Q_simplified_toCheckIfZero = pop();
18569 if (DEBUG) {
18570 console.log("Q simplified and abs" + R_Q_simplified_toCheckIfZero.toString());
18571 }
18572 if (iszero(R_Q_simplified_toCheckIfZero) && (!iszero(R_determinant_simplified_toCheckIfZero) && iszero(R_DELTA0_simplified_toCheckIfZero))) {
18573 if (DEBUG) {
18574 console.log(" *********************************** Q IS ZERO and it matters, flipping the sign");
18575 }
18576 flipSignOFRadicalSoQIsNotZero = true;
18577 } else {
18578 Q_CHECKED_AS_NOT_ZERO = true;
18579 }
18580 if (DEBUG) {
18581 console.log("tos: " + tos);
18582 }
18583 }
18584 push_rational(-2, 3);
18585 push(R_p);
18586 multiply();
18587 push(R_Q);
18588 push(R_DELTA0);
18589 push(R_Q);
18590 divide();
18591 add();
18592 push(R_3_a);
18593 divide();
18594 add();
18595 push_rational(1, 2);
18596 power();
18597 push_integer(2);
18598 divide();
18599 show_power_debug = true;
18600 simplify();
18601 R_S = pop();
18602 if (DEBUG) {
18603 console.log("S " + R_S.toString());
18604 }
18605 push(R_S);
18606 simplify();
18607 absValFloat();
18608 R_S_simplified_toCheckIfZero = pop();
18609 if (DEBUG) {
18610 console.log("S " + R_S_simplified_toCheckIfZero.toString());
18611 }
18612 if (iszero(R_S_simplified_toCheckIfZero)) {
18613 if (DEBUG) {
18614 console.log(" *********************************** S IS ZERO chosing another cubic root");
18615 }
18616 choiceOfRadicalInQSoSIsNotZero++;
18617 } else {
18618 S_CHECKED_AS_NOT_ZERO = true;
18619 }
18620 if (DEBUG) {
18621 console.log("tos: " + tos);
18622 }
18623 }
18624 if (DEBUG) {
18625 console.log("tos: " + tos);
18626 }
18627 push(p4);
18628 negate();
18629 push(p3);
18630 push_integer(4);
18631 multiply();
18632 divide();
18633 R_minus_b_over_4a = pop();
18634 push_integer(-4);
18635 push(R_S);
18636 push_integer(2);
18637 power();
18638 multiply();
18639 push_integer(2);
18640 push(R_p);
18641 multiply();
18642 subtract();
18643 R_minus_4S2_minus_2p = pop();
18644 push(R_q);
18645 push(R_S);
18646 divide();
18647 R_q_over_S = pop();
18648 if (DEBUG) {
18649 console.log("tos before putting together the 4 solutions: " + tos);
18650 }
18651 push(R_minus_b_over_4a);
18652 push(R_S);
18653 subtract();
18654 push(R_minus_4S2_minus_2p);
18655 push(R_q_over_S);
18656 add();
18657 push_rational(1, 2);
18658 power();
18659 push_integer(2);
18660 divide();
18661 add();
18662 simplify();
18663 push(R_minus_b_over_4a);
18664 push(R_S);
18665 subtract();
18666 push(R_minus_4S2_minus_2p);
18667 push(R_q_over_S);
18668 add();
18669 push_rational(1, 2);
18670 power();
18671 push_integer(2);
18672 divide();
18673 subtract();
18674 simplify();
18675 push(R_minus_b_over_4a);
18676 push(R_S);
18677 add();
18678 push(R_minus_4S2_minus_2p);
18679 push(R_q_over_S);
18680 subtract();
18681 push_rational(1, 2);
18682 power();
18683 push_integer(2);
18684 divide();
18685 add();
18686 simplify();
18687 push(R_minus_b_over_4a);
18688 push(R_S);
18689 add();
18690 push(R_minus_4S2_minus_2p);
18691 push(R_q_over_S);
18692 subtract();
18693 push_rational(1, 2);
18694 power();
18695 push_integer(2);
18696 divide();
18697 subtract();
18698 simplify();
18699 restore();
18700 return;
18701 }
18702 }
18703 moveTos(tos - n);
18704 return restore();
18705 };
18706
18707 Eval_round = function() {
18708 push(cadr(p1));
18709 Eval();
18710 return yround();
18711 };
18712
18713 yround = function() {
18714 save();
18715 yyround();
18716 return restore();
18717 };
18718
18719 yyround = function() {
18720 var d;
18721 d = 0.0;
18722 p1 = pop();
18723 if (!isnum(p1)) {
18724 push_symbol(ROUND);
18725 push(p1);
18726 list(2);
18727 return;
18728 }
18729 if (isdouble(p1)) {
18730 d = Math.round(p1.d);
18731 push_double(d);
18732 return;
18733 }
18734 if (isinteger(p1)) {
18735 push(p1);
18736 return;
18737 }
18738 push(p1);
18739 yyfloat();
18740 p1 = pop();
18741 return push_integer(Math.round(p1.d));
18742 };
18743
18744 T_INTEGER = 1001;
18745
18746 T_DOUBLE = 1002;
18747
18748 T_SYMBOL = 1003;
18749
18750 T_FUNCTION = 1004;
18751
18752 T_NEWLINE = 1006;
18753
18754 T_STRING = 1007;
18755
18756 T_GTEQ = 1008;
18757
18758 T_LTEQ = 1009;
18759
18760 T_EQ = 1010;
18761
18762 T_NEQ = 1011;
18763
18764 T_QUOTASSIGN = 1012;
18765
18766 token = "";
18767
18768 newline_flag = 0;
18769
18770 meta_mode = 0;
18771
18772 input_str = 0;
18773
18774 scan_str = 0;
18775
18776 token_str = 0;
18777
18778 token_buf = 0;
18779
18780 lastFoundSymbol = null;
18781
18782 symbolsRightOfAssignment = null;
18783
18784 symbolsLeftOfAssignment = null;
18785
18786 isSymbolLeftOfAssignment = null;
18787
18788 scanningParameters = null;
18789
18790 functionInvokationsScanningStack = null;
18791
18792 skipRootVariableToBeSolved = false;
18793
18794 assignmentFound = null;
18795
18796 scanned = "";
18797
18798 scan = function(s) {
18799 if (DEBUG) {
18800 console.log("#### scanning " + s);
18801 }
18802 lastFoundSymbol = null;
18803 symbolsRightOfAssignment = [];
18804 symbolsLeftOfAssignment = [];
18805 isSymbolLeftOfAssignment = true;
18806 scanningParameters = [];
18807 functionInvokationsScanningStack = [""];
18808 assignmentFound = false;
18809 scanned = s;
18810 meta_mode = 0;
18811 expanding++;
18812 input_str = 0;
18813 scan_str = 0;
18814 get_next_token();
18815 if (token === "") {
18816 push(symbol(NIL));
18817 expanding--;
18818 return 0;
18819 }
18820 scan_stmt();
18821 expanding--;
18822 if (!assignmentFound) {
18823 symbolsInExpressionsWithoutAssignments = symbolsInExpressionsWithoutAssignments.concat(symbolsLeftOfAssignment);
18824 }
18825 return token_str - input_str;
18826 };
18827
18828 scan_meta = function(s) {
18829 scanned = s;
18830 meta_mode = 1;
18831 expanding++;
18832 input_str = 0;
18833 scan_str = 0;
18834 get_next_token();
18835 if (token === "") {
18836 push(symbol(NIL));
18837 expanding--;
18838 return 0;
18839 }
18840 scan_stmt();
18841 expanding--;
18842 return token_str - input_str;
18843 };
18844
18845 scan_stmt = function() {
18846 var assignmentIsOfQuotedType, existingDependencies, i, indexOfSymbolLeftOfAssignment, l1, len, len1, m1, symbolLeftOfAssignment;
18847 scan_relation();
18848 assignmentIsOfQuotedType = false;
18849 if (token === T_QUOTASSIGN) {
18850 assignmentIsOfQuotedType = true;
18851 }
18852 if (token === T_QUOTASSIGN || token === '=') {
18853 symbolLeftOfAssignment = lastFoundSymbol;
18854 if (DEBUG) {
18855 console.log("assignment!");
18856 }
18857 assignmentFound = true;
18858 isSymbolLeftOfAssignment = false;
18859 get_next_token();
18860 push_symbol(SETQ);
18861 swap();
18862 if (assignmentIsOfQuotedType) {
18863 push_symbol(QUOTE);
18864 }
18865 scan_relation();
18866 if (assignmentIsOfQuotedType) {
18867 list(2);
18868 }
18869 list(3);
18870 isSymbolLeftOfAssignment = true;
18871 if (codeGen) {
18872 indexOfSymbolLeftOfAssignment = symbolsRightOfAssignment.indexOf(symbolLeftOfAssignment);
18873 if (indexOfSymbolLeftOfAssignment !== -1) {
18874 symbolsRightOfAssignment.splice(indexOfSymbolLeftOfAssignment, 1);
18875 symbolsHavingReassignments.push(symbolLeftOfAssignment);
18876 }
18877 if (DEBUG) {
18878 console.log("locally, " + symbolLeftOfAssignment + " depends on: ");
18879 for (l1 = 0, len = symbolsRightOfAssignment.length; l1 < len; l1++) {
18880 i = symbolsRightOfAssignment[l1];
18881 console.log(" " + i);
18882 }
18883 }
18884 if (symbolsDependencies[symbolLeftOfAssignment] == null) {
18885 symbolsDependencies[symbolLeftOfAssignment] = [];
18886 }
18887 existingDependencies = symbolsDependencies[symbolLeftOfAssignment];
18888 for (m1 = 0, len1 = symbolsRightOfAssignment.length; m1 < len1; m1++) {
18889 i = symbolsRightOfAssignment[m1];
18890 if (existingDependencies.indexOf(i) === -1) {
18891 existingDependencies.push(i);
18892 }
18893 }
18894 return symbolsRightOfAssignment = [];
18895 }
18896 }
18897 };
18898
18899 scan_relation = function() {
18900 scan_expression();
18901 switch (token) {
18902 case T_EQ:
18903 push_symbol(TESTEQ);
18904 swap();
18905 get_next_token();
18906 scan_expression();
18907 return list(3);
18908 case T_NEQ:
18909 push_symbol(NOT);
18910 swap();
18911 push_symbol(TESTEQ);
18912 swap();
18913 get_next_token();
18914 scan_expression();
18915 list(3);
18916 return list(2);
18917 case T_LTEQ:
18918 push_symbol(TESTLE);
18919 swap();
18920 get_next_token();
18921 scan_expression();
18922 return list(3);
18923 case T_GTEQ:
18924 push_symbol(TESTGE);
18925 swap();
18926 get_next_token();
18927 scan_expression();
18928 return list(3);
18929 case '<':
18930 push_symbol(TESTLT);
18931 swap();
18932 get_next_token();
18933 scan_expression();
18934 return list(3);
18935 case '>':
18936 push_symbol(TESTGT);
18937 swap();
18938 get_next_token();
18939 scan_expression();
18940 return list(3);
18941 }
18942 };
18943
18944 scan_expression = function() {
18945 var h;
18946 h = tos;
18947 switch (token) {
18948 case '+':
18949 get_next_token();
18950 scan_term();
18951 break;
18952 case '-':
18953 get_next_token();
18954 scan_term();
18955 negate();
18956 break;
18957 default:
18958 scan_term();
18959 }
18960 while (newline_flag === 0 && (token === '+' || token === '-')) {
18961 if (token === '+') {
18962 get_next_token();
18963 scan_term();
18964 } else {
18965 get_next_token();
18966 scan_term();
18967 negate();
18968 }
18969 }
18970 if (tos - h > 1) {
18971 list(tos - h);
18972 push_symbol(ADD);
18973 swap();
18974 return cons();
18975 }
18976 };
18977
18978 is_factor = function() {
18979 if ((typeof token.charCodeAt === "function" ? token.charCodeAt(0) : void 0) === dotprod_unicode) {
18980 return 1;
18981 }
18982 switch (token) {
18983 case '*':
18984 case '/':
18985 return 1;
18986 case '(':
18987 case T_SYMBOL:
18988 case T_FUNCTION:
18989 case T_INTEGER:
18990 case T_DOUBLE:
18991 case T_STRING:
18992 if (newline_flag) {
18993 scan_str = token_str;
18994 return 0;
18995 } else {
18996 return 1;
18997 }
18998 }
18999 return 0;
19000 };
19001
19002 simplify_1_in_products = function(tos, h) {
19003 if (tos > h && isrational(stack[tos - 1]) && equaln(stack[tos - 1], 1)) {
19004 return pop();
19005 }
19006 };
19007
19008 multiply_consecutive_constants = function(tos, h) {
19009 if (tos > h + 1 && isnum(stack[tos - 2]) && isnum(stack[tos - 1])) {
19010 return multiply();
19011 }
19012 };
19013
19014 scan_term = function() {
19015 var h;
19016 h = tos;
19017 scan_factor();
19018 if (parse_time_simplifications) {
19019 simplify_1_in_products(tos, h);
19020 }
19021 while (is_factor()) {
19022 if (token === '*') {
19023 get_next_token();
19024 scan_factor();
19025 } else if (token === '/') {
19026 simplify_1_in_products(tos, h);
19027 get_next_token();
19028 scan_factor();
19029 inverse();
19030 } else if ((typeof token.charCodeAt === "function" ? token.charCodeAt(0) : void 0) === dotprod_unicode) {
19031 get_next_token();
19032 push_symbol(INNER);
19033 swap();
19034 scan_factor();
19035 list(3);
19036 } else {
19037 scan_factor();
19038 }
19039 if (parse_time_simplifications) {
19040 multiply_consecutive_constants(tos, h);
19041 simplify_1_in_products(tos, h);
19042 }
19043 }
19044 if (h === tos) {
19045 return push_integer(1);
19046 } else if (tos - h > 1) {
19047 list(tos - h);
19048 push_symbol(MULTIPLY);
19049 swap();
19050 return cons();
19051 }
19052 };
19053
19054 scan_power = function() {
19055 if (token === '^') {
19056 get_next_token();
19057 push_symbol(POWER);
19058 swap();
19059 scan_factor();
19060 return list(3);
19061 }
19062 };
19063
19064 scan_index = function(h) {
19065 get_next_token();
19066 push_symbol(INDEX);
19067 swap();
19068 scan_expression();
19069 while (token === ',') {
19070 get_next_token();
19071 scan_expression();
19072 }
19073 if (token !== ']') {
19074 scan_error("] expected");
19075 }
19076 get_next_token();
19077 return list(tos - h);
19078 };
19079
19080 scan_factor = function() {
19081 var firstFactorIsNumber, h;
19082 h = tos;
19083 firstFactorIsNumber = false;
19084 if (token === '(') {
19085 scan_subexpr();
19086 } else if (token === T_SYMBOL) {
19087 scan_symbol();
19088 } else if (token === T_FUNCTION) {
19089 scan_function_call_with_function_name();
19090 } else if (token === '[') {
19091 scan_tensor();
19092 } else if (token === T_INTEGER) {
19093 firstFactorIsNumber = true;
19094 bignum_scan_integer(token_buf);
19095 get_next_token();
19096 } else if (token === T_DOUBLE) {
19097 firstFactorIsNumber = true;
19098 bignum_scan_float(token_buf);
19099 get_next_token();
19100 } else if (token === T_STRING) {
19101 scan_string();
19102 } else {
19103 scan_error("syntax error");
19104 }
19105 while (token === '[' || token === '(' && newline_flag === 0 && !firstFactorIsNumber) {
19106 if (token === '[') {
19107 scan_index(h);
19108 } else if (token === '(') {
19109 scan_function_call_without_function_name();
19110 }
19111 }
19112 while (token === '!') {
19113 get_next_token();
19114 push_symbol(FACTORIAL);
19115 swap();
19116 list(2);
19117 }
19118 while ((typeof token.charCodeAt === "function" ? token.charCodeAt(0) : void 0) === transpose_unicode) {
19119 get_next_token();
19120 push_symbol(TRANSPOSE);
19121 swap();
19122 list(2);
19123 }
19124 return scan_power();
19125 };
19126
19127 addSymbolRightOfAssignment = function(theSymbol) {
19128 var i, l1, prefixVar, ref2;
19129 if (predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(theSymbol) === -1 && symbolsRightOfAssignment.indexOf(theSymbol) === -1 && symbolsRightOfAssignment.indexOf("'" + theSymbol) === -1 && !skipRootVariableToBeSolved) {
19130 if (DEBUG) {
19131 console.log("... adding symbol: " + theSymbol + " to the set of the symbols right of assignment");
19132 }
19133 prefixVar = "";
19134 for (i = l1 = 1, ref2 = functionInvokationsScanningStack.length; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
19135 if (functionInvokationsScanningStack[i] !== "") {
19136 prefixVar += functionInvokationsScanningStack[i] + "_" + i + "_";
19137 }
19138 }
19139 theSymbol = prefixVar + theSymbol;
19140 return symbolsRightOfAssignment.push(theSymbol);
19141 }
19142 };
19143
19144 addSymbolLeftOfAssignment = function(theSymbol) {
19145 var i, l1, prefixVar, ref2;
19146 if (predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(theSymbol) === -1 && symbolsLeftOfAssignment.indexOf(theSymbol) === -1 && symbolsLeftOfAssignment.indexOf("'" + theSymbol) === -1 && !skipRootVariableToBeSolved) {
19147 if (DEBUG) {
19148 console.log("... adding symbol: " + theSymbol + " to the set of the symbols left of assignment");
19149 }
19150 prefixVar = "";
19151 for (i = l1 = 1, ref2 = functionInvokationsScanningStack.length; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
19152 if (functionInvokationsScanningStack[i] !== "") {
19153 prefixVar += functionInvokationsScanningStack[i] + "_" + i + "_";
19154 }
19155 }
19156 theSymbol = prefixVar + theSymbol;
19157 return symbolsLeftOfAssignment.push(theSymbol);
19158 }
19159 };
19160
19161 scan_symbol = function() {
19162 if (token !== T_SYMBOL) {
19163 scan_error("symbol expected");
19164 }
19165 if (meta_mode && token_buf.length === 1) {
19166 switch (token_buf[0]) {
19167 case 'a':
19168 push(symbol(METAA));
19169 break;
19170 case 'b':
19171 push(symbol(METAB));
19172 break;
19173 case 'x':
19174 push(symbol(METAX));
19175 break;
19176 default:
19177 push(usr_symbol(token_buf));
19178 }
19179 } else {
19180 push(usr_symbol(token_buf));
19181 }
19182 if (scanningParameters.length === 0) {
19183 if (DEBUG) {
19184 console.log("out of scanning parameters, processing " + token_buf);
19185 }
19186 lastFoundSymbol = token_buf;
19187 if (isSymbolLeftOfAssignment) {
19188 addSymbolLeftOfAssignment(token_buf);
19189 }
19190 } else {
19191 if (DEBUG) {
19192 console.log("still scanning parameters, skipping " + token_buf);
19193 }
19194 if (isSymbolLeftOfAssignment) {
19195 addSymbolRightOfAssignment("'" + token_buf);
19196 }
19197 }
19198 if (DEBUG) {
19199 console.log("found symbol: " + token_buf + " left of assignment: " + isSymbolLeftOfAssignment);
19200 }
19201 if (!isSymbolLeftOfAssignment) {
19202 addSymbolRightOfAssignment(token_buf);
19203 }
19204 return get_next_token();
19205 };
19206
19207 scan_string = function() {
19208 new_string(token_buf);
19209 return get_next_token();
19210 };
19211
19212 scan_function_call_with_function_name = function() {
19213 var functionName, i, l1, n, p, ref2;
19214 if (DEBUG) {
19215 console.log("-- scan_function_call_with_function_name start");
19216 }
19217 n = 1;
19218 p = new U();
19219 p = usr_symbol(token_buf);
19220 push(p);
19221 get_next_token();
19222 functionName = token_buf;
19223 if (functionName === "roots" || functionName === "defint" || functionName === "sum" || functionName === "product" || functionName === "for") {
19224 functionInvokationsScanningStack.push(token_buf);
19225 }
19226 lastFoundSymbol = token_buf;
19227 if (!isSymbolLeftOfAssignment) {
19228 addSymbolRightOfAssignment(token_buf);
19229 }
19230 get_next_token();
19231 scanningParameters.push(true);
19232 if (token !== ')') {
19233 scan_stmt();
19234 n++;
19235 while (token === ',') {
19236 get_next_token();
19237 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("roots") !== -1) {
19238 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19239 return !(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19240 });
19241 skipRootVariableToBeSolved = true;
19242 }
19243 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("sum") !== -1) {
19244 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19245 return !(new RegExp("sum_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19246 });
19247 skipRootVariableToBeSolved = true;
19248 }
19249 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("product") !== -1) {
19250 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19251 return !(new RegExp("product_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19252 });
19253 skipRootVariableToBeSolved = true;
19254 }
19255 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("for") !== -1) {
19256 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19257 return !(new RegExp("for_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19258 });
19259 skipRootVariableToBeSolved = true;
19260 }
19261 if (functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("defint") !== -1 && (n === 2 || (n > 2 && ((n - 2) % 3 === 0)))) {
19262 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19263 return !(new RegExp("defint_" + (functionInvokationsScanningStack.length - 1) + "_" + token_buf)).test(x);
19264 });
19265 skipRootVariableToBeSolved = true;
19266 }
19267 scan_stmt();
19268 skipRootVariableToBeSolved = false;
19269 n++;
19270 }
19271 if (n === 2 && functionInvokationsScanningStack[functionInvokationsScanningStack.length - 1].indexOf("roots") !== -1) {
19272 symbolsRightOfAssignment = symbolsRightOfAssignment.filter(function(x) {
19273 return !(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_" + "x")).test(x);
19274 });
19275 }
19276 }
19277 scanningParameters.pop();
19278 for (i = l1 = 0, ref2 = symbolsRightOfAssignment.length; 0 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19279 if (symbolsRightOfAssignment[i] != null) {
19280 if (functionName === "roots") {
19281 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("roots_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19282 }
19283 if (functionName === "defint") {
19284 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("defint_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19285 }
19286 if (functionName === "sum") {
19287 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("sum_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19288 }
19289 if (functionName === "product") {
19290 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("product_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19291 }
19292 if (functionName === "for") {
19293 symbolsRightOfAssignment[i] = symbolsRightOfAssignment[i].replace(new RegExp("for_" + (functionInvokationsScanningStack.length - 1) + "_"), "");
19294 }
19295 }
19296 }
19297 if (token !== ')') {
19298 scan_error(") expected");
19299 }
19300 get_next_token();
19301 list(n);
19302 if (functionName === "roots" || functionName === "defint" || functionName === "sum" || functionName === "product" || functionName === "for") {
19303 functionInvokationsScanningStack.pop();
19304 }
19305 if (functionName === symbol(PATTERN).printname) {
19306 patternHasBeenFound = true;
19307 }
19308 if (DEBUG) {
19309 return console.log("-- scan_function_call_with_function_name end");
19310 }
19311 };
19312
19313 scan_function_call_without_function_name = function() {
19314 var n;
19315 if (DEBUG) {
19316 console.log("-- scan_function_call_without_function_name start");
19317 }
19318 push_symbol(EVAL);
19319 swap();
19320 list(2);
19321 n = 1;
19322 get_next_token();
19323 scanningParameters.push(true);
19324 if (token !== ')') {
19325 scan_stmt();
19326 n++;
19327 while (token === ',') {
19328 get_next_token();
19329 scan_stmt();
19330 n++;
19331 }
19332 }
19333 scanningParameters.pop();
19334 if (token !== ')') {
19335 scan_error(") expected");
19336 }
19337 get_next_token();
19338 list(n);
19339 if (DEBUG) {
19340 return console.log("-- scan_function_call_without_function_name end: " + stack[tos - 1]);
19341 }
19342 };
19343
19344 scan_subexpr = function() {
19345 var n;
19346 n = 0;
19347 if (token !== '(') {
19348 scan_error("( expected");
19349 }
19350 get_next_token();
19351 scan_stmt();
19352 if (token !== ')') {
19353 scan_error(") expected");
19354 }
19355 return get_next_token();
19356 };
19357
19358 scan_tensor = function() {
19359 var n;
19360 n = 0;
19361 if (token !== '[') {
19362 scan_error("[ expected");
19363 }
19364 get_next_token();
19365 scan_stmt();
19366 n = 1;
19367 while (token === ',') {
19368 get_next_token();
19369 scan_stmt();
19370 n++;
19371 }
19372 build_tensor(n);
19373 if (token !== ']') {
19374 scan_error("] expected");
19375 }
19376 return get_next_token();
19377 };
19378
19379 scan_error = function(errmsg) {
19380 errorMessage = "";
19381 while (input_str !== scan_str) {
19382 if ((scanned[input_str] === '\n' || scanned[input_str] === '\r') && input_str + 1 === scan_str) {
19383 break;
19384 }
19385 errorMessage += scanned[input_str++];
19386 }
19387 errorMessage += " ? ";
19388 while (scanned[input_str] && (scanned[input_str] !== '\n' && scanned[input_str] !== '\r')) {
19389 errorMessage += scanned[input_str++];
19390 }
19391 errorMessage += '\n';
19392 return stop(errmsg);
19393 };
19394
19395 build_tensor = function(n) {
19396 var i, l1, ref2;
19397 i = 0;
19398 save();
19399 p2 = alloc_tensor(n);
19400 p2.tensor.ndim = 1;
19401 p2.tensor.dim[0] = n;
19402 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19403 p2.tensor.elem[i] = stack[tos - n + i];
19404 }
19405 check_tensor_dimensions(p2);
19406 moveTos(tos - n);
19407 push(p2);
19408 return restore();
19409 };
19410
19411 get_next_token = function() {
19412 newline_flag = 0;
19413 while (1) {
19414 get_token();
19415 if (token !== T_NEWLINE) {
19416 break;
19417 }
19418 newline_flag = 1;
19419 }
19420 if (DEBUG) {
19421 return console.log("get_next_token token: " + token);
19422 }
19423 };
19424
19425 get_token = function() {
19426 while (isspace(scanned[scan_str])) {
19427 if (scanned[scan_str] === '\n' || scanned[scan_str] === '\r') {
19428 token = T_NEWLINE;
19429 scan_str++;
19430 return;
19431 }
19432 scan_str++;
19433 }
19434 token_str = scan_str;
19435 if (scan_str === scanned.length) {
19436 token = "";
19437 return;
19438 }
19439 if (isdigit(scanned[scan_str]) || scanned[scan_str] === '.') {
19440 while (isdigit(scanned[scan_str])) {
19441 scan_str++;
19442 }
19443 if (scanned[scan_str] === '.') {
19444 scan_str++;
19445 while (isdigit(scanned[scan_str])) {
19446 scan_str++;
19447 }
19448 if (scanned[scan_str] === 'e' && (scanned[scan_str + 1] === '+' || scanned[scan_str + 1] === '-' || isdigit(scanned[scan_str + 1]))) {
19449 scan_str += 2;
19450 while (isdigit(scanned[scan_str])) {
19451 scan_str++;
19452 }
19453 }
19454 token = T_DOUBLE;
19455 } else {
19456 token = T_INTEGER;
19457 }
19458 update_token_buf(token_str, scan_str);
19459 return;
19460 }
19461 if (isalpha(scanned[scan_str])) {
19462 while (isalnumorunderscore(scanned[scan_str])) {
19463 scan_str++;
19464 }
19465 if (scanned[scan_str] === '(') {
19466 token = T_FUNCTION;
19467 } else {
19468 token = T_SYMBOL;
19469 }
19470 update_token_buf(token_str, scan_str);
19471 return;
19472 }
19473 if (scanned[scan_str] === '"') {
19474 scan_str++;
19475 while (scanned[scan_str] !== '"') {
19476 if (scan_str === scanned.length - 1) {
19477 scan_str++;
19478 scan_error("runaway string");
19479 scan_str--;
19480 }
19481 scan_str++;
19482 }
19483 scan_str++;
19484 token = T_STRING;
19485 update_token_buf(token_str + 1, scan_str - 1);
19486 return;
19487 }
19488 if (scanned[scan_str] === '#' || scanned[scan_str] === '-' && scanned[scan_str + 1] === '-') {
19489 while (scanned[scan_str] && scanned[scan_str] !== '\n' && scanned[scan_str] !== '\r') {
19490 scan_str++;
19491 }
19492 if (scanned[scan_str]) {
19493 scan_str++;
19494 }
19495 token = T_NEWLINE;
19496 return;
19497 }
19498 if (scanned[scan_str] === ':' && scanned[scan_str + 1] === '=') {
19499 scan_str += 2;
19500 token = T_QUOTASSIGN;
19501 return;
19502 }
19503 if (scanned[scan_str] === '=' && scanned[scan_str + 1] === '=') {
19504 scan_str += 2;
19505 token = T_EQ;
19506 return;
19507 }
19508 if (scanned[scan_str] === '!' && scanned[scan_str + 1] === '=') {
19509 scan_str += 2;
19510 token = T_NEQ;
19511 return;
19512 }
19513 if (scanned[scan_str] === '<' && scanned[scan_str + 1] === '=') {
19514 scan_str += 2;
19515 token = T_LTEQ;
19516 return;
19517 }
19518 if (scanned[scan_str] === '>' && scanned[scan_str + 1] === '=') {
19519 scan_str += 2;
19520 token = T_GTEQ;
19521 return;
19522 }
19523 return token = scanned[scan_str++];
19524 };
19525
19526 update_token_buf = function(a, b) {
19527 return token_buf = scanned.substring(a, b);
19528 };
19529
19530 $.scan = scan;
19531
19532 Eval_sgn = function() {
19533 push(cadr(p1));
19534 Eval();
19535 return sgn();
19536 };
19537
19538 sgn = function() {
19539 save();
19540 yysgn();
19541 return restore();
19542 };
19543
19544 yysgn = function() {
19545 p1 = pop();
19546 if (isdouble(p1)) {
19547 if (p1.d > 0) {
19548 push_integer(1);
19549 return;
19550 } else {
19551 if (p1.d === 0) {
19552 push_integer(1);
19553 return;
19554 } else {
19555 push_integer(-1);
19556 return;
19557 }
19558 }
19559 }
19560 if (isrational(p1)) {
19561 if (MSIGN(mmul(p1.q.a, p1.q.b)) === -1) {
19562 push_integer(-1);
19563 return;
19564 } else {
19565 if (MZERO(mmul(p1.q.a, p1.q.b))) {
19566 push_integer(0);
19567 return;
19568 } else {
19569 push_integer(1);
19570 return;
19571 }
19572 }
19573 }
19574 if (iscomplexnumber(p1)) {
19575 push_integer(-1);
19576 push(p1);
19577 absval();
19578 power();
19579 push(p1);
19580 multiply();
19581 return;
19582 }
19583 if (isnegativeterm(p1)) {
19584 push_symbol(SGN);
19585 push(p1);
19586 negate();
19587 list(2);
19588 push_integer(-1);
19589 multiply();
19590 return;
19591 }
19592
19593 /*
19594 push_integer(2)
19595 push(p1)
19596 heaviside()
19597 multiply()
19598 push_integer(-1)
19599 add()
19600 */
19601 push_symbol(SGN);
19602 push(p1);
19603 return list(2);
19604 };
19605
19606 Eval_shape = function() {
19607 push(cadr(p1));
19608 Eval();
19609 return shape();
19610 };
19611
19612 shape = function() {
19613 var ai, an, i, l1, m1, ndim, ref2, ref3, t;
19614 i = 0;
19615 ndim = 0;
19616 t = 0;
19617 ai = [];
19618 an = [];
19619 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
19620 ai[i] = 0;
19621 an[i] = 0;
19622 }
19623 save();
19624 p1 = pop();
19625 if (!istensor(p1)) {
19626 if (!iszero(p1)) {
19627 stop("transpose: tensor expected, 1st arg is not a tensor");
19628 }
19629 push(zero);
19630 restore();
19631 return;
19632 }
19633 ndim = p1.tensor.ndim;
19634 p2 = alloc_tensor(ndim);
19635 p2.tensor.ndim = 1;
19636 p2.tensor.dim[0] = ndim;
19637 for (i = m1 = 0, ref3 = ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
19638 push_integer(p1.tensor.dim[i]);
19639 p2.tensor.elem[i] = pop();
19640 }
19641 push(p2);
19642 return restore();
19643 };
19644
19645
19646 /*
19647 Simplify factorials
19648
19649 The following script
19650
19651 F(n,k) = k binomial(n,k)
19652 (F(n,k) + F(n,k-1)) / F(n+1,k)
19653
19654 generates
19655
19656 k! n! n! (1 - k + n)! k! n!
19657 -------------------- + -------------------- - ----------------------
19658 (-1 + k)! (1 + n)! (1 + n)! (-k + n)! k (-1 + k)! (1 + n)!
19659
19660 Simplify each term to get
19661
19662 k 1 - k + n 1
19663 ------- + ----------- - -------
19664 1 + n 1 + n 1 + n
19665
19666 Then simplify the sum to get
19667
19668 n
19669 -------
19670 1 + n
19671 */
19672
19673 Eval_simfac = function() {
19674 push(cadr(p1));
19675 Eval();
19676 return simfac();
19677 };
19678
19679 simfac = function() {
19680 var h;
19681 h = 0;
19682 save();
19683 p1 = pop();
19684 if (car(p1) === symbol(ADD)) {
19685 h = tos;
19686 p1 = cdr(p1);
19687 while (p1 !== symbol(NIL)) {
19688 push(car(p1));
19689 simfac_term();
19690 p1 = cdr(p1);
19691 }
19692 add_all(tos - h);
19693 } else {
19694 push(p1);
19695 simfac_term();
19696 }
19697 return restore();
19698 };
19699
19700
19701 /*
19702 void
19703 simfac(void)
19704 {
19705 int h
19706 save()
19707 p1 = pop()
19708 if (car(p1) == symbol(ADD)) {
19709 h = tos
19710 p1 = cdr(p1)
19711 while (p1 != symbol(NIL)) {
19712 push(car(p1))
19713 simfac_term()
19714 p1 = cdr(p1)
19715 }
19716 addk(tos - h)
19717 p1 = pop()
19718 if (find(p1, symbol(FACTORIAL))) {
19719 push(p1)
19720 if (car(p1) == symbol(ADD)) {
19721 Condense()
19722 simfac_term()
19723 }
19724 }
19725 } else {
19726 push(p1)
19727 simfac_term()
19728 }
19729 restore()
19730 }
19731
19732 #endif
19733 */
19734
19735 simfac_term = function() {
19736 var doNothing, h;
19737 h = 0;
19738 save();
19739 p1 = pop();
19740 if (car(p1) !== symbol(MULTIPLY)) {
19741 push(p1);
19742 restore();
19743 return;
19744 }
19745 h = tos;
19746 p1 = cdr(p1);
19747 while (p1 !== symbol(NIL)) {
19748 push(car(p1));
19749 p1 = cdr(p1);
19750 }
19751 while (yysimfac(h)) {
19752 doNothing = 1;
19753 }
19754 multiply_all_noexpand(tos - h);
19755 return restore();
19756 };
19757
19758 yysimfac = function(h) {
19759 var i, j, l1, m1, ref2, ref3, ref4, ref5;
19760 i = 0;
19761 j = 0;
19762 for (i = l1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
19763 p1 = stack[i];
19764 for (j = m1 = ref4 = h, ref5 = tos; ref4 <= ref5 ? m1 < ref5 : m1 > ref5; j = ref4 <= ref5 ? ++m1 : --m1) {
19765 if (i === j) {
19766 continue;
19767 }
19768 p2 = stack[j];
19769 if (car(p1) === symbol(FACTORIAL) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && equal(cadr(p1), cadr(p2))) {
19770 push(cadr(p1));
19771 push(one);
19772 subtract();
19773 factorial();
19774 stack[i] = pop();
19775 stack[j] = one;
19776 return 1;
19777 }
19778 if (car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL) && equal(p1, cadadr(p2))) {
19779 push(p1);
19780 push_integer(-1);
19781 add();
19782 factorial();
19783 reciprocate();
19784 stack[i] = pop();
19785 stack[j] = one;
19786 return 1;
19787 }
19788 if (car(p2) === symbol(FACTORIAL)) {
19789 push(p1);
19790 push(cadr(p2));
19791 subtract();
19792 p3 = pop();
19793 if (isplusone(p3)) {
19794 push(p1);
19795 factorial();
19796 stack[i] = pop();
19797 stack[j] = one;
19798 return 1;
19799 }
19800 }
19801 if (car(p1) === symbol(POWER) && isminusone(caddr(p1)) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL)) {
19802 push(cadr(p1));
19803 push(cadr(cadr(p2)));
19804 subtract();
19805 p3 = pop();
19806 if (isplusone(p3)) {
19807 push(cadr(p1));
19808 factorial();
19809 reciprocate();
19810 stack[i] = pop();
19811 stack[j] = one;
19812 return 1;
19813 }
19814 }
19815 if (car(p1) === symbol(FACTORIAL) && car(p2) === symbol(POWER) && isminusone(caddr(p2)) && caadr(p2) === symbol(FACTORIAL)) {
19816 push(cadr(p1));
19817 push(cadr(cadr(p2)));
19818 subtract();
19819 p3 = pop();
19820 if (isplusone(p3)) {
19821 stack[i] = cadr(p1);
19822 stack[j] = one;
19823 return 1;
19824 }
19825 if (isminusone(p3)) {
19826 push(cadr(cadr(p2)));
19827 reciprocate();
19828 stack[i] = pop();
19829 stack[j] = one;
19830 return 1;
19831 }
19832 if (equaln(p3, 2)) {
19833 stack[i] = cadr(p1);
19834 push(cadr(p1));
19835 push_integer(-1);
19836 add();
19837 stack[j] = pop();
19838 return 1;
19839 }
19840 if (equaln(p3, -2)) {
19841 push(cadr(cadr(p2)));
19842 reciprocate();
19843 stack[i] = pop();
19844 push(cadr(cadr(p2)));
19845 push_integer(-1);
19846 add();
19847 reciprocate();
19848 stack[j] = pop();
19849 return 1;
19850 }
19851 }
19852 }
19853 }
19854 return 0;
19855 };
19856
19857 Eval_simplify = function() {
19858 push(cadr(p1));
19859 runUserDefinedSimplifications();
19860 Eval();
19861 return simplify();
19862 };
19863
19864 runUserDefinedSimplifications = function() {
19865 var atLeastOneSuccessInRouldOfRulesApplications, eachConsecutiveRuleApplication, eachSimplification, l1, len, len1, m1, numberOfRulesApplications, originalexpanding, success;
19866 if (userSimplificationsInListForm.length !== 0 && !Find(cadr(p1), symbol(INTEGRAL))) {
19867 originalexpanding = expanding;
19868 expanding = false;
19869 if (DEBUG) {
19870 console.log("runUserDefinedSimplifications passed: " + stack[tos - 1].toString());
19871 }
19872 Eval();
19873 if (DEBUG) {
19874 console.log("runUserDefinedSimplifications after eval no expanding: " + stack[tos - 1].toString());
19875 }
19876 expanding = originalexpanding;
19877 p1 = stack[tos - 1];
19878 if (DEBUG) {
19879 console.log("patterns to be checked: ");
19880 }
19881 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
19882 eachSimplification = userSimplificationsInListForm[l1];
19883 if (DEBUG) {
19884 console.log("..." + eachSimplification);
19885 }
19886 }
19887 atLeastOneSuccessInRouldOfRulesApplications = true;
19888 numberOfRulesApplications = 0;
19889 while (atLeastOneSuccessInRouldOfRulesApplications && numberOfRulesApplications < MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES) {
19890 atLeastOneSuccessInRouldOfRulesApplications = false;
19891 numberOfRulesApplications++;
19892 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
19893 eachSimplification = userSimplificationsInListForm[m1];
19894 success = true;
19895 eachConsecutiveRuleApplication = 0;
19896 while (success && eachConsecutiveRuleApplication < MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE) {
19897 eachConsecutiveRuleApplication++;
19898 if (DEBUG) {
19899 console.log("simplify - tos: " + tos + " checking pattern: " + eachSimplification + " on: " + p1);
19900 }
19901 push_symbol(NIL);
19902 success = transform(eachSimplification, true);
19903 if (success) {
19904 atLeastOneSuccessInRouldOfRulesApplications = true;
19905 }
19906 p1 = stack[tos - 1];
19907 if (DEBUG) {
19908 console.log("p1 at this stage of simplification: " + p1);
19909 }
19910 }
19911 if (eachConsecutiveRuleApplication === MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE) {
19912 stop("maximum application of single transformation rule exceeded: " + eachSimplification);
19913 }
19914 }
19915 }
19916 if (numberOfRulesApplications === MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES) {
19917 stop("maximum application of all transformation rules exceeded ");
19918 }
19919 if (DEBUG) {
19920 console.log("METAX = " + get_binding(symbol(METAX)));
19921 console.log("METAA = " + get_binding(symbol(METAA)));
19922 return console.log("METAB = " + get_binding(symbol(METAB)));
19923 }
19924 }
19925 };
19926
19927 simplifyForCodeGeneration = function() {
19928 save();
19929 runUserDefinedSimplifications();
19930 codeGen = true;
19931 simplify_main();
19932 codeGen = false;
19933 return restore();
19934 };
19935
19936 simplify = function() {
19937 save();
19938 simplify_main();
19939 return restore();
19940 };
19941
19942 simplify_main = function() {
19943 var args, fbody;
19944 p1 = pop();
19945 if (codeGen && car(p1) === symbol(FUNCTION)) {
19946 fbody = cadr(p1);
19947 push(fbody);
19948 eval();
19949 simplify();
19950 p3 = pop();
19951 args = caddr(p1);
19952 push_symbol(FUNCTION);
19953 push(p3);
19954 push(args);
19955 list(3);
19956 p1 = pop();
19957 }
19958 if (istensor(p1)) {
19959 simplify_tensor();
19960 return;
19961 }
19962 if (Find(p1, symbol(FACTORIAL))) {
19963 push(p1);
19964 simfac();
19965 p2 = pop();
19966 push(p1);
19967 rationalize();
19968 simfac();
19969 p3 = pop();
19970 if (count(p2) < count(p3)) {
19971 p1 = p2;
19972 } else {
19973 p1 = p3;
19974 }
19975 }
19976 f10();
19977 f1();
19978 f2();
19979 f3();
19980 f4();
19981 f5();
19982 f9();
19983 simplify_polarRect();
19984 if (do_simplify_nested_radicals) {
19985 if (simplify_nested_radicals()) {
19986 if (DEBUG) {
19987 console.log("de-nesting successful into: " + p1.toString());
19988 }
19989 push(p1);
19990 simplify();
19991 return;
19992 }
19993 }
19994 simplify_rectToClock();
19995 return push(p1);
19996 };
19997
19998 simplify_tensor = function() {
19999 var i, l1, m1, ref2, ref3;
20000 i = 0;
20001 p2 = alloc_tensor(p1.tensor.nelem);
20002 p2.tensor.ndim = p1.tensor.ndim;
20003 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
20004 p2.tensor.dim[i] = p1.tensor.dim[i];
20005 }
20006 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
20007 push(p1.tensor.elem[i]);
20008 simplify();
20009 p2.tensor.elem[i] = pop();
20010 }
20011 check_tensor_dimensions(p2);
20012 if (iszero(p2)) {
20013 p2 = zero;
20014 }
20015 return push(p2);
20016 };
20017
20018 f1 = function() {
20019 if (car(p1) !== symbol(ADD)) {
20020 return;
20021 }
20022 push(p1);
20023 rationalize();
20024 p2 = pop();
20025 if (count(p2) < count(p1)) {
20026 return p1 = p2;
20027 }
20028 };
20029
20030 f2 = function() {
20031 if (car(p1) !== symbol(ADD)) {
20032 return;
20033 }
20034 push(p1);
20035 Condense();
20036 p2 = pop();
20037 if (count(p2) <= count(p1)) {
20038 return p1 = p2;
20039 }
20040 };
20041
20042 f3 = function() {
20043 push(p1);
20044 rationalize();
20045 negate();
20046 rationalize();
20047 negate();
20048 rationalize();
20049 p2 = pop();
20050 if (count(p2) < count(p1)) {
20051 return p1 = p2;
20052 }
20053 };
20054
20055 f10 = function() {
20056 var a, b, carp1, miao, originalexpanding;
20057 carp1 = car(p1);
20058 miao = cdr(p1);
20059 if (carp1 === symbol(MULTIPLY) || isinnerordot(p1)) {
20060 if ((car(car(cdr(p1))) === symbol(TRANSPOSE)) && (car(car(cdr(cdr(p1)))) === symbol(TRANSPOSE))) {
20061 if (DEBUG) {
20062 console.log("maybe collecting a transpose " + p1);
20063 }
20064 a = cadr(car(cdr(p1)));
20065 b = cadr(car(cdr(cdr(p1))));
20066 if (carp1 === symbol(MULTIPLY)) {
20067 push(a);
20068 push(b);
20069 multiply();
20070 } else if (isinnerordot(p1)) {
20071 push(b);
20072 push(a);
20073 inner();
20074 }
20075 push_integer(1);
20076 push_integer(2);
20077 originalexpanding = expanding;
20078 expanding = false;
20079 transpose();
20080 expanding = originalexpanding;
20081 p2 = pop();
20082 if (count(p2) < count(p1)) {
20083 p1 = p2;
20084 }
20085 if (DEBUG) {
20086 return console.log("collecting a transpose " + p2);
20087 }
20088 }
20089 }
20090 };
20091
20092 f4 = function() {
20093 if (iszero(p1)) {
20094 return;
20095 }
20096 push(p1);
20097 rationalize();
20098 inverse();
20099 rationalize();
20100 inverse();
20101 rationalize();
20102 p2 = pop();
20103 if (count(p2) < count(p1)) {
20104 return p1 = p2;
20105 }
20106 };
20107
20108 simplify_trig = function() {
20109 save();
20110 p1 = pop();
20111 f5();
20112 push(p1);
20113 return restore();
20114 };
20115
20116 f5 = function() {
20117 if (Find(p1, symbol(SIN)) === 0 && Find(p1, symbol(COS)) === 0) {
20118 return;
20119 }
20120 p2 = p1;
20121 trigmode = 1;
20122 push(p2);
20123 Eval();
20124 p3 = pop();
20125 trigmode = 2;
20126 push(p2);
20127 Eval();
20128 p4 = pop();
20129 trigmode = 0;
20130 if (count(p4) < count(p3) || nterms(p4) < nterms(p3)) {
20131 p3 = p4;
20132 }
20133 if (count(p3) < count(p1) || nterms(p3) < nterms(p1)) {
20134 return p1 = p3;
20135 }
20136 };
20137
20138 f9 = function() {
20139 if (car(p1) !== symbol(ADD)) {
20140 return;
20141 }
20142 push_integer(0);
20143 p2 = cdr(p1);
20144 while (iscons(p2)) {
20145 push(car(p2));
20146 simplify();
20147 add();
20148 p2 = cdr(p2);
20149 }
20150 p2 = pop();
20151 if (count(p2) < count(p1)) {
20152 return p1 = p2;
20153 }
20154 };
20155
20156 simplify_rectToClock = function() {
20157 if (Find(p1, symbol(SIN)) === 0 && Find(p1, symbol(COS)) === 0) {
20158 return;
20159 }
20160 push(p1);
20161 Eval();
20162 clockform();
20163 p2 = pop();
20164 if (DEBUG) {
20165 console.log("before simplification clockform: " + p1 + " after: " + p2);
20166 }
20167 if (count(p2) < count(p1)) {
20168 return p1 = p2;
20169 }
20170 };
20171
20172 simplify_polarRect = function() {
20173 push(p1);
20174 polarRectAMinusOneBase();
20175 Eval();
20176 p2 = pop();
20177 if (count(p2) < count(p1)) {
20178 return p1 = p2;
20179 }
20180 };
20181
20182 polarRectAMinusOneBase = function() {
20183 var h;
20184 save();
20185 p1 = pop();
20186 if (isimaginaryunit(p1)) {
20187 push(p1);
20188 restore();
20189 return;
20190 }
20191 if (equal(car(p1), symbol(POWER)) && isminusone(cadr(p1))) {
20192 push(one);
20193 negate();
20194 push(caddr(p1));
20195 polarRectAMinusOneBase();
20196 power();
20197 polar();
20198 rect();
20199 } else if (iscons(p1)) {
20200 h = tos;
20201 while (iscons(p1)) {
20202 push(car(p1));
20203 polarRectAMinusOneBase();
20204 p1 = cdr(p1);
20205 }
20206 list(tos - h);
20207 } else {
20208 push(p1);
20209 }
20210 restore();
20211 };
20212
20213 nterms = function(p) {
20214 if (car(p) !== symbol(ADD)) {
20215 return 1;
20216 } else {
20217 return length(p) - 1;
20218 }
20219 };
20220
20221 simplify_nested_radicals = function() {
20222 var prev_expanding, simplificationWithCondense, simplificationWithoutCondense, somethingSimplified;
20223 if (recursionLevelNestedRadicalsRemoval > 0) {
20224 if (DEBUG) {
20225 console.log("denesting bailing out because of too much recursion");
20226 }
20227 return false;
20228 }
20229 push(p1);
20230 somethingSimplified = take_care_of_nested_radicals();
20231 simplificationWithoutCondense = stack[tos - 1];
20232 prev_expanding = expanding;
20233 expanding = 0;
20234 yycondense();
20235 expanding = prev_expanding;
20236 simplificationWithCondense = pop();
20237 if (countOccurrencesOfSymbol(symbol(POWER), simplificationWithoutCondense) < countOccurrencesOfSymbol(symbol(POWER), simplificationWithCondense)) {
20238 push(simplificationWithoutCondense);
20239 } else {
20240 push(simplificationWithCondense);
20241 }
20242 p1 = pop();
20243 return somethingSimplified;
20244 };
20245
20246 take_care_of_nested_radicals = function() {
20247 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;
20248 if (recursionLevelNestedRadicalsRemoval > 0) {
20249 if (DEBUG) {
20250 console.log("denesting bailing out because of too much recursion");
20251 }
20252 return false;
20253 }
20254 save();
20255 p1 = pop();
20256 if (equal(car(p1), symbol(POWER))) {
20257 base = cadr(p1);
20258 exponent = caddr(p1);
20259 if (!isminusone(exponent) && equal(car(base), symbol(ADD)) && isfraction(exponent) && (equalq(exponent, 1, 3) || equalq(exponent, 1, 2))) {
20260 firstTerm = cadr(base);
20261 push(firstTerm);
20262 take_care_of_nested_radicals();
20263 pop();
20264 secondTerm = caddr(base);
20265 push(secondTerm);
20266 take_care_of_nested_radicals();
20267 pop();
20268 numberOfTerms = 0;
20269 countingTerms = base;
20270 while (cdr(countingTerms) !== symbol(NIL)) {
20271 numberOfTerms++;
20272 countingTerms = cdr(countingTerms);
20273 }
20274 if (numberOfTerms > 2) {
20275 push(p1);
20276 restore();
20277 return false;
20278 }
20279 commonInnerExponent = null;
20280 commonBases = [];
20281 termsThatAreNotPowers = [];
20282 if (car(secondTerm) === symbol(MULTIPLY)) {
20283 secondTermFactor = cdr(secondTerm);
20284 if (iscons(secondTermFactor)) {
20285 while (iscons(secondTermFactor)) {
20286 potentialPower = car(secondTermFactor);
20287 if (car(potentialPower) === symbol(POWER)) {
20288 innerbase = cadr(potentialPower);
20289 innerexponent = caddr(potentialPower);
20290 if (equalq(innerexponent, 1, 2)) {
20291 if (commonInnerExponent == null) {
20292 commonInnerExponent = innerexponent;
20293 commonBases.push(innerbase);
20294 } else {
20295 if (equal(innerexponent, commonInnerExponent)) {
20296 commonBases.push(innerbase);
20297 } else {
20298
20299 }
20300 }
20301 }
20302 } else {
20303 termsThatAreNotPowers.push(potentialPower);
20304 }
20305 secondTermFactor = cdr(secondTermFactor);
20306 }
20307 }
20308 } else if (car(secondTerm) === symbol(POWER)) {
20309 innerbase = cadr(secondTerm);
20310 innerexponent = caddr(secondTerm);
20311 if ((commonInnerExponent == null) && equalq(innerexponent, 1, 2)) {
20312 commonInnerExponent = innerexponent;
20313 commonBases.push(innerbase);
20314 }
20315 }
20316 if (commonBases.length === 0) {
20317 push(p1);
20318 restore();
20319 return false;
20320 }
20321 A = firstTerm;
20322 push_integer(1);
20323 for (l1 = 0, len = commonBases.length; l1 < len; l1++) {
20324 i = commonBases[l1];
20325 push(i);
20326 multiply();
20327 }
20328 C = pop();
20329 push_integer(1);
20330 for (m1 = 0, len1 = termsThatAreNotPowers.length; m1 < len1; m1++) {
20331 i = termsThatAreNotPowers[m1];
20332 push(i);
20333 multiply();
20334 }
20335 B = pop();
20336 if (equalq(exponent, 1, 3)) {
20337 push(A);
20338 negate();
20339 push(C);
20340 multiply();
20341 push(B);
20342 divide();
20343 checkSize = pop();
20344 push(checkSize);
20345 real();
20346 yyfloat();
20347 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20348 push(p1);
20349 restore();
20350 return false;
20351 }
20352 push(checkSize);
20353 push_integer(3);
20354 push(C);
20355 multiply();
20356 checkSize = pop();
20357 push(checkSize);
20358 real();
20359 yyfloat();
20360 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20361 pop();
20362 push(p1);
20363 restore();
20364 return false;
20365 }
20366 push(checkSize);
20367 push(symbol(SECRETX));
20368 multiply();
20369 push_integer(-3);
20370 push(A);
20371 multiply();
20372 push(B);
20373 divide();
20374 checkSize = pop();
20375 push(checkSize);
20376 real();
20377 yyfloat();
20378 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20379 pop();
20380 pop();
20381 push(p1);
20382 restore();
20383 return false;
20384 }
20385 push(checkSize);
20386 push(symbol(SECRETX));
20387 push_integer(2);
20388 power();
20389 multiply();
20390 push_integer(1);
20391 push(symbol(SECRETX));
20392 push_integer(3);
20393 power();
20394 multiply();
20395 add();
20396 add();
20397 add();
20398 } else if (equalq(exponent, 1, 2)) {
20399 push(C);
20400 checkSize = pop();
20401 push(checkSize);
20402 real();
20403 yyfloat();
20404 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20405 push(p1);
20406 restore();
20407 return false;
20408 }
20409 push(checkSize);
20410 push_integer(-2);
20411 push(A);
20412 multiply();
20413 push(B);
20414 divide();
20415 checkSize = pop();
20416 push(checkSize);
20417 real();
20418 yyfloat();
20419 if (Math.abs(pop().d) > Math.pow(2, 32)) {
20420 pop();
20421 push(p1);
20422 restore();
20423 return false;
20424 }
20425 push(checkSize);
20426 push(symbol(SECRETX));
20427 multiply();
20428 push_integer(1);
20429 push(symbol(SECRETX));
20430 push_integer(2);
20431 power();
20432 multiply();
20433 add();
20434 add();
20435 }
20436 push(symbol(SECRETX));
20437 recursionLevelNestedRadicalsRemoval++;
20438 roots();
20439 recursionLevelNestedRadicalsRemoval--;
20440 if (equal(stack[tos - 1], symbol(NIL))) {
20441 if (DEBUG) {
20442 console.log("roots bailed out because of too much recursion");
20443 }
20444 pop();
20445 push(p1);
20446 restore();
20447 return false;
20448 }
20449 possibleSolutions = [];
20450 ref2 = stack[tos - 1].tensor.elem;
20451 for (n1 = 0, len2 = ref2.length; n1 < len2; n1++) {
20452 eachSolution = ref2[n1];
20453 if (!Find(eachSolution, symbol(POWER))) {
20454 possibleSolutions.push(eachSolution);
20455 }
20456 }
20457 pop();
20458 if (possibleSolutions.length === 0) {
20459 push(p1);
20460 restore();
20461 return false;
20462 }
20463 possibleRationalSolutions = [];
20464 realOfpossibleRationalSolutions = [];
20465 for (o1 = 0, len3 = possibleSolutions.length; o1 < len3; o1++) {
20466 i = possibleSolutions[o1];
20467 push(i);
20468 real();
20469 yyfloat();
20470 possibleRationalSolutions.push(i);
20471 realOfpossibleRationalSolutions.push(pop().d);
20472 }
20473 whichRationalSolution = realOfpossibleRationalSolutions.indexOf(Math.max.apply(Math, realOfpossibleRationalSolutions));
20474 SOLUTION = possibleRationalSolutions[whichRationalSolution];
20475
20476 /*
20477 #possibleNewExpressions = []
20478 #realOfPossibleNewExpressions = []
20479 * pick the solution which cubic root has no radicals
20480 lowercase_b = null
20481 for SOLUTION in possibleSolutions
20482 console.log("testing solution: " + SOLUTION.toString())
20483
20484 debugger
20485 if equalq(exponent,1,3)
20486 push(A)
20487 push(SOLUTION)
20488 push_integer(3)
20489 power()
20490 push_integer(3)
20491 push(C)
20492 multiply()
20493 push(SOLUTION)
20494 multiply()
20495 add()
20496 divide()
20497 console.log("argument of cubic root: " + stack[tos-1].toString())
20498 push_rational(1,3)
20499 power()
20500 else if equalq(exponent,1,2)
20501 push(A)
20502 push(SOLUTION)
20503 push_integer(2)
20504 power()
20505 push(C)
20506 add()
20507 divide()
20508 console.log("argument of cubic root: " + stack[tos-1].toString())
20509 push_rational(1,2)
20510 power()
20511 console.log("b is: " + stack[tos-1].toString())
20512
20513 lowercase_b = pop()
20514
20515 if !Find(lowercase_b, symbol(POWER))
20516 break
20517 */
20518 if (equalq(exponent, 1, 3)) {
20519 push(A);
20520 push(SOLUTION);
20521 push_integer(3);
20522 power();
20523 push_integer(3);
20524 push(C);
20525 multiply();
20526 push(SOLUTION);
20527 multiply();
20528 add();
20529 divide();
20530 push_rational(1, 3);
20531 power();
20532 } else if (equalq(exponent, 1, 2)) {
20533 push(A);
20534 push(SOLUTION);
20535 push_integer(2);
20536 power();
20537 push(C);
20538 add();
20539 divide();
20540 push_rational(1, 2);
20541 power();
20542 }
20543 lowercase_b = pop();
20544 if (lowercase_b == null) {
20545 push(p1);
20546 restore();
20547 return false;
20548 }
20549 push(lowercase_b);
20550 push(SOLUTION);
20551 multiply();
20552 if (equalq(exponent, 1, 3)) {
20553 lowercase_a = pop();
20554 push(lowercase_b);
20555 push(C);
20556 push_rational(1, 2);
20557 power();
20558 multiply();
20559 push(lowercase_a);
20560 add();
20561 simplify();
20562 } else if (equalq(exponent, 1, 2)) {
20563 lowercase_a = pop();
20564 push(lowercase_b);
20565 push(C);
20566 push_rational(1, 2);
20567 power();
20568 multiply();
20569 push(lowercase_a);
20570 add();
20571 simplify();
20572 possibleNewExpression = pop();
20573 push(possibleNewExpression);
20574 real();
20575 yyfloat();
20576 possibleNewExpressionValue = pop();
20577 if (!isnegativenumber(possibleNewExpressionValue)) {
20578 push(possibleNewExpression);
20579 } else {
20580 push(lowercase_b);
20581 negate();
20582 lowercase_b = pop();
20583 push(lowercase_a);
20584 negate();
20585 lowercase_a = pop();
20586 push(lowercase_b);
20587 push(C);
20588 push_rational(1, 2);
20589 power();
20590 multiply();
20591 push(lowercase_a);
20592 add();
20593 simplify();
20594 }
20595 }
20596 p1 = pop();
20597 push(p1);
20598 restore();
20599 return true;
20600 } else {
20601 push(p1);
20602 restore();
20603 return false;
20604 }
20605 } else if (iscons(p1)) {
20606 h = tos;
20607 anyRadicalSimplificationWorked = false;
20608 while (iscons(p1)) {
20609 push(car(p1));
20610 anyRadicalSimplificationWorked = anyRadicalSimplificationWorked || take_care_of_nested_radicals();
20611 p1 = cdr(p1);
20612 }
20613 list(tos - h);
20614 restore();
20615 return anyRadicalSimplificationWorked;
20616 } else {
20617 push(p1);
20618 restore();
20619 return false;
20620 }
20621 throw new Error("control flow should never reach here");
20622 };
20623
20624 Eval_sin = function() {
20625 push(cadr(p1));
20626 Eval();
20627 return sine();
20628 };
20629
20630 sine = function() {
20631 save();
20632 p1 = pop();
20633 if (car(p1) === symbol(ADD)) {
20634 sine_of_angle_sum();
20635 } else {
20636 sine_of_angle();
20637 }
20638 return restore();
20639 };
20640
20641 sine_of_angle_sum = function() {
20642 p2 = cdr(p1);
20643 while (iscons(p2)) {
20644 p4 = car(p2);
20645 if (isnpi(p4)) {
20646 push(p1);
20647 push(p4);
20648 subtract();
20649 p3 = pop();
20650 push(p3);
20651 sine();
20652 push(p4);
20653 cosine();
20654 multiply();
20655 push(p3);
20656 cosine();
20657 push(p4);
20658 sine();
20659 multiply();
20660 add();
20661 return;
20662 }
20663 p2 = cdr(p2);
20664 }
20665 return sine_of_angle();
20666 };
20667
20668 sine_of_angle = function() {
20669 var d, n;
20670 if (car(p1) === symbol(ARCSIN)) {
20671 push(cadr(p1));
20672 return;
20673 }
20674 if (isdouble(p1)) {
20675 d = Math.sin(p1.d);
20676 if (Math.abs(d) < 1e-10) {
20677 d = 0.0;
20678 }
20679 push_double(d);
20680 return;
20681 }
20682 if (isnegative(p1)) {
20683 push(p1);
20684 negate();
20685 sine();
20686 negate();
20687 return;
20688 }
20689 if (car(p1) === symbol(ARCTAN)) {
20690 push(cadr(p1));
20691 push_integer(1);
20692 push(cadr(p1));
20693 push_integer(2);
20694 power();
20695 add();
20696 push_rational(-1, 2);
20697 power();
20698 multiply();
20699 return;
20700 }
20701 push(p1);
20702 push_integer(180);
20703 multiply();
20704 if (evaluatingAsFloats) {
20705 push_double(Math.PI);
20706 } else {
20707 push_symbol(PI);
20708 }
20709 divide();
20710 n = pop_integer();
20711 if (n < 0 || isNaN(n)) {
20712 push(symbol(SIN));
20713 push(p1);
20714 list(2);
20715 return;
20716 }
20717 switch (n % 360) {
20718 case 0:
20719 case 180:
20720 return push_integer(0);
20721 case 30:
20722 case 150:
20723 return push_rational(1, 2);
20724 case 210:
20725 case 330:
20726 return push_rational(-1, 2);
20727 case 45:
20728 case 135:
20729 push_rational(1, 2);
20730 push_integer(2);
20731 push_rational(1, 2);
20732 power();
20733 return multiply();
20734 case 225:
20735 case 315:
20736 push_rational(-1, 2);
20737 push_integer(2);
20738 push_rational(1, 2);
20739 power();
20740 return multiply();
20741 case 60:
20742 case 120:
20743 push_rational(1, 2);
20744 push_integer(3);
20745 push_rational(1, 2);
20746 power();
20747 return multiply();
20748 case 240:
20749 case 300:
20750 push_rational(-1, 2);
20751 push_integer(3);
20752 push_rational(1, 2);
20753 power();
20754 return multiply();
20755 case 90:
20756 return push_integer(1);
20757 case 270:
20758 return push_integer(-1);
20759 default:
20760 push(symbol(SIN));
20761 push(p1);
20762 return list(2);
20763 }
20764 };
20765
20766 Eval_sinh = function() {
20767 push(cadr(p1));
20768 Eval();
20769 return ysinh();
20770 };
20771
20772 ysinh = function() {
20773 save();
20774 yysinh();
20775 return restore();
20776 };
20777
20778 yysinh = function() {
20779 var d;
20780 d = 0.0;
20781 p1 = pop();
20782 if (car(p1) === symbol(ARCSINH)) {
20783 push(cadr(p1));
20784 return;
20785 }
20786 if (isdouble(p1)) {
20787 d = Math.sinh(p1.d);
20788 if (Math.abs(d) < 1e-10) {
20789 d = 0.0;
20790 }
20791 push_double(d);
20792 return;
20793 }
20794 if (iszero(p1)) {
20795 push(zero);
20796 return;
20797 }
20798 push_symbol(SINH);
20799 push(p1);
20800 return list(2);
20801 };
20802
20803
20804 /*
20805 Substitute new expr for old expr in expr.
20806
20807 Input: push expr
20808
20809 push old expr
20810
20811 push new expr
20812
20813 Output: Result on stack
20814 */
20815
20816 subst = function() {
20817 var i, l1, m1, ref2, ref3;
20818 i = 0;
20819 save();
20820 p3 = pop();
20821 p2 = pop();
20822 if (p2 === symbol(NIL) || p3 === symbol(NIL)) {
20823 restore();
20824 return;
20825 }
20826 p1 = pop();
20827 if (istensor(p1)) {
20828 p4 = alloc_tensor(p1.tensor.nelem);
20829 p4.tensor.ndim = p1.tensor.ndim;
20830 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
20831 p4.tensor.dim[i] = p1.tensor.dim[i];
20832 }
20833 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
20834 push(p1.tensor.elem[i]);
20835 push(p2);
20836 push(p3);
20837 subst();
20838 p4.tensor.elem[i] = pop();
20839 check_tensor_dimensions(p4);
20840 }
20841 push(p4);
20842 } else if (equal(p1, p2)) {
20843 push(p3);
20844 } else if (iscons(p1)) {
20845 push(car(p1));
20846 push(p2);
20847 push(p3);
20848 subst();
20849 push(cdr(p1));
20850 push(p2);
20851 push(p3);
20852 subst();
20853 cons();
20854 } else {
20855 push(p1);
20856 }
20857 return restore();
20858 };
20859
20860 Eval_sum = function() {
20861 var body, i, indexVariable, j, k, l1, ref2, ref3;
20862 i = 0;
20863 j = 0;
20864 k = 0;
20865 body = cadr(p1);
20866 indexVariable = caddr(p1);
20867 if (!issymbol(p6)) {
20868 stop("sum: 1st arg?");
20869 }
20870 push(cadddr(p1));
20871 Eval();
20872 j = pop_integer();
20873 if (isNaN(j)) {
20874 push(p1);
20875 return;
20876 }
20877 push(caddddr(p1));
20878 Eval();
20879 k = pop_integer();
20880 if (isNaN(k)) {
20881 push(p1);
20882 return;
20883 }
20884 p4 = get_binding(indexVariable);
20885 push_integer(0);
20886 for (i = l1 = ref2 = j, ref3 = k; ref2 <= ref3 ? l1 <= ref3 : l1 >= ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
20887 push_integer(i);
20888 p5 = pop();
20889 set_binding(indexVariable, p5);
20890 push(body);
20891 Eval();
20892 add();
20893 }
20894 return set_binding(indexVariable, p4);
20895 };
20896
20897 Eval_tan = function() {
20898 push(cadr(p1));
20899 Eval();
20900 return tangent();
20901 };
20902
20903 tangent = function() {
20904 save();
20905 yytangent();
20906 return restore();
20907 };
20908
20909 yytangent = function() {
20910 var d, n;
20911 n = 0;
20912 d = 0.0;
20913 p1 = pop();
20914 if (car(p1) === symbol(ARCTAN)) {
20915 push(cadr(p1));
20916 return;
20917 }
20918 if (isdouble(p1)) {
20919 d = Math.tan(p1.d);
20920 if (Math.abs(d) < 1e-10) {
20921 d = 0.0;
20922 }
20923 push_double(d);
20924 return;
20925 }
20926 if (isnegative(p1)) {
20927 push(p1);
20928 negate();
20929 tangent();
20930 negate();
20931 return;
20932 }
20933 push(p1);
20934 push_integer(180);
20935 multiply();
20936 if (evaluatingAsFloats) {
20937 push_double(Math.PI);
20938 } else {
20939 push_symbol(PI);
20940 }
20941 divide();
20942 n = pop_integer();
20943 if (n < 0 || isNaN(n)) {
20944 push(symbol(TAN));
20945 push(p1);
20946 list(2);
20947 return;
20948 }
20949 switch (n % 360) {
20950 case 0:
20951 case 180:
20952 return push_integer(0);
20953 case 30:
20954 case 210:
20955 push_rational(1, 3);
20956 push_integer(3);
20957 push_rational(1, 2);
20958 power();
20959 return multiply();
20960 case 150:
20961 case 330:
20962 push_rational(-1, 3);
20963 push_integer(3);
20964 push_rational(1, 2);
20965 power();
20966 return multiply();
20967 case 45:
20968 case 225:
20969 return push_integer(1);
20970 case 135:
20971 case 315:
20972 return push_integer(-1);
20973 case 60:
20974 case 240:
20975 push_integer(3);
20976 push_rational(1, 2);
20977 return power();
20978 case 120:
20979 case 300:
20980 push_integer(3);
20981 push_rational(1, 2);
20982 power();
20983 return negate();
20984 default:
20985 push(symbol(TAN));
20986 push(p1);
20987 return list(2);
20988 }
20989 };
20990
20991 Eval_tanh = function() {
20992 var d;
20993 d = 0.0;
20994 push(cadr(p1));
20995 Eval();
20996 p1 = pop();
20997 if (car(p1) === symbol(ARCTANH)) {
20998 push(cadr(p1));
20999 return;
21000 }
21001 if (isdouble(p1)) {
21002 d = Math.tanh(p1.d);
21003 if (Math.abs(d) < 1e-10) {
21004 d = 0.0;
21005 }
21006 push_double(d);
21007 return;
21008 }
21009 if (iszero(p1)) {
21010 push(zero);
21011 return;
21012 }
21013 push_symbol(TANH);
21014 push(p1);
21015 return list(2);
21016 };
21017
21018
21019 /*
21020 Taylor expansion of a function
21021
21022 push(F)
21023 push(X)
21024 push(N)
21025 push(A)
21026 taylor()
21027 */
21028
21029 Eval_taylor = function() {
21030 p1 = cdr(p1);
21031 push(car(p1));
21032 Eval();
21033 p1 = cdr(p1);
21034 push(car(p1));
21035 Eval();
21036 p2 = pop();
21037 if (p2 === symbol(NIL)) {
21038 guess();
21039 } else {
21040 push(p2);
21041 }
21042 p1 = cdr(p1);
21043 push(car(p1));
21044 Eval();
21045 p2 = pop();
21046 if (p2 === symbol(NIL)) {
21047 push_integer(24);
21048 } else {
21049 push(p2);
21050 }
21051 p1 = cdr(p1);
21052 push(car(p1));
21053 Eval();
21054 p2 = pop();
21055 if (p2 === symbol(NIL)) {
21056 push_integer(0);
21057 } else {
21058 push(p2);
21059 }
21060 return taylor();
21061 };
21062
21063 taylor = function() {
21064 var i, k, l1, ref2;
21065 i = 0;
21066 k = 0;
21067 save();
21068 p4 = pop();
21069 p3 = pop();
21070 p2 = pop();
21071 p1 = pop();
21072 push(p3);
21073 k = pop_integer();
21074 if (isNaN(k)) {
21075 push_symbol(TAYLOR);
21076 push(p1);
21077 push(p2);
21078 push(p3);
21079 push(p4);
21080 list(5);
21081 restore();
21082 return;
21083 }
21084 push(p1);
21085 push(p2);
21086 push(p4);
21087 subst();
21088 Eval();
21089 push_integer(1);
21090 p5 = pop();
21091 for (i = l1 = 1, ref2 = k; 1 <= ref2 ? l1 <= ref2 : l1 >= ref2; i = 1 <= ref2 ? ++l1 : --l1) {
21092 push(p1);
21093 push(p2);
21094 derivative();
21095 p1 = pop();
21096 if (iszero(p1)) {
21097 break;
21098 }
21099 push(p5);
21100 push(p2);
21101 push(p4);
21102 subtract();
21103 multiply();
21104 p5 = pop();
21105 push(p1);
21106 push(p2);
21107 push(p4);
21108 subst();
21109 Eval();
21110 push(p5);
21111 multiply();
21112 push_integer(i);
21113 factorial();
21114 divide();
21115 add();
21116 }
21117 return restore();
21118 };
21119
21120
21121 /* tensor =====================================================================
21122
21123 Tags
21124 ----
21125 scripting, JS, internal, treenode, general concept
21126
21127 General description
21128 -------------------
21129 Tensors are a strange in-between of matrices and "computer"
21130 rectangular data structures.
21131
21132 Tensors, unlike matrices, and like rectangular data structures,
21133 can have an arbitrary number of dimensions (rank), although a tensor with
21134 rank zero is just a scalar.
21135
21136 Tensors, like matrices and unlike many computer rectangular data structures,
21137 must be "contiguous" i.e. have no empty spaces within its size, and "uniform",
21138 i.e. each element must have the same shape and hence the same rank.
21139
21140 Also tensors have necessarily to make a distinction between row vectors,
21141 column vectors (which have a rank of 2) and uni-dimensional vectors (rank 1).
21142 They look very similar but they are fundamentally different.
21143
21144 Tensors with elements that are also tensors get promoted to a higher rank
21145 , this is so we can represent and get the rank of a matrix correctly.
21146 Example:
21147 Start with a tensor of rank 1 with 2 elements (i.e. shape: 2)
21148 if you put in both its elements another 2 tensors
21149 of rank 1 with 2 elements (i.e. shape: 2)
21150 then the result is a tensor of rank 2 with shape 2,2
21151 i.e. the dimension of a tensor at all times must be
21152 the number of nested tensors in it.
21153 Also, all tensors must be "uniform" i.e. they must be accessed
21154 uniformly, which means that all existing elements of a tensor
21155 must be contiguous and have the same shape.
21156 Implication of it all is that you can't put arbitrary
21157 tensors inside tensors (like you would do to represent block matrices)
21158 Rather, all tensors inside tensors must have same shape (and hence, rank)
21159
21160 Limitations
21161 -----------
21162 n.a.
21163
21164 Implementation info
21165 -------------------
21166 Tensors are implemented...
21167 */
21168
21169 Eval_tensor = function() {
21170 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21171 i = 0;
21172 ndim = 0;
21173 nelem = 0;
21174 check_tensor_dimensions(p1);
21175 nelem = p1.tensor.nelem;
21176 ndim = p1.tensor.ndim;
21177 p2 = alloc_tensor(nelem);
21178 p2.tensor.ndim = ndim;
21179 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21180 p2.tensor.dim[i] = p1.tensor.dim[i];
21181 }
21182 a = p1.tensor.elem;
21183 b = p2.tensor.elem;
21184 check_tensor_dimensions(p2);
21185 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21186 push(a[i]);
21187 Eval();
21188 b[i] = pop();
21189 }
21190 check_tensor_dimensions(p1);
21191 check_tensor_dimensions(p2);
21192 push(p2);
21193 return promote_tensor();
21194 };
21195
21196 tensor_plus_tensor = function() {
21197 var a, b, c, i, l1, m1, n1, ndim, nelem, ref2, ref3, ref4;
21198 i = 0;
21199 ndim = 0;
21200 nelem = 0;
21201 save();
21202 p2 = pop();
21203 p1 = pop();
21204 ndim = p1.tensor.ndim;
21205 if (ndim !== p2.tensor.ndim) {
21206 push(symbol(NIL));
21207 restore();
21208 return;
21209 }
21210 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21211 if (p1.tensor.dim[i] !== p2.tensor.dim[i]) {
21212 push(symbol(NIL));
21213 restore();
21214 return;
21215 }
21216 }
21217 nelem = p1.tensor.nelem;
21218 p3 = alloc_tensor(nelem);
21219 p3.tensor.ndim = ndim;
21220 for (i = m1 = 0, ref3 = ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21221 p3.tensor.dim[i] = p1.tensor.dim[i];
21222 }
21223 a = p1.tensor.elem;
21224 b = p2.tensor.elem;
21225 c = p3.tensor.elem;
21226 for (i = n1 = 0, ref4 = nelem; 0 <= ref4 ? n1 < ref4 : n1 > ref4; i = 0 <= ref4 ? ++n1 : --n1) {
21227 push(a[i]);
21228 push(b[i]);
21229 add();
21230 c[i] = pop();
21231 }
21232 push(p3);
21233 return restore();
21234 };
21235
21236 tensor_times_scalar = function() {
21237 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21238 i = 0;
21239 ndim = 0;
21240 nelem = 0;
21241 save();
21242 p2 = pop();
21243 p1 = pop();
21244 ndim = p1.tensor.ndim;
21245 nelem = p1.tensor.nelem;
21246 p3 = alloc_tensor(nelem);
21247 p3.tensor.ndim = ndim;
21248 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21249 p3.tensor.dim[i] = p1.tensor.dim[i];
21250 }
21251 a = p1.tensor.elem;
21252 b = p3.tensor.elem;
21253 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21254 push(a[i]);
21255 push(p2);
21256 multiply();
21257 b[i] = pop();
21258 }
21259 push(p3);
21260 return restore();
21261 };
21262
21263 scalar_times_tensor = function() {
21264 var a, b, i, l1, m1, ndim, nelem, ref2, ref3;
21265 i = 0;
21266 ndim = 0;
21267 nelem = 0;
21268 save();
21269 p2 = pop();
21270 p1 = pop();
21271 ndim = p2.tensor.ndim;
21272 nelem = p2.tensor.nelem;
21273 p3 = alloc_tensor(nelem);
21274 p3.tensor.ndim = ndim;
21275 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21276 p3.tensor.dim[i] = p2.tensor.dim[i];
21277 }
21278 a = p2.tensor.elem;
21279 b = p3.tensor.elem;
21280 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21281 push(p1);
21282 push(a[i]);
21283 multiply();
21284 b[i] = pop();
21285 }
21286 push(p3);
21287 return restore();
21288 };
21289
21290 check_tensor_dimensions = function(p) {
21291 if (p.tensor.nelem !== p.tensor.elem.length) {
21292 console.log("something wrong in tensor dimensions");
21293 debugger;
21294 }
21295 };
21296
21297 is_square_matrix = function(p) {
21298 if (istensor(p) && p.tensor.ndim === 2 && p.tensor.dim[0] === p.tensor.dim[1]) {
21299 return 1;
21300 } else {
21301 return 0;
21302 }
21303 };
21304
21305 d_tensor_tensor = function() {
21306 var a, b, c, i, j, l1, m1, n1, ndim, nelem, ref2, ref3, ref4;
21307 i = 0;
21308 j = 0;
21309 ndim = 0;
21310 nelem = 0;
21311 ndim = p1.tensor.ndim;
21312 nelem = p1.tensor.nelem;
21313 if (ndim + 1 >= MAXDIM) {
21314 push_symbol(DERIVATIVE);
21315 push(p1);
21316 push(p2);
21317 list(3);
21318 return;
21319 }
21320 p3 = alloc_tensor(nelem * p2.tensor.nelem);
21321 p3.tensor.ndim = ndim + 1;
21322 for (i = l1 = 0, ref2 = ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21323 p3.tensor.dim[i] = p1.tensor.dim[i];
21324 }
21325 p3.tensor.dim[ndim] = p2.tensor.dim[0];
21326 a = p1.tensor.elem;
21327 b = p2.tensor.elem;
21328 c = p3.tensor.elem;
21329 for (i = m1 = 0, ref3 = nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21330 for (j = n1 = 0, ref4 = p2.tensor.nelem; 0 <= ref4 ? n1 < ref4 : n1 > ref4; j = 0 <= ref4 ? ++n1 : --n1) {
21331 push(a[i]);
21332 push(b[j]);
21333 derivative();
21334 c[i * p2.tensor.nelem + j] = pop();
21335 }
21336 }
21337 return push(p3);
21338 };
21339
21340 d_scalar_tensor = function() {
21341 var a, b, i, l1, ref2;
21342 p3 = alloc_tensor(p2.tensor.nelem);
21343 p3.tensor.ndim = 1;
21344 p3.tensor.dim[0] = p2.tensor.dim[0];
21345 a = p2.tensor.elem;
21346 b = p3.tensor.elem;
21347 for (i = l1 = 0, ref2 = p2.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21348 push(p1);
21349 push(a[i]);
21350 derivative();
21351 b[i] = pop();
21352 }
21353 return push(p3);
21354 };
21355
21356 d_tensor_scalar = function() {
21357 var a, b, i, l1, m1, ref2, ref3;
21358 i = 0;
21359 p3 = alloc_tensor(p1.tensor.nelem);
21360 p3.tensor.ndim = p1.tensor.ndim;
21361 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21362 p3.tensor.dim[i] = p1.tensor.dim[i];
21363 }
21364 a = p1.tensor.elem;
21365 b = p3.tensor.elem;
21366 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21367 push(a[i]);
21368 push(p2);
21369 derivative();
21370 b[i] = pop();
21371 }
21372 return push(p3);
21373 };
21374
21375 compare_tensors = function(p1, p2) {
21376 var i, l1, m1, ref2, ref3;
21377 i = 0;
21378 if (p1.tensor.ndim < p2.tensor.ndim) {
21379 return -1;
21380 }
21381 if (p1.tensor.ndim > p2.tensor.ndim) {
21382 return 1;
21383 }
21384 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21385 if (p1.tensor.dim[i] < p2.tensor.dim[i]) {
21386 return -1;
21387 }
21388 if (p1.tensor.dim[i] > p2.tensor.dim[i]) {
21389 return 1;
21390 }
21391 }
21392 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21393 if (equal(p1.tensor.elem[i], p2.tensor.elem[i])) {
21394 continue;
21395 }
21396 if (lessp(p1.tensor.elem[i], p2.tensor.elem[i])) {
21397 return -1;
21398 } else {
21399 return 1;
21400 }
21401 }
21402 return 0;
21403 };
21404
21405 power_tensor = function() {
21406 var i, k, l1, m1, n, ref2, ref3, results;
21407 i = 0;
21408 k = 0;
21409 n = 0;
21410 k = p1.tensor.ndim - 1;
21411 if (p1.tensor.dim[0] !== p1.tensor.dim[k]) {
21412 push_symbol(POWER);
21413 push(p1);
21414 push(p2);
21415 list(3);
21416 return;
21417 }
21418 push(p2);
21419 n = pop_integer();
21420 if (isNaN(n)) {
21421 push_symbol(POWER);
21422 push(p1);
21423 push(p2);
21424 list(3);
21425 return;
21426 }
21427 if (n === 0) {
21428 if (p1.tensor.ndim !== 2) {
21429 stop("power(tensor,0) with tensor rank not equal to 2");
21430 }
21431 n = p1.tensor.dim[0];
21432 p1 = alloc_tensor(n * n);
21433 p1.tensor.ndim = 2;
21434 p1.tensor.dim[0] = n;
21435 p1.tensor.dim[1] = n;
21436 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21437 p1.tensor.elem[n * i + i] = one;
21438 }
21439 check_tensor_dimensions(p1);
21440 push(p1);
21441 return;
21442 }
21443 if (n < 0) {
21444 n = -n;
21445 push(p1);
21446 inv();
21447 p1 = pop();
21448 }
21449 push(p1);
21450 results = [];
21451 for (i = m1 = 1, ref3 = n; 1 <= ref3 ? m1 < ref3 : m1 > ref3; i = 1 <= ref3 ? ++m1 : --m1) {
21452 push(p1);
21453 inner();
21454 if (iszero(stack[tos - 1])) {
21455 break;
21456 } else {
21457 results.push(void 0);
21458 }
21459 }
21460 return results;
21461 };
21462
21463 copy_tensor = function() {
21464 var i, l1, m1, ref2, ref3;
21465 i = 0;
21466 save();
21467 p1 = pop();
21468 p2 = alloc_tensor(p1.tensor.nelem);
21469 p2.tensor.ndim = p1.tensor.ndim;
21470 for (i = l1 = 0, ref2 = p1.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21471 p2.tensor.dim[i] = p1.tensor.dim[i];
21472 }
21473 for (i = m1 = 0, ref3 = p1.tensor.nelem; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21474 p2.tensor.elem[i] = p1.tensor.elem[i];
21475 }
21476 check_tensor_dimensions(p1);
21477 check_tensor_dimensions(p2);
21478 push(p2);
21479 return restore();
21480 };
21481
21482 promote_tensor = function() {
21483 var i, j, k, l1, m1, n1, ndim, nelem, o1, q1, ref2, ref3, ref4, ref5, ref6;
21484 i = 0;
21485 j = 0;
21486 k = 0;
21487 nelem = 0;
21488 ndim = 0;
21489 save();
21490 p1 = pop();
21491 if (!istensor(p1)) {
21492 push(p1);
21493 restore();
21494 return;
21495 }
21496 p2 = p1.tensor.elem[0];
21497 for (i = l1 = 1, ref2 = p1.tensor.nelem; 1 <= ref2 ? l1 < ref2 : l1 > ref2; i = 1 <= ref2 ? ++l1 : --l1) {
21498 if (!compatible(p2, p1.tensor.elem[i])) {
21499 stop("Cannot promote tensor due to inconsistent tensor components.");
21500 }
21501 }
21502 if (!istensor(p2)) {
21503 push(p1);
21504 restore();
21505 return;
21506 }
21507 ndim = p1.tensor.ndim + p2.tensor.ndim;
21508 if (ndim > MAXDIM) {
21509 stop("tensor rank > " + MAXDIM);
21510 }
21511 nelem = p1.tensor.nelem * p2.tensor.nelem;
21512 p3 = alloc_tensor(nelem);
21513 p3.tensor.ndim = ndim;
21514 for (i = m1 = 0, ref3 = p1.tensor.ndim; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
21515 p3.tensor.dim[i] = p1.tensor.dim[i];
21516 }
21517 for (j = n1 = 0, ref4 = p2.tensor.ndim; 0 <= ref4 ? n1 < ref4 : n1 > ref4; j = 0 <= ref4 ? ++n1 : --n1) {
21518 p3.tensor.dim[i + j] = p2.tensor.dim[j];
21519 }
21520 k = 0;
21521 for (i = o1 = 0, ref5 = p1.tensor.nelem; 0 <= ref5 ? o1 < ref5 : o1 > ref5; i = 0 <= ref5 ? ++o1 : --o1) {
21522 p2 = p1.tensor.elem[i];
21523 for (j = q1 = 0, ref6 = p2.tensor.nelem; 0 <= ref6 ? q1 < ref6 : q1 > ref6; j = 0 <= ref6 ? ++q1 : --q1) {
21524 p3.tensor.elem[k++] = p2.tensor.elem[j];
21525 }
21526 }
21527 check_tensor_dimensions(p2);
21528 check_tensor_dimensions(p3);
21529 push(p3);
21530 return restore();
21531 };
21532
21533 compatible = function(p, q) {
21534 var i, l1, ref2;
21535 if (!istensor(p) && !istensor(q)) {
21536 return 1;
21537 }
21538 if (!istensor(p) || !istensor(q)) {
21539 return 0;
21540 }
21541 if (p.tensor.ndim !== q.tensor.ndim) {
21542 return 0;
21543 }
21544 for (i = l1 = 0, ref2 = p.tensor.ndim; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21545 if (p.tensor.dim[i] !== q.tensor.dim[i]) {
21546 return 0;
21547 }
21548 }
21549 return 1;
21550 };
21551
21552 Eval_test = function() {
21553 var orig;
21554 orig = p1;
21555 p1 = cdr(p1);
21556 while (iscons(p1)) {
21557 if (cdr(p1) === symbol(NIL)) {
21558 push(car(p1));
21559 Eval();
21560 return;
21561 }
21562 push(car(p1));
21563 Eval_predicate();
21564 p2 = pop();
21565 if (isone(p2)) {
21566 push(cadr(p1));
21567 Eval();
21568 return;
21569 } else if (!iszero(p2)) {
21570 push(orig);
21571 return;
21572 }
21573 p1 = cddr(p1);
21574 }
21575 return push_integer(0);
21576 };
21577
21578 Eval_testeq = function() {
21579 var orig, subtractionResult;
21580 orig = p1;
21581 push(cadr(p1));
21582 Eval();
21583 push(caddr(p1));
21584 Eval();
21585 subtract();
21586 subtractionResult = pop();
21587 if (iszero(subtractionResult)) {
21588 p1 = subtractionResult;
21589 return push_integer(1);
21590 } else {
21591 push(cadr(p1));
21592 Eval();
21593 simplify();
21594 push(caddr(p1));
21595 Eval();
21596 simplify();
21597 subtract();
21598 p1 = pop();
21599 if (iszero(p1)) {
21600 return push_integer(1);
21601 } else {
21602 push(p1);
21603 yyfloat();
21604 p1 = pop();
21605 if (iszero(p1)) {
21606 return push_integer(1);
21607 } else if (isnum(p1)) {
21608 return push_integer(0);
21609 } else {
21610 return push(orig);
21611 }
21612 }
21613 }
21614 };
21615
21616 Eval_testge = function() {
21617 var comparison, orig;
21618 orig = p1;
21619 comparison = cmp_args();
21620 if (comparison == null) {
21621 push(orig);
21622 return;
21623 }
21624 if (comparison >= 0) {
21625 return push_integer(1);
21626 } else {
21627 return push_integer(0);
21628 }
21629 };
21630
21631 Eval_testgt = function() {
21632 var comparison, orig;
21633 orig = p1;
21634 comparison = cmp_args();
21635 if (comparison == null) {
21636 push(orig);
21637 return;
21638 }
21639 if (comparison > 0) {
21640 return push_integer(1);
21641 } else {
21642 return push_integer(0);
21643 }
21644 };
21645
21646 Eval_testle = function() {
21647 var comparison, orig;
21648 orig = p1;
21649 comparison = cmp_args();
21650 if (comparison == null) {
21651 push(orig);
21652 return;
21653 }
21654 if (comparison <= 0) {
21655 return push_integer(1);
21656 } else {
21657 return push_integer(0);
21658 }
21659 };
21660
21661 Eval_testlt = function() {
21662 var comparison, orig;
21663 orig = p1;
21664 comparison = cmp_args();
21665 if (comparison == null) {
21666 push(orig);
21667 return;
21668 }
21669 if (comparison < 0) {
21670 return push_integer(1);
21671 } else {
21672 return push_integer(0);
21673 }
21674 };
21675
21676 Eval_not = function() {
21677 push(cadr(p1));
21678 Eval_predicate();
21679 p1 = pop();
21680 if (iszero(p1)) {
21681 return push_integer(1);
21682 } else {
21683 return push_integer(0);
21684 }
21685 };
21686
21687
21688 /* and =====================================================================
21689
21690 Tags
21691 ----
21692 scripting, JS, internal, treenode, general concept
21693
21694 Parameters
21695 ----------
21696 a,b,...
21697
21698 General description
21699 -------------------
21700 Logical-and of predicate expressions.
21701 */
21702
21703 Eval_and = function() {
21704 p1 = cdr(p1);
21705 while (iscons(p1)) {
21706 push(car(p1));
21707 Eval_predicate();
21708 p2 = pop();
21709 if (iszero(p2)) {
21710 push_integer(0);
21711 return;
21712 }
21713 p1 = cdr(p1);
21714 }
21715 return push_integer(1);
21716 };
21717
21718 Eval_or = function() {
21719 p1 = cdr(p1);
21720 while (iscons(p1)) {
21721 push(car(p1));
21722 Eval_predicate();
21723 p2 = pop();
21724 if (!iszero(p2)) {
21725 push_integer(1);
21726 return;
21727 }
21728 p1 = cdr(p1);
21729 }
21730 return push_integer(0);
21731 };
21732
21733 cmp_args = function() {
21734 var t;
21735 t = 0;
21736 push(cadr(p1));
21737 Eval();
21738 simplify();
21739 push(caddr(p1));
21740 Eval();
21741 simplify();
21742 subtract();
21743 p1 = pop();
21744 if (p1.k !== NUM && p1.k !== DOUBLE) {
21745 push(p1);
21746 yyfloat();
21747 Eval();
21748 p1 = pop();
21749 }
21750 if (iszero(p1)) {
21751 return 0;
21752 }
21753 switch (p1.k) {
21754 case NUM:
21755 if (MSIGN(p1.q.a) === -1) {
21756 t = -1;
21757 } else {
21758 t = 1;
21759 }
21760 break;
21761 case DOUBLE:
21762 if (p1.d < 0.0) {
21763 t = -1;
21764 } else {
21765 t = 1;
21766 }
21767 break;
21768 default:
21769 t = null;
21770 }
21771 return t;
21772 };
21773
21774
21775 /*
21776 Transform an expression using a pattern. The
21777 pattern can come from the integrals table or
21778 the user-defined patterns.
21779
21780 The expression and free variable are on the stack.
21781
21782 The argument s is a null terminated list of transform rules.
21783
21784 For example, see the itab (integrals table)
21785
21786 Internally, the following symbols are used:
21787
21788 F input expression
21789
21790 X free variable, i.e. F of X
21791
21792 A template expression
21793
21794 B result expression
21795
21796 C list of conditional expressions
21797
21798 Puts the final expression on top of stack
21799 (whether it's transformed or not) and returns
21800 true is successful, false if not.
21801 */
21802
21803 transform = function(s, generalTransform) {
21804 var bookmarkTosToPrintDecomps, eachTransformEntry, i, l1, len, len1, m1, n1, numberOfDecomps, ref2, restTerm, secondTerm, success, theTransform, transform_h, transformationSuccessful, transformedTerms;
21805 transform_h = 0;
21806 save();
21807 p1 = null;
21808 p4 = pop();
21809 p3 = pop();
21810 if (DEBUG) {
21811 console.log(" !!!!!!!!! transform on: " + p3);
21812 }
21813 saveMetaBindings();
21814 set_binding(symbol(METAX), p4);
21815 transform_h = tos;
21816 push_integer(1);
21817 push(p3);
21818 push(p4);
21819 polyform();
21820 push(p4);
21821 bookmarkTosToPrintDecomps = tos - 2;
21822 decomp(generalTransform);
21823 numberOfDecomps = tos - bookmarkTosToPrintDecomps;
21824 if (DEBUG) {
21825 console.log(" " + numberOfDecomps + " decomposed elements ====== ");
21826 for (i = l1 = 0, ref2 = numberOfDecomps; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
21827 console.log(" decomposition element " + i + ": " + stack[tos - 1 - i]);
21828 }
21829 }
21830 transformationSuccessful = false;
21831 if (generalTransform) {
21832 if (!isnum(p3)) {
21833 theTransform = s;
21834 if (DEBUG) {
21835 console.log("applying transform: " + theTransform);
21836 }
21837 if (DEBUG) {
21838 console.log("scanning table entry " + theTransform);
21839 }
21840 push(theTransform);
21841 push(symbol(SYMBOL_A_UNDERSCORE));
21842 push(symbol(METAA));
21843 subst();
21844 push(symbol(SYMBOL_B_UNDERSCORE));
21845 push(symbol(METAB));
21846 subst();
21847 push(symbol(SYMBOL_X_UNDERSCORE));
21848 push(symbol(METAX));
21849 subst();
21850 p1 = pop();
21851 p5 = car(p1);
21852 if (DEBUG) {
21853 console.log("template expression: " + p5);
21854 }
21855 p6 = cadr(p1);
21856 p7 = cddr(p1);
21857
21858 /*
21859 p5 = p1.tensor.elem[0]
21860 p6 = p1.tensor.elem[1]
21861 for i in [2..(p1.tensor.elem.length-1)]
21862 push p1.tensor.elem[i]
21863 list(p1.tensor.elem.length - 2)
21864 p7 = pop()
21865 */
21866 if (f_equals_a(transform_h, generalTransform)) {
21867 transformationSuccessful = true;
21868 } else {
21869 if (DEBUG) {
21870 console.log("p3 at this point: " + p3);
21871 }
21872 transformedTerms = [];
21873 if (DEBUG) {
21874 console.log("car(p3): " + car(p3));
21875 }
21876 restTerm = p3;
21877 if (iscons(restTerm)) {
21878 transformedTerms.push(car(p3));
21879 restTerm = cdr(p3);
21880 }
21881 while (iscons(restTerm)) {
21882 secondTerm = car(restTerm);
21883 restTerm = cdr(restTerm);
21884 if (DEBUG) {
21885 console.log("tos before recursive transform: " + tos);
21886 }
21887 push(secondTerm);
21888 push_symbol(NIL);
21889 if (DEBUG) {
21890 console.log("testing: " + secondTerm);
21891 }
21892 if (DEBUG) {
21893 console.log("about to try to simplify other term: " + secondTerm);
21894 }
21895 success = transform(s, generalTransform);
21896 transformationSuccessful = transformationSuccessful || success;
21897 transformedTerms.push(pop());
21898 if (DEBUG) {
21899 console.log("tried to simplify other term: " + secondTerm + " ...successful?: " + success + " ...transformed: " + transformedTerms[transformedTerms.length - 1]);
21900 }
21901 }
21902 if (transformedTerms.length !== 0) {
21903 for (m1 = 0, len = transformedTerms.length; m1 < len; m1++) {
21904 i = transformedTerms[m1];
21905 push(i);
21906 }
21907 list(transformedTerms.length);
21908 p6 = pop();
21909 }
21910 }
21911 }
21912 } else {
21913 for (n1 = 0, len1 = s.length; n1 < len1; n1++) {
21914 eachTransformEntry = s[n1];
21915 if (DEBUG) {
21916 console.log("scanning table entry " + eachTransformEntry);
21917 if ((eachTransformEntry + "").indexOf("f(sqrt(a+b*x),2/3*1/b*sqrt((a+b*x)^3))") !== -1) {
21918 debugger;
21919 }
21920 }
21921 if (eachTransformEntry) {
21922 scan_meta(eachTransformEntry);
21923 p1 = pop();
21924 p5 = cadr(p1);
21925 p6 = caddr(p1);
21926 p7 = cdddr(p1);
21927
21928 /*
21929 p5 = p1.tensor.elem[0]
21930 p6 = p1.tensor.elem[1]
21931 for i in [2..(p1.tensor.elem.length-1)]
21932 push p1.tensor.elem[i]
21933 list(p1.tensor.elem.length - 2)
21934 p7 = pop()
21935 */
21936 if (f_equals_a(transform_h, generalTransform)) {
21937 transformationSuccessful = true;
21938 break;
21939 }
21940 }
21941 }
21942 }
21943 moveTos(transform_h);
21944 if (transformationSuccessful) {
21945 push(p6);
21946 Eval();
21947 p1 = pop();
21948 transformationSuccessful = true;
21949 } else {
21950 if (generalTransform) {
21951 p1 = p3;
21952 } else {
21953 p1 = symbol(NIL);
21954 }
21955 }
21956 restoreMetaBindings();
21957 push(p1);
21958 restore();
21959 return transformationSuccessful;
21960 };
21961
21962 saveMetaBindings = function() {
21963 push(get_binding(symbol(METAA)));
21964 push(get_binding(symbol(METAB)));
21965 return push(get_binding(symbol(METAX)));
21966 };
21967
21968 restoreMetaBindings = function() {
21969 set_binding(symbol(METAX), pop());
21970 set_binding(symbol(METAB), pop());
21971 return set_binding(symbol(METAA), pop());
21972 };
21973
21974 f_equals_a = function(h, generalTransform) {
21975 var fea_i, fea_j, l1, m1, originalexpanding, ref2, ref3, ref4, ref5;
21976 fea_i = 0;
21977 fea_j = 0;
21978 for (fea_i = l1 = ref2 = h, ref3 = tos; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; fea_i = ref2 <= ref3 ? ++l1 : --l1) {
21979 set_binding(symbol(METAA), stack[fea_i]);
21980 if (DEBUG) {
21981 console.log(" binding METAA to " + get_binding(symbol(METAA)));
21982 }
21983 for (fea_j = m1 = ref4 = h, ref5 = tos; ref4 <= ref5 ? m1 < ref5 : m1 > ref5; fea_j = ref4 <= ref5 ? ++m1 : --m1) {
21984 set_binding(symbol(METAB), stack[fea_j]);
21985 if (DEBUG) {
21986 console.log(" binding METAB to " + get_binding(symbol(METAB)));
21987 }
21988 p1 = p7;
21989 while (iscons(p1)) {
21990 push(car(p1));
21991 Eval();
21992 p2 = pop();
21993 if (iszero(p2)) {
21994 break;
21995 }
21996 p1 = cdr(p1);
21997 }
21998 if (iscons(p1)) {
21999 continue;
22000 }
22001 push(p3);
22002 if (DEBUG) {
22003 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)));
22004 }
22005 push(p5);
22006 if (generalTransform) {
22007 originalexpanding = expanding;
22008 expanding = false;
22009 }
22010 Eval();
22011 if (generalTransform) {
22012 expanding = originalexpanding;
22013 }
22014 if (DEBUG) {
22015 console.log(" comparing " + stack[tos - 1] + " to: " + stack[tos - 2]);
22016 }
22017 subtract();
22018 p1 = pop();
22019 if (iszero(p1)) {
22020 if (DEBUG) {
22021 console.log("binding METAA to " + get_binding(symbol(METAA)));
22022 console.log("binding METAB to " + get_binding(symbol(METAB)));
22023 console.log("binding METAX to " + get_binding(symbol(METAX)));
22024 console.log("comparing " + p3 + " to: " + p5);
22025 }
22026 return 1;
22027 }
22028 }
22029 }
22030 return 0;
22031 };
22032
22033 Eval_transpose = function() {
22034 push(cadr(p1));
22035 Eval();
22036 if (cddr(p1) === symbol(NIL)) {
22037 push_integer(1);
22038 push_integer(2);
22039 } else {
22040 push(caddr(p1));
22041 Eval();
22042 push(cadddr(p1));
22043 Eval();
22044 }
22045 return transpose();
22046 };
22047
22048 transpose = function() {
22049 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;
22050 i = 0;
22051 j = 0;
22052 k = 0;
22053 l = 0;
22054 m = 0;
22055 ndim = 0;
22056 nelem = 0;
22057 t = 0;
22058 ai = [];
22059 an = [];
22060 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22061 ai[i] = 0;
22062 an[i] = 0;
22063 }
22064 save();
22065 p3 = pop();
22066 p2 = pop();
22067 p1 = pop();
22068 if (isnum(p1)) {
22069 push(p1);
22070 restore();
22071 return;
22072 }
22073 if ((isplusone(p2) && isplustwo(p3)) || (isplusone(p3) && isplustwo(p2))) {
22074 if (isidentitymatrix(p1)) {
22075 push(p1);
22076 restore();
22077 return;
22078 }
22079 }
22080 if (istranspose(p1)) {
22081 innerTranspSwitch1 = car(cdr(cdr(p1)));
22082 innerTranspSwitch2 = car(cdr(cdr(cdr(p1))));
22083 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))))) {
22084 push(car(cdr(p1)));
22085 restore();
22086 return;
22087 }
22088 }
22089 if (expanding && isadd(p1)) {
22090 p1 = cdr(p1);
22091 push(zero);
22092 while (iscons(p1)) {
22093 push(car(p1));
22094 push(p2);
22095 push(p3);
22096 transpose();
22097 add();
22098 p1 = cdr(p1);
22099 }
22100 restore();
22101 return;
22102 }
22103 if (expanding && ismultiply(p1)) {
22104 p1 = cdr(p1);
22105 push(one);
22106 while (iscons(p1)) {
22107 push(car(p1));
22108 push(p2);
22109 push(p3);
22110 transpose();
22111 multiply();
22112 p1 = cdr(p1);
22113 }
22114 restore();
22115 return;
22116 }
22117 if (expanding && isinnerordot(p1)) {
22118 p1 = cdr(p1);
22119 accumulator = [];
22120 while (iscons(p1)) {
22121 accumulator.push([car(p1), p2, p3]);
22122 p1 = cdr(p1);
22123 }
22124 for (eachEntry = m1 = ref3 = accumulator.length - 1; ref3 <= 0 ? m1 <= 0 : m1 >= 0; eachEntry = ref3 <= 0 ? ++m1 : --m1) {
22125 push(accumulator[eachEntry][0]);
22126 push(accumulator[eachEntry][1]);
22127 push(accumulator[eachEntry][2]);
22128 transpose();
22129 if (eachEntry !== accumulator.length - 1) {
22130 inner();
22131 }
22132 }
22133 restore();
22134 return;
22135 }
22136 if (!istensor(p1)) {
22137 if (!iszero(p1)) {
22138 push_symbol(TRANSPOSE);
22139 push(p1);
22140 if ((!isplusone(p2) || !isplustwo(p3)) && (!isplusone(p3) || !isplustwo(p2))) {
22141 push(p2);
22142 push(p3);
22143 list(4);
22144 } else {
22145 list(2);
22146 }
22147 restore();
22148 return;
22149 }
22150 push(zero);
22151 restore();
22152 return;
22153 }
22154 ndim = p1.tensor.ndim;
22155 nelem = p1.tensor.nelem;
22156 if (ndim === 1) {
22157 push(p1);
22158 restore();
22159 return;
22160 }
22161 push(p2);
22162 l = pop_integer();
22163 push(p3);
22164 m = pop_integer();
22165 if (l < 1 || l > ndim || m < 1 || m > ndim) {
22166 stop("transpose: index out of range");
22167 }
22168 l--;
22169 m--;
22170 p2 = alloc_tensor(nelem);
22171 p2.tensor.ndim = ndim;
22172 for (i = n1 = 0, ref4 = ndim; 0 <= ref4 ? n1 < ref4 : n1 > ref4; i = 0 <= ref4 ? ++n1 : --n1) {
22173 p2.tensor.dim[i] = p1.tensor.dim[i];
22174 }
22175 p2.tensor.dim[l] = p1.tensor.dim[m];
22176 p2.tensor.dim[m] = p1.tensor.dim[l];
22177 a = p1.tensor.elem;
22178 b = p2.tensor.elem;
22179 for (i = o1 = 0, ref5 = ndim; 0 <= ref5 ? o1 < ref5 : o1 > ref5; i = 0 <= ref5 ? ++o1 : --o1) {
22180 ai[i] = 0;
22181 an[i] = p1.tensor.dim[i];
22182 }
22183 for (i = q1 = 0, ref6 = nelem; 0 <= ref6 ? q1 < ref6 : q1 > ref6; i = 0 <= ref6 ? ++q1 : --q1) {
22184 t = ai[l];
22185 ai[l] = ai[m];
22186 ai[m] = t;
22187 t = an[l];
22188 an[l] = an[m];
22189 an[m] = t;
22190 k = 0;
22191 for (j = r1 = 0, ref7 = ndim; 0 <= ref7 ? r1 < ref7 : r1 > ref7; j = 0 <= ref7 ? ++r1 : --r1) {
22192 k = (k * an[j]) + ai[j];
22193 }
22194 t = ai[l];
22195 ai[l] = ai[m];
22196 ai[m] = t;
22197 t = an[l];
22198 an[l] = an[m];
22199 an[m] = t;
22200 b[k] = a[i];
22201 for (j = s1 = ref8 = ndim - 1; ref8 <= 0 ? s1 <= 0 : s1 >= 0; j = ref8 <= 0 ? ++s1 : --s1) {
22202 if (++ai[j] < an[j]) {
22203 break;
22204 }
22205 ai[j] = 0;
22206 }
22207 }
22208 push(p2);
22209 return restore();
22210 };
22211
22212
22213 /* d =====================================================================
22214
22215 Tags
22216 ----
22217 scripting, JS, internal, treenode, general concept
22218
22219 Parameters
22220 ----------
22221 f,x
22222
22223 General description
22224 -------------------
22225 Returns the partial derivative of f with respect to x. x can be a vector e.g. [x,y].
22226 */
22227
22228 Eval_user_function = function() {
22229 var bodyAndFormalArguments, h;
22230 if (DEBUG) {
22231 console.log("Eval_user_function evaluating: " + car(p1));
22232 }
22233 if (car(p1) === symbol(SYMBOL_D) && get_binding(symbol(SYMBOL_D)) === symbol(SYMBOL_D)) {
22234 Eval_derivative();
22235 return;
22236 }
22237 push(car(p1));
22238 Eval();
22239 bodyAndFormalArguments = pop();
22240 p3 = car(cdr(bodyAndFormalArguments));
22241 p4 = car(cdr(cdr(bodyAndFormalArguments)));
22242 p5 = cdr(p1);
22243 if (bodyAndFormalArguments === car(p1)) {
22244 h = tos;
22245 push(bodyAndFormalArguments);
22246 p1 = p5;
22247 while (iscons(p1)) {
22248 push(car(p1));
22249 Eval();
22250 p1 = cdr(p1);
22251 }
22252 list(tos - h);
22253 return;
22254 }
22255 p1 = p4;
22256 p2 = p5;
22257 h = tos;
22258 while (iscons(p1) && iscons(p2)) {
22259 push(car(p1));
22260 push(car(p2));
22261 p1 = cdr(p1);
22262 p2 = cdr(p2);
22263 }
22264 list(tos - h);
22265 p6 = pop();
22266 push(p3);
22267 if (iscons(p6)) {
22268 push(p6);
22269 rewrite_args();
22270 }
22271 return Eval();
22272 };
22273
22274 rewrite_args = function() {
22275 var h, n;
22276 n = 0;
22277 save();
22278 p2 = pop();
22279 p1 = pop();
22280 if (istensor(p1)) {
22281 n = rewrite_args_tensor();
22282 restore();
22283 return n;
22284 }
22285 if (iscons(p1)) {
22286 h = tos;
22287 if (car(p1) === car(p2)) {
22288 push_symbol(EVAL);
22289 push(car(cdr(p2)));
22290 list(2);
22291 } else {
22292 push(car(p1));
22293 }
22294 p1 = cdr(p1);
22295 while (iscons(p1)) {
22296 push(car(p1));
22297 push(p2);
22298 n += rewrite_args();
22299 p1 = cdr(p1);
22300 }
22301 list(tos - h);
22302 restore();
22303 return n;
22304 }
22305 if (!issymbol(p1)) {
22306 push(p1);
22307 restore();
22308 return 0;
22309 }
22310 p3 = p2;
22311 while (iscons(p3)) {
22312 if (p1 === car(p3)) {
22313 push(cadr(p3));
22314 restore();
22315 return 1;
22316 }
22317 p3 = cddr(p3);
22318 }
22319 p3 = get_binding(p1);
22320 push(p3);
22321 if (p1 !== p3) {
22322 push(p2);
22323 n = rewrite_args();
22324 if (n === 0) {
22325 pop();
22326 push(p1);
22327 }
22328 }
22329 restore();
22330 return n;
22331 };
22332
22333 rewrite_args_tensor = function() {
22334 var i, l1, n, ref2;
22335 n = 0;
22336 i = 0;
22337 push(p1);
22338 copy_tensor();
22339 p1 = pop();
22340 for (i = l1 = 0, ref2 = p1.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22341 push(p1.tensor.elem[i]);
22342 push(p2);
22343 n += rewrite_args();
22344 p1.tensor.elem[i] = pop();
22345 }
22346 check_tensor_dimensions(p1);
22347 push(p1);
22348 return n;
22349 };
22350
22351 Eval_zero = function() {
22352 var i, k, l1, m, m1, n, ref2, ref3;
22353 i = 0;
22354 k = [];
22355 m = 0;
22356 n = 0;
22357 for (i = l1 = 0, ref2 = MAXDIM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22358 k[i] = 0;
22359 }
22360 m = 1;
22361 n = 0;
22362 p2 = cdr(p1);
22363 while (iscons(p2)) {
22364 push(car(p2));
22365 Eval();
22366 i = pop_integer();
22367 if (i < 1 || isNaN(i)) {
22368 push(zero);
22369 return;
22370 }
22371 m *= i;
22372 k[n++] = i;
22373 p2 = cdr(p2);
22374 }
22375 if (n === 0) {
22376 push(zero);
22377 return;
22378 }
22379 p1 = alloc_tensor(m);
22380 p1.tensor.ndim = n;
22381 for (i = m1 = 0, ref3 = n; 0 <= ref3 ? m1 < ref3 : m1 > ref3; i = 0 <= ref3 ? ++m1 : --m1) {
22382 p1.tensor.dim[i] = k[i];
22383 }
22384 return push(p1);
22385 };
22386
22387
22388 /*
22389 // up to 100 blocks of 100,000 atoms
22390
22391 #define M 100
22392 #define N 100000
22393
22394 U *mem[M]
22395 int mcount
22396
22397 U *free_list
22398 int free_count
22399
22400 U *
22401 alloc(void)
22402 {
22403 U *p
22404 if (free_count == 0) {
22405 if (mcount == 0)
22406 alloc_mem()
22407 else {
22408 gc()
22409 if (free_count < N * mcount / 2)
22410 alloc_mem()
22411 }
22412 if (free_count == 0)
22413 stop("atom space exhausted")
22414 }
22415 p = free_list
22416 free_list = free_list->u.cons.cdr
22417 free_count--
22418 return p
22419 }
22420 */
22421
22422 allocatedId = 0;
22423
22424 alloc_tensor = function(nelem) {
22425 var i, l1, p, ref2;
22426 i = 0;
22427 p = new U();
22428 p.k = TENSOR;
22429 p.tensor = new tensor();
22430 p.tensor.nelem = nelem;
22431 for (i = l1 = 0, ref2 = nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22432 p.tensor.elem[i] = zero;
22433 }
22434 p.tensor.allocatedId = allocatedId;
22435 allocatedId++;
22436 check_tensor_dimensions(p);
22437 return p;
22438 };
22439
22440
22441 /*
22442 // garbage collector
22443
22444 void
22445 gc(void)
22446 {
22447 int i, j
22448 U *p
22449
22450 // tag everything
22451
22452 for (i = 0; i < mcount; i++) {
22453 p = mem[i]
22454 for (j = 0; j < N; j++)
22455 p[j].tag = 1
22456 }
22457
22458 // untag what's used
22459
22460 untag(p0)
22461 untag(p1)
22462 untag(p2)
22463 untag(p3)
22464 untag(p4)
22465 untag(p5)
22466 untag(p6)
22467 untag(p7)
22468 untag(p8)
22469 untag(p9)
22470
22471 untag(one)
22472 untag(zero)
22473 untag(imaginaryunit)
22474
22475 for (i = 0; i < NSYM; i++) {
22476 untag(binding[i])
22477 untag(arglist[i])
22478 }
22479
22480 for (i = 0; i < tos; i++)
22481 untag(stack[i])
22482
22483 for (i = (int) (frame - stack); i < TOS; i++)
22484 untag(stack[i])
22485
22486 // collect everything that's still tagged
22487
22488 free_count = 0
22489
22490 for (i = 0; i < mcount; i++) {
22491 p = mem[i]
22492 for (j = 0; j < N; j++) {
22493 if (p[j].tag == 0)
22494 continue
22495 // still tagged so it's unused, put on free list
22496 switch (p[j].k) {
22497 case TENSOR:
22498 free(p[j].u.tensor)
22499 break
22500 case STR:
22501 free(p[j].u.str)
22502 break
22503 case NUM:
22504 mfree(p[j].u.q.a)
22505 mfree(p[j].u.q.b)
22506 break
22507 }
22508 p[j].k = CONS; // so no double free occurs above
22509 p[j].u.cons.cdr = free_list
22510 free_list = p + j
22511 free_count++
22512 }
22513 }
22514 }
22515
22516 void
22517 untag(U *p)
22518 {
22519 int i
22520
22521 if (iscons(p)) {
22522 do {
22523 if (p->tag == 0)
22524 return
22525 p->tag = 0
22526 untag(p->u.cons.car)
22527 p = p->u.cons.cdr
22528 } while (iscons(p))
22529 untag(p)
22530 return
22531 }
22532
22533 if (p->tag) {
22534 p->tag = 0
22535 if (istensor(p)) {
22536 for (i = 0; i < p->u.tensor->nelem; i++)
22537 untag(p->u.tensor->elem[i])
22538 }
22539 }
22540 }
22541
22542 // get memory for 100,000 atoms
22543
22544 void
22545 alloc_mem(void)
22546 {
22547 int i
22548 U *p
22549 if (mcount == M)
22550 return
22551 p = (U *) malloc(N * sizeof (struct U))
22552 if (p == NULL)
22553 return
22554 mem[mcount++] = p
22555 for (i = 0; i < N; i++) {
22556 p[i].k = CONS; // so no free in gc
22557 p[i].u.cons.cdr = p + i + 1
22558 }
22559 p[N - 1].u.cons.cdr = free_list
22560 free_list = p
22561 free_count += N
22562 }
22563
22564 void
22565 print_mem_info(void)
22566 {
22567 char buf[100]
22568
22569 sprintf(buf, "%d blocks (%d bytes/block)\n", N * mcount, (int) sizeof (U))
22570 printstr(buf)
22571
22572 sprintf(buf, "%d free\n", free_count)
22573 printstr(buf)
22574
22575 sprintf(buf, "%d used\n", N * mcount - free_count)
22576 printstr(buf)
22577 }
22578 */
22579
22580 Find = function(p, q) {
22581 var i, l1, ref2;
22582 i = 0;
22583 if (equal(p, q)) {
22584 return 1;
22585 }
22586 if (istensor(p)) {
22587 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22588 if (Find(p.tensor.elem[i], q)) {
22589 return 1;
22590 }
22591 }
22592 return 0;
22593 }
22594 while (iscons(p)) {
22595 if (Find(car(p), q)) {
22596 return 1;
22597 }
22598 p = cdr(p);
22599 }
22600 return 0;
22601 };
22602
22603 findPossibleClockForm = function(p) {
22604 var i, l1, ref2;
22605 i = 0;
22606 if (isimaginaryunit(p)) {
22607 return 0;
22608 }
22609 if (car(p) === symbol(POWER) && !isinteger(caddr(p1))) {
22610 if (Find(cadr(p), imaginaryunit)) {
22611 return 1;
22612 }
22613 }
22614 if (car(p) === symbol(POWER) && equaln(cadr(p), -1) && !isinteger(caddr(p1))) {
22615 return 1;
22616 }
22617 if (istensor(p)) {
22618 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22619 if (findPossibleClockForm(p.tensor.elem[i])) {
22620 return 1;
22621 }
22622 }
22623 return 0;
22624 }
22625 while (iscons(p)) {
22626 if (findPossibleClockForm(car(p))) {
22627 return 1;
22628 }
22629 p = cdr(p);
22630 }
22631 return 0;
22632 };
22633
22634 findPossibleExponentialForm = function(p) {
22635 var i, l1, ref2;
22636 i = 0;
22637 if (car(p) === symbol(POWER) && cadr(p) === symbol(E)) {
22638 return Find(caddr(p), imaginaryunit);
22639 }
22640 if (istensor(p)) {
22641 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22642 if (findPossibleExponentialForm(p.tensor.elem[i])) {
22643 return 1;
22644 }
22645 }
22646 return 0;
22647 }
22648 while (iscons(p)) {
22649 if (findPossibleExponentialForm(car(p))) {
22650 return 1;
22651 }
22652 p = cdr(p);
22653 }
22654 return 0;
22655 };
22656
22657 $.Find = Find;
22658
22659 init = function() {
22660 var i, l1, ref2;
22661 i = 0;
22662 flag = 0;
22663 reset_after_error();
22664 chainOfUserSymbolsNotFunctionsBeingEvaluated = [];
22665 if (flag) {
22666 return;
22667 }
22668 flag = 1;
22669 for (i = l1 = 0, ref2 = NSYM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
22670 symtab[i] = new U();
22671 symtab[i].k = SYM;
22672 binding[i] = symtab[i];
22673 isSymbolReclaimable[i] = false;
22674 }
22675 return defn();
22676 };
22677
22678
22679 /* cross =====================================================================
22680
22681 Tags
22682 ----
22683 scripting, JS, internal, treenode, general concept, script_defined
22684
22685 Parameters
22686 ----------
22687 u,v
22688
22689 General description
22690 -------------------
22691 Returns the cross product of vectors u and v.
22692 */
22693
22694
22695 /* curl =====================================================================
22696
22697 Tags
22698 ----
22699 scripting, JS, internal, treenode, general concept, script_defined
22700
22701 Parameters
22702 ----------
22703 u
22704
22705 General description
22706 -------------------
22707 Returns the curl of vector u.
22708 */
22709
22710 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)"];
22711
22712 defn = function() {
22713 var definitionOfInterest, defn_i, l1, originalCodeGen, ref2;
22714 p0 = symbol(NIL);
22715 p1 = symbol(NIL);
22716 p2 = symbol(NIL);
22717 p3 = symbol(NIL);
22718 p4 = symbol(NIL);
22719 p5 = symbol(NIL);
22720 p6 = symbol(NIL);
22721 p7 = symbol(NIL);
22722 p8 = symbol(NIL);
22723 p9 = symbol(NIL);
22724 std_symbol("abs", ABS);
22725 std_symbol("add", ADD);
22726 std_symbol("adj", ADJ);
22727 std_symbol("and", AND);
22728 std_symbol("approxratio", APPROXRATIO);
22729 std_symbol("arccos", ARCCOS);
22730 std_symbol("arccosh", ARCCOSH);
22731 std_symbol("arcsin", ARCSIN);
22732 std_symbol("arcsinh", ARCSINH);
22733 std_symbol("arctan", ARCTAN);
22734 std_symbol("arctanh", ARCTANH);
22735 std_symbol("arg", ARG);
22736 std_symbol("atomize", ATOMIZE);
22737 std_symbol("besselj", BESSELJ);
22738 std_symbol("bessely", BESSELY);
22739 std_symbol("binding", BINDING);
22740 std_symbol("binomial", BINOMIAL);
22741 std_symbol("ceiling", CEILING);
22742 std_symbol("check", CHECK);
22743 std_symbol("choose", CHOOSE);
22744 std_symbol("circexp", CIRCEXP);
22745 std_symbol("clear", CLEAR);
22746 std_symbol("clearall", CLEARALL);
22747 std_symbol("clearpatterns", CLEARPATTERNS);
22748 std_symbol("clock", CLOCK);
22749 std_symbol("coeff", COEFF);
22750 std_symbol("cofactor", COFACTOR);
22751 std_symbol("condense", CONDENSE);
22752 std_symbol("conj", CONJ);
22753 std_symbol("contract", CONTRACT);
22754 std_symbol("cos", COS);
22755 std_symbol("cosh", COSH);
22756 std_symbol("decomp", DECOMP);
22757 std_symbol("defint", DEFINT);
22758 std_symbol("deg", DEGREE);
22759 std_symbol("denominator", DENOMINATOR);
22760 std_symbol("det", DET);
22761 std_symbol("derivative", DERIVATIVE);
22762 std_symbol("dim", DIM);
22763 std_symbol("dirac", DIRAC);
22764 std_symbol("divisors", DIVISORS);
22765 std_symbol("do", DO);
22766 std_symbol("dot", DOT);
22767 std_symbol("draw", DRAW);
22768 std_symbol("dsolve", DSOLVE);
22769 std_symbol("erf", ERF);
22770 std_symbol("erfc", ERFC);
22771 std_symbol("eigen", EIGEN);
22772 std_symbol("eigenval", EIGENVAL);
22773 std_symbol("eigenvec", EIGENVEC);
22774 std_symbol("eval", EVAL);
22775 std_symbol("exp", EXP);
22776 std_symbol("expand", EXPAND);
22777 std_symbol("expcos", EXPCOS);
22778 std_symbol("expsin", EXPSIN);
22779 std_symbol("factor", FACTOR);
22780 std_symbol("factorial", FACTORIAL);
22781 std_symbol("factorpoly", FACTORPOLY);
22782 std_symbol("filter", FILTER);
22783 std_symbol("float", FLOATF);
22784 std_symbol("floor", FLOOR);
22785 std_symbol("for", FOR);
22786 std_symbol("function", FUNCTION);
22787 std_symbol("Gamma", GAMMA);
22788 std_symbol("gcd", GCD);
22789 std_symbol("hermite", HERMITE);
22790 std_symbol("hilbert", HILBERT);
22791 std_symbol("imag", IMAG);
22792 std_symbol("component", INDEX);
22793 std_symbol("inner", INNER);
22794 std_symbol("integral", INTEGRAL);
22795 std_symbol("inv", INV);
22796 std_symbol("invg", INVG);
22797 std_symbol("isinteger", ISINTEGER);
22798 std_symbol("isprime", ISPRIME);
22799 std_symbol("laguerre", LAGUERRE);
22800 std_symbol("lcm", LCM);
22801 std_symbol("leading", LEADING);
22802 std_symbol("legendre", LEGENDRE);
22803 std_symbol("log", LOG);
22804 std_symbol("lookup", LOOKUP);
22805 std_symbol("mod", MOD);
22806 std_symbol("multiply", MULTIPLY);
22807 std_symbol("not", NOT);
22808 std_symbol("nroots", NROOTS);
22809 std_symbol("number", NUMBER);
22810 std_symbol("numerator", NUMERATOR);
22811 std_symbol("operator", OPERATOR);
22812 std_symbol("or", OR);
22813 std_symbol("outer", OUTER);
22814 std_symbol("pattern", PATTERN);
22815 std_symbol("patternsinfo", PATTERNSINFO);
22816 std_symbol("polar", POLAR);
22817 std_symbol("power", POWER);
22818 std_symbol("prime", PRIME);
22819 std_symbol("print", PRINT);
22820 std_symbol("print2dascii", PRINT2DASCII);
22821 std_symbol("printfull", PRINTFULL);
22822 std_symbol("printlatex", PRINTLATEX);
22823 std_symbol("printlist", PRINTLIST);
22824 std_symbol("printplain", PRINTPLAIN);
22825 std_symbol("printLeaveEAlone", PRINT_LEAVE_E_ALONE);
22826 std_symbol("printLeaveXAlone", PRINT_LEAVE_X_ALONE);
22827 std_symbol("product", PRODUCT);
22828 std_symbol("quote", QUOTE);
22829 std_symbol("quotient", QUOTIENT);
22830 std_symbol("rank", RANK);
22831 std_symbol("rationalize", RATIONALIZE);
22832 std_symbol("real", REAL);
22833 std_symbol("rect", YYRECT);
22834 std_symbol("roots", ROOTS);
22835 std_symbol("round", ROUND);
22836 std_symbol("equals", SETQ);
22837 std_symbol("sgn", SGN);
22838 std_symbol("silentpattern", SILENTPATTERN);
22839 std_symbol("simplify", SIMPLIFY);
22840 std_symbol("sin", SIN);
22841 std_symbol("sinh", SINH);
22842 std_symbol("shape", SHAPE);
22843 std_symbol("sqrt", SQRT);
22844 std_symbol("stop", STOP);
22845 std_symbol("subst", SUBST);
22846 std_symbol("sum", SUM);
22847 std_symbol("symbolsinfo", SYMBOLSINFO);
22848 std_symbol("tan", TAN);
22849 std_symbol("tanh", TANH);
22850 std_symbol("taylor", TAYLOR);
22851 std_symbol("test", TEST);
22852 std_symbol("testeq", TESTEQ);
22853 std_symbol("testge", TESTGE);
22854 std_symbol("testgt", TESTGT);
22855 std_symbol("testle", TESTLE);
22856 std_symbol("testlt", TESTLT);
22857 std_symbol("transpose", TRANSPOSE);
22858 std_symbol("unit", UNIT);
22859 std_symbol("zero", ZERO);
22860 std_symbol("nil", NIL);
22861 std_symbol("autoexpand", AUTOEXPAND);
22862 std_symbol("bake", BAKE);
22863 std_symbol("assumeRealVariables", ASSUME_REAL_VARIABLES);
22864 std_symbol("last", LAST);
22865 std_symbol("lastprint", LAST_PRINT);
22866 std_symbol("last2dasciiprint", LAST_2DASCII_PRINT);
22867 std_symbol("lastfullprint", LAST_FULL_PRINT);
22868 std_symbol("lastlatexprint", LAST_LATEX_PRINT);
22869 std_symbol("lastlistprint", LAST_LIST_PRINT);
22870 std_symbol("lastplainprint", LAST_PLAIN_PRINT);
22871 std_symbol("trace", TRACE);
22872 std_symbol("~", YYE);
22873 std_symbol("$DRAWX", DRAWX);
22874 std_symbol("$METAA", METAA);
22875 std_symbol("$METAB", METAB);
22876 std_symbol("$METAX", METAX);
22877 std_symbol("$SECRETX", SECRETX);
22878 std_symbol("version", VERSION);
22879 std_symbol("pi", PI);
22880 std_symbol("a", SYMBOL_A);
22881 std_symbol("b", SYMBOL_B);
22882 std_symbol("c", SYMBOL_C);
22883 std_symbol("d", SYMBOL_D);
22884 std_symbol("i", SYMBOL_I);
22885 std_symbol("j", SYMBOL_J);
22886 std_symbol("n", SYMBOL_N);
22887 std_symbol("r", SYMBOL_R);
22888 std_symbol("s", SYMBOL_S);
22889 std_symbol("t", SYMBOL_T);
22890 std_symbol("x", SYMBOL_X);
22891 std_symbol("y", SYMBOL_Y);
22892 std_symbol("z", SYMBOL_Z);
22893 std_symbol("I", SYMBOL_IDENTITY_MATRIX);
22894 std_symbol("a_", SYMBOL_A_UNDERSCORE);
22895 std_symbol("b_", SYMBOL_B_UNDERSCORE);
22896 std_symbol("x_", SYMBOL_X_UNDERSCORE);
22897 std_symbol("$C1", C1);
22898 std_symbol("$C2", C2);
22899 std_symbol("$C3", C3);
22900 std_symbol("$C4", C4);
22901 std_symbol("$C5", C5);
22902 std_symbol("$C6", C6);
22903 defineSomeHandyConstants();
22904 originalCodeGen = codeGen;
22905 codeGen = false;
22906 for (defn_i = l1 = 0, ref2 = defn_str.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; defn_i = 0 <= ref2 ? ++l1 : --l1) {
22907 definitionOfInterest = defn_str[defn_i];
22908 scan(definitionOfInterest);
22909 if (DEBUG) {
22910 console.log("... evaling " + definitionOfInterest);
22911 console.log("top of stack:");
22912 console.log(print_list(stack[tos - 1]));
22913 }
22914 Eval();
22915 pop();
22916 }
22917 return codeGen = originalCodeGen;
22918 };
22919
22920 defineSomeHandyConstants = function() {
22921 push_integer(0);
22922 zero = pop();
22923 push_integer(1);
22924 one = pop();
22925 push_double(1.0);
22926 one_as_double = pop();
22927 push_symbol(POWER);
22928 if (DEBUG) {
22929 console.log(print_list(stack[tos - 1]));
22930 }
22931 push_integer(-1);
22932 if (DEBUG) {
22933 console.log(print_list(stack[tos - 1]));
22934 }
22935 push_rational(1, 2);
22936 if (DEBUG) {
22937 console.log(print_list(stack[tos - 1]));
22938 }
22939 list(3);
22940 if (DEBUG) {
22941 console.log(print_list(stack[tos - 1]));
22942 }
22943 return imaginaryunit = pop();
22944 };
22945
22946 mcmp = function(a, b) {
22947 return a.compare(b);
22948 };
22949
22950 mcmpint = function(a, n) {
22951 var b, t;
22952 b = bigInt(n);
22953 t = mcmp(a, b);
22954 return t;
22955 };
22956
22957
22958 /*
22959 #if SELFTEST
22960
22961 void
22962 test_mcmp(void)
22963 {
22964 int i, j, k
22965 unsigned int *x, *y
22966 logout("testing mcmp\n")
22967 for (i = -1000; i < 1000; i++) {
22968 x = mint(i)
22969 for (j = -1000; j < 1000; j++) {
22970 y = mint(j)
22971 k = mcmp(x, y)
22972 if (i == j && k != 0) {
22973 logout("failed\n")
22974 errout()
22975 }
22976 if (i < j && k != -1) {
22977 logout("failed\n")
22978 errout()
22979 }
22980 if (i > j && k != 1) {
22981 logout("failed\n")
22982 errout()
22983 }
22984 mfree(y)
22985 }
22986 mfree(x)
22987 }
22988 logout("ok\n")
22989 }
22990
22991 #endif
22992 */
22993
22994 strcmp = function(str1, str2) {
22995 if (str1 === str2) {
22996 return 0;
22997 } else if (str1 > str2) {
22998 return 1;
22999 } else {
23000 return -1;
23001 }
23002 };
23003
23004 doubleToReasonableString = function(d) {
23005 var stringRepresentation;
23006 if (codeGen) {
23007 return d + "";
23008 }
23009 stringRepresentation = "" + parseFloat(d.toPrecision(6));
23010 if (stringRepresentation.indexOf(".") === -1) {
23011 stringRepresentation += ".0";
23012 }
23013 return stringRepresentation;
23014 };
23015
23016 clear_term = function() {};
23017
23018 isspace = function(s) {
23019 if (s == null) {
23020 return false;
23021 }
23022 return s === ' ' || s === '\t' || s === '\n' || s === '\v' || s === '\f' || s === '\r';
23023 };
23024
23025 isdigit = function(str) {
23026 if (str == null) {
23027 return false;
23028 }
23029 return /^\d+$/.test(str);
23030 };
23031
23032 isalpha = function(str) {
23033 if (str == null) {
23034 return false;
23035 }
23036 return str.search(/[^A-Za-z]/) === -1;
23037 };
23038
23039 isalphaOrUnderscore = function(str) {
23040 if (str == null) {
23041 return false;
23042 }
23043 return str.search(/[^A-Za-z_]/) === -1;
23044 };
23045
23046 isunderscore = function(str) {
23047 if (str == null) {
23048 return false;
23049 }
23050 return str.search(/_/) === -1;
23051 };
23052
23053 isalnumorunderscore = function(str) {
23054 if (str == null) {
23055 return false;
23056 }
23057 return isalphaOrUnderscore(str) || isdigit(str);
23058 };
23059
23060 count = function(p) {
23061 var n;
23062 if (iscons(p)) {
23063 n = 0;
23064 while (iscons(p)) {
23065 n += count(car(p)) + 1;
23066 p = cdr(p);
23067 }
23068 } else {
23069 n = 1;
23070 }
23071 return n;
23072 };
23073
23074 countOccurrencesOfSymbol = function(needle, p) {
23075 var n;
23076 n = 0;
23077 if (iscons(p)) {
23078 while (iscons(p)) {
23079 n += countOccurrencesOfSymbol(needle, car(p));
23080 p = cdr(p);
23081 }
23082 } else {
23083 if (equal(needle, p)) {
23084 n = 1;
23085 }
23086 }
23087 return n;
23088 };
23089
23090 countsize = function(p) {
23091 var i, l1, n, ref2;
23092 n = 0;
23093 if (istensor(p)) {
23094 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
23095 n += p.tensor.elem[i];
23096 }
23097 } else if (iscons(p)) {
23098 while (iscons(p)) {
23099 n += count(car(p)) + 1;
23100 p = cdr(p);
23101 }
23102 } else {
23103 n = 1;
23104 }
23105 return n;
23106 };
23107
23108 stop = function(s) {
23109 var message;
23110 errorMessage += "Stop: ";
23111 errorMessage += s;
23112 message = errorMessage;
23113 errorMessage = '';
23114 moveTos(0);
23115 throw new Error(message);
23116 };
23117
23118 findDependenciesInScript = function(stringToBeParsed, dontGenerateCode) {
23119 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;
23120 if (DEBUG) {
23121 console.log("stringToBeParsed: " + stringToBeParsed);
23122 }
23123 timeStartFromAlgebra = new Date().getTime();
23124 if (CACHE_DEBUGS || CACHE_HITSMISS_DEBUGS || TIMING_DEBUGS) {
23125 console.log(" --------- findDependenciesInScript input: " + stringToBeParsed + " at: " + (new Date()));
23126 currentStateHash = getStateHash();
23127 console.log("state hash: " + currentStateHash);
23128 }
23129 inited = true;
23130 codeGen = true;
23131 symbolsDependencies = {};
23132 symbolsHavingReassignments = [];
23133 symbolsInExpressionsWithoutAssignments = [];
23134 patternHasBeenFound = false;
23135 indexOfPartRemainingToBeParsed = 0;
23136 allReturnedPlainStrings = "";
23137 allReturnedLatexStrings = "";
23138 n = 0;
23139 dependencyInfo = {
23140 affectsVariables: [],
23141 affectedBy: []
23142 };
23143 stringToBeRun = stringToBeParsed;
23144 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23145 currentStateHash = getStateHash();
23146 cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun + " - " + dontGenerateCode;
23147 if (CACHE_DEBUGS) {
23148 console.log("cached_findDependenciesInScript key: " + cacheKey);
23149 }
23150 possiblyCached = cached_findDependenciesInScript.get(cacheKey);
23151 if (possiblyCached != null) {
23152 if (CACHE_HITSMISS_DEBUGS) {
23153 console.log("cached_findDependenciesInScript hit on " + stringToBeRun);
23154 }
23155 unfreeze(possiblyCached);
23156 if (TIMING_DEBUGS) {
23157 totalTime = new Date().getTime() - timeStartFromAlgebra;
23158 console.log("findDependenciesInScript input: " + stringToBeRun + " time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length - 5] - totalTime) + "ms due to cache hit");
23159 }
23160 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]];
23161 } else {
23162 if (CACHE_HITSMISS_DEBUGS) {
23163 console.log("cached_findDependenciesInScript miss on: " + stringToBeRun);
23164 }
23165 if (TIMING_DEBUGS) {
23166 cacheMissPenalty = new Date().getTime() - timeStartFromAlgebra;
23167 }
23168 }
23169 }
23170 while (1) {
23171 try {
23172 errorMessage = "";
23173 check_stack();
23174 if (DEBUG) {
23175 console.log("findDependenciesInScript: scanning");
23176 }
23177 n = scan(stringToBeParsed.substring(indexOfPartRemainingToBeParsed));
23178 if (DEBUG) {
23179 console.log("scanned");
23180 }
23181 pop();
23182 check_stack();
23183 } catch (error1) {
23184 error = error1;
23185 if (PRINTOUTRESULT) {
23186 console.log(error);
23187 }
23188 errorMessage = error + "";
23189 reset_after_error();
23190 break;
23191 }
23192 if (n === 0) {
23193 break;
23194 }
23195 indexOfPartRemainingToBeParsed += n;
23196 }
23197 testableString = "";
23198 if (DEBUG) {
23199 console.log("all local dependencies ----------------");
23200 }
23201 testableString += "All local dependencies: ";
23202 for (key in symbolsDependencies) {
23203 value = symbolsDependencies[key];
23204 if (DEBUG) {
23205 console.log("variable " + key + " depends on: ");
23206 }
23207 dependencyInfo.affectsVariables.push(key);
23208 testableString += " variable " + key + " depends on: ";
23209 for (l1 = 0, len = value.length; l1 < len; l1++) {
23210 i = value[l1];
23211 if (DEBUG) {
23212 console.log(" " + i);
23213 }
23214 if (i[0] !== "'") {
23215 dependencyInfo.affectedBy.push(i);
23216 }
23217 testableString += i + ", ";
23218 }
23219 testableString += "; ";
23220 }
23221 testableString += ". ";
23222 if (DEBUG) {
23223 console.log("Symbols with reassignments ----------------");
23224 }
23225 testableString += "Symbols with reassignments: ";
23226 for (m1 = 0, len1 = symbolsHavingReassignments.length; m1 < len1; m1++) {
23227 key = symbolsHavingReassignments[m1];
23228 if (dependencyInfo.affectedBy.indexOf(key) === -1) {
23229 dependencyInfo.affectedBy.push(key);
23230 testableString += key + ", ";
23231 }
23232 }
23233 testableString += ". ";
23234 if (DEBUG) {
23235 console.log("Symbols in expressions without assignments ----------------");
23236 }
23237 testableString += "Symbols in expressions without assignments: ";
23238 for (n1 = 0, len2 = symbolsInExpressionsWithoutAssignments.length; n1 < len2; n1++) {
23239 key = symbolsInExpressionsWithoutAssignments[n1];
23240 if (dependencyInfo.affectedBy.indexOf(key) === -1) {
23241 dependencyInfo.affectedBy.push(key);
23242 testableString += key + ", ";
23243 }
23244 }
23245 testableString += ". ";
23246 dependencyInfo.affectedBy.push("PATTERN_DEPENDENCY");
23247 if (patternHasBeenFound) {
23248 dependencyInfo.affectsVariables.push("PATTERN_DEPENDENCY");
23249 testableString += " - PATTERN_DEPENDENCY inserted - ";
23250 }
23251 if (DEBUG) {
23252 console.log("All dependencies recursively ----------------");
23253 }
23254 testableString += "All dependencies recursively: ";
23255 scriptEvaluation = ["", ""];
23256 generatedCode = "";
23257 readableSummaryOfGeneratedCode = "";
23258 if (errorMessage === "" && !dontGenerateCode) {
23259 try {
23260 allReturnedPlainStrings = "";
23261 allReturnedLatexStrings = "";
23262 scriptEvaluation = run(stringToBeParsed, true);
23263 allReturnedPlainStrings = "";
23264 allReturnedLatexStrings = "";
23265 } catch (error1) {
23266 error = error1;
23267 if (PRINTOUTRESULT) {
23268 console.log(error);
23269 }
23270 errorMessage = error + "";
23271 init();
23272 }
23273 if (errorMessage === "") {
23274 for (key in symbolsDependencies) {
23275 codeGen = true;
23276 if (DEBUG) {
23277 console.log(" variable " + key + " is: " + get_binding(usr_symbol(key)).toString());
23278 }
23279 codeGen = false;
23280 if (DEBUG) {
23281 console.log(" variable " + key + " depends on: ");
23282 }
23283 testableString += " variable " + key + " depends on: ";
23284 recursedDependencies = [];
23285 variablesWithCycles = [];
23286 cyclesDescriptions = [];
23287 recursiveDependencies(key, recursedDependencies, [], variablesWithCycles, [], cyclesDescriptions);
23288 for (o1 = 0, len3 = variablesWithCycles.length; o1 < len3; o1++) {
23289 i = variablesWithCycles[o1];
23290 if (DEBUG) {
23291 console.log(" --> cycle through " + i);
23292 }
23293 }
23294 for (q1 = 0, len4 = recursedDependencies.length; q1 < len4; q1++) {
23295 i = recursedDependencies[q1];
23296 if (DEBUG) {
23297 console.log(" " + i);
23298 }
23299 testableString += i + ", ";
23300 }
23301 testableString += "; ";
23302 for (r1 = 0, len5 = cyclesDescriptions.length; r1 < len5; r1++) {
23303 i = cyclesDescriptions[r1];
23304 testableString += " " + i + ", ";
23305 }
23306 if (DEBUG) {
23307 console.log(" code generation:" + key + " is: " + get_binding(usr_symbol(key)).toString());
23308 }
23309 push(get_binding(usr_symbol(key)));
23310 replacementsFrom = [];
23311 replacementsTo = [];
23312 for (s1 = 0, len6 = recursedDependencies.length; s1 < len6; s1++) {
23313 eachDependency = recursedDependencies[s1];
23314 if (eachDependency[0] === "'") {
23315 deQuotedDep = eachDependency.substring(1);
23316 originalUserSymbol = usr_symbol(deQuotedDep);
23317 newUserSymbol = usr_symbol("AVOID_BINDING_TO_EXTERNAL_SCOPE_VALUE" + deQuotedDep);
23318 replacementsFrom.push(originalUserSymbol);
23319 replacementsTo.push(newUserSymbol);
23320 push(originalUserSymbol);
23321 push(newUserSymbol);
23322 subst();
23323 if (DEBUG) {
23324 console.log("after substitution: " + stack[tos - 1]);
23325 }
23326 }
23327 }
23328 try {
23329 simplifyForCodeGeneration();
23330 } catch (error1) {
23331 error = error1;
23332 if (PRINTOUTRESULT) {
23333 console.log(error);
23334 }
23335 errorMessage = error + "";
23336 init();
23337 }
23338 for (indexOfEachReplacement = t1 = 0, ref2 = replacementsFrom.length; 0 <= ref2 ? t1 < ref2 : t1 > ref2; indexOfEachReplacement = 0 <= ref2 ? ++t1 : --t1) {
23339 push(replacementsTo[indexOfEachReplacement]);
23340 push(replacementsFrom[indexOfEachReplacement]);
23341 subst();
23342 }
23343 clearRenamedVariablesToAvoidBindingToExternalScope();
23344 if (errorMessage === "") {
23345 toBePrinted = pop();
23346 userVariablesMentioned = [];
23347 collectUserSymbols(toBePrinted, userVariablesMentioned);
23348 allReturnedPlainStrings = "";
23349 allReturnedLatexStrings = "";
23350 codeGen = true;
23351 generatedBody = toBePrinted.toString();
23352 codeGen = false;
23353 origPrintMode = printMode;
23354 printMode = PRINTMODE_LATEX;
23355 bodyForReadableSummaryOfGeneratedCode = toBePrinted.toString();
23356 printMode = origPrintMode;
23357 if (variablesWithCycles.indexOf(key) !== -1) {
23358 generatedCode += "// " + key + " is part of a cyclic dependency, no code generated.";
23359 readableSummaryOfGeneratedCode += "#" + key + " is part of a cyclic dependency, no code generated.";
23360 } else {
23361
23362 /*
23363 * using this paragraph instead of the following one
23364 * creates methods signatures that
23365 * are slightly less efficient
23366 * i.e. variables compare even if they are
23367 * simplified away.
23368 * In theory these signatures are more stable, but
23369 * in practice signatures vary quite a bit anyways
23370 * depending on previous assignments for example,
23371 * so it's unclear whether going for stability
23372 * is sensible at all..
23373 if recursedDependencies.length != 0
23374 parameters = "("
23375 for i in recursedDependencies
23376 if i.indexOf("'") != 0
23377 parameters += i + ", "
23378 else
23379 if recursedDependencies.indexOf(i.substring(1)) == -1
23380 parameters += i.substring(1) + ", "
23381 */
23382 userVariablesMentioned = userVariablesMentioned.filter(function(x) {
23383 return predefinedSymbolsInGlobalScope_doNotTrackInDependencies.indexOf(x + "") === -1;
23384 });
23385 userVariablesMentioned = userVariablesMentioned.filter(function(x) {
23386 return recursedDependencies.indexOf(x + "") !== -1 || recursedDependencies.indexOf("\'" + x + "") !== -1;
23387 });
23388 if (userVariablesMentioned.length !== 0) {
23389 parameters = "(";
23390 for (u1 = 0, len7 = userVariablesMentioned.length; u1 < len7; u1++) {
23391 i = userVariablesMentioned[u1];
23392 if (i.printname !== key) {
23393 parameters += i.printname + ", ";
23394 }
23395 }
23396 parameters = parameters.replace(/, $/gm, "");
23397 parameters += ")";
23398 generatedCode += key + " = function " + parameters + " { return ( " + generatedBody + " ); }";
23399 readableSummaryOfGeneratedCode += key + parameters + " = " + bodyForReadableSummaryOfGeneratedCode;
23400 } else {
23401 generatedCode += key + " = " + generatedBody + ";";
23402 readableSummaryOfGeneratedCode += key + " = " + bodyForReadableSummaryOfGeneratedCode;
23403 }
23404 }
23405 generatedCode += "\n";
23406 readableSummaryOfGeneratedCode += "\n";
23407 if (DEBUG) {
23408 console.log(" " + generatedCode);
23409 }
23410 }
23411 }
23412 }
23413 }
23414 generatedCode = generatedCode.replace(/\n$/gm, "");
23415 readableSummaryOfGeneratedCode = readableSummaryOfGeneratedCode.replace(/\n$/gm, "");
23416 symbolsDependencies = {};
23417 symbolsHavingReassignments = [];
23418 patternHasBeenFound = false;
23419 symbolsInExpressionsWithoutAssignments = [];
23420 if (DEBUG) {
23421 console.log("testable string: " + testableString);
23422 }
23423 if (TIMING_DEBUGS) {
23424 console.log("findDependenciesInScript time for: " + stringToBeRun + " : " + ((new Date().getTime()) - timeStartFromAlgebra) + "ms");
23425 }
23426 if (ENABLE_CACHING && stringToBeRun !== "clearall" && errorMessage === "") {
23427 frozen = freeze();
23428 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];
23429 if (CACHE_DEBUGS) {
23430 console.log("setting cached_findDependenciesInScript on key: " + cacheKey);
23431 }
23432 cached_findDependenciesInScript.set(cacheKey, toBeFrozen);
23433 }
23434 return [testableString, scriptEvaluation[0], generatedCode, readableSummaryOfGeneratedCode, scriptEvaluation[1], errorMessage, dependencyInfo];
23435 };
23436
23437 recursiveDependencies = function(variableToBeChecked, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions) {
23438 var cyclesDescription, i, k, l1, len, len1, m1, ref2;
23439 variablesAlreadyFleshedOut.push(variableToBeChecked);
23440 if (symbolsDependencies[chainBeingChecked[chainBeingChecked.length - 1]] != null) {
23441 if (symbolsDependencies[chainBeingChecked[chainBeingChecked.length - 1]].indexOf("'" + variableToBeChecked) !== -1) {
23442 if (DEBUG) {
23443 console.log("can't keep following the chain of " + variableToBeChecked + " because it's actually a variable bound to a parameter");
23444 }
23445 if (arrayWhereDependenciesWillBeAdded.indexOf("'" + variableToBeChecked) === -1 && arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) === -1) {
23446 arrayWhereDependenciesWillBeAdded.push(variableToBeChecked);
23447 }
23448 return arrayWhereDependenciesWillBeAdded;
23449 }
23450 }
23451 chainBeingChecked.push(variableToBeChecked);
23452 if (symbolsDependencies[variableToBeChecked] == null) {
23453 if (arrayWhereDependenciesWillBeAdded.indexOf(variableToBeChecked) === -1) {
23454 arrayWhereDependenciesWillBeAdded.push(variableToBeChecked);
23455 }
23456 return arrayWhereDependenciesWillBeAdded;
23457 } else {
23458 ref2 = symbolsDependencies[variableToBeChecked];
23459 for (l1 = 0, len = ref2.length; l1 < len; l1++) {
23460 i = ref2[l1];
23461 if (chainBeingChecked.indexOf(i) !== -1) {
23462 if (DEBUG) {
23463 console.log(" found cycle:");
23464 }
23465 cyclesDescription = "";
23466 for (m1 = 0, len1 = chainBeingChecked.length; m1 < len1; m1++) {
23467 k = chainBeingChecked[m1];
23468 if (variablesWithCycles.indexOf(k) === -1) {
23469 variablesWithCycles.push(k);
23470 }
23471 if (DEBUG) {
23472 console.log(k + " --> ");
23473 }
23474 cyclesDescription += k + " --> ";
23475 }
23476 if (DEBUG) {
23477 console.log(" ... then " + i + " again");
23478 }
23479 cyclesDescription += " ... then " + i + " again";
23480 cyclesDescriptions.push(cyclesDescription);
23481 if (variablesWithCycles.indexOf(i) === -1) {
23482 variablesWithCycles.push(i);
23483 }
23484 } else {
23485 recursiveDependencies(i, arrayWhereDependenciesWillBeAdded, variablesAlreadyFleshedOut, variablesWithCycles, chainBeingChecked, cyclesDescriptions);
23486 chainBeingChecked.pop();
23487 }
23488 }
23489 return arrayWhereDependenciesWillBeAdded;
23490 }
23491 };
23492
23493 inited = false;
23494
23495 latexErrorSign = "\\rlap{\\large\\color{red}\\bigtriangleup}{\\ \\ \\tiny\\color{red}!}";
23496
23497 turnErrorMessageToLatex = function(theErrorMessage) {
23498 theErrorMessage = theErrorMessage.replace(/\n/g, "");
23499 theErrorMessage = theErrorMessage.replace(/_/g, "} \\_ \\text{");
23500 theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(transpose_unicode), 'g'), "}{}^{T}\\text{");
23501 theErrorMessage = theErrorMessage.replace(new RegExp(String.fromCharCode(dotprod_unicode), 'g'), "}\\cdot \\text{");
23502 theErrorMessage = theErrorMessage.replace("Stop:", "} \\quad \\text{Stop:");
23503 theErrorMessage = theErrorMessage.replace("->", "} \\rightarrow \\text{");
23504 theErrorMessage = theErrorMessage.replace("?", "}\\enspace " + latexErrorSign + " \\enspace \\text{");
23505 theErrorMessage = "$$\\text{" + theErrorMessage.replace(/\n/g, "") + "}$$";
23506 return theErrorMessage;
23507 };
23508
23509 normaliseDots = function(stringToNormalise) {
23510 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8901), 'g'), String.fromCharCode(dotprod_unicode));
23511 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(8226), 'g'), String.fromCharCode(dotprod_unicode));
23512 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(12539), 'g'), String.fromCharCode(dotprod_unicode));
23513 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(55296), 'g'), String.fromCharCode(dotprod_unicode));
23514 stringToNormalise = stringToNormalise.replace(new RegExp(String.fromCharCode(65381), 'g'), String.fromCharCode(dotprod_unicode));
23515 return stringToNormalise;
23516 };
23517
23518 CACHE_DEBUGS = false;
23519
23520 CACHE_HITSMISS_DEBUGS = false;
23521
23522 TIMING_DEBUGS = false;
23523
23524 cacheMissPenalty = 0;
23525
23526 run = function(stringToBeRun, generateLatex) {
23527 var allReturnedLatexStrings, allReturnedPlainStrings, cacheKey, collectedLatexResult, collectedPlainResult, currentStateHash, error, errorWhileExecution, frozen, i, indexOfPartRemainingToBeParsed, n, possiblyCached, stringToBeReturned, theErrorMessage, timeStart, timingDebugWrite, toBeFrozen, totalTime;
23528 if (generateLatex == null) {
23529 generateLatex = false;
23530 }
23531 timeStart = new Date().getTime();
23532 stringToBeRun = normaliseDots(stringToBeRun);
23533 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23534 currentStateHash = getStateHash();
23535 cacheKey = currentStateHash + " stringToBeRun: " + stringToBeRun;
23536 if (CACHE_DEBUGS) {
23537 console.log("cached_runs key: " + cacheKey);
23538 }
23539 possiblyCached = cached_runs.get(cacheKey);
23540 if (possiblyCached != null) {
23541 if (CACHE_HITSMISS_DEBUGS) {
23542 console.log("cached_runs hit on: " + stringToBeRun);
23543 }
23544 unfreeze(possiblyCached);
23545 if (TIMING_DEBUGS) {
23546 totalTime = new Date().getTime() - timeStart;
23547 console.log("run time: " + totalTime + "ms, saved " + (possiblyCached[possiblyCached.length - 2] - totalTime) + "ms due to cache hit");
23548 }
23549 return possiblyCached[possiblyCached.length - 1];
23550 } else {
23551 if (CACHE_HITSMISS_DEBUGS) {
23552 console.log("cached_runs miss on: " + stringToBeRun);
23553 }
23554 if (TIMING_DEBUGS) {
23555 cacheMissPenalty = new Date().getTime() - timeStart;
23556 }
23557 }
23558 }
23559 if (stringToBeRun === "selftest") {
23560 selftest();
23561 return;
23562 }
23563 if (!inited) {
23564 inited = true;
23565 init();
23566 }
23567 i = 0;
23568 n = 0;
23569 indexOfPartRemainingToBeParsed = 0;
23570 allReturnedPlainStrings = "";
23571 allReturnedLatexStrings = "";
23572 while (1) {
23573 try {
23574 errorMessage = "";
23575 check_stack();
23576 n = scan(stringToBeRun.substring(indexOfPartRemainingToBeParsed));
23577 p1 = pop();
23578 check_stack();
23579 } catch (error1) {
23580 error = error1;
23581 if (PRINTOUTRESULT) {
23582 console.log(error);
23583 }
23584 allReturnedPlainStrings += error.message;
23585 if (generateLatex) {
23586 theErrorMessage = turnErrorMessageToLatex(error.message);
23587 allReturnedLatexStrings += theErrorMessage;
23588 }
23589 reset_after_error();
23590 break;
23591 }
23592 if (n === 0) {
23593 break;
23594 }
23595 indexOfPartRemainingToBeParsed += n;
23596 push(p1);
23597 errorWhileExecution = false;
23598 try {
23599 stringsEmittedByUserPrintouts = "";
23600 top_level_eval();
23601 p2 = pop();
23602 check_stack();
23603 if (isstr(p2)) {
23604 if (DEBUG) {
23605 console.log(p2.str);
23606 }
23607 if (DEBUG) {
23608 console.log("\n");
23609 }
23610 }
23611 if (p2 === symbol(NIL)) {
23612 collectedPlainResult = stringsEmittedByUserPrintouts;
23613 if (generateLatex) {
23614 collectedLatexResult = "$$" + stringsEmittedByUserPrintouts + "$$";
23615 }
23616 } else {
23617 collectedPlainResult = print_expr(p2);
23618 collectedPlainResult += "\n";
23619 if (generateLatex) {
23620 collectedLatexResult = "$$" + collectLatexStringFromReturnValue(p2) + "$$";
23621 if (DEBUG) {
23622 console.log("collectedLatexResult: " + collectedLatexResult);
23623 }
23624 }
23625 }
23626 allReturnedPlainStrings += collectedPlainResult;
23627 if (generateLatex) {
23628 allReturnedLatexStrings += collectedLatexResult;
23629 }
23630 if (PRINTOUTRESULT) {
23631 if (DEBUG) {
23632 console.log("printline");
23633 }
23634 if (DEBUG) {
23635 console.log(collectedPlainResult);
23636 }
23637 }
23638 if (PRINTOUTRESULT) {
23639 if (DEBUG) {
23640 console.log("display:");
23641 }
23642 print2dascii(p2);
23643 }
23644 if (generateLatex) {
23645 allReturnedLatexStrings += "\n";
23646 }
23647 } catch (error1) {
23648 error = error1;
23649 errorWhileExecution = true;
23650 collectedPlainResult = error.message;
23651 if (generateLatex) {
23652 collectedLatexResult = turnErrorMessageToLatex(error.message);
23653 }
23654 if (PRINTOUTRESULT) {
23655 console.log(collectedPlainResult);
23656 }
23657 allReturnedPlainStrings += collectedPlainResult;
23658 if (collectedPlainResult !== "") {
23659 allReturnedPlainStrings += "\n";
23660 }
23661 if (generateLatex) {
23662 allReturnedLatexStrings += collectedLatexResult;
23663 allReturnedLatexStrings += "\n";
23664 }
23665 resetCache();
23666 init();
23667 }
23668 }
23669 if (allReturnedPlainStrings[allReturnedPlainStrings.length - 1] === "\n") {
23670 allReturnedPlainStrings = allReturnedPlainStrings.substring(0, allReturnedPlainStrings.length - 1);
23671 }
23672 if (generateLatex) {
23673 if (allReturnedLatexStrings[allReturnedLatexStrings.length - 1] === "\n") {
23674 allReturnedLatexStrings = allReturnedLatexStrings.substring(0, allReturnedLatexStrings.length - 1);
23675 }
23676 }
23677 if (generateLatex) {
23678 if (DEBUG) {
23679 console.log("allReturnedLatexStrings: " + allReturnedLatexStrings);
23680 }
23681 stringToBeReturned = [allReturnedPlainStrings, allReturnedLatexStrings];
23682 } else {
23683 stringToBeReturned = allReturnedPlainStrings;
23684 }
23685 if (ENABLE_CACHING && stringToBeRun !== "clearall" && !errorWhileExecution) {
23686 frozen = freeze();
23687 toBeFrozen = [frozen[0], frozen[1], frozen[2], frozen[3], frozen[4], frozen[5], new Date().getTime() - timeStart, stringToBeReturned];
23688 if (CACHE_DEBUGS) {
23689 console.log("setting cached_runs on key: " + cacheKey);
23690 }
23691 cached_runs.set(cacheKey, toBeFrozen);
23692 }
23693 if (TIMING_DEBUGS) {
23694 timingDebugWrite = "run time on: " + stringToBeRun + " : " + (new Date().getTime() - timeStart) + "ms";
23695 if (ENABLE_CACHING && stringToBeRun !== "clearall") {
23696 timingDebugWrite += ", of which cache miss penalty: " + cacheMissPenalty + "ms";
23697 }
23698 console.log(timingDebugWrite);
23699 }
23700 allReturnedPlainStrings = "";
23701 allReturnedLatexStrings = "";
23702 return stringToBeReturned;
23703 };
23704
23705 check_stack = function() {
23706 if (tos !== 0) {
23707 debugger;
23708 stop("stack error");
23709 }
23710 if (frame !== TOS) {
23711 debugger;
23712 stop("frame error");
23713 }
23714 if (chainOfUserSymbolsNotFunctionsBeingEvaluated.length !== 0) {
23715 debugger;
23716 stop("symbols evaluation still ongoing?");
23717 }
23718 if (evaluatingAsFloats !== 0) {
23719 debugger;
23720 stop("numeric evaluation still ongoing?");
23721 }
23722 if (evaluatingPolar !== 0) {
23723 debugger;
23724 return stop("evaluation of polar still ongoing?");
23725 }
23726 };
23727
23728 top_level_eval = function() {
23729 var doNothing;
23730 if (DEBUG) {
23731 console.log("#### top level eval");
23732 }
23733 save();
23734 trigmode = 0;
23735 p1 = symbol(AUTOEXPAND);
23736 if (iszero(get_binding(p1))) {
23737 expanding = 0;
23738 } else {
23739 expanding = 1;
23740 }
23741 p1 = pop();
23742 push(p1);
23743 Eval();
23744 p2 = pop();
23745 if (p2 === symbol(NIL)) {
23746 push(p2);
23747 restore();
23748 return;
23749 }
23750 set_binding(symbol(LAST), p2);
23751 if (!iszero(get_binding(symbol(BAKE)))) {
23752 push(p2);
23753 bake();
23754 p2 = pop();
23755 }
23756 if ((p1 === symbol(SYMBOL_I) || p1 === symbol(SYMBOL_J)) && isimaginaryunit(p2)) {
23757 doNothing = 0;
23758 } else if (isimaginaryunit(get_binding(symbol(SYMBOL_J)))) {
23759 push(p2);
23760 push(imaginaryunit);
23761 push_symbol(SYMBOL_J);
23762 subst();
23763 p2 = pop();
23764 } else if (isimaginaryunit(get_binding(symbol(SYMBOL_I)))) {
23765 push(p2);
23766 push(imaginaryunit);
23767 push_symbol(SYMBOL_I);
23768 subst();
23769 p2 = pop();
23770 }
23771 push(p2);
23772 return restore();
23773 };
23774
23775 check_esc_flag = function() {
23776 if (esc_flag) {
23777 return stop("esc key");
23778 }
23779 };
23780
23781 clearAlgebraEnvironment = function() {
23782 return do_clearall();
23783 };
23784
23785 computeDependenciesFromAlgebra = function(codeFromAlgebraBlock) {
23786 var i, keepState, l1, len, len1, m1, originalcodeFromAlgebraBlock, userSimplificationsInProgramForm;
23787 if (DEBUG) {
23788 console.log("computeDependenciesFromAlgebra!!!");
23789 }
23790 originalcodeFromAlgebraBlock = codeFromAlgebraBlock;
23791 keepState = true;
23792 called_from_Algebra_block = true;
23793 codeFromAlgebraBlock = normaliseDots(codeFromAlgebraBlock);
23794 if (!keepState) {
23795 userSimplificationsInListForm = [];
23796 userSimplificationsInProgramForm = "";
23797 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
23798 i = userSimplificationsInListForm[l1];
23799 userSimplificationsInProgramForm += "silentpattern(" + car(i) + "," + car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n";
23800 }
23801 do_clearall();
23802 codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock;
23803 if (DEBUG) {
23804 console.log("codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock);
23805 }
23806 }
23807 if (DEBUG) {
23808 console.log("computeDependenciesFromAlgebra: patterns in the list --------------- ");
23809 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
23810 i = userSimplificationsInListForm[m1];
23811 console.log(car(i) + "," + cdr(i) + ")");
23812 }
23813 console.log("...end of list --------------- ");
23814 }
23815 called_from_Algebra_block = false;
23816 return findDependenciesInScript(codeFromAlgebraBlock, true)[6];
23817 };
23818
23819 computeResultsAndJavaScriptFromAlgebra = function(codeFromAlgebraBlock) {
23820 var code, dependencyInfo, i, keepState, l1, latexResult, len, len1, m1, originalcodeFromAlgebraBlock, readableSummaryOfCode, ref2, result, stringToBeRun, testableStringIsIgnoredHere, timeStartFromAlgebra, userSimplificationsInProgramForm;
23821 originalcodeFromAlgebraBlock = codeFromAlgebraBlock;
23822 keepState = true;
23823 called_from_Algebra_block = true;
23824 timeStartFromAlgebra = new Date().getTime();
23825 if (TIMING_DEBUGS) {
23826 console.log(" --------- computeResultsAndJavaScriptFromAlgebra input: " + codeFromAlgebraBlock + " at: " + (new Date()));
23827 }
23828 codeFromAlgebraBlock = normaliseDots(codeFromAlgebraBlock);
23829 stringToBeRun = codeFromAlgebraBlock;
23830 if (DEBUG) {
23831 console.log("computeResultsAndJavaScriptFromAlgebra: patterns in the list --------------- ");
23832 for (l1 = 0, len = userSimplificationsInListForm.length; l1 < len; l1++) {
23833 i = userSimplificationsInListForm[l1];
23834 console.log(car(i) + "," + cdr(i) + ")");
23835 }
23836 console.log("...end of list --------------- ");
23837 }
23838 if (!keepState) {
23839 userSimplificationsInListForm = [];
23840 userSimplificationsInProgramForm = "";
23841 for (m1 = 0, len1 = userSimplificationsInListForm.length; m1 < len1; m1++) {
23842 i = userSimplificationsInListForm[m1];
23843 userSimplificationsInProgramForm += "silentpattern(" + car(i) + "," + car(cdr(i)) + "," + car(cdr(cdr(i))) + ")\n";
23844 }
23845 do_clearall();
23846 codeFromAlgebraBlock = userSimplificationsInProgramForm + codeFromAlgebraBlock;
23847 if (DEBUG) {
23848 console.log("codeFromAlgebraBlock including patterns: " + codeFromAlgebraBlock);
23849 }
23850 }
23851 ref2 = findDependenciesInScript(codeFromAlgebraBlock), testableStringIsIgnoredHere = ref2[0], result = ref2[1], code = ref2[2], readableSummaryOfCode = ref2[3], latexResult = ref2[4], errorMessage = ref2[5], dependencyInfo = ref2[6];
23852 called_from_Algebra_block = false;
23853 if (readableSummaryOfCode !== "" || errorMessage !== "") {
23854 result += "\n" + readableSummaryOfCode;
23855 if (errorMessage !== "") {
23856 result += "\n" + errorMessage;
23857 }
23858 result = result.replace(/\n/g, "\n\n");
23859 latexResult += "\n" + "$$" + readableSummaryOfCode + "$$";
23860 if (errorMessage !== "") {
23861 latexResult += turnErrorMessageToLatex(errorMessage);
23862 }
23863 latexResult = latexResult.replace(/\n/g, "\n\n");
23864 }
23865 latexResult = latexResult.replace(/\n*/, "");
23866 latexResult = latexResult.replace(/\$\$\$\$\n*/g, "");
23867 code = code.replace(/Math\./g, "");
23868 code = code.replace(/\n/g, "\n\n");
23869 if (TIMING_DEBUGS) {
23870 console.log("computeResultsAndJavaScriptFromAlgebra time (total time from notebook and back) for: " + stringToBeRun + " : " + ((new Date().getTime()) - timeStartFromAlgebra) + "ms");
23871 }
23872 return {
23873 code: code,
23874 result: latexResult,
23875 latexResult: latexResult,
23876 dependencyInfo: dependencyInfo
23877 };
23878 };
23879
23880 enableCaching = function() {
23881 return ENABLE_CACHING = true;
23882 };
23883
23884 disableCaching = function() {
23885 return ENABLE_CACHING = false;
23886 };
23887
23888 (typeof exports !== "undefined" && exports !== null ? exports : this).run = run;
23889
23890 (typeof exports !== "undefined" && exports !== null ? exports : this).findDependenciesInScript = findDependenciesInScript;
23891
23892 (typeof exports !== "undefined" && exports !== null ? exports : this).computeDependenciesFromAlgebra = computeDependenciesFromAlgebra;
23893
23894 (typeof exports !== "undefined" && exports !== null ? exports : this).computeResultsAndJavaScriptFromAlgebra = computeResultsAndJavaScriptFromAlgebra;
23895
23896 (typeof exports !== "undefined" && exports !== null ? exports : this).clearAlgebraEnvironment = clearAlgebraEnvironment;
23897
23898 (typeof exports !== "undefined" && exports !== null ? exports : this).enableCaching = enableCaching;
23899
23900 (typeof exports !== "undefined" && exports !== null ? exports : this).disableCaching = disableCaching;
23901
23902 tos = 0;
23903
23904 nil_symbols = 0;
23905
23906 push = function(p) {
23907 if (p == null) {
23908 debugger;
23909 }
23910 if (p.isZero != null) {
23911 debugger;
23912 }
23913 if (p === symbol(NIL)) {
23914 nil_symbols++;
23915 if (DEBUG) {
23916 console.log("pushing symbol(NIL) #" + nil_symbols);
23917 }
23918 }
23919 if (tos >= frame) {
23920 stop("stack overflow");
23921 }
23922 return stack[tos++] = p;
23923 };
23924
23925 moveTos = function(stackPos) {
23926 if (tos <= stackPos) {
23927 tos = stackPos;
23928 return;
23929 }
23930 while (tos > stackPos) {
23931 stack[tos] = null;
23932 tos--;
23933 }
23934 };
23935
23936 top = function() {
23937 return stack[tos - 1];
23938 };
23939
23940 pop = function() {
23941 var elementToBeReturned;
23942 if (tos === 0) {
23943 debugger;
23944 stop("stack underflow");
23945 }
23946 if (stack[tos - 1] == null) {
23947 debugger;
23948 }
23949 elementToBeReturned = stack[--tos];
23950 stack[tos] = null;
23951 return elementToBeReturned;
23952 };
23953
23954 push_frame = function(n) {
23955 var i, l1, ref2, results;
23956 i = 0;
23957 frame -= n;
23958 if (frame < tos) {
23959 debugger;
23960 stop("frame overflow, circular reference?");
23961 }
23962 results = [];
23963 for (i = l1 = 0, ref2 = n; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
23964 results.push(stack[frame + i] = symbol(NIL));
23965 }
23966 return results;
23967 };
23968
23969 pop_frame = function(n) {
23970 frame += n;
23971 if (frame > TOS) {
23972 return stop("frame underflow");
23973 }
23974 };
23975
23976 save = function() {
23977 frame -= 10;
23978 if (frame < tos) {
23979 debugger;
23980 stop("frame overflow, circular reference?");
23981 }
23982 stack[frame + 0] = p0;
23983 stack[frame + 1] = p1;
23984 stack[frame + 2] = p2;
23985 stack[frame + 3] = p3;
23986 stack[frame + 4] = p4;
23987 stack[frame + 5] = p5;
23988 stack[frame + 6] = p6;
23989 stack[frame + 7] = p7;
23990 stack[frame + 8] = p8;
23991 return stack[frame + 9] = p9;
23992 };
23993
23994 restore = function() {
23995 if (frame > TOS - 10) {
23996 stop("frame underflow");
23997 }
23998 p0 = stack[frame + 0];
23999 p1 = stack[frame + 1];
24000 p2 = stack[frame + 2];
24001 p3 = stack[frame + 3];
24002 p4 = stack[frame + 4];
24003 p5 = stack[frame + 5];
24004 p6 = stack[frame + 6];
24005 p7 = stack[frame + 7];
24006 p8 = stack[frame + 8];
24007 p9 = stack[frame + 9];
24008 return frame += 10;
24009 };
24010
24011 swap = function() {
24012 var p, q;
24013 p = pop();
24014 q = pop();
24015 push(p);
24016 return push(q);
24017 };
24018
24019 dupl = function() {
24020 var p;
24021 p = pop();
24022 push(p);
24023 return push(p);
24024 };
24025
24026 $.dupl = dupl;
24027
24028 $.swap = swap;
24029
24030 $.restore = restore;
24031
24032 $.save = save;
24033
24034 $.push = push;
24035
24036 $.pop = pop;
24037
24038 Eval_symbolsinfo = function() {
24039 var symbolsinfoToBePrinted;
24040 symbolsinfoToBePrinted = symbolsinfo();
24041 if (symbolsinfoToBePrinted !== "") {
24042 return new_string(symbolsinfoToBePrinted);
24043 } else {
24044 return push_symbol(NIL);
24045 }
24046 };
24047
24048 symbolsinfo = function() {
24049 var bindingi, i, l1, ref2, ref3, symbolsinfoToBePrinted, symtabi;
24050 symbolsinfoToBePrinted = "";
24051 for (i = l1 = ref2 = NIL + 1, ref3 = symtab.length; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24052 if (symtab[i].printname === "") {
24053 if (isSymbolReclaimable[i] === false) {
24054 break;
24055 } else {
24056 continue;
24057 }
24058 }
24059 symtabi = symtab[i] + "";
24060 bindingi = (binding[i] + "").substring(0, 4);
24061 symbolsinfoToBePrinted += "symbol: " + symtabi + " size: " + countsize(binding[i]) + " value: " + bindingi + "...\n";
24062 }
24063 return symbolsinfoToBePrinted;
24064 };
24065
24066 std_symbol = function(s, n, latexPrint) {
24067 var p;
24068 p = symtab[n];
24069 if (p == null) {
24070 debugger;
24071 }
24072 p.printname = s;
24073 if (latexPrint != null) {
24074 return p.latexPrint = latexPrint;
24075 } else {
24076 return p.latexPrint = s;
24077 }
24078 };
24079
24080 usr_symbol = function(s) {
24081 var i, l1, ref2;
24082 i = 0;
24083 for (i = l1 = 0, ref2 = NSYM; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24084 if (symtab[i].printname === "") {
24085 break;
24086 }
24087 if (s === symtab[i].printname) {
24088 return symtab[i];
24089 }
24090 }
24091 if (i === NSYM) {
24092 stop("symbol table overflow");
24093 }
24094 symtab[i] = new U();
24095 symtab[i].k = SYM;
24096 symtab[i].printname = s;
24097 binding[i] = symtab[i];
24098 isSymbolReclaimable[i] = false;
24099 return symtab[i];
24100 };
24101
24102 get_printname = function(p) {
24103 if (p.k !== SYM) {
24104 stop("symbol error");
24105 }
24106 return p.printname;
24107 };
24108
24109 set_binding = function(p, q) {
24110 var indexFound;
24111 if (p.k !== SYM) {
24112 stop("symbol error");
24113 }
24114 indexFound = symtab.indexOf(p);
24115
24116 /*
24117 if indexFound == -1
24118 debugger
24119 for i in [0...symtab.length]
24120 if p.printname == symtab[i].printname
24121 indexFound = i
24122 console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
24123 break
24124 */
24125 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24126 console.log("ops, more than one element!");
24127 debugger;
24128 }
24129 if (DEBUG) {
24130 console.log("lookup >> set_binding lookup " + indexFound);
24131 }
24132 isSymbolReclaimable[indexFound] = false;
24133 return binding[indexFound] = q;
24134 };
24135
24136 get_binding = function(p) {
24137 var indexFound;
24138 if (p.k !== SYM) {
24139 stop("symbol error");
24140 }
24141 indexFound = symtab.indexOf(p);
24142
24143 /*
24144 if indexFound == -1
24145 debugger
24146 for i in [0...symtab.length]
24147 if p.printname == symtab[i].printname
24148 indexFound = i
24149 console.log "remedied an index not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
24150 break
24151 */
24152 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24153 console.log("ops, more than one element!");
24154 debugger;
24155 }
24156 if (DEBUG) {
24157 console.log("lookup >> get_binding lookup " + indexFound);
24158 }
24159 return binding[indexFound];
24160 };
24161
24162 is_usr_symbol = function(p) {
24163 var theSymnum;
24164 if (p.k !== SYM) {
24165 return false;
24166 }
24167 theSymnum = symnum(p);
24168 if (theSymnum > PI && theSymnum !== SYMBOL_I && theSymnum !== SYMBOL_IDENTITY_MATRIX) {
24169 return true;
24170 }
24171 return false;
24172 };
24173
24174 lookupsTotal = 0;
24175
24176 symnum = function(p) {
24177 var indexFound;
24178 lookupsTotal++;
24179 if (p.k !== SYM) {
24180 stop("symbol error");
24181 }
24182 indexFound = symtab.indexOf(p);
24183 if (symtab.indexOf(p, indexFound + 1) !== -1) {
24184 console.log("ops, more than one element!");
24185 debugger;
24186 }
24187 if (DEBUG) {
24188 console.log("lookup >> symnum lookup " + indexFound + " lookup # " + lookupsTotal);
24189 }
24190 return indexFound;
24191 };
24192
24193 push_symbol = function(k) {
24194 return push(symtab[k]);
24195 };
24196
24197 clear_symbols = function() {
24198 var i, l1, ref2, ref3, results;
24199 results = [];
24200 for (i = l1 = ref2 = NIL + 1, ref3 = NSYM; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24201 if (symtab[i].printname === "") {
24202 if (isSymbolReclaimable[i] === false) {
24203 break;
24204 } else {
24205 continue;
24206 }
24207 }
24208 symtab[i] = new U();
24209 symtab[i].k = SYM;
24210 binding[i] = symtab[i];
24211 results.push(isSymbolReclaimable[i] = false);
24212 }
24213 return results;
24214 };
24215
24216 collectUserSymbols = function(p, accumulator) {
24217 var i, l1, ref2;
24218 if (accumulator == null) {
24219 accumulator = [];
24220 }
24221 if (is_usr_symbol(p)) {
24222 if (accumulator.indexOf(p) === -1) {
24223 accumulator.push(p);
24224 return;
24225 }
24226 }
24227 if (istensor(p)) {
24228 for (i = l1 = 0, ref2 = p.tensor.nelem; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24229 collectUserSymbols(p.tensor.elem[i], accumulator);
24230 }
24231 return;
24232 }
24233 while (iscons(p)) {
24234 collectUserSymbols(car(p), accumulator);
24235 p = cdr(p);
24236 }
24237 };
24238
24239 $.get_binding = get_binding;
24240
24241 $.set_binding = set_binding;
24242
24243 $.usr_symbol = usr_symbol;
24244
24245 $.symbolsinfo = symbolsinfo;
24246
24247 $.collectUserSymbols = collectUserSymbols;
24248
24249 if (!inited) {
24250 inited = true;
24251 init();
24252 }
24253
24254 $.init = init;
24255
24256 parse_internal = function(argu) {
24257 if (typeof argu === 'string') {
24258 return scan(argu);
24259 } else if (typeof argu === 'number') {
24260 if (argu % 1 === 0) {
24261 return push_integer(argu);
24262 } else {
24263 return push_double(argu);
24264 }
24265 } else if (argu instanceof U) {
24266 return push(argu);
24267 } else {
24268 console.warn('unknown argument type', argu);
24269 return push(symbol(NIL));
24270 }
24271 };
24272
24273 parse = function(argu) {
24274 var data, error;
24275 try {
24276 parse_internal(argu);
24277 data = pop();
24278 check_stack();
24279 } catch (error1) {
24280 error = error1;
24281 reset_after_error();
24282 throw error;
24283 }
24284 return data;
24285 };
24286
24287 exec = function() {
24288 var argu, argus, error, fn, l1, len, name, result;
24289 name = arguments[0], argus = 2 <= arguments.length ? slice.call(arguments, 1) : [];
24290 fn = get_binding(usr_symbol(name));
24291 check_stack();
24292 push(fn);
24293 for (l1 = 0, len = argus.length; l1 < len; l1++) {
24294 argu = argus[l1];
24295 parse_internal(argu);
24296 }
24297 list(1 + argus.length);
24298 p1 = pop();
24299 push(p1);
24300 try {
24301 fixed_top_level_eval();
24302 result = pop();
24303 check_stack();
24304 } catch (error1) {
24305 error = error1;
24306 reset_after_error();
24307 throw error;
24308 }
24309 return result;
24310 };
24311
24312 fixed_top_level_eval = function() {
24313 save();
24314 trigmode = 0;
24315 p1 = symbol(AUTOEXPAND);
24316 if (iszero(get_binding(p1))) {
24317 expanding = 0;
24318 } else {
24319 expanding = 1;
24320 }
24321 p1 = pop();
24322 push(p1);
24323 Eval();
24324 p2 = pop();
24325 if (p2 === symbol(NIL)) {
24326 push(p2);
24327 restore();
24328 return;
24329 }
24330 if (!iszero(get_binding(symbol(BAKE)))) {
24331 push(p2);
24332 bake();
24333 p2 = pop();
24334 }
24335 push(p2);
24336 return restore();
24337 };
24338
24339 $.exec = exec;
24340
24341 $.parse = parse;
24342
24343 (function() {
24344 var builtin_fns, fn, l1, len, results;
24345 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"];
24346 results = [];
24347 for (l1 = 0, len = builtin_fns.length; l1 < len; l1++) {
24348 fn = builtin_fns[l1];
24349 results.push($[fn] = exec.bind(this, fn));
24350 }
24351 return results;
24352 })();
24353
24354 DoubleLinkedList = (function() {
24355 function DoubleLinkedList() {
24356 this.headNode = this.tailNode = null;
24357 }
24358
24359 DoubleLinkedList.prototype.remove = function(node) {
24360 if (node.pre) {
24361 node.pre.next = node.next;
24362 } else {
24363 this.headNode = node.next;
24364 }
24365 if (node.next) {
24366 return node.next.pre = node.pre;
24367 } else {
24368 return this.tailNode = node.pre;
24369 }
24370 };
24371
24372 DoubleLinkedList.prototype.insertBeginning = function(node) {
24373 if (this.headNode) {
24374 node.next = this.headNode;
24375 this.headNode.pre = node;
24376 return this.headNode = node;
24377 } else {
24378 return this.headNode = this.tailNode = node;
24379 }
24380 };
24381
24382 DoubleLinkedList.prototype.moveToHead = function(node) {
24383 this.remove(node);
24384 return this.insertBeginning(node);
24385 };
24386
24387 DoubleLinkedList.prototype.clear = function() {
24388 return this.headNode = this.tailNode = null;
24389 };
24390
24391 return DoubleLinkedList;
24392
24393 })();
24394
24395 LRUCache = (function() {
24396 function LRUCache(capacity, maxAge) {
24397 this.capacity = capacity != null ? capacity : 10;
24398 this.maxAge = maxAge != null ? maxAge : 60000;
24399 this._linkList = new DoubleLinkedList();
24400 this.reset();
24401 this.hitCount = this.missCount = 0;
24402 }
24403
24404 LRUCache.prototype.resetHitMissCount = function() {
24405 return this.hitCount = this.missCount = 0;
24406 };
24407
24408 LRUCache.prototype.keys = function() {
24409 return Object.keys(this._hash);
24410 };
24411
24412 LRUCache.prototype.values = function() {
24413 var values;
24414 values = this.keys().map((function(_this) {
24415 return function(key) {
24416 return _this.get(key);
24417 };
24418 })(this));
24419 return values.filter(function(v) {
24420 return v !== void 0;
24421 });
24422 };
24423
24424 LRUCache.prototype.remove = function(key) {
24425 var node;
24426 if (this._hash[key] != null) {
24427 node = this._hash[key];
24428 this._linkList.remove(node);
24429 delete this._hash[key];
24430 if (node.data.onDispose) {
24431 node.data.onDispose.call(this, node.data.key, node.data.value);
24432 }
24433 return this.size--;
24434 }
24435 };
24436
24437 LRUCache.prototype.reset = function() {
24438 this._hash = {};
24439 this.size = 0;
24440 this.resetHitMissCount();
24441 return this._linkList.clear();
24442 };
24443
24444 LRUCache.prototype.set = function(key, value, onDispose) {
24445 var createNode, node;
24446 node = this._hash[key];
24447 if (node) {
24448 node.data.value = value;
24449 node.data.onDispose = onDispose;
24450 return this._refreshNode(node);
24451 } else {
24452 if (this.size === this.capacity) {
24453 this.remove(this._linkList.tailNode.data.key);
24454 }
24455 createNode = function(data, pre, next) {
24456 return {
24457 data: data,
24458 pre: pre,
24459 next: next
24460 };
24461 };
24462 node = createNode({
24463 key: key,
24464 value: value,
24465 onDispose: onDispose
24466 });
24467 node.data.lastVisitTime = Date.now();
24468 this._linkList.insertBeginning(node);
24469 this._hash[key] = node;
24470 this.size++;
24471 }
24472 };
24473
24474 LRUCache.prototype.get = function(key) {
24475 var node;
24476 node = this._hash[key];
24477 if (!node) {
24478 this.missCount++;
24479 return void 0;
24480 }
24481 if (this._isExpiredNode(node)) {
24482 this.remove(key);
24483 this.missCount++;
24484 return void 0;
24485 }
24486 this._refreshNode(node);
24487 this.hitCount++;
24488 return node.data.value;
24489 };
24490
24491 LRUCache.prototype._refreshNode = function(node) {
24492 node.data.lastVisitTime = Date.now();
24493 return this._linkList.moveToHead(node);
24494 };
24495
24496 LRUCache.prototype._isExpiredNode = function(node) {
24497 return Date.now() - node.data.lastVisitTime > this.maxAge;
24498 };
24499
24500 LRUCache.prototype.has = function(key) {
24501 return this._hash[key] != null;
24502 };
24503
24504 return LRUCache;
24505
24506 })();
24507
24508 cached_runs = new LRUCache(100, 60000 * 60 * 24 * 265);
24509
24510 cached_findDependenciesInScript = new LRUCache(100, 60000 * 60 * 24 * 265);
24511
24512 freeze = function() {
24513 var frozenContents, frozenHash, frozenPatterns, frozenSymbols, i, l1, ref2;
24514 frozenSymbols = [];
24515 frozenContents = [];
24516 frozenPatterns = [];
24517 frozenHash = "";
24518 for (i = l1 = 0, ref2 = symtab.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24519 if (isSymbolReclaimable[i] === false) {
24520 frozenSymbols.push(symtab[i]);
24521 frozenContents.push(binding[i]);
24522 }
24523 }
24524 frozenPatterns = userSimplificationsInListForm.slice(0);
24525 return [frozenSymbols, frozenContents, frozenPatterns, zero, one, imaginaryunit, getStateHash()];
24526 };
24527
24528 unfreeze = function(frozen) {
24529 var frozenContents, frozenPatterns, frozenSymbols, i, l1, ref2;
24530 frozenSymbols = frozen[0], frozenContents = frozen[1], frozenPatterns = frozen[2], zero = frozen[3], one = frozen[4], imaginaryunit = frozen[5];
24531 for (i = l1 = 0, ref2 = frozenSymbols.length; 0 <= ref2 ? l1 < ref2 : l1 > ref2; i = 0 <= ref2 ? ++l1 : --l1) {
24532 symtab[i] = frozenSymbols[i];
24533 binding[i] = frozenContents[i];
24534 }
24535 return userSimplificationsInListForm = frozenPatterns.slice(0);
24536 };
24537
24538 compareState = function(previousHash) {
24539 var frozenHash;
24540 frozenHash = getStateHash();
24541 if (frozenHash === previousHash) {
24542 return true;
24543 } else {
24544 return false;
24545 }
24546 };
24547
24548 resetCache = function() {
24549 if (cached_runs != null) {
24550 cached_runs.reset();
24551 if (DEBUG) {
24552 console.log("resetting cached_runs");
24553 }
24554 }
24555 if (cached_findDependenciesInScript != null) {
24556 cached_findDependenciesInScript.reset();
24557 if (DEBUG) {
24558 return console.log("resetting cached_findDependenciesInScript");
24559 }
24560 }
24561 };
24562
24563 resetCacheHitMissCounts = function() {
24564 if (cached_runs != null) {
24565 cached_runs.resetHitMissCount();
24566 }
24567 if (cached_findDependenciesInScript != null) {
24568 return cached_findDependenciesInScript.resetHitMissCount();
24569 }
24570 };
24571
24572 totalAllCachesHits = function() {
24573 return cached_runs.hitCount + cached_findDependenciesInScript.hitCount;
24574 };
24575
24576 totalAllCachesMisses = function() {
24577 return cached_runs.missCount + cached_findDependenciesInScript.missCount;
24578 };
24579
24580 getStateHash = function() {
24581 var bindingi, frozenHash, i, l1, len, m1, ref2, ref3, symtabi;
24582 frozenHash = "";
24583 for (i = l1 = ref2 = NIL + 1, ref3 = symtab.length; ref2 <= ref3 ? l1 < ref3 : l1 > ref3; i = ref2 <= ref3 ? ++l1 : --l1) {
24584 if (symtab[i].printname === "") {
24585 if (isSymbolReclaimable[i] === false) {
24586 break;
24587 } else {
24588 continue;
24589 }
24590 }
24591 symtabi = print_list(symtab[i]);
24592 bindingi = print_list(binding[i]);
24593 frozenHash += " //" + symtabi + " : " + bindingi;
24594 }
24595 for (m1 = 0, len = userSimplificationsInListForm.length; m1 < len; m1++) {
24596 i = userSimplificationsInListForm[m1];
24597 frozenHash += " pattern: " + i;
24598 }
24599 if (DEBUG) {
24600 console.log("frozenHash: " + frozenHash);
24601 }
24602 return frozenHash;
24603 };
24604
24605}).call(this);