algebrite
Version:
Computer Algebra System in Coffeescript
2,323 lines (1,870 loc) • 359 kB
JavaScript
// 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);