UNPKG

algebrite

Version:

Computer Algebra System in Coffeescript

209 lines (164 loc) 3.38 kB
# s is a string new_string = (s) -> save() p1 = new U() p1.k = STR p1.str = s push(p1) restore() out_of_memory = -> stop("out of memory") # both ints push_zero_matrix = (i,j) -> push(alloc_tensor(i * j)) stack[tos - 1].tensor.ndim = 2 stack[tos - 1].tensor.dim[0] = i stack[tos - 1].tensor.dim[1] = j push_identity_matrix = (n) -> push_zero_matrix(n, n) i = 0 for i in [0...n] stack[tos - 1].tensor.elem[i * n + i] = one check_tensor_dimensions stack[tos - 1] push_cars = (p) -> while (iscons(p)) push(car(p)) p = cdr(p) peek = -> save() p1 = pop() push(p1) restore() # see cmp_expr definition, this # function alone just does simple structure comparison # or compares numbers (either rationals or integers or doubles) # but can't be used alone to test # more complex mathematical equalities... equal = (p1,p2) -> if (cmp_expr(p1, p2) == 0) return 1 else return 0 lessp = (p1,p2) -> if (cmp_expr(p1, p2) < 0) return 1 else return 0 sign = (n) -> if (n < 0) return -1 else if (n > 0) return 1 else return 0 # compares whether two expressions # have the same structure. # For example this method alone # would compare "1+1" and "2" # as different. # It just so happens though that one oftens # evaluates the two sides before passing them # to this function, so chances are that the two # sides have the same normal form. # Even a simple evaluation might not cut it # though... a simplification of both sides # would then help. And even that might not # cut it in some cases... cmp_expr = (p1, p2) -> n = 0 if (p1 == p2) return 0 if (p1 == symbol(NIL)) return -1 if (p2 == symbol(NIL)) return 1 if (isnum(p1) && isnum(p2)) return sign(compare_numbers(p1, p2)) if (isnum(p1)) return -1 if (isnum(p2)) return 1 if (isstr(p1) && isstr(p2)) return sign(strcmp(p1.str,p2.str)) if (isstr(p1)) return -1 if (isstr(p2)) return 1 if (issymbol(p1) && issymbol(p2)) return sign(strcmp(get_printname(p1),get_printname(p2))) if (issymbol(p1)) return -1 if (issymbol(p2)) return 1 if (istensor(p1) && istensor(p2)) return compare_tensors(p1, p2) if (istensor(p1)) return -1 if (istensor(p2)) return 1 # recursion here while (iscons(p1) && iscons(p2)) n = cmp_expr(car(p1), car(p2)) if (n != 0) return n p1 = cdr(p1) p2 = cdr(p2) if (iscons(p2)) return -1 if (iscons(p1)) return 1 return 0 length = (p) -> n = 0 while (iscons(p)) p = cdr(p) n++ return n unique = (p) -> save() p1 = symbol(NIL) p2 = symbol(NIL) unique_f(p) if (p2 != symbol(NIL)) p1 = symbol(NIL) p = p1 restore() return p unique_f = (p) -> if (isstr(p)) if (p1 == symbol(NIL)) p1 = p else if (p != p1) p2 = p return while (iscons(p)) unique_f(car(p)) if (p2 != symbol(NIL)) return p = cdr(p) ssqrt = -> push_rational(1, 2) power() yyexpand = -> prev_expanding = expanding expanding = 1 Eval() expanding = prev_expanding exponential = -> push_symbol(E) swap() power() square = -> push_integer(2) power() #__cmp = (p1, p2) -> # return cmp_expr(p1, p2) # n an integer sort_stack = (n) -> #qsort(stack + tos - n, n, sizeof (U *), __cmp) h = tos - n subsetOfStack = stack.slice(h,h+n) subsetOfStack.sort(cmp_expr) stack = stack.slice(0,h).concat(subsetOfStack).concat(stack.slice(h+n)) $.equal = equal $.length = length