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