UNPKG

algebrite

Version:

Computer Algebra System in Coffeescript

2,323 lines (1,870 loc) 359 kB
// Generated by CoffeeScript 1.10.0 (function() { var $, ABS, ADD, ADJ, AND, ARCCOS, ARCCOSH, ARCSIN, ARCSINH, ARCTAN, ARCTANH, ARG, ATOMIZE, AUTOEXPAND, BAKE, BESSELJ, BESSELY, BINDING, BINOMIAL, BINOM_check_args, BUF, C1, C2, C3, C4, C5, C6, CEILING, CHECK, CHOOSE, CIRCEXP, CLEAR, CLOCK, COEFF, COFACTOR, CONDENSE, CONJ, CONS, CONTRACT, COS, COSH, Condense, DEBUG, DECOMP, DEFINT, DEGREE, DENOMINATOR, DERIVATIVE, DET, DET_check_arg, DIM, DIRAC, DISPLAY, DIVISORS, DO, DOT, DOUBLE, DRAW, DRAWX, DSOLVE, E, EIGEN, EIGENVAL, EIGENVEC, EIG_N, EIG_check_arg, EIG_yydd, EIG_yyqq, ERF, ERFC, EVAL, EXP, EXPAND, EXPCOS, EXPSIN, Eval, Eval_Eval, Eval_abs, Eval_add, Eval_adj, Eval_and, 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_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_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_mag, Eval_mod, Eval_multiply, Eval_noexpand, Eval_not, Eval_nroots, Eval_number, Eval_numerator, Eval_operator, Eval_or, Eval_outer, Eval_polar, Eval_power, Eval_predicate, Eval_prime, Eval_print, Eval_product, Eval_quote, Eval_quotient, Eval_rank, Eval_rationalize, Eval_real, Eval_rect, Eval_roots, Eval_setq, Eval_sgn, Eval_shape, Eval_simfac, Eval_simplify, Eval_sin, Eval_sinh, Eval_sqrt, Eval_stop, Eval_subst, Eval_sym, 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, Find, GAMMA, GCD, HERMITE, HILBERT, IMAG, INDEX, INNER, INTEGRAL, INV, INVG, INV_check_arg, INV_decomp, ISINTEGER, ISPRIME, LAGUERRE, LAST, LCM, LEADING, LEGENDRE, LOG, M, MAG, MAXDIM, MAXPRIMETAB, MAX_PROGRAM_SIZE, MEQUAL, METAA, METAB, METAX, MLENGTH, MOD, MP_MAX_FREE, MP_MIN_SIZE, 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, PI, POLAR, POWER, PRIME, PRINT, PRINTOUTRESULT, PRODUCT, QUOTE, QUOTIENT, RANK, RATIONALIZE, REAL, ROOTS, SECRETX, SELFTEST, SETQ, SGN, SHAPE, SIMPLIFY, SIN, SINH, SPACE_BETWEEN_COLUMNS, SPACE_BETWEEN_ROWS, SQRT, STOP, STR, SUBST, SUM, SYM, SYMBOL_A, SYMBOL_B, SYMBOL_C, SYMBOL_D, SYMBOL_I, SYMBOL_J, SYMBOL_N, SYMBOL_R, SYMBOL_S, SYMBOL_T, SYMBOL_X, SYMBOL_Y, SYMBOL_Z, TAN, TANH, TAYLOR, TENSOR, TEST, TESTEQ, TESTGE, TESTGT, TESTLE, TESTLT, TOS, TRACE, TRANSPOSE, TTY, T_DOUBLE, T_EQ, T_FUNCTION, T_GTEQ, T_INTEGER, T_LTEQ, T_NEWLINE, T_STRING, T_SYMBOL, U, UNIT, USR_SYMBOLS, 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, absval, absval_tensor, ac, ad, add, add_all, add_numbers, add_terms, addf, adj, alloc_tensor, allocatedId, any_denominators, arccos, arccosh, arcsin, arcsinh, arctan, arctanh, arg, arglist, 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, cadaddr, cadadr, cadar, caddaddr, caddadr, caddar, caddddr, cadddr, caddr, cadr, car, cdaddr, cdadr, cdar, cddaddr, cddar, cdddaddr, cddddr, cdddr, cddr, cdr, ceiling, charTabIndex, chartab, check_esc_flag, check_stack, choose, choose_check_args, circexp, clear, clear_symbols, clear_term, clockform, cmpGlyphs, cmp_args, cmp_expr, cmp_terms, cmp_terms_count, coeff, cofactor, collectResultLine, combine_factors, combine_gammas, combine_terms, compare_numbers, compare_rationals, compare_tensors, compatible, 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, count_denominators, counter, 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, define_user_function, defn, defn_str, degree, denominator, derf, derfc, derivative, derivative_of_integral, det, determinant, detg, dfunction, dhermite, dirac, display, display_flag, displaychar, divide, divide_numbers, divisors, divisors_onstack, divpoly, dlog, doubleToReasonableString, dpow, dpower, dproduct, draw_flag, draw_stop_return, dsgn, dsin, dsinh, dsum, dtan, dtanh, dupl, echo_input, 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, equal, equaln, equalq, erfc, errorMessage, esc_flag, 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, 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, findroot, fixed_top_level_eval, fixup_fraction, fixup_power, flag, fmt_index, fmt_level, fmt_x, frame, free_stack, 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, get_arglist, get_binding, get_factor, get_next_token, get_printname, get_size, get_token, getdisplaystr, glyph, gp, guess, hasImaginaryCoeff, hermite, hilbert, 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, is_denominator, is_factor, is_small_integer, is_square_matrix, isadd, isalnum, isalpha, iscomplexnumber, iscons, isdenominator, isdigit, isdouble, iseveninteger, isfactor, isfactorial, isfloating, isfraction, isimaginarynumber, isimaginaryunit, isinteger, isintegerfactor, iskeyword, isminusone, isminusoneoversqrttwo, ismultiply, isnegative, isnegativenumber, isnegativeterm, isnonnegativeinteger, isnpi, isnum, isoneover, isoneoversqrttwo, isplusone, ispoly, ispoly_expr, ispoly_factor, ispoly_term, isposint, ispower, isquarterturn, isrational, isspace, isstr, issymbol, issymbolic, istensor, iszero, itab, laguerre, laguerre2, lcm, leading, legendre, length, lessp, level, list, logarithm, logbuf, lookupsTotal, lu_decomp, madd, mag, makePositive, makeSignSameAs, mask, mcmp, mcmpint, mdiv, mdivrem, meta_mode, mgcd, mini_solve, mint, mmod, mmul, mod, monic, move, 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_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, normalize_angle, nroots_a, nroots_b, nroots_c, nroots_df, nroots_dx, nroots_fa, nroots_fb, nroots_x, nroots_y, nterms, numerator, numericRootOfPolynomial, o, one, oneElement, 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, partition, peek, peek2, polar, polycoeff, polyform, pop, pop_double, pop_frame, pop_integer, power, power_str, power_sum, power_tensor, prime, primetab, print1, print_a_over_b, print_char, print_denom, print_double, print_expr, print_factor, print_factorial_function, print_it, print_multiply_sign, print_number, print_str, print_subexpr, print_tensor, print_tensor_inner, print_term, printchar, printchar_nowrap, printline, program_buf, promote_tensor, push, 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, ref, ref1, remove_negative_exponents, reset_after_error, restore, rewrite_args, rewrite_args_tensor, roots, roots2, roots3, run, save, scalar_times_tensor, scan, scan_error, scan_expression, scan_factor, scan_function_call, scan_meta, scan_power, scan_relation, scan_stmt, scan_str, scan_string, scan_subexpr, scan_symbol, scan_term, scanned, setM, setSignTo, set_binding, set_binding_and_arglist, set_component, setq_indexed, sfac_product, sfac_product_f, sgn, shape, sign, sign_of_term, simfac, simfac_term, simplify, simplify_main, simplify_polar, simplify_tensor, simplify_trig, simplifyfactorials, sine, sine_of_angle, sine_of_angle_sum, sort_stack, square, ssqrt, stack, stackAddsCount, std_symbol, step, step2, stop, strcmp, stringToBePrinted, subf, subst, subtract, subtract_numbers, swap, symbol, symnum, symtab, tangent, taylor, tensor, tensor_plus_tensor, tensor_times_scalar, test_flag, text_metric, theRandom, token, token_buf, token_str, top_level_eval, tos, transform, transpose, trigmode, trivial_divide, try_kth_prime, ucmp, unique, unique_f, update_token_buf, usr_symbol, verbosing, will_be_displayed_as_fraction, ybinomial, ycosh, ydirac, yerf, yerfc, yfloor, yindex, ysinh, yyarg, yybesselj, yybessely, yyceiling, yycondense, yycontract, yycosh, yydegree, yydetg, yydivpoly, yyerf, yyerfc, yyexpand, yyfactorpoly, yyfloat, yyfloor, yyhermite, yyhermite2, yyinvg, yylcm, yylog, yymag, yymultiply, yyouter, yypower, yyrationalize, yysgn, yysimfac, yysinh, yytangent, zero, slice = [].slice; bigInt = require('big-integer'); SELFTEST = 1; NSYM = 1000; DEBUG = false; PRINTOUTRESULT = false; rational = (function() { function rational() {} rational.prototype.a = null; rational.prototype.b = null; return rational; })(); U = (function() { U.prototype.cons = null; U.prototype.printname = ""; U.prototype.str = ""; U.prototype.tensor = null; U.prototype.q = null; U.prototype.d = 0.0; U.prototype.k = 0; U.prototype.tag = 0; U.prototype.toString = function() { return collectResultLine(this); }; function U() { this.cons = {}; this.cons.car = null; this.cons.cdr = null; this.q = new rational(); } return U; })(); errorMessage = ""; CONS = 0; NUM = 1; DOUBLE = 2; STR = 3; TENSOR = 4; SYM = 5; counter = 0; ABS = counter++; ADD = counter++; ADJ = counter++; AND = counter++; ARCCOS = counter++; ARCCOSH = counter++; ARCSIN = counter++; ARCSINH = counter++; ARCTAN = counter++; ARCTANH = counter++; ARG = counter++; ATOMIZE = counter++; BESSELJ = counter++; BESSELY = counter++; BINDING = counter++; BINOMIAL = counter++; CEILING = counter++; CHECK = counter++; CHOOSE = counter++; CIRCEXP = counter++; CLEAR = counter++; CLOCK = counter++; COEFF = counter++; COFACTOR = counter++; CONDENSE = counter++; CONJ = counter++; CONTRACT = counter++; COS = counter++; COSH = counter++; DECOMP = counter++; DEFINT = counter++; DEGREE = counter++; DENOMINATOR = counter++; DERIVATIVE = counter++; DET = counter++; DIM = counter++; DIRAC = counter++; DISPLAY = counter++; DIVISORS = counter++; DO = counter++; DOT = counter++; DRAW = counter++; DSOLVE = counter++; EIGEN = counter++; EIGENVAL = counter++; EIGENVEC = counter++; ERF = counter++; ERFC = counter++; EVAL = counter++; EXP = counter++; EXPAND = counter++; EXPCOS = counter++; EXPSIN = counter++; FACTOR = counter++; FACTORIAL = counter++; FACTORPOLY = counter++; FILTER = counter++; FLOATF = counter++; FLOOR = counter++; FOR = counter++; GAMMA = counter++; GCD = counter++; HERMITE = counter++; HILBERT = counter++; IMAG = counter++; INDEX = counter++; INNER = counter++; INTEGRAL = counter++; INV = counter++; INVG = counter++; ISINTEGER = counter++; ISPRIME = counter++; LAGUERRE = counter++; LCM = counter++; LEADING = counter++; LEGENDRE = counter++; LOG = counter++; MAG = counter++; MOD = counter++; MULTIPLY = counter++; NOT = counter++; NROOTS = counter++; NUMBER = counter++; NUMERATOR = counter++; OPERATOR = counter++; OR = counter++; OUTER = counter++; POLAR = counter++; POWER = counter++; PRIME = counter++; PRINT = counter++; PRODUCT = counter++; QUOTE = counter++; QUOTIENT = counter++; RANK = counter++; RATIONALIZE = counter++; REAL = counter++; YYRECT = counter++; ROOTS = counter++; SETQ = counter++; SGN = counter++; SIMPLIFY = counter++; SIN = counter++; SINH = counter++; SHAPE = counter++; SQRT = counter++; STOP = counter++; SUBST = counter++; SUM = counter++; TAN = counter++; TANH = counter++; TAYLOR = counter++; TEST = counter++; TESTEQ = counter++; TESTGE = counter++; TESTGT = counter++; TESTLE = counter++; TESTLT = counter++; TRANSPOSE = counter++; UNIT = counter++; ZERO = counter++; NIL = counter++; AUTOEXPAND = counter++; BAKE = counter++; LAST = counter++; TRACE = counter++; TTY = counter++; YYE = counter++; DRAWX = counter++; METAA = counter++; METAB = counter++; METAX = counter++; SECRETX = counter++; PI = counter++; SYMBOL_A = counter++; SYMBOL_B = counter++; SYMBOL_C = counter++; SYMBOL_D = counter++; SYMBOL_I = counter++; SYMBOL_J = counter++; SYMBOL_N = counter++; SYMBOL_R = counter++; SYMBOL_S = counter++; SYMBOL_T = counter++; SYMBOL_X = counter++; SYMBOL_Y = counter++; SYMBOL_Z = counter++; C1 = counter++; C2 = counter++; C3 = counter++; C4 = counter++; C5 = counter++; C6 = counter++; USR_SYMBOLS = counter++; E = YYE; TOS = 100000; BUF = 10000; MAX_PROGRAM_SIZE = 100001; MAXPRIMETAB = 10000; MAXDIM = 24; tensor = (function() { tensor.prototype.ndim = 0; tensor.prototype.dim = null; tensor.prototype.nelem = 0; tensor.prototype.elem = null; function tensor() { this.dim = (function() { var o, ref, results; results = []; for (o = 0, ref = MAXDIM; 0 <= ref ? o <= ref : o >= ref; 0 <= ref ? o++ : o--) { results.push(0); } return results; })(); this.elem = []; } return tensor; })(); display = (function() { function display() {} display.prototype.h = 0; display.prototype.w = 0; display.prototype.n = 0; display.prototype.a = []; return display; })(); text_metric = (function() { function text_metric() {} text_metric.prototype.ascent = 0; text_metric.prototype.descent = 0; text_metric.prototype.width = 0; return text_metric; })(); tos = 0; expanding = 0; fmt_x = 0; fmt_index = 0; fmt_level = 0; verbosing = 0; primetab = (function() { var ceil, i, j, primes; primes = [2]; i = 3; while (primes.length < MAXPRIMETAB) { j = 0; ceil = Math.sqrt(i); while (j < primes.length && primes[j] <= ceil) { if (i % primes[j] === 0) { j = -1; break; } j++; } if (j !== -1) { primes.push(i); } i += 2; } primes[MAXPRIMETAB] = 0; return primes; })(); esc_flag = 0; draw_flag = 0; mtotal = 0; trigmode = 0; logbuf = ""; program_buf = ""; symtab = []; binding = []; arglist = []; stack = []; frame = 0; p0 = null; p1 = null; p2 = null; p3 = null; p4 = null; p5 = null; p6 = null; p7 = null; p8 = null; p9 = null; zero = null; one = null; imaginaryunit = null; symtab = []; out_buf = ""; out_count = 0; test_flag = 0; draw_stop_return = null; symbol = function(x) { return symtab[x]; }; iscons = function(p) { return p.k === CONS; }; isrational = function(p) { return p.k === NUM; }; isdouble = function(p) { return p.k === DOUBLE; }; isnum = function(p) { return isrational(p) || isdouble(p); }; isstr = function(p) { return p.k === STR; }; istensor = function(p) { if (p == null) { debugger; } else { return p.k === TENSOR; } }; issymbol = function(p) { return p.k === SYM; }; iskeyword = function(p) { return issymbol(p) && symnum(p) < NIL; }; car = function(p) { if (iscons(p)) { return p.cons.car; } else { return symbol(NIL); } }; cdr = function(p) { if (iscons(p)) { return p.cons.cdr; } else { return symbol(NIL); } }; caar = function(p) { return car(car(p)); }; cadr = function(p) { return car(cdr(p)); }; cdar = function(p) { return cdr(car(p)); }; cddr = function(p) { return cdr(cdr(p)); }; caadr = function(p) { return car(car(cdr(p))); }; caddr = function(p) { return car(cdr(cdr(p))); }; cadar = function(p) { return car(cdr(car(p))); }; cdadr = function(p) { return cdr(car(cdr(p))); }; cddar = function(p) { return cdr(cdr(car(p))); }; cdddr = function(p) { return cdr(cdr(cdr(p))); }; caaddr = function(p) { return car(car(cdr(cdr(p)))); }; cadadr = function(p) { return car(cdr(car(cdr(p)))); }; caddar = function(p) { return car(cdr(cdr(car(p)))); }; cdaddr = function(p) { return cdr(car(cdr(cdr(p)))); }; cadddr = function(p) { return car(cdr(cdr(cdr(p)))); }; cddddr = function(p) { return cdr(cdr(cdr(cdr(p)))); }; caddddr = function(p) { return car(cdr(cdr(cdr(cdr(p))))); }; cadaddr = function(p) { return car(cdr(car(cdr(cdr(p))))); }; cddaddr = function(p) { return cdr(cdr(car(cdr(cdr(p))))); }; caddadr = function(p) { return car(cdr(cdr(car(cdr(p))))); }; cdddaddr = function(p) { return cdr(cdr(cdr(car(cdr(cdr(p)))))); }; caddaddr = function(p) { return car(cdr(cdr(car(cdr(cdr(p)))))); }; isadd = function(p) { return car(p) === symbol(ADD); }; ismultiply = function(p) { return car(p) === symbol(MULTIPLY); }; ispower = function(p) { return car(p) === symbol(POWER); }; isfactorial = function(p) { return car(p) === symbol(FACTORIAL); }; MSIGN = function(p) { if (p.isPositive()) { return 1; } else if (p.isZero()) { return 0; } else { return -1; } }; MLENGTH = function(p) { return p.toString().length; }; MZERO = function(p) { return p.isZero(); }; MEQUAL = function(p, n) { if (p == null) { debugger; } return p.equals(n); }; $ = typeof exports !== "undefined" && exports !== null ? exports : this; $.isadd = isadd; $.ismultiply = ismultiply; $.ispower = ispower; $.isfactorial = isfactorial; $.car = car; $.cdr = cdr; $.caar = caar; $.cadr = cadr; $.cdar = cdar; $.cddr = cddr; $.caadr = caadr; $.caddr = caddr; $.cadar = cadar; $.cdadr = cdadr; $.cddar = cddar; $.cdddr = cdddr; $.caaddr = caaddr; $.cadadr = cadadr; $.caddar = caddar; $.cdaddr = cdaddr; $.cadddr = cadddr; $.cddddr = cddddr; $.caddddr = caddddr; $.cadaddr = cadaddr; $.cddaddr = cddaddr; $.caddadr = caddadr; $.cdddaddr = cdddaddr; $.caddaddr = caddaddr; $.symbol = symbol; $.iscons = iscons; $.isrational = isrational; $.isdouble = isdouble; $.isnum = isnum; $.isstr = isstr; $.istensor = istensor; $.issymbol = issymbol; $.iskeyword = iskeyword; $.CONS = CONS; $.NUM = NUM; $.DOUBLE = DOUBLE; $.STR = STR; $.TENSOR = TENSOR; $.SYM = SYM; Eval_abs = function() { push(cadr(p1)); Eval(); return absval(); }; absval = function() { var h; h = 0; save(); p1 = pop(); if (istensor(p1)) { absval_tensor(); restore(); return; } if (isnum(p1)) { push(p1); if (isnegativenumber(p1)) { negate(); } restore(); return; } if (iscomplexnumber(p1)) { push(p1); push(p1); conjugate(); multiply(); push_rational(1, 2); power(); restore(); return; } if (car(p1) === symbol(POWER) && isnegativeterm(caddr(p1))) { push(p1); reciprocate(); absval(); reciprocate(); restore(); return; } if (car(p1) === symbol(MULTIPLY)) { h = tos; p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); absval(); p1 = cdr(p1); } multiply_all(tos - h); restore(); return; } if (isnegativeterm(p1) || (car(p1) === symbol(ADD) && isnegativeterm(cadr(p1)))) { push(p1); negate(); p1 = pop(); } push_symbol(ABS); push(p1); list(2); return restore(); }; absval_tensor = function() { if (p1.tensor.ndim !== 1) { stop("abs(tensor) with tensor rank > 1"); } push(p1); push(p1); conjugate(); inner(); push_rational(1, 2); power(); simplify(); return Eval(); }; /* Symbolic addition Terms in a sum are combined if they are identical modulo rational coefficients. For example, A + 2A becomes 3A. However, the sum A + sqrt(2) A is not modified. Combining terms can lead to second-order effects. For example, consider the case of 1/sqrt(2) A + 3/sqrt(2) A + sqrt(2) A The first two terms are combined to yield 2 sqrt(2) A. This result can now be combined with the third term to yield 3 sqrt(2) A */ flag = 0; Eval_add = function() { var h; h = tos; p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); Eval(); p2 = pop(); push_terms(p2); p1 = cdr(p1); } return add_terms(tos - h); }; stackAddsCount = 0; add_terms = function(n) { var ac, ad, h, i, o, ref, ref1, results, s, subsetOfStack; stackAddsCount++; i = 0; h = tos - n; s = h; if (DEBUG) { console.log("stack before adding terms #" + stackAddsCount); } if (DEBUG) { for (i = o = 0, ref = tos; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { print1(stack[i]); } } for (i = ac = 0; ac < 10; i = ++ac) { if (n < 2) { break; } flag = 0; subsetOfStack = stack.slice(h, h + n); subsetOfStack.sort(cmp_terms); stack = stack.slice(0, h).concat(subsetOfStack).concat(stack.slice(h + n)); if (flag === 0) { break; } n = combine_terms(h, n); } tos = h + n; switch (n) { case 0: push_integer(0); break; case 1: break; default: list(n); p1 = pop(); push_symbol(ADD); push(p1); cons(); } if (DEBUG) { console.log("stack after adding terms #" + stackAddsCount); } if (DEBUG) { results = []; for (i = ad = 0, ref1 = tos; 0 <= ref1 ? ad < ref1 : ad > ref1; i = 0 <= ref1 ? ++ad : --ad) { results.push(print1(stack[i])); } return results; } }; cmp_terms_count = 0; cmp_terms = function(p1, p2) { var i, o, ref, t; cmp_terms_count++; i = 0; if (isnum(p1) && isnum(p2)) { flag = 1; return 0; } if (istensor(p1) && istensor(p2)) { if (p1.tensor.ndim < p2.tensor.ndim) { return -1; } if (p1.tensor.ndim > p2.tensor.ndim) { return 1; } for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { if (p1.tensor.dim[i] < p2.tensor.dim[i]) { return -1; } if (p1.tensor.dim[i] > p2.tensor.dim[i]) { return 1; } } flag = 1; return 0; } if (car(p1) === symbol(MULTIPLY)) { p1 = cdr(p1); if (isnum(car(p1))) { p1 = cdr(p1); if (cdr(p1) === symbol(NIL)) { p1 = car(p1); } } } if (car(p2) === symbol(MULTIPLY)) { p2 = cdr(p2); if (isnum(car(p2))) { p2 = cdr(p2); if (cdr(p2) === symbol(NIL)) { p2 = car(p2); } } } t = cmp_expr(p1, p2); if (t === 0) { flag = 1; } return t; }; /* Compare adjacent terms in s[] and combine if possible. Returns the number of terms remaining in s[]. n number of terms in s[] initially */ combine_terms = function(s, n) { var ac, ad, ae, af, i, j, o, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, t; i = 0; while (i < (n - 1)) { check_esc_flag(); p3 = stack[s + i]; p4 = stack[s + i + 1]; if (istensor(p3) && istensor(p4)) { push(p3); push(p4); tensor_plus_tensor(); p1 = pop(); if (p1 !== symbol(NIL)) { stack[s + i] = p1; for (j = o = ref = i + 1, ref1 = n - 1; ref <= ref1 ? o < ref1 : o > ref1; j = ref <= ref1 ? ++o : --o) { stack[s + j] = stack[s + j + 1]; } n--; i--; } i++; continue; } if (istensor(p3) || istensor(p4)) { i++; continue; } if (isnum(p3) && isnum(p4)) { push(p3); push(p4); add_numbers(); p1 = pop(); if (iszero(p1)) { for (j = ac = ref2 = i, ref3 = n - 2; ref2 <= ref3 ? ac < ref3 : ac > ref3; j = ref2 <= ref3 ? ++ac : --ac) { stack[s + j] = stack[s + j + 2]; } n -= 2; } else { stack[s + i] = p1; for (j = ad = ref4 = i + 1, ref5 = n - 1; ref4 <= ref5 ? ad < ref5 : ad > ref5; j = ref4 <= ref5 ? ++ad : --ad) { stack[s + j] = stack[s + j + 1]; } n--; } i--; i++; continue; } if (isnum(p3) || isnum(p4)) { i++; continue; } p1 = one; p2 = one; t = 0; if (car(p3) === symbol(MULTIPLY)) { p3 = cdr(p3); t = 1; if (isnum(car(p3))) { p1 = car(p3); p3 = cdr(p3); if (cdr(p3) === symbol(NIL)) { p3 = car(p3); t = 0; } } } if (car(p4) === symbol(MULTIPLY)) { p4 = cdr(p4); if (isnum(car(p4))) { p2 = car(p4); p4 = cdr(p4); if (cdr(p4) === symbol(NIL)) { p4 = car(p4); } } } if (!equal(p3, p4)) { i++; continue; } push(p1); push(p2); add_numbers(); p1 = pop(); if (iszero(p1)) { for (j = ae = ref6 = i, ref7 = n - 2; ref6 <= ref7 ? ae < ref7 : ae > ref7; j = ref6 <= ref7 ? ++ae : --ae) { stack[s + j] = stack[s + j + 2]; } n -= 2; i--; i++; continue; } push(p1); if (t) { push(symbol(MULTIPLY)); push(p3); cons(); } else { push(p3); } multiply(); stack[s + i] = pop(); for (j = af = ref8 = i + 1, ref9 = n - 1; ref8 <= ref9 ? af < ref9 : af > ref9; j = ref8 <= ref9 ? ++af : --af) { stack[s + j] = stack[s + j + 1]; } n--; i--; i++; } return n; }; push_terms = function(p) { var results; if (car(p) === symbol(ADD)) { p = cdr(p); results = []; while (iscons(p)) { push(car(p)); results.push(p = cdr(p)); } return results; } else if (!iszero(p)) { return push(p); } }; add = function() { var h; save(); p2 = pop(); p1 = pop(); h = tos; push_terms(p1); push_terms(p2); add_terms(tos - h); return restore(); }; add_all = function(k) { var h, i, o, ref, s; i = 0; save(); s = tos - k; h = tos; for (i = o = 0, ref = k; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { push_terms(stack[s + i]); } add_terms(tos - h); p1 = pop(); tos -= k; push(p1); return restore(); }; subtract = function() { negate(); return add(); }; Eval_adj = function() { push(cadr(p1)); Eval(); return adj(); }; adj = function() { var ac, doNothing, i, j, n, o, ref, ref1; i = 0; j = 0; n = 0; save(); p1 = pop(); if (istensor(p1) && p1.tensor.ndim === 2 && p1.tensor.dim[0] === p1.tensor.dim[1]) { doNothing = 1; } else { stop("adj: square matrix expected"); } n = p1.tensor.dim[0]; p2 = alloc_tensor(n * n); p2.tensor.ndim = 2; p2.tensor.dim[0] = n; p2.tensor.dim[1] = n; for (i = o = 0, ref = n; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) { for (j = ac = 0, ref1 = n; 0 <= ref1 ? ac < ref1 : ac > ref1; j = 0 <= ref1 ? ++ac : --ac) { cofactor(p1, n, i, j); p2.tensor.elem[n * j + i] = pop(); } } push(p2); return restore(); }; Eval_arccos = function() { push(cadr(p1)); Eval(); return arccos(); }; arccos = function() { var d, errno, n; n = 0; d = 0.0; save(); p1 = pop(); if (car(p1) === symbol(COS)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { errno = 0; d = Math.acos(p1.d); if (errno) { stop("arccos function argument is not in the interval [-1,1]"); } push_double(d); restore(); return; } if (isoneoversqrttwo(p1)) { push_rational(1, 4); push_symbol(PI); multiply(); restore(); return; } if (isminusoneoversqrttwo(p1)) { push_rational(3, 4); push_symbol(PI); multiply(); restore(); return; } if (!isrational(p1)) { push_symbol(ARCCOS); push(p1); list(2); restore(); return; } push(p1); push_integer(2); multiply(); n = pop_integer(); switch (n) { case -2: push_symbol(PI); break; case -1: push_rational(2, 3); push_symbol(PI); multiply(); break; case 0: push_rational(1, 2); push_symbol(PI); multiply(); break; case 1: push_rational(1, 3); push_symbol(PI); multiply(); break; case 2: push(zero); break; default: push_symbol(ARCCOS); push(p1); list(2); } return restore(); }; Eval_arccosh = function() { push(cadr(p1)); Eval(); return arccosh(); }; arccosh = function() { var d; d = 0.0; save(); p1 = pop(); if (car(p1) === symbol(COSH)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { d = p1.d; if (d < 1.0) { stop("arccosh function argument is less than 1.0"); } d = Math.log(d + Math.sqrt(d * d - 1.0)); push_double(d); restore(); return; } if (isplusone(p1)) { push(zero); restore(); return; } push_symbol(ARCCOSH); push(p1); list(2); return restore(); }; Eval_arcsin = function() { push(cadr(p1)); Eval(); return arcsin(); }; arcsin = function() { var d, errno, n; n = 0; d = 0; save(); p1 = pop(); if (car(p1) === symbol(SIN)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { errno = 0; d = Math.asin(p1.d); if (errno) { stop("arcsin function argument is not in the interval [-1,1]"); } push_double(d); restore(); return; } if (isoneoversqrttwo(p1)) { push_rational(1, 4); push_symbol(PI); multiply(); restore(); return; } if (isminusoneoversqrttwo(p1)) { push_rational(-1, 4); push_symbol(PI); multiply(); restore(); return; } if (!isrational(p1)) { push_symbol(ARCSIN); push(p1); list(2); restore(); return; } push(p1); push_integer(2); multiply(); n = pop_integer(); switch (n) { case -2: push_rational(-1, 2); push_symbol(PI); multiply(); break; case -1: push_rational(-1, 6); push_symbol(PI); multiply(); break; case 0: push(zero); break; case 1: push_rational(1, 6); push_symbol(PI); multiply(); break; case 2: push_rational(1, 2); push_symbol(PI); multiply(); break; default: push_symbol(ARCSIN); push(p1); list(2); } return restore(); }; Eval_arcsinh = function() { push(cadr(p1)); Eval(); return arcsinh(); }; arcsinh = function() { var d; d = 0.0; save(); p1 = pop(); if (car(p1) === symbol(SINH)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { d = p1.d; d = Math.log(d + Math.sqrt(d * d + 1.0)); push_double(d); restore(); return; } if (iszero(p1)) { push(zero); restore(); return; } push_symbol(ARCSINH); push(p1); list(2); return restore(); }; Eval_arctan = function() { push(cadr(p1)); Eval(); return arctan(); }; arctan = function() { var d, errno; d = 0; save(); p1 = pop(); if (car(p1) === symbol(TAN)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { errno = 0; d = Math.atan(p1.d); if (errno) { stop("arctan function error"); } push_double(d); restore(); return; } if (iszero(p1)) { push(zero); restore(); return; } if (isnegative(p1)) { push(p1); negate(); arctan(); negate(); restore(); return; } if (Find(p1, symbol(SIN)) && Find(p1, symbol(COS))) { push(p1); numerator(); p2 = pop(); push(p1); denominator(); p3 = pop(); if (car(p2) === symbol(SIN) && car(p3) === symbol(COS) && equal(cadr(p2), cadr(p3))) { push(cadr(p2)); restore(); return; } } if (car(p1) === symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), -1, 2)) { push_rational(1, 6); push(symbol(PI)); multiply(); restore(); return; } if (equaln(p1, 1)) { push_rational(1, 4); push(symbol(PI)); multiply(); restore(); return; } if (car(p1) === symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), 1, 2)) { push_rational(1, 3); push(symbol(PI)); multiply(); restore(); return; } push_symbol(ARCTAN); push(p1); list(2); return restore(); }; Eval_arctanh = function() { push(cadr(p1)); Eval(); return arctanh(); }; arctanh = function() { var d; d = 0.0; save(); p1 = pop(); if (car(p1) === symbol(TANH)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { d = p1.d; if (d < -1.0 || d > 1.0) { stop("arctanh function argument is not in the interval [-1,1]"); } d = Math.log((1.0 + d) / (1.0 - d)) / 2.0; push_double(d); restore(); return; } if (iszero(p1)) { push(zero); restore(); return; } push_symbol(ARCTANH); push(p1); list(2); return restore(); }; /* Argument (angle) of complex z z arg(z) - ------ a 0 -a -pi See note 3 below (-1)^a a pi exp(a + i b) b a b arg(a) + arg(b) a + i b arctan(b/a) Result by quadrant z arg(z) - ------ 1 + i 1/4 pi 1 - i -1/4 pi -1 + i 3/4 pi -1 - i -3/4 pi Notes 1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3) 2. Symbols in z are assumed to be positive and real. 3. Negative direction adds -pi to angle. Example: z = (-1)^(1/3), mag(z) = 1/3 pi, mag(-z) = -2/3 pi 4. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then arg(numerator(z)) - arg(denominator(z)) must be used to get the correct answer. Now the operation is automatic. */ Eval_arg = function() { push(cadr(p1)); Eval(); return arg(); }; arg = function() { save(); p1 = pop(); push(p1); numerator(); yyarg(); push(p1); denominator(); yyarg(); subtract(); return restore(); }; yyarg = function() { save(); p1 = pop(); if (isnegativenumber(p1)) { push(symbol(PI)); negate(); } else if (car(p1) === symbol(POWER) && equaln(cadr(p1), -1)) { push(symbol(PI)); push(caddr(p1)); multiply(); } else if (car(p1) === symbol(POWER) && cadr(p1) === symbol(E)) { push(caddr(p1)); imag(); } else if (car(p1) === symbol(MULTIPLY)) { push_integer(0); p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); arg(); add(); p1 = cdr(p1); } } else if (car(p1) === symbol(ADD)) { push(p1); rect(); p1 = pop(); push(p1); real(); p2 = pop(); push(p1); imag(); p3 = pop(); if (iszero(p2)) { push(symbol(PI)); if (isnegative(p3)) { negate(); } } else { push(p3); push(p2); divide(); arctan(); if (isnegative(p2)) { push_symbol(PI); if (isnegative(p3)) { subtract(); } else { add(); } } } } else { push_integer(0); } return restore(); }; bake = function() { var h, s, t, x, y, z; h = 0; s = 0; t = 0; x = 0; y = 0; z = 0; expanding++; save(); p1 = pop(); s = ispoly(p1, symbol(SYMBOL_S)); t = ispoly(p1, symbol(SYMBOL_T)); x = ispoly(p1, symbol(SYMBOL_X)); y = ispoly(p1, symbol(SYMBOL_Y)); z = ispoly(p1, symbol(SYMBOL_Z)); if (s === 1 && t === 0 && x === 0 && y === 0 && z === 0) { p2 = symbol(SYMBOL_S); bake_poly(); } else if (s === 0 && t === 1 && x === 0 && y === 0 && z === 0) { p2 = symbol(SYMBOL_T); bake_poly(); } else if (s === 0 && t === 0 && x === 1 && y === 0 && z === 0) { p2 = symbol(SYMBOL_X); bake_poly(); } else if (s === 0 && t === 0 && x === 0 && y === 1 && z === 0) { p2 = symbol(SYMBOL_Y); bake_poly(); } else if (s === 0 && t === 0 && x === 0 && y === 0 && z === 1) { p2 = symbol(SYMBOL_Z); bake_poly(); } else if (iscons(p1)) { h = tos; push(car(p1)); p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); bake(); p1 = cdr(p1); } list(tos - h); } else { push(p1); } restore(); return expanding--; }; polyform = function() { var h; h = 0; save(); p2 = pop(); p1 = pop(); if (ispoly(p1, p2)) { bake_poly(); } else if (iscons(p1)) { h = tos; push(car(p1)); p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); push(p2); polyform(); p1 = cdr(p1); } list(tos - h); } else { push(p1); } return restore(); }; bake_poly = function() { var a, h, i, k, n, o, ref; h = 0; i = 0; k = 0; n = 0; a = tos; push(p1); push(p2); k = coeff(); h = tos; for (i = o = ref = k - 1; o >= 0; i = o += -1) { p1 = stack[a + i]; bake_poly_term(i); } n = tos - h; if (n > 1) { list(n); push(symbol(ADD)); swap(); cons(); } p1 = pop(); tos -= k; return push(p1); }; bake_poly_term = function(k) { var h, n; h = 0; n = 0; if (iszero(p1)) { return; } if (k === 0) { if (car(p1) === symbol(ADD)) { p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); p1 = cdr(p1); } } else { push(p1); } return; } h = tos; if (car(p1) === symbol(MULTIPLY)) { p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); p1 = cdr(p1); } } else if (!equaln(p1, 1)) { push(p1); } if (k === 1) { push(p2); } else { push(symbol(POWER)); push(p2); push_integer(k); list(3); } n = tos - h; if (n > 1) { list(n); push(symbol(MULTIPLY)); swap(); return cons(); } }; /* Bessel J function 1st arg x 2nd arg n Recurrence relation besselj(x,n) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n-2) besselj(x,1/2) = sqrt(2/pi/x) sin(x) besselj(x,-1/2) = sqrt(2/pi/x) cos(x) For negative n, reorder the recurrence relation as besselj(x,n-2) = (2/x) (n-1) besselj(x,n-1) - besselj(x,n) Substitute n+2 for n to obtain besselj(x,n) = (2/x) (n+1) besselj(x,n+1) - besselj(x,n+2) Examples besselj(x,3/2) = (1/x) besselj(x,1/2) - besselj(x,-1/2) besselj(x,-3/2) = -(1/x) besselj(x,-1/2) - besselj(x,1/2) */ Eval_besselj = function() { push(cadr(p1)); Eval(); push(caddr(p1)); Eval(); return besselj(); }; besselj = function() { save(); yybesselj(); return restore(); }; yybesselj = function() { var d, n; d = 0.0; n = 0; p2 = pop(); p1 = pop(); push(p2); n = pop_integer(); if (isdouble(p1) && n !== 0x80000000) { d = jn(n, p1.d); push_double(d); return; } if (iszero(p1) && iszero(p2)) { push_integer(1); return; } if (iszero(p1) && n !== 0x80000000) { push_integer(0); return; } if (p2.k === NUM && MEQUAL(p2.q.b, 2)) { if (MEQUAL(p2.q.a, 1)) { push_integer(2); push_symbol(PI); divide(); push(p1); divide(); push_rational(1, 2); power(); push(p1); sine(); multiply(); return; } if (MEQUAL(p2.q.a, -1)) { push_integer(2); push_symbol(PI); divide(); push(p1); divide(); push_rational(1, 2); power(); push(p1); cosine(); multiply(); return; } push_integer(MSIGN(p2.q.a)); p3 = pop(); push_integer(2); push(p1); divide(); push(p2); push(p3); subtract(); multiply(); push(p1); push(p2); push(p3); subtract(); besselj(); multiply(); push(p1); push(p2); push_integer(2); push(p3); multiply(); subtract(); besselj(); subtract(); return; } if (isnegativeterm(p1)) { push(p1); negate(); push(p2); power(); push(p1); push(p2); negate(); power(); multiply(); push_symbol(BESSELJ); push(p1); negate(); push(p2); list(3); multiply(); return; } if (isnegativeterm(p2)) { push_integer(-1); push(p2); power(); push_symbol(BESSELJ); push(p1); push(p2); negate(); list(3); multiply(); return; } push(symbol(BESSELJ)); push(p1); push(p2); return list(3); }; Eval_bessely = function() { push(cadr(p1)); Eval(); push(caddr(p1)); Eval(); return bessely(); }; bessely = function() { save(); yybessely(); return restore(); }; yybessely = function() { var d, n; d = 0.0; n = 0; p2 = pop(); p1 = pop(); push(p2); n = pop_integer(); if (isdouble(p1) && n !== 0x80000000) { d = yn(n, p1.d); push_double(d); return; } if (isnegativeterm(p2)) { push_integer(-1); push(p2); power(); push_symbol(BESSELY); push(p1); push(p2); negate(); list(3); multiply(); return; } push_symbol(BESSELY); push(p1); push(p2); list(3); }; MP_MIN_SIZE = 2; MP_MAX_FREE = 1000; mtotal = 0; free_stack = []; mint = function(a) { return bigInt(a); }; setSignTo = function(a, b) { if (a.isPositive()) { if (b < 0) { return a.multiply(bigInt(-1)); } } else { if (b > 0) { return a.multiply(bigInt(-1)); } } return a; }; makeSignSameAs = function(a, b) { if (a.isPositive()) { if (b.isNegative()) { return a.multiply(bigInt(-1)); } } else { if (b.isPositive()) { return a.multiply(bigInt(-1)); } } return a; }; makePositive = function(a) { if (a.isNegative()) { return a.multiply(bigInt(-1)); } return a; }; /* mnew = (n) -> if (n < MP_MIN_SIZE) n = MP_MIN_SIZE if (n == MP_MIN_SIZE && mfreecount) p = free_stack[--mfreecount] else p = [] #(unsigned int *) malloc((n + 3) * sizeof (int)) #if (p == 0) * stop("malloc failure") p[0] = n mtotal += n return p[3] */ /* mfree = (array, p) -> p -= 3 mtotal -= array[p] if (array[p] == MP_MIN_SIZE && mfreecount < MP_MAX_FREE) free_stack[mfreecount++] = p else free(p) */ /* mint = (n) -> p = mnew(1) if (n < 0) * !!! this is FU * MSIGN(p) = -1 fu = true else * !!! this is FU #MSIGN(p) = 1 fu = true * !!! this is FU #MLENGTH(p) = 1 p[0] = Math.abs(n) return p */ /* mcopy = (a) -> #unsigned int *b b = mnew(MLENGTH(a)) * !!! fu #MSIGN(b) = MSIGN(a) #MLENGTH(b) = MLENGTH(a) for i in [0...MLENGTH(a)] b[i] = a[i] return b */ /* * * ge not invoked from anywhere - is you need ge * just use the bigNum's ge implementation * leaving it here just in case I decide to backport to C * * a >= b ? * and and b arrays of ints, len is an int ge = (a, b, len) -> i = 0 for i in [0...len] if (a[i] == b[i]) continue else break if (a[i] >= b[i]) return 1 else return 0 */ add_numbers = function() { var a, b, theResult; a = 1.0; b = 1.0; if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) { qadd(); return; } save(); p2 = pop(); p1 = pop(); if (isdouble(p1)) { a = p1.d; } else { a = convert_rational_to_double(p1); } if (isdouble(p2)) { b = p2.d; } else { b = convert_rational_to_double(p2); } theResult = a + b; push_double(theResult); return restore(); }; subtract_numbers = function() { var a, b; a = 0.0; b = 0.0; if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) { qsub(); return; } save(); p2 = pop(); p1 = pop(); if (isdouble(p1)) { a = p1.d; } else { a = convert_rational_to_double(p1); } if (isdouble(p2)) { b = p2.d; } else { b = convert_rational_to_double(p2); } push_double(a - b); return restore(); }; multiply_numbers = function() { var a, b; a = 0.0; b = 0.0; if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) { qmul(); return; } save(); p2 = pop(); p1 = pop(); if (isdouble(p1)) { a = p1.d; } else { a = convert_rational_to_double(p1); } if (isdouble(p2)) { b = p2.d; } else { b = convert_rational_to_double(p2); } push_double(a * b); return restore(); }; divide_numbers = function() { var a, b; a = 0.0; b = 0.0; if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) { qdiv(); return; } save(); p2 = pop(); p1 = pop(); if (iszero(p2)) { stop("divide by zero"); } if (isdouble(p1)) { a = p1.d; } else { a = convert_rational_to_double(p1); } if (isdouble(p2)) { b = p2.d; } else { b = convert_rational_to_double(p2); } push_double(a / b); return restore(); }; invert_number = function() { var a, b; save(); p1 = pop(); if (iszero(p1)) { stop("divide by zero"); } if (isdouble(p1)) { push_double(1 / p1.d); restore(); return; } a = bigInt(p1.q.a); b = bigInt(p1.q.b); b = makeSignSameAs(b, a); a = setSignTo(a, 1); p1 = new U(); p1.k = NUM; p1.q.a = b; p1.q.b = a; push(p1);