algebrite
Version:
Computer Algebra System in Coffeescript
1,821 lines (1,354 loc) • 599 kB
JavaScript
// Generated by CoffeeScript 1.10.0
(function() {
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_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, 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, 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, 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, ac, ad, 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, 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, free_stack, 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, 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, isinv, iskeyword, isminusone, isminusoneoversqrttwo, isminusoneovertwo, ismultiply, isnegative, isnegativenumber, isnegativeterm, isnonnegativeinteger, isnpi, isnum, 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, laguerre, laguerre2, lastFoundSymbol, latexErrorSign, lcm, leading, legendre, length, lessp, level, list, logarithm, logbuf, lookupsTotal, lu_decomp, madd, 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_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, 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_BINOMIAL_latex, print_DEFINT_latex, print_DOT_latex, print_INV_latex, print_SQRT_latex, print_TRANSPOSE_latex, 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_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, scan_meta, scan_power, scan_relation, scan_stmt, scan_str, scan_string, scan_subexpr, scan_symbol, 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_dependencies, test_flag, text_metric, theRandom, token, token_buf, token_str, 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, 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, yysgn, yysimfac, yysinh, yytangent, zero, zzfloat,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
slice = [].slice;
bigInt = require('big-integer');
version = "0.4.4";
SELFTEST = 1;
NSYM = 1000;
DEBUG = false;
PRINTOUTRESULT = false;
PRINTMODE_LATEX = "PRINTMODE_LATEX";
PRINTMODE_2DASCII = "PRINTMODE_2DASCII";
PRINTMODE_FULL = "PRINTMODE_FULL";
PRINTMODE_PLAIN = "PRINTMODE_PLAIN";
PRINTMODE_LIST = "PRINTMODE_LIST";
environment_printmode = PRINTMODE_PLAIN;
printMode = PRINTMODE_PLAIN;
dontCreateNewRadicalsInDenominatorWhenEvalingMultiplication = true;
recursionLevelNestedRadicalsRemoval = 0;
do_simplify_nested_radicals = true;
avoidCalculatingPowersIntoArctans = true;
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 print_expr(this);
};
U.prototype.toLatexString = function() {
return collectLatexStringFromReturnValue(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++;
APPROXRATIO = 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++;
CLEARALL = counter++;
CLEARPATTERNS = 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++;
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++;
FUNCTION = 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++;
LOOKUP = counter++;
MOD = counter++;
MULTIPLY = counter++;
NOT = counter++;
NROOTS = counter++;
NUMBER = counter++;
NUMERATOR = counter++;
OPERATOR = counter++;
OR = counter++;
OUTER = counter++;
PATTERN = counter++;
PATTERNSINFO = counter++;
POLAR = counter++;
POWER = counter++;
PRIME = counter++;
PRINT_LEAVE_E_ALONE = counter++;
PRINT_LEAVE_X_ALONE = counter++;
PRINT = counter++;
PRINT2DASCII = counter++;
PRINTFULL = counter++;
PRINTLATEX = counter++;
PRINTLIST = counter++;
PRINTPLAIN = counter++;
PRODUCT = counter++;
QUOTE = counter++;
QUOTIENT = counter++;
RANK = counter++;
RATIONALIZE = counter++;
REAL = counter++;
YYRECT = counter++;
ROOTS = counter++;
SETQ = counter++;
SGN = counter++;
SILENTPATTERN = counter++;
SIMPLIFY = counter++;
SIN = counter++;
SINH = counter++;
SHAPE = counter++;
SQRT = counter++;
STOP = counter++;
SUBST = counter++;
SUM = counter++;
SYMBOLSINFO = 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++;
LAST = counter++;
LAST_PRINT = counter++;
LAST_2DASCII_PRINT = counter++;
LAST_FULL_PRINT = counter++;
LAST_LATEX_PRINT = counter++;
LAST_LIST_PRINT = counter++;
LAST_PLAIN_PRINT = counter++;
AUTOEXPAND = counter++;
BAKE = counter++;
ASSUME_REAL_VARIABLES = counter++;
TRACE = counter++;
YYE = counter++;
DRAWX = counter++;
METAA = counter++;
METAB = counter++;
METAX = counter++;
SECRETX = counter++;
VERSION = 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++;
SYMBOL_IDENTITY_MATRIX = counter++;
SYMBOL_A_UNDERSCORE = counter++;
SYMBOL_B_UNDERSCORE = counter++;
SYMBOL_X_UNDERSCORE = 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;
MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES = 5;
MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE = 10;
ENABLE_CACHING = true;
cached_runs = null;
cached_findDependenciesInScript = null;
MAXDIM = 24;
symbolsDependencies = {};
symbolsHavingReassignments = [];
symbolsInExpressionsWithoutAssignments = [];
patternHasBeenFound = false;
predefinedSymbolsInGlobalScope_doNotTrackInDependencies = ["rationalize", "abs", "i", "pi", "sin", "cos", "roots", "integral", "derivative", "defint", "sqrt", "eig", "cov", "deig", "dcov"];
parse_time_simplifications = true;
chainOfUserSymbolsNotFunctionsBeingEvaluated = [];
stringsEmittedByUserPrintouts = "";
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;
evaluatingAsFloats = 0;
evaluatingPolar = 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 = [];
isSymbolReclaimable = [];
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;
one_as_double = null;
imaginaryunit = null;
out_buf = "";
out_count = 0;
test_flag = 0;
codeGen = false;
draw_stop_return = null;
userSimplificationsInListForm = [];
userSimplificationsInStringForm = [];
transpose_unicode = 7488;
dotprod_unicode = 183;
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);
};
isinnerordot = function(p) {
return (car(p) === symbol(INNER)) || (car(p) === symbol(DOT));
};
istranspose = function(p) {
return car(p) === symbol(TRANSPOSE);
};
isinv = function(p) {
return car(p) === symbol(INV);
};
isidentitymatrix = function(p) {
return p === symbol(SYMBOL_IDENTITY_MATRIX);
};
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);
};
reset_after_error = function() {
tos = 0;
esc_flag = 0;
draw_flag = 0;
frame = TOS;
evaluatingAsFloats = 0;
return evaluatingPolar = 0;
};
$ = typeof exports !== "undefined" && exports !== null ? exports : this;
$.version = version;
$.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;
/*
Absolute value of a number,or magnitude of complex z, or norm of a vector
z abs(z)
- ------
a a
-a a
(-1)^a 1
exp(a + i b) exp(a)
a b abs(a) abs(b)
a + i b sqrt(a^2 + b^2)
Notes
1. Handles mixed polar and rectangular forms, e.g. 1 + exp(i pi/3)
2. jean-francois.debroux reports that when z=(a+i*b)/(c+i*d) then
abs(numerator(z)) / abs(denominator(z))
must be used to get the correct answer. Now the operation is
automatic.
*/
DEBUG_ABS = false;
Eval_abs = function() {
push(cadr(p1));
Eval();
return abs();
};
absValFloat = function() {
Eval();
absval();
Eval();
return zzfloat();
};
abs = function() {
save();
p1 = pop();
push(p1);
numerator();
absval();
push(p1);
denominator();
absval();
divide();
return restore();
};
absval = function() {
var input;
save();
p1 = pop();
input = p1;
if (DEBUG_ABS) {
console.log("ABS of " + p1);
}
if (iszero(p1)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " just zero");
}
push(zero);
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (isnegativenumber(p1)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " just a negative");
}
push(p1);
negate();
restore();
return;
}
if (ispositivenumber(p1)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " just a positive");
}
push(p1);
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (p1 === symbol(PI)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " of PI");
}
push(p1);
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (car(p1) === symbol(ADD) && (findPossibleClockForm(p1) || findPossibleExponentialForm(p1) || Find(p1, imaginaryunit))) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " is a sum");
}
if (DEBUG_ABS) {
console.log("abs of a sum");
}
push(p1);
rect();
p1 = pop();
push(p1);
real();
push_integer(2);
power();
push(p1);
imag();
push_integer(2);
power();
add();
push_rational(1, 2);
power();
simplify_trig();
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (car(p1) === symbol(POWER) && equaln(cadr(p1), -1)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " is -1 to any power");
}
if (evaluatingAsFloats) {
if (DEBUG_ABS) {
console.log(" abs: numeric, so result is 1.0");
}
push_double(1.0);
} else {
if (DEBUG_ABS) {
console.log(" abs: symbolic, so result is 1");
}
push_integer(1);
}
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (car(p1) === symbol(POWER) && ispositivenumber(caddr(p1))) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " is something to the power of a positive number");
}
push(cadr(p1));
abs();
push(caddr(p1));
power();
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (car(p1) === symbol(POWER) && cadr(p1) === symbol(E)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " is an exponential");
}
push(caddr(p1));
real();
exponential();
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (car(p1) === symbol(MULTIPLY)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " is a product");
}
push_integer(1);
p1 = cdr(p1);
while (iscons(p1)) {
push(car(p1));
abs();
multiply();
p1 = cdr(p1);
}
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
if (car(p1) === symbol(ABS)) {
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " is abs of a abs");
}
push_symbol(ABS);
push(cadr(p1));
list(2);
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
restore();
return;
}
/*
* Evaluation via zzfloat()
* ...while this is in theory a powerful mechanism, I've commented it
* out because I've refined this method enough to not need this.
* Evaling via zzfloat() is in principle more problematic because it could
* require further evaluations which could end up in further "abs" which
* would end up in infinite loops. Better not use it if not necessary.
* we look directly at the float evaluation of the argument
* to see if we end up with a number, which would mean that there
* is no imaginary component and we can just return the input
* (or its negation) as the result.
push p1
zzfloat()
floatEvaluation = pop()
if (isnegativenumber(floatEvaluation))
if DEBUG_ABS then console.log " abs: " + p1 + " just a negative"
push(p1)
negate()
restore()
return
if (ispositivenumber(floatEvaluation))
if DEBUG_ABS then console.log " abs: " + p1 + " just a positive"
push(p1)
if DEBUG_ABS then console.log " --> ABS of " + input + " : " + stack[tos-1]
restore()
return
*/
if (istensor(p1)) {
absval_tensor();
restore();
return;
}
if (isnegativeterm(p1) || (car(p1) === symbol(ADD) && isnegativeterm(cadr(p1)))) {
push(p1);
negate();
p1 = pop();
}
if (DEBUG_ABS) {
console.log(" abs: " + p1 + " is nothing decomposable");
}
push_symbol(ABS);
push(p1);
list(2);
if (DEBUG_ABS) {
console.log(" --> ABS of " + input + " : " + stack[tos - 1]);
}
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) {
console.log(print_list(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:
if (evaluatingAsFloats) {
push_double(0.0);
} else {
push(zero);
}
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(console.log(print_list(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;
}
if (evaluatingAsFloats) {
p1 = one_as_double;
p2 = one_as_double;
} else {
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();
};
/*
Guesses a rational for each float in the passed expression
*/
Eval_approxratio = function() {
var theArgument;
theArgument = cadr(p1);
push(theArgument);
return approxratioRecursive();
};
approxratioRecursive = function() {
var ac, i, o, ref, ref1;
i = 0;
save();
p1 = pop();
if (istensor(p1)) {
p4 = alloc_tensor(p1.tensor.nelem);
p4.tensor.ndim = p1.tensor.ndim;
for (i = o = 0, ref = p1.tensor.ndim; 0 <= ref ? o < ref : o > ref; i = 0 <= ref ? ++o : --o) {
p4.tensor.dim[i] = p1.tensor.dim[i];
}
for (i = ac = 0, ref1 = p1.tensor.nelem; 0 <= ref1 ? ac < ref1 : ac > ref1; i = 0 <= ref1 ? ++ac : --ac) {
push(p1.tensor.elem[i]);
approxratioRecursive();
p4.tensor.elem[i] = pop();
check_tensor_dimensions(p4);
}
push(p4);
} else if (p1.k === DOUBLE) {
push(p1);
approxOneRatioOnly();
} else if (iscons(p1)) {
push(car(p1));
approxratioRecursive();
push(cdr(p1));
approxratioRecursive();
cons();
} else {
push(p1);
}
return restore();
};
approxOneRatioOnly = function() {
var numberOfDigitsAfterTheDot, precision, splitBeforeAndAfterDot, supposedlyTheFloat, theFloat, theRatio;
zzfloat();
supposedlyTheFloat = pop();
if (supposedlyTheFloat.k === DOUBLE) {
theFloat = supposedlyTheFloat.d;
splitBeforeAndAfterDot = theFloat.toString().split(".");
if (splitBeforeAndAfterDot.length === 2) {
numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
theRatio = floatToRatioRoutine(theFloat, precision);
push_rational(theRatio[0], theRatio[1]);
} else {
push_integer(theFloat);
}
return;
}
push_symbol(APPROXRATIO);
push(theArgument);
return list(2);
};
floatToRatioRoutine = function(decimal, AccuracyFactor) {
var DecimalSign, FractionDenominator, FractionNumerator, PreviousDenominator, ScratchValue, Z, ret;
FractionNumerator = void 0;
FractionDenominator = void 0;
DecimalSign = void 0;
Z = void 0;
PreviousDenominator = void 0;
ScratchValue = void 0;
ret = [0, 0];
if (isNaN(decimal)) {
return ret;
}
if (decimal === Infinity) {
ret[0] = 1;
ret[1] = 0;
return ret;
}
if (decimal === -Infinity) {
ret[0] = -1;
ret[1] = 0;
return ret;
}
if (decimal < 0.0) {
DecimalSign = -1.0;
} else {
DecimalSign = 1.0;
}
decimal = Math.abs(decimal);
if (Math.abs(decimal - Math.floor(decimal)) < AccuracyFactor) {
FractionNumerator = decimal * DecimalSign;
FractionDenominator = 1.0;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
}
if (decimal < 1.0e-19) {
FractionNumerator = DecimalSign;
FractionDenominator = 9999999999999999999.0;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
}
if (decimal > 1.0e19) {
FractionNumerator = 9999999999999999999.0 * DecimalSign;
FractionDenominator = 1.0;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
}
Z = decimal;
PreviousDenominator = 0.0;
FractionDenominator = 1.0;
while (true) {
Z = 1.0 / (Z - Math.floor(Z));
ScratchValue = FractionDenominator;
FractionDenominator = FractionDenominator * Math.floor(Z) + PreviousDenominator;
PreviousDenominator = ScratchValue;
FractionNumerator = Math.floor(decimal * FractionDenominator + 0.5);
if (!(Math.abs(decimal - (FractionNumerator / FractionDenominator)) > AccuracyFactor && Z !== Math.floor(Z))) {
break;
}
}
FractionNumerator = DecimalSign * FractionNumerator;
ret[0] = FractionNumerator;
ret[1] = FractionDenominator;
return ret;
};
approx_just_an_integer = 0;
approx_sine_of_rational = 1;
approx_sine_of_pi_times_rational = 2;
approx_rationalOfPi = 3;
approx_radicalOfRatio = 4;
approx_nothingUseful = 5;
approx_ratioOfRadical = 6;
approx_rationalOfE = 7;
approx_logarithmsOfRationals = 8;
approx_rationalsOfLogarithms = 9;
approxRationalsOfRadicals = function(theFloat) {
var ac, bestResultSoFar, complexity, error, hypothesis, i, j, len, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, ref, result, splitBeforeAndAfterDot;
splitBeforeAndAfterDot = theFloat.toString().split(".");
if (splitBeforeAndAfterDot.length === 2) {
numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
} else {
return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
}
console.log("precision: " + precision);
bestResultSoFar = null;
minimumComplexity = Number.MAX_VALUE;
ref = [2, 3, 5, 6, 7, 8, 10];
for (o = 0, len = ref.length; o < len; o++) {
i = ref[o];
for (j = ac = 1; ac <= 10; j = ++ac) {
hypothesis = Math.sqrt(i) / j;
if (Math.abs(hypothesis) > 1e-10) {
ratio = theFloat / hypothesis;
likelyMultiplier = Math.round(ratio);
error = Math.abs(1 - ratio / likelyMultiplier);
} else {
ratio = 1;
likelyMultiplier = 1;
error = Math.abs(theFloat - hypothesis);
}
if (error < 2 * precision) {
complexity = simpleComplexityMeasure(likelyMultiplier, i, j);
if (complexity < minimumComplexity) {
minimumComplexity = complexity;
result = likelyMultiplier + " * sqrt( " + i + " ) / " + j;
bestResultSoFar = [result, approx_ratioOfRadical, likelyMultiplier, i, j];
}
}
}
}
return bestResultSoFar;
};
approxRadicalsOfRationals = function(theFloat) {
var ac, bestResultSoFar, complexity, error, hypothesis, i, j, len, len1, likelyMultiplier, minimumComplexity, numberOfDigitsAfterTheDot, o, precision, ratio, ref, ref1, result, splitBeforeAndAfterDot;
splitBeforeAndAfterDot = theFloat.toString().split(".");
if (splitBeforeAndAfterDot.length === 2) {
numberOfDigitsAfterTheDot = splitBeforeAndAfterDot[1].length;
precision = 1 / Math.pow(10, numberOfDigitsAfterTheDot);
} else {
return ["" + Math.floor(theFloat), approx_just_an_integer, Math.floor(theFloat), 1, 2];
}
console.log("precision: " + precision);
bestResultSoFar = null;
minimumComplexity = Number.MAX_VALUE;
ref = [1, 2, 3, 5, 6, 7, 8, 10];
for (o = 0, len = ref.length; o < len; o++) {
i = ref[o];
ref1 = [1, 2, 3, 5, 6, 7, 8, 10];
for (ac = 0, len1 = ref1.length; ac < len1; ac++) {
j = ref1[ac];
hypothesis = Math.sqrt(i / j);
if (Math.abs(hypothesis) > 1e-10) {
ratio = theFloat / hypothesis;