UNPKG

algebrite

Version:

Computer Algebra System in Coffeescript

448 lines (374 loc) 7.98 kB
power_str = "^" stringToBePrinted = "" print_str = (s) -> stringToBePrinted += s print_char = (c) -> stringToBePrinted += c collectResultLine = (p) -> stringToBePrinted = "" print_expr(p) return stringToBePrinted printline = (p) -> #debugger stringToBePrinted = "" print_expr(p) console.log stringToBePrinted # prints stuff after the divide symbol "/" # d is the number of denominators #define BASE p1 #define EXPO p2 print_denom = (p, d) -> save() p1 = cadr(p); # p1 is BASE p2 = caddr(p); # p2 is EXPO # i.e. 1 / (2^(1/3)) if (d == 1 && !isminusone(p2)) # p2 is EXPO print_char('(') if (isfraction(p1) || car(p1) == symbol(ADD) || car(p1) == symbol(MULTIPLY) || car(p1) == symbol(POWER) || lessp(p1, zero)) # p1 is BASE print_char('(') print_expr(p1); # p1 is BASE print_char(')') else print_expr(p1); # p1 is BASE if (isminusone(p2)) # p2 is EXPO restore() return if (test_flag == 0) print_str(power_str) else print_char('^') push(p2); # p2 is EXPO negate() p2 = pop(); # p2 is EXPO if (isfraction(p2) || car(p2) == symbol(ADD) || car(p2) == symbol(MULTIPLY) || car(p2) == symbol(POWER)) # p2 is EXPO print_char('(') print_expr(p2); # p2 is EXPO print_char(')') else print_expr(p2); # p2 is EXPO if (d == 1) print_char(')') restore() #define A p3 #define B p4 print_a_over_b = (p) -> flag = 0 n = 0 d = 0 save() # count numerators and denominators n = 0 d = 0 p1 = cdr(p) p2 = car(p1) if (isrational(p2)) push(p2) mp_numerator() absval() p3 = pop(); # p3 is A push(p2) mp_denominator() p4 = pop(); # p4 is B if (!isplusone(p3)) # p3 is A n++ if (!isplusone(p4)) # p4 is B d++ p1 = cdr(p1) else p3 = one; # p3 is A p4 = one; # p4 is B while (iscons(p1)) p2 = car(p1) if (is_denominator(p2)) d++ else n++ p1 = cdr(p1) if (n == 0) print_char('1') else flag = 0 p1 = cdr(p) if (isrational(car(p1))) p1 = cdr(p1) if (!isplusone(p3)) # p3 is A print_factor(p3); # p3 is A flag = 1 while (iscons(p1)) p2 = car(p1) if (is_denominator(p2)) doNothing = 1 else if (flag) print_multiply_sign() print_factor(p2) flag = 1 p1 = cdr(p1) if (test_flag == 0) print_str(" / ") else print_str("/") if (d > 1) print_char('(') flag = 0 p1 = cdr(p) if (isrational(car(p1))) p1 = cdr(p1) if (!isplusone(p4)) # p4 is B print_factor(p4); # p4 is B flag = 1 while (iscons(p1)) p2 = car(p1) if (is_denominator(p2)) if (flag) print_multiply_sign() print_denom(p2, d) flag = 1 p1 = cdr(p1) if (d > 1) print_char(')') restore() print_expr = (p) -> if (isadd(p)) p = cdr(p) if (sign_of_term(car(p)) == '-') print_str("-") print_term(car(p)) p = cdr(p) while (iscons(p)) if (sign_of_term(car(p)) == '+') if (test_flag == 0) print_str(" + ") else print_str("+") else if (test_flag == 0) print_str(" - ") else print_str("-") print_term(car(p)) p = cdr(p) else if (sign_of_term(p) == '-') print_str("-") print_term(p) sign_of_term = (p) -> if (car(p) == symbol(MULTIPLY) && isnum(cadr(p)) && lessp(cadr(p), zero)) return '-' else if (isnum(p) && lessp(p, zero)) return '-' else return '+' print_term = (p) -> if (car(p) == symbol(MULTIPLY) && any_denominators(p)) print_a_over_b(p) return if (car(p) == symbol(MULTIPLY)) p = cdr(p) # coeff -1? if (isminusone(car(p))) # print_char('-') p = cdr(p) print_factor(car(p)) p = cdr(p) while (iscons(p)) print_multiply_sign() print_factor(car(p)) p = cdr(p) else print_factor(p) print_subexpr = (p) -> print_char('(') print_expr(p) print_char(')') print_factorial_function = (p) -> p = cadr(p) if (car(p) == symbol(ADD) || car(p) == symbol(MULTIPLY) || car(p) == symbol(POWER) || car(p) == symbol(FACTORIAL)) print_subexpr(p) else print_expr(p) print_char('!') print_tensor = (p) -> print_tensor_inner(p, 0, 0) print_tensor_inner = (p, j, k) -> i = 0 print_str("(") for i in [0...p.tensor.dim[j]] if (j + 1 == p.tensor.ndim) print_expr(p.tensor.elem[k]) k++ else k = print_tensor_inner(p, j + 1, k) if (i + 1 < p.tensor.dim[j]) if (test_flag == 0) print_str(",") else print_str(",") print_str(")") return k print_factor = (p) -> if (isnum(p)) print_number(p) return if (isstr(p)) #print_str("\"") print_str(p.str) #print_str("\"") return if (istensor(p)) print_tensor(p) return if (isadd(p) || car(p) == symbol(MULTIPLY)) print_str("(") print_expr(p) print_str(")") return if (car(p) == symbol(POWER)) if (cadr(p) == symbol(E)) print_str("exp(") print_expr(caddr(p)) print_str(")") return if (isminusone(caddr(p))) if (test_flag == 0) print_str("1 / ") else print_str("1/") if (iscons(cadr(p))) print_str("(") print_expr(cadr(p)) print_str(")") else print_expr(cadr(p)) return if (isadd(cadr(p)) || caadr(p) == symbol(MULTIPLY) || caadr(p) == symbol(POWER) || isnegativenumber(cadr(p))) print_str("(") print_expr(cadr(p)) print_str(")") else if (isnum(cadr(p)) && (lessp(cadr(p), zero) || isfraction(cadr(p)))) print_str("(") print_factor(cadr(p)) print_str(")") else print_factor(cadr(p)) if (test_flag == 0) #print_str(" ^ ") print_str(power_str) else print_str("^") if (iscons(caddr(p)) || isfraction(caddr(p)) || (isnum(caddr(p)) && lessp(caddr(p), zero))) print_str("(") print_expr(caddr(p)) print_str(")") else print_factor(caddr(p)) return # if (car(p) == _list) { # print_str("{") # p = cdr(p) # if (iscons(p)) { # print_expr(car(p)) # p = cdr(p) # } # while (iscons(p)) { # print_str(",") # print_expr(car(p)) # p = cdr(p) # } # print_str("}") # return # } if (car(p) == symbol(INDEX) && issymbol(cadr(p))) print_index_function(p) return if (car(p) == symbol(FACTORIAL)) print_factorial_function(p) return if (iscons(p)) #if (car(p) == symbol(FORMAL) && cadr(p)->k == SYM) { # print_str(((struct symbol *) cadr(p))->name) # return #} print_factor(car(p)) p = cdr(p) print_str("(") if (iscons(p)) print_expr(car(p)) p = cdr(p) while (iscons(p)) if (test_flag == 0) print_str(",") else print_str(",") print_expr(car(p)) p = cdr(p) print_str(")") return if (p == symbol(DERIVATIVE)) print_char('d') else if (p == symbol(E)) print_str("exp(1)") else if (p == symbol(PI)) print_str("pi") else print_str(get_printname(p)) print1 = (p, accumulator) -> topLevelCall = false if !accumulator? topLevelCall = true accumulator = "" switch (p.k) when CONS accumulator += ("(") accumulator = print1(car(p), accumulator) if p == cdr(p) console.log "oh no recursive!" debugger p = cdr(p) while (iscons(p)) accumulator += (" ") accumulator = print1(car(p), accumulator) p = cdr(p) if p == cdr(p) console.log "oh no recursive!" debugger if (p != symbol(NIL)) accumulator += (" . ") accumulator = print1(p, accumulator) accumulator += (")") when STR #print_str("\"") accumulator += (p.str) #print_str("\"") when NUM, DOUBLE accumulator = print_number(p, accumulator) when SYM accumulator += get_printname(p) else accumulator += ("<tensor>") if topLevelCall console.log accumulator else return accumulator print_multiply_sign = -> if (test_flag == 0) print_str(" ") else print_str("*") is_denominator = (p) -> if (car(p) == symbol(POWER) && cadr(p) != symbol(E) && isnegativeterm(caddr(p))) return 1 else return 0 # don't consider the leading fraction # we want 2/3*a*b*c instead of 2*a*b*c/3 any_denominators = (p) -> p = cdr(p) # if (isfraction(car(p))) # return 1 while (iscons(p)) q = car(p) if (is_denominator(q)) return 1 p = cdr(p) return 0