UNPKG

algebrite

Version:

Computer Algebra System in Coffeescript

1,821 lines (1,354 loc) 599 kB
// 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;