1 /*
2
3 HyPhy - Hypothesis Testing Using Phylogenies.
4
5 Copyright (C) 1997-now
6 Core Developers:
7 Sergei L Kosakovsky Pond (sergeilkp@icloud.com)
8 Art FY Poon (apoon42@uwo.ca)
9 Steven Weaver (sweaver@temple.edu)
10
11 Module Developers:
12 Lance Hepler (nlhepler@gmail.com)
13 Martin Smith (martin.audacis@gmail.com)
14
15 Significant contributions from:
16 Spencer V Muse (muse@stat.ncsu.edu)
17 Simon DW Frost (sdf22@cam.ac.uk)
18
19 Permission is hereby granted, free of charge, to any person obtaining a
20 copy of this software and associated documentation files (the
21 "Software"), to deal in the Software without restriction, including
22 without limitation the rights to use, copy, modify, merge, publish,
23 distribute, sublicense, and/or sell copies of the Software, and to
24 permit persons to whom the Software is furnished to do so, subject to
25 the following conditions:
26
27 The above copyright notice and this permission notice shall be included
28 in all copies or substantial portions of the Software.
29
30 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
31 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
33 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
34 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
35 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
36 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37
38 */
39
40 #include "parser.h"
41 #include "mathobj.h"
42 #include "global_things.h"
43
44 using namespace hy_global;
45
46
47 _MathObject default_null_argument;
48
_null_handler()49 _MathObject* _MathObject:: _null_handler() {
50 HandleApplicationError (kErrorStringNullOperand);
51 this->AddAReference();
52 return this;
53 }
54
Add(_MathObject *,_MathObject *)55 _MathObject* _MathObject:: Add (_MathObject*, _MathObject*) {
56 return _null_handler();
57 }
Sub(_MathObject *,_MathObject *)58 _MathObject* _MathObject:: Sub (_MathObject*, _MathObject*) {
59 return _null_handler();
60 }
Minus(_MathObject *)61 _MathObject* _MathObject:: Minus (_MathObject*) {
62 return _null_handler();
63 }
Sum(_MathObject *)64 _MathObject* _MathObject:: Sum (_MathObject*) {
65 return _null_handler();
66 }
Mult(_MathObject *,_MathObject *)67 _MathObject* _MathObject:: Mult (_MathObject*,_MathObject*) {
68 return _null_handler();
69 }
Div(_MathObject *,_MathObject *)70 _MathObject* _MathObject:: Div (_MathObject*,_MathObject*) {
71 return _null_handler();
72 }
lDiv(_MathObject *,_MathObject *)73 _MathObject* _MathObject:: lDiv (_MathObject*,_MathObject*) {
74 return _null_handler();
75 }
longDiv(_MathObject *,_MathObject *)76 _MathObject* _MathObject:: longDiv (_MathObject*,_MathObject*) {
77 return _null_handler();
78 }
Raise(_MathObject *,_MathObject *)79 _MathObject* _MathObject:: Raise (_MathObject*,_MathObject*) {
80 return _null_handler();
81 }
82
Equal(_MathObject * rhs)83 bool _MathObject:: Equal (_MathObject* rhs) {
84 if (rhs->ObjectClass() == HY_UNDEFINED) {
85 return true;
86 }
87 return false;
88 // null is equal to null, otherwise false\
89 return false;
90 }
Abs(_MathObject *)91 _MathObject* _MathObject:: Abs (_MathObject*) {
92 return _null_handler();
93 }
Sin(_MathObject *)94 _MathObject* _MathObject:: Sin (_MathObject*) {
95 return _null_handler();
96 }
Cos(_MathObject *)97 _MathObject* _MathObject:: Cos (_MathObject*) {
98 return _null_handler();
99 }
Tan(_MathObject *)100 _MathObject* _MathObject:: Tan (_MathObject*) {
101 return _null_handler();
102 }
Exp(_MathObject *)103 _MathObject* _MathObject:: Exp (_MathObject*) {
104 return _null_handler();
105 }
Log(_MathObject *)106 _MathObject* _MathObject:: Log (_MathObject*) {
107 return _null_handler();
108 }
Sqrt(_MathObject *)109 _MathObject* _MathObject:: Sqrt (_MathObject*) {
110 return _null_handler();
111 }
Gamma(_MathObject *)112 _MathObject* _MathObject:: Gamma (_MathObject*) {
113 return _null_handler();
114 }
Erf(_MathObject *)115 _MathObject* _MathObject:: Erf (_MathObject*) {
116 return _null_handler();
117 }
LnGamma(_MathObject *)118 _MathObject* _MathObject:: LnGamma (_MathObject*) {
119 return _null_handler();
120 }
121
Beta(_MathObject *,_MathObject *)122 _MathObject* _MathObject:: Beta (_MathObject*,_MathObject*) {
123 return _null_handler();
124 }
IGamma(_MathObject *,_MathObject *)125 _MathObject* _MathObject:: IGamma (_MathObject*,_MathObject*) {
126 return _null_handler();
127 }
CChi2(_MathObject *,_MathObject *)128 _MathObject* _MathObject:: CChi2 (_MathObject*,_MathObject*) {
129 return _null_handler();
130 }
IBeta(_MathObject *,_MathObject *,_MathObject *)131 _MathObject* _MathObject:: IBeta (_MathObject*,_MathObject*,_MathObject*) {
132 return _null_handler();
133 }
Simplex(_MathObject *)134 _MathObject* _MathObject:: Simplex (_MathObject*) {
135 return _null_handler();
136 }
137
Simplify(_MathObject *)138 _MathObject* _MathObject:: Simplify (_MathObject*) {
139 return _null_handler();
140 }
141
Min(_MathObject *,_MathObject *)142 _MathObject* _MathObject:: Min (_MathObject*,_MathObject*) {
143 return _null_handler();
144 }
Max(_MathObject *,_MathObject *)145 _MathObject* _MathObject:: Max (_MathObject*,_MathObject*) {
146 return _null_handler();
147 }
InvChi2(_MathObject *,_MathObject *)148 _MathObject* _MathObject:: InvChi2 (_MathObject*,_MathObject*) {
149 return _null_handler();
150 }
ZCDF(_MathObject *)151 _MathObject* _MathObject:: ZCDF (_MathObject*) {
152 return _null_handler();
153 }
Time(_MathObject *)154 _MathObject* _MathObject:: Time (_MathObject*) {
155 return _null_handler();
156 }
Arctan(_MathObject *)157 _MathObject* _MathObject:: Arctan (_MathObject*) {
158 return _null_handler();
159 }
Less(_MathObject *,_MathObject *)160 _MathObject* _MathObject:: Less (_MathObject*,_MathObject*) {
161 return _null_handler();
162 }
Random(_MathObject *,_MathObject *)163 _MathObject* _MathObject:: Random (_MathObject*,_MathObject*) {
164 return _null_handler();
165 }
Greater(_MathObject *,_MathObject *)166 _MathObject* _MathObject:: Greater (_MathObject*,_MathObject*) {
167 return _null_handler();
168 }
LessEq(_MathObject *,_MathObject *)169 _MathObject* _MathObject:: LessEq (_MathObject*,_MathObject*) {
170 return _null_handler();
171 }
GreaterEq(_MathObject *,_MathObject *)172 _MathObject* _MathObject:: GreaterEq (_MathObject*,_MathObject*) {
173 return _null_handler();
174 }
AreEqual(_MathObject *,_MathObject *)175 _MathObject* _MathObject:: AreEqual (_MathObject*,_MathObject*) {
176 return _null_handler();
177 }
NotEqual(_MathObject *,_MathObject *)178 _MathObject* _MathObject:: NotEqual (_MathObject*,_MathObject*) {
179 return _null_handler();
180 }
LAnd(_MathObject *,_MathObject *)181 _MathObject* _MathObject:: LAnd (_MathObject*,_MathObject*) {
182 return _null_handler();
183 }
LOr(_MathObject *,_MathObject *)184 _MathObject* _MathObject:: LOr (_MathObject*,_MathObject*) {
185 return _null_handler();
186 }
GammaDist(_MathObject *,_MathObject *,_MathObject *)187 _MathObject* _MathObject:: GammaDist (_MathObject*,_MathObject*,_MathObject*) {
188 return _null_handler();
189 }
CGammaDist(_MathObject *,_MathObject *,_MathObject *)190 _MathObject* _MathObject:: CGammaDist (_MathObject*,_MathObject*,_MathObject*) {
191 return _null_handler();
192 }
LNot(_MathObject *)193 _MathObject* _MathObject:: LNot (_MathObject*) {
194 return _null_handler();
195 }
TipCount(_MathObject *)196 _MathObject* _MathObject:: TipCount (_MathObject*) {
197 return _null_handler();
198 }
BranchCount(_MathObject *)199 _MathObject* _MathObject:: BranchCount (_MathObject*) {
200 return _null_handler();
201 }
TipName(_MathObject *,_MathObject *)202 _MathObject* _MathObject:: TipName (_MathObject*,_MathObject*) {
203 return _null_handler();
204 }
BranchName(_MathObject *,_MathObject *)205 _MathObject* _MathObject:: BranchName (_MathObject*,_MathObject*) {
206 return _null_handler();
207 }
BranchLength(_MathObject *,_MathObject *)208 _MathObject* _MathObject:: BranchLength(_MathObject*,_MathObject*) {
209 return _null_handler();
210 }
RerootTree(_MathObject *,_MathObject *)211 _MathObject* _MathObject:: RerootTree (_MathObject*,_MathObject*) {
212 return _null_handler();
213 }
TEXTreeString(_MathObject *,_MathObject *) const214 _MathObject* _MathObject:: TEXTreeString(_MathObject*,_MathObject*) const {
215 HandleApplicationError (kErrorStringNullOperand);
216 return new _MathObject;
217 }
218
PlainTreeString(_MathObject *,_MathObject *,_MathObject *)219 _MathObject* _MathObject:: PlainTreeString(_MathObject*,_MathObject*,_MathObject*) {
220 return _null_handler();
221 }
FormatNumberString(_MathObject *,_MathObject *,_MathObject *)222 _MathObject* _MathObject:: FormatNumberString (_MathObject*,_MathObject*,_MathObject*) {
223 return _null_handler();
224 }
Value(void)225 hyFloat _MathObject:: Value (void) {
226 HandleApplicationError (kErrorStringNullOperand);
227 return 0.0;
228 }
229
230
_extract_argument(_List * arguments,unsigned long index,bool fill_in) const231 _MathObject* _MathObject:: _extract_argument (_List * arguments, unsigned long index, bool fill_in) const {
232 if (arguments && index < arguments->lLength) {
233 return (_MathObject*)arguments->GetItem(index);
234 }
235 return fill_in ? &default_null_argument : nil;
236 }
237
238
_returnConstantOrUseCache(hyFloat value,HBLObjectRef cache)239 HBLObjectRef _returnConstantOrUseCache (hyFloat value, HBLObjectRef cache) {
240 if (cache && cache->ObjectClass() == NUMBER) {
241 ((_Constant*)cache)->theValue = value;
242 return cache;
243 }
244 return new _Constant (value);
245 }
246
247 //SW: This calls the function with the opcode after it's been parsed
ExecuteSingleOp(long opCode,_List * arguments,_hyExecutionContext * context,HBLObjectRef cache)248 HBLObjectRef _MathObject::ExecuteSingleOp (long opCode, _List* arguments, _hyExecutionContext* context, HBLObjectRef cache) {
249
250 switch (opCode) { // first check operations without arguments
251 case HY_OP_CODE_NOT: // !
252 return LNot(cache);
253 case HY_OP_CODE_ABS: // Abs
254 return Abs(cache);
255 case HY_OP_CODE_ARCTAN: // Arctan
256 return Arctan(cache);
257 case HY_OP_CODE_COS: // Cos
258 return Cos(cache);
259 case HY_OP_CODE_COLUMNS: // Columns
260 case HY_OP_CODE_ROWS: // Rows
261 return _returnConstantOrUseCache (0., cache);
262 case HY_OP_CODE_ERF: // Erf
263 return Erf(cache);
264 case HY_OP_CODE_EVAL:
265 return (HBLObjectRef)Compute()->makeDynamic();
266 case HY_OP_CODE_EXP: // Exp
267 return Exp(cache);
268 case HY_OP_CODE_GAMMA: // Gamma
269 return Gamma(cache);
270 case HY_OP_CODE_LNGAMMA: // LnGamma
271 return LnGamma(cache);
272 case HY_OP_CODE_LOG: // Log
273 return Log(cache);
274 case HY_OP_CODE_MACCESS:
275 return new _MathObject; // indexing None returns None
276 case HY_OP_CODE_SIMPLEX: // Simplex
277 return Simplex(cache);
278 case HY_OP_CODE_SIN: // Sin
279 return Sin(cache);
280 case HY_OP_CODE_SQRT: // Sqrt
281 return Sqrt(cache);
282 case HY_OP_CODE_TAN: // Tan
283 return Tan(cache);
284 case HY_OP_CODE_TIME: // Time
285 return Time(cache);
286 case HY_OP_CODE_TYPE: // Type
287 return Type(cache);
288 case HY_OP_CODE_ZCDF: // ZCDF
289 return ZCDF(cache);
290 }
291
292 _MathObject * arg0 = _extract_argument (arguments, 0UL, false);
293
294 switch (opCode) { // next check operations without arguments or with one argument
295 case HY_OP_CODE_ADD: // +
296 if (arg0)
297 return Add(arg0,cache);
298 return Sum (cache);
299 case HY_OP_CODE_SUB: // -
300 if (arg0)
301 return Sub(arg0,cache);
302 return Minus(cache);
303 break;
304 }
305
306 if (arg0) {
307 switch (opCode) { // operations that require exactly one argument
308 case HY_OP_CODE_NEQ: // !=
309 if (ObjectClass () == HY_UNDEFINED) {
310 if (arg0->ObjectClass () == HY_UNDEFINED)
311 return _returnConstantOrUseCache (0., cache);
312 //return new HY_CONSTANT_FALSE;
313 else
314 return _returnConstantOrUseCache (1., cache);
315 //return new HY_CONSTANT_TRUE;
316 }
317 if (arg0->ObjectClass() == NUMBER)
318 return NotEqual(arg0,cache);
319 return new HY_CONSTANT_TRUE;
320 case HY_OP_CODE_IDIV: // $
321 return longDiv(arg0,cache);
322 case HY_OP_CODE_MOD: // %
323 return lDiv(arg0,cache);
324 case HY_OP_CODE_AND: // &&
325 return LAnd(arg0,cache);
326 case HY_OP_CODE_MUL: // *
327 return Mult(arg0,cache);
328 case HY_OP_CODE_DIV: // /
329 return Div(arg0,cache);
330 case HY_OP_CODE_LESS: // <
331 return Less(arg0,cache);
332 case HY_OP_CODE_LEQ: // <=
333 return LessEq(arg0,cache);
334 case HY_OP_CODE_EQ: // ==
335 {
336 if (ObjectClass () == HY_UNDEFINED) {
337 if (arg0->ObjectClass () == HY_UNDEFINED)
338 return _returnConstantOrUseCache (1., cache);
339 //return new HY_CONSTANT_TRUE;
340 else
341 return _returnConstantOrUseCache (0., cache);
342 //return new HY_CONSTANT_FALSE;
343 }
344 if (arg0->ObjectClass() == NUMBER)
345 return AreEqual(arg0,cache);
346 return new HY_CONSTANT_FALSE;
347 }
348 break;
349 case HY_OP_CODE_GREATER: // >
350 return Greater(arg0,cache);
351 case HY_OP_CODE_GEQ: // >=
352 return GreaterEq(arg0,cache);
353 case HY_OP_CODE_BETA: // Beta
354 return Beta(arg0,cache);
355 case HY_OP_CODE_CCHI2: // CChi2
356 return CChi2(arg0,cache);
357 case HY_OP_CODE_IGAMMA: // IGamma
358 return IGamma(arg0,cache);
359 case HY_OP_CODE_INVCHI2: // InvChi2
360 return InvChi2(arg0,cache);
361 case HY_OP_CODE_MAX: // Max
362 return Max(arg0,cache);
363 case HY_OP_CODE_MIN: // Min
364 return Min(arg0,cache);
365 case HY_OP_CODE_RANDOM: // Random
366 return Random(arg0,cache);
367 case HY_OP_CODE_POWER: // ^
368 return Raise(arg0,cache);
369 case HY_OP_CODE_OR: // ||
370 return LOr(arg0,cache);
371 }
372
373 _MathObject * arg1 = _extract_argument (arguments, 1UL, false);
374
375 if (arg1) {
376 /** ops that require exactly TWO arguments */
377
378 switch (opCode) {
379 case HY_OP_CODE_CGAMMADIST: // CGammaDist
380 return CGammaDist(arg0,arg1,cache);
381 case HY_OP_CODE_FORMAT: // Format
382 return FormatNumberString(arg0,arg1,cache);
383 case HY_OP_CODE_GAMMADIST: // GammaDist
384 return GammaDist(arg0,arg1,cache);
385 case HY_OP_CODE_IBETA: // IBeta
386 return IBeta(arg0,arg1,cache);
387 }
388 }
389
390 }
391
392 switch (opCode) {
393 case HY_OP_CODE_CGAMMADIST: // CGammaDist
394 case HY_OP_CODE_FORMAT: // Format
395 case HY_OP_CODE_GAMMADIST: // GammaDist
396 case HY_OP_CODE_IBETA: // IBeta
397 case HY_OP_CODE_NEQ: // !=
398 case HY_OP_CODE_IDIV: // $
399 case HY_OP_CODE_MOD: // %
400 case HY_OP_CODE_AND: // &&
401 case HY_OP_CODE_MUL: // *
402 case HY_OP_CODE_DIV: // /
403 case HY_OP_CODE_LESS: // <
404 case HY_OP_CODE_LEQ: // <=
405 case HY_OP_CODE_EQ: // ==
406 case HY_OP_CODE_GREATER: // >
407 case HY_OP_CODE_GEQ: // >=
408 case HY_OP_CODE_BETA: // Beta
409 case HY_OP_CODE_CCHI2: // CChi2
410 case HY_OP_CODE_IGAMMA: // IGamma
411 case HY_OP_CODE_INVCHI2: // InvChi2
412 case HY_OP_CODE_MAX: // Max
413 case HY_OP_CODE_MIN: // Min
414 case HY_OP_CODE_RANDOM: // Random
415 case HY_OP_CODE_POWER: // ^
416 case HY_OP_CODE_OR: // ||
417 WarnWrongNumberOfArguments (this, opCode,context, arguments);
418 break;
419 default:
420 WarnNotDefined (this, opCode,context);
421 }
422
423 return new _MathObject;
424 }
425
426 //__________________________________________________________________________________
427
makeDynamic(void) const428 BaseRef _MathObject::makeDynamic (void) const {
429 return new _MathObject;
430 }
431
432 //__________________________________________________________________________________
433
Duplicate(BaseRefConst)434 void _MathObject::Duplicate (BaseRefConst) {
435 }
436
437
438
439 //__________________________________________________________________________________
440
441 //SW: Why do we need a string for the type?
Type(HBLObjectRef cache)442 HBLObjectRef _MathObject::Type (HBLObjectRef cache) {
443
444 static const _FString kNumber ("Number", false);
445 static const _FString kMatrix ("Matrix", false);
446 static const _FString kContainer ("Container", false);
447 static const _FString kTreeNode ("TreeNode", false);
448 static const _FString kTree ("Tree", false);
449 static const _FString kString ("String", false);
450 static const _FString kAssociativeList
451 ("AssociativeList", false);
452 static const _FString kTopology ("Topology", false);
453 static const _FString kPolynomial ("Polynomial", false);
454 static const _FString kUnknown ("Unknown", false);
455
456 switch (ObjectClass()) {
457
458 case NUMBER:
459 return new _FString (kNumber);
460 case MATRIX:
461 return new _FString (kMatrix);
462 case CONTAINER:
463 return new _FString (kContainer);
464 case TREE_NODE:
465 return new _FString (kTreeNode);
466 case TREE:
467 return new _FString (kTree);
468 case STRING:
469 return new _FString (kString);
470 case ASSOCIATIVE_LIST:
471 return new _FString (kAssociativeList);
472 case TOPOLOGY:
473 return new _FString (kTopology);
474 case POLYNOMIAL:
475 return new _FString (kPolynomial);
476
477 }
478
479 return new _FString (kUnknown);
480 }
481