UNPKG

13.7 kBtext/coffeescriptView Raw
1bigInt = require('big-integer')
2
3# also change the version in the package.json file
4version = "1.1.1"
5
6SELFTEST = 1
7
8# size of the symbol table
9NSYM = 1000
10
11DEBUG = false
12PRINTOUTRESULT = false
13
14# printing-related constants
15PRINTMODE_LATEX = "PRINTMODE_LATEX"
16PRINTMODE_2DASCII = "PRINTMODE_2DASCII"
17PRINTMODE_FULL = "PRINTMODE_FULL"
18PRINTMODE_PLAIN = "PRINTMODE_PLAIN"
19PRINTMODE_LIST = "PRINTMODE_LIST"
20
21# when the user uses the generic "print" statement
22# this setting kicks-in.
23environment_printmode = PRINTMODE_PLAIN
24printMode = PRINTMODE_PLAIN
25
26dontCreateNewRadicalsInDenominatorWhenEvalingMultiplication = true
27recursionLevelNestedRadicalsRemoval = 0
28do_simplify_nested_radicals = true
29avoidCalculatingPowersIntoArctans = true
30
31# Symbolic expressions are built by connecting U structs.
32#
33# For example, (a b + c) is built like this:
34#
35# _______ _______ _______
36# |CONS |--->|CONS |----------------------------->|CONS |
37# | | | | | |
38# |_______| |_______| |_______|
39# | | |
40# ___v___ ___v___ _______ _______ ___v___
41# |ADD | |CONS |--->|CONS |--->|CONS | |SYM c |
42# | | | | | | | | | |
43# |_______| |_______| |_______| |_______| |_______|
44# | | |
45# ___v___ ___v___ ___v___
46# |MUL | |SYM a | |SYM b |
47# | | | | | |
48# |_______| |_______| |_______|
49
50
51
52class rational
53 a: null # a bigInteger
54 b: null # a bigInteger
55
56class U
57 cons: null # will have a car and cdr
58 printname: ""
59 str: ""
60 tensor: null
61 # rational number a over b
62 q: null # will point to a rational
63 d: 0.0 # a double
64 k: 0
65 tag: 0
66
67 toString: -> print_expr(this)
68 toLatexString: -> collectLatexStringFromReturnValue(this)
69
70 constructor: ->
71 @cons = {}
72 @cons.car = null
73 @cons.cdr = null
74 @q = new rational()
75
76
77errorMessage = ""
78
79
80# the following enum is for struct U, member k
81
82CONS = 0
83NUM = 1
84DOUBLE = 2
85STR = 3
86TENSOR = 4
87SYM = 5
88
89# the following enum is for indexing the symbol table
90
91# standard functions first, then nil, then everything else
92
93counter = 0
94ABS = counter++
95ADD = counter++
96ADJ = counter++
97AND = counter++
98APPROXRATIO = counter++
99ARCCOS = counter++
100ARCCOSH = counter++
101ARCSIN = counter++
102ARCSINH = counter++
103ARCTAN = counter++
104ARCTANH = counter++
105ARG = counter++
106ATOMIZE = counter++
107BESSELJ = counter++
108BESSELY = counter++
109BINDING = counter++
110BINOMIAL = counter++
111CEILING = counter++
112CHECK = counter++
113CHOOSE = counter++
114CIRCEXP = counter++
115CLEAR = counter++
116CLEARALL = counter++
117CLEARPATTERNS = counter++
118CLOCK = counter++
119COEFF = counter++
120COFACTOR = counter++
121CONDENSE = counter++
122CONJ = counter++
123CONTRACT = counter++
124COS = counter++
125COSH = counter++
126DECOMP = counter++
127DEFINT = counter++
128DEGREE = counter++
129DENOMINATOR = counter++
130DERIVATIVE = counter++
131DET = counter++
132DIM = counter++
133DIRAC = counter++
134DIVISORS = counter++
135DO = counter++
136DOT = counter++
137DRAW = counter++
138DSOLVE = counter++
139EIGEN = counter++
140EIGENVAL = counter++
141EIGENVEC = counter++
142ERF = counter++
143ERFC = counter++
144EVAL = counter++
145EXP = counter++
146EXPAND = counter++
147EXPCOS = counter++
148EXPSIN = counter++
149FACTOR = counter++
150FACTORIAL = counter++
151FACTORPOLY = counter++
152FILTER = counter++
153FLOATF = counter++
154FLOOR = counter++
155FOR = counter++
156FUNCTION = counter++
157GAMMA = counter++
158GCD = counter++
159HERMITE = counter++
160HILBERT = counter++
161IMAG = counter++
162INDEX = counter++
163INNER = counter++
164INTEGRAL = counter++
165INV = counter++
166INVG = counter++
167ISINTEGER = counter++
168ISPRIME = counter++
169LAGUERRE = counter++
170# LAPLACE = counter++
171LCM = counter++
172LEADING = counter++
173LEGENDRE = counter++
174LOG = counter++
175LOOKUP = counter++
176MOD = counter++
177MULTIPLY = counter++
178NOT = counter++
179NROOTS = counter++
180NUMBER = counter++
181NUMERATOR = counter++
182OPERATOR = counter++
183OR = counter++
184OUTER = counter++
185PATTERN = counter++
186PATTERNSINFO = counter++
187POLAR = counter++
188POWER = counter++
189PRIME = counter++
190PRINT_LEAVE_E_ALONE = counter++
191PRINT_LEAVE_X_ALONE = counter++
192PRINT = counter++
193PRINT2DASCII = counter++
194PRINTFULL = counter++
195PRINTLATEX = counter++
196PRINTLIST = counter++
197PRINTPLAIN = counter++
198PRODUCT = counter++
199QUOTE = counter++
200QUOTIENT = counter++
201RANK = counter++
202RATIONALIZE = counter++
203REAL = counter++
204ROUND = counter++
205YYRECT = counter++
206ROOTS = counter++
207SETQ = counter++
208SGN = counter++
209SILENTPATTERN = counter++
210SIMPLIFY = counter++
211SIN = counter++
212SINH = counter++
213SHAPE = counter++
214SQRT = counter++
215STOP = counter++
216SUBST = counter++
217SUM = counter++
218SYMBOLSINFO = counter++
219TAN = counter++
220TANH = counter++
221TAYLOR = counter++
222TEST = counter++
223TESTEQ = counter++
224TESTGE = counter++
225TESTGT = counter++
226TESTLE = counter++
227TESTLT = counter++
228TRANSPOSE = counter++
229UNIT = counter++
230ZERO = counter++
231
232# ALL THE SYMBOLS ABOVE NIL ARE KEYWORDS,
233# WHICH MEANS THAT USER CANNOT REDEFINE THEM
234NIL = counter++ # nil goes here, after standard functions
235LAST = counter++
236
237LAST_PRINT = counter++
238LAST_2DASCII_PRINT = counter++
239LAST_FULL_PRINT = counter++
240LAST_LATEX_PRINT = counter++
241LAST_LIST_PRINT = counter++
242LAST_PLAIN_PRINT = counter++
243
244AUTOEXPAND = counter++
245BAKE = counter++
246ASSUME_REAL_VARIABLES = counter++
247TRACE = counter++
248
249YYE = counter++
250
251DRAWX = counter++ # special purpose internal symbols
252METAA = counter++
253METAB = counter++
254METAX = counter++
255SECRETX = counter++
256
257VERSION = counter++
258
259PI = counter++
260SYMBOL_A = counter++
261SYMBOL_B = counter++
262SYMBOL_C = counter++
263SYMBOL_D = counter++
264SYMBOL_I = counter++
265SYMBOL_J = counter++
266SYMBOL_N = counter++
267SYMBOL_R = counter++
268SYMBOL_S = counter++
269SYMBOL_T = counter++
270SYMBOL_X = counter++
271SYMBOL_Y = counter++
272SYMBOL_Z = counter++
273SYMBOL_IDENTITY_MATRIX = counter++
274
275SYMBOL_A_UNDERSCORE = counter++
276SYMBOL_B_UNDERSCORE = counter++
277SYMBOL_X_UNDERSCORE = counter++
278
279C1 = counter++
280C2 = counter++
281C3 = counter++
282C4 = counter++
283C5 = counter++
284C6 = counter++
285
286USR_SYMBOLS = counter++ # this must be last
287
288E = YYE
289
290# TOS cannot be arbitrarily large because the OS seg faults on deep recursion.
291# For example, a circular evaluation like x=x+1 can cause a seg fault.
292# At this setting (100,000) the evaluation stack overruns before seg fault.
293
294TOS = 100000
295
296BUF = 10000
297
298MAX_PROGRAM_SIZE = 100001
299MAXPRIMETAB = 10000
300MAX_CONSECUTIVE_APPLICATIONS_OF_ALL_RULES = 5
301MAX_CONSECUTIVE_APPLICATIONS_OF_SINGLE_RULE = 10
302ENABLE_CACHING = true
303cached_runs = null # the LRU cache will go here
304cached_findDependenciesInScript = null # the LRU cache will go here
305
306#define _USE_MATH_DEFINES // for MS C++
307
308MAXDIM = 24
309
310# needed for the mechanism to
311# find all dependencies between variables
312# in a script
313symbolsDependencies = {}
314symbolsHavingReassignments = []
315symbolsInExpressionsWithoutAssignments = []
316patternHasBeenFound = false
317
318predefinedSymbolsInGlobalScope_doNotTrackInDependencies = [
319 "rationalize"
320 "abs"
321 "e"
322 "i"
323 "pi"
324 "sin"
325 "ceiling"
326 "cos"
327 "roots"
328 "integral"
329 "derivative"
330 "defint"
331 "sqrt"
332 "eig"
333 "cov"
334 "deig"
335 "dcov"
336 "float"
337 "floor"
338 "product"
339 "root"
340 "round"
341 "sum"
342 "test"
343 "unit"
344]
345
346# you can do some little simplifications
347# at parse time, such as calculating away
348# immediately simple operations on
349# constants, removing 1s from products
350# etc.
351parse_time_simplifications = true
352
353chainOfUserSymbolsNotFunctionsBeingEvaluated = []
354
355stringsEmittedByUserPrintouts = ""
356
357# flag use to potentially switch on/off some quirks "deep"
358# in the code due to call from Algebra block.
359# Currently not used.
360called_from_Algebra_block = false
361
362
363class tensor
364 ndim: 0 # number of dimensions
365 dim: null # dimension length, for each dimension
366 nelem: 0 # total number of elements
367 elem: null # an array containing all the data
368
369 constructor: ->
370 @dim = (0 for [0..MAXDIM])
371 @elem = []
372
373
374class display
375 h: 0
376 w: 0
377 n: 0
378 a: [] # will contain an array of c,x,y (color,x,y)
379
380
381class text_metric
382 ascent: 0
383 descent: 0
384 width: 0
385
386
387tos = 0 # top of stack
388expanding = 0
389evaluatingAsFloats = 0
390evaluatingPolar = 0
391fmt_x = 0
392fmt_index = 0
393fmt_level = 0
394verbosing = 0
395
396
397
398primetab = do ->
399 primes = [2]
400 i = 3
401 while primes.length < MAXPRIMETAB
402 j = 0
403 ceil = Math.sqrt(i)
404 while j < primes.length and primes[j] <= ceil
405 if i % primes[j] == 0
406 j = -1
407 break
408 j++
409 if j != -1
410 primes.push(i)
411 i += 2
412 primes[MAXPRIMETAB] = 0
413 return primes
414
415
416
417esc_flag = 0
418draw_flag = 0
419mtotal = 0
420trigmode = 0
421logbuf = ""
422program_buf = ""
423
424# will contain the variable names
425symtab = []
426# will contain the contents of the variable
427# in the corresponding position in symtab array
428binding = []
429isSymbolReclaimable = []
430
431arglist = [] # will contain U
432stack = [] # will contain *U
433frame = 0
434p0 = null # will contain U
435p1 = null # will contain U
436p2 = null # will contain U
437p3 = null # will contain U
438p4 = null # will contain U
439p5 = null # will contain U
440p6 = null # will contain U
441p7 = null # will contain U
442p8 = null # will contain U
443p9 = null # will contain U
444
445zero = null # will contain U
446one = null # will contain U
447one_as_double = null
448imaginaryunit = null # will contain U
449
450out_buf = ""
451out_count = 0
452test_flag = 0
453codeGen = false
454draw_stop_return = null # extern jmp_buf ?????
455userSimplificationsInListForm = []
456userSimplificationsInStringForm = []
457
458transpose_unicode = 7488
459dotprod_unicode = 183
460
461symbol = (x) -> (symtab[x])
462iscons = (p) -> (p.k == CONS)
463isrational = (p) -> (p.k == NUM)
464isdouble = (p) -> (p.k == DOUBLE)
465isnum = (p) -> (isrational(p) || isdouble(p))
466isstr = (p) -> (p.k == STR)
467istensor = (p) -> (if !p? then debugger else p.k == TENSOR)
468
469# because of recursion, we consider a scalar to be
470# a tensor, so a numeric scalar will return true
471isnumerictensor = (p) ->
472 if isnum(p) or p == symbol(SYMBOL_IDENTITY_MATRIX)
473 return 1
474
475 if !istensor(p) and !isnum(p)
476 #console.log "p not even a tensor: " + p
477 return 0
478
479 n = p.tensor.nelem
480 a = p.tensor.elem
481
482 for i in [0...n]
483 if !isnumerictensor(a[i])
484 #console.log "non-numeric element: " + a[i]
485 return 0
486 return 1
487
488issymbol = (p) -> (p.k == SYM)
489iskeyword = (p) -> (issymbol(p) && symnum(p) < NIL)
490
491car = (p) -> if iscons(p) then p.cons.car else symbol(NIL)
492cdr = (p) -> if iscons(p) then p.cons.cdr else symbol(NIL)
493caar = (p) -> car(car(p))
494cadr = (p) -> car(cdr(p))
495cdar = (p) -> cdr(car(p))
496cddr = (p) -> cdr(cdr(p))
497caadr = (p) -> car(car(cdr(p)))
498caddr = (p) -> car(cdr(cdr(p)))
499cadar = (p) -> car(cdr(car(p)))
500cdadr = (p) -> cdr(car(cdr(p)))
501cddar = (p) -> cdr(cdr(car(p)))
502cdddr = (p) -> cdr(cdr(cdr(p)))
503caaddr = (p) -> car(car(cdr(cdr(p))))
504cadadr = (p) -> car(cdr(car(cdr(p))))
505caddar = (p) -> car(cdr(cdr(car(p))))
506cdaddr = (p) -> cdr(car(cdr(cdr(p))))
507cadddr = (p) -> car(cdr(cdr(cdr(p))))
508cddddr = (p) -> cdr(cdr(cdr(cdr(p))))
509caddddr = (p) -> car(cdr(cdr(cdr(cdr(p)))))
510cadaddr = (p) -> car(cdr(car(cdr(cdr(p)))))
511cddaddr = (p) -> cdr(cdr(car(cdr(cdr(p)))))
512caddadr = (p) -> car(cdr(cdr(car(cdr(p)))))
513cdddaddr = (p) -> cdr(cdr(cdr(car(cdr(cdr(p))))))
514caddaddr = (p) -> car(cdr(cdr(car(cdr(cdr(p))))))
515
516# not used yet
517listLength = (p) ->
518 startCount = -1
519
520 while iscons(p)
521 p = cdr(p)
522 startCount++
523
524 return startCount
525
526# not used yet
527nthCadr = (p,n) ->
528 startCount = 0
529
530 while startCount <= n
531 p = cdr(p)
532 startCount++
533
534 return car(p)
535
536isadd = (p) -> (car(p) == symbol(ADD))
537ismultiply = (p) -> (car(p) == symbol(MULTIPLY))
538ispower = (p) -> (car(p) == symbol(POWER))
539isfactorial = (p) -> (car(p) == symbol(FACTORIAL))
540isinnerordot = (p) -> ((car(p) == symbol(INNER)) or (car(p) == symbol(DOT)))
541istranspose = (p) -> (car(p) == symbol(TRANSPOSE))
542isinv = (p) -> (car(p) == symbol(INV))
543# TODO this is a bit of a shallow check, we should
544# check when we are passed an actual tensor and possibly
545# cache the test result.
546isidentitymatrix = (p) -> (p == symbol(SYMBOL_IDENTITY_MATRIX))
547
548MSIGN = (p) ->
549 if p.isPositive()
550 return 1
551 else if p.isZero()
552 return 0
553 else
554 return -1
555
556MLENGTH = (p) -> p.toString().length
557
558MZERO = (p) -> p.isZero()
559MEQUAL = (p, n) ->
560 if !p?
561 debugger
562 p.equals(n)
563
564
565reset_after_error = ->
566 moveTos 0
567 esc_flag = 0
568 draw_flag = 0
569 frame = TOS
570 evaluatingAsFloats = 0
571 evaluatingPolar = 0
572
573
574$ = (exports ? this)
575
576$.version = version
577
578$.isadd = isadd
579$.ismultiply = ismultiply
580$.ispower = ispower
581$.isfactorial = isfactorial
582
583
584
585$.car = car
586$.cdr = cdr
587$.caar = caar
588$.cadr = cadr
589$.cdar = cdar
590$.cddr = cddr
591$.caadr = caadr
592$.caddr = caddr
593$.cadar = cadar
594$.cdadr = cdadr
595$.cddar = cddar
596$.cdddr = cdddr
597$.caaddr = caaddr
598$.cadadr = cadadr
599$.caddar = caddar
600$.cdaddr = cdaddr
601$.cadddr = cadddr
602$.cddddr = cddddr
603$.caddddr = caddddr
604$.cadaddr = cadaddr
605$.cddaddr = cddaddr
606$.caddadr = caddadr
607$.cdddaddr = cdddaddr
608$.caddaddr = caddaddr
609
610
611
612$.symbol = symbol
613$.iscons = iscons
614$.isrational = isrational
615$.isdouble = isdouble
616$.isnum = isnum
617$.isstr = isstr
618$.istensor = istensor
619$.issymbol = issymbol
620$.iskeyword = iskeyword
621
622
623
624
625$.CONS = CONS
626$.NUM = NUM
627$.DOUBLE = DOUBLE
628$.STR = STR
629$.TENSOR = TENSOR
630$.SYM = SYM