@live-codes/pascal-wasm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +501 -0
  2. package/README.md +278 -0
  3. package/THIRD-PARTY-NOTICES.md +48 -0
  4. package/assets/pas2js.wasm +0 -0
  5. package/assets/rtl/Rtl.BrowserLoadHelper.pas +179 -0
  6. package/assets/rtl/browserconsole.pas +190 -0
  7. package/assets/rtl/classes.pas +11371 -0
  8. package/assets/rtl/js.pas +2211 -0
  9. package/assets/rtl/manifest.json +19 -0
  10. package/assets/rtl/math.pas +903 -0
  11. package/assets/rtl/p2jsres.pp +334 -0
  12. package/assets/rtl/rtl.js +1563 -0
  13. package/assets/rtl/rtlconsts.pas +97 -0
  14. package/assets/rtl/simplelinkedlist.pas +152 -0
  15. package/assets/rtl/system.pas +1166 -0
  16. package/assets/rtl/sysutils.pas +8959 -0
  17. package/assets/rtl/types.pas +2296 -0
  18. package/assets/rtl/typinfo.pas +1680 -0
  19. package/assets/rtl/web.pas +3586 -0
  20. package/assets/rtl/weborworker.pas +2101 -0
  21. package/dist/pascal-wasm.iife.min.js +6 -0
  22. package/dist/pascal-wasm.iife.min.js.map +7 -0
  23. package/package.json +54 -0
  24. package/src/assets.js +119 -0
  25. package/src/compiler.js +142 -0
  26. package/src/config.js +24 -0
  27. package/src/iife.js +27 -0
  28. package/src/index.js +130 -0
  29. package/src/vendor/browser_wasi_shim/debug.js +1 -0
  30. package/src/vendor/browser_wasi_shim/fd.js +1 -0
  31. package/src/vendor/browser_wasi_shim/fs_mem.js +1 -0
  32. package/src/vendor/browser_wasi_shim/fs_opfs.js +1 -0
  33. package/src/vendor/browser_wasi_shim/index.js +1 -0
  34. package/src/vendor/browser_wasi_shim/strace.js +1 -0
  35. package/src/vendor/browser_wasi_shim/wasi.js +1 -0
  36. package/src/vendor/browser_wasi_shim/wasi_defs.js +1 -0
  37. package/types/index.d.ts +89 -0
@@ -0,0 +1,903 @@
1
+ {
2
+ This file is part of the Pas2JS run time library.
3
+ Copyright (c) 2017 by Mattias Gaertner
4
+
5
+ See the file COPYING.FPC, included in this distribution,
6
+ for details about the copyright.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
+
12
+ **********************************************************************}
13
+ {$IFNDEF FPC_DOTTEDUNITS}
14
+ unit Math;
15
+ {$ENDIF}
16
+
17
+ {$mode objfpc}
18
+
19
+ interface
20
+
21
+ const
22
+ MinInteger = -$fffffffffffff+1;
23
+ MaxInteger = $fffffffffffff;
24
+ MinDouble = 5.0e-324;
25
+ MaxDouble = 1.7e+308;
26
+ Epsilon = 1.1e-10;
27
+ const
28
+ NaN: Double; external name 'NaN';
29
+ Infinity: Double; external name 'Infinity';
30
+ NegInfinity: Double; external name '-Infinity';
31
+
32
+ type
33
+ float = double;
34
+
35
+ //EInvalidArgument = class(EMathError);
36
+
37
+ function Min(const a, b: Double): Double; varargs; external name 'Math.min'; overload;
38
+ function Max(const a, b: Double): Double; varargs; external name 'Math.max'; overload;
39
+ function Min(const a, b: NativeLargeUInt): NativeLargeUInt; varargs; external name 'Math.min'; overload;
40
+ function Max(const a, b: NativeLargeUInt): NativeLargeUInt; varargs; external name 'Math.max'; overload;
41
+ function Min(const a, b: NativeLargeInt): NativeLargeInt; varargs; external name 'Math.min'; overload;
42
+ function Max(const a, b: NativeLargeInt): NativeLargeInt; varargs; external name 'Math.max'; overload;
43
+ function Min(const a, b: Integer): Integer; varargs; external name 'Math.min'; overload;
44
+ function Max(const a, b: Integer): Integer; varargs; external name 'Math.max'; overload;
45
+
46
+ function InRange(const AValue, AMin, AMax: Integer): Boolean; assembler; overload;
47
+ function InRange(const AValue, AMin, AMax: Double): Boolean; assembler; overload;
48
+
49
+ function EnsureRange(const AValue, AMin, AMax: Integer): Integer; assembler; overload;
50
+ function EnsureRange(const AValue, AMin, AMax: Double): Double; assembler; overload;
51
+
52
+ type
53
+ TRoundToRange = -37..37;
54
+
55
+ function RoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
56
+ function SimpleRoundTo(const AValue: Double; const Digits: TRoundToRange = -2): Double;
57
+
58
+ function randg(mean,stddev : float) : float;
59
+ function RandomRange(const aFrom, aTo: Integer): Integer;
60
+ function RandomRange(const aFrom, aTo: NativeLargeInt): NativeLargeInt;
61
+
62
+ Type
63
+ TValueSign = -1..1;
64
+
65
+ const
66
+ NegativeValue = -1;
67
+ ZeroValue = 0;
68
+ PositiveValue = 1;
69
+
70
+ function Sign(const AValue: NativeInt): TValueSign; external name 'Math.sign'; overload;
71
+ function Sign(const AValue: Double): TValueSign; external name 'Math.sign'; overload;
72
+
73
+ function IsZero(const d: Double; Epsilon: Double): Boolean; overload;
74
+ function IsZero(const d: Double): Boolean; overload;
75
+
76
+ function IsNaN(const v: JSValue): boolean; external name {$IFDEF ECMAScript5}'isNaN'{$ELSE}'Number.isNaN'{$ENDIF}; overload;
77
+ function IsFinite(const d: JSValue): Boolean; external name 'isFinite'; overload;// false if NaN, positive or negative infinity
78
+ function IsInfinite(const d: JSValue): Boolean; assembler; overload; // negative or positive infinity
79
+ {$IFDEF ECMAScript6}
80
+ function IsInteger(const d: JSValue): Boolean; external name 'Number.isInteger'; // any integer representable by a double
81
+ function IsSafeInteger(const d: JSValue): Boolean; external name 'Number.isSafeInteger'; // an integer between MinInteger and MaxInteger, inclusive
82
+ {$ENDIF}
83
+
84
+ function SameValue(const A, B: Double; Epsilon: Double = 0.0): Boolean; overload;
85
+
86
+ // function Abs is in System.pas
87
+ function ArcCos(const A : Double): Double; external name 'Math.acos';
88
+ function ArcCosH(const A: Double): Double; external name 'Math.acosh'; // not on IE
89
+ function ArcSin(const A : Double): Double; external name 'Math.asin';
90
+ function ArcSinH(const A : Double): Double; external name 'Math.asinh'; // not on IE
91
+ function ArcTanH(const A: Double): Double; external name 'Math.atanh'; // not on IE
92
+ function CosH(const A: Double): Double; external name 'Math.cosh'; // not on IE
93
+ procedure SinCos(const A: Double; var B: Double; var C: Double);
94
+ function ExpM1(const A: Double): Double; external name 'Math.expm1'; // not on IE
95
+ function FRound(const A: Double): Double; overload; external name 'Math.fround'; // not on IE
96
+ function FTrunc(const A: Double): double; overload; external name 'Math.trunc'; // not on IE
97
+ function Hypot(const A : Double): Double; varargs; external name 'Math.hypot'; // not on IE
98
+ function IMul(const A, B: Integer): Integer; external name 'Math.imul'; // not on IE
99
+ function Log10(const A: Double): Double; external name 'Math.log10';
100
+ function Log1p(const A: Double): Double; external name 'Math.log1p'; // not on IE
101
+ function Log2(const A: Double): Double; external name 'Math.log2'; // not on IE
102
+ function LogN(const Base, N: Double): Double;
103
+ function Power(const Base, Exponent: Double): Double; external name 'Math.pow';
104
+ // ln, round, sqrt, trunc, cos, sin, arctan, round, exp are in unit system
105
+ function Ceil(const A: Double): Integer;
106
+ function Floor(const A: Double): Integer;
107
+ function Ceil64(const A: Double): NativeLargeInt;
108
+ function Floor64(const A: Double): NativeLargeInt;
109
+ function ldexp(x : double;const p : Integer) : double;
110
+ procedure Frexp(X: double; out Mantissa: double; out Exponent: integer);
111
+ function lnxp1(x : double) : double;
112
+
113
+ function IntPower(base : float;const exponent : Integer) : double;
114
+
115
+ procedure DivMod(Dividend: LongInt; Divisor: Word; out Result, Remainder: Word);
116
+ procedure DivMod(Dividend: LongInt; Divisor: Word; out Result, Remainder: SmallInt);
117
+ procedure DivMod(Dividend: DWord; Divisor: DWord; out Result, Remainder: DWord);
118
+ procedure DivMod(Dividend: LongInt; Divisor: LongInt; out Result, Remainder: LongInt);
119
+
120
+ { Angle conversion }
121
+ function DegToRad(deg : double) : double;
122
+ function RadToDeg(rad : double) : double;
123
+ function GradToRad(grad : double) : double;
124
+ function RadToGrad(rad : double) : double;
125
+ function DegToGrad(deg : double) : double;
126
+ function GradToDeg(grad : double) : double;
127
+ { one cycle are 2*Pi rad }
128
+ function CycleToRad(cycle : double) : double;
129
+ function RadToCycle(rad : double) : double;
130
+ Function DegNormalize(deg : double) : double;
131
+
132
+ function Norm(const data : array of double) : double;
133
+
134
+ // Statistical functions
135
+ function Mean(const data : array of double) : double;
136
+ function Sum(const data : array of double) : double;
137
+ procedure SumsAndSquares(const data : Array of Double; out Sum,SumOfSquares : double);
138
+
139
+ function StdDev(const data : array of Double) : float;
140
+ procedure MeanAndStdDev(const data : array of Double; out Mean,StdDev : double);
141
+ function Variance(const data : array of Double) : double;
142
+ function TotalVariance(const data : array of Double) : double;
143
+ function PopNStdDev(const data : array of Double) : double;
144
+ function PopNVariance(const data : array of Double) : double;
145
+ procedure MomentSkewKurtosis(const data : array of Double; out m1,m2,m3,m4,skew,kurtosis : double);
146
+
147
+ function MaxIntValue(const AData: array of Integer): Integer;
148
+
149
+ // Financial functions
150
+
151
+ Type
152
+ TPaymentTime = (ptEndOfPeriod,ptStartOfPeriod);
153
+
154
+ function FutureValue(ARate: double; NPeriods: Integer;
155
+ APayment, APresentValue: double; APaymentTime: TPaymentTime): double;
156
+
157
+ function InterestRate(NPeriods: Integer; APayment, APresentValue, AFutureValue: double;
158
+ APaymentTime: TPaymentTime): double;
159
+
160
+ function NumberOfPeriods(ARate, APayment, APresentValue, AFutureValue: double;
161
+ APaymentTime: TPaymentTime): double;
162
+
163
+ function Payment(ARate: double; NPeriods: Integer;
164
+ APresentValue, AFutureValue: double; APaymentTime: TPaymentTime): double;
165
+
166
+ function PresentValue(ARate: double; NPeriods: Integer;
167
+ APayment, AFutureValue: double; APaymentTime: TPaymentTime): double;
168
+
169
+ // Miscellaneous
170
+
171
+ function IfThen(val:boolean;const ifTrue:integer; const ifFalse:integer= 0) :integer; overload;
172
+ function IfThen(val:boolean;const ifTrue:double ; const ifFalse:double =0.0):double; overload;
173
+
174
+ Type
175
+ TValueRelationship = -1..1;
176
+
177
+ const
178
+ EqualsValue = 0;
179
+ LessThanValue = Low(TValueRelationship);
180
+ GreaterThanValue = High(TValueRelationship);
181
+
182
+ function CompareValue ( const A, B : Integer) : TValueRelationship;
183
+ function CompareValue ( const A, B : NativeLargeInt) : TValueRelationship;
184
+ function CompareValue ( const A, B : NativeLargeUInt) : TValueRelationship;
185
+ function CompareValue ( const A, B : Double; delta : Double = 0.0) : TValueRelationship;
186
+
187
+ implementation
188
+
189
+ function InRange(const AValue, AMin, AMax: Integer): Boolean; assembler;
190
+ asm
191
+ return (AValue >= AMin) && (AValue <= AMax);
192
+ end;
193
+
194
+ function InRange(const AValue, AMin, AMax: Double): Boolean; assembler;
195
+ asm
196
+ return (AValue >= AMin) && (AValue <= AMax);
197
+ end;
198
+
199
+ function EnsureRange(const AValue, AMin, AMax: Integer): Integer; assembler;
200
+ asm
201
+ if (AValue<AMin){ return AMin;
202
+ } else if (AValue>AMax){ return AMax;
203
+ } else return AValue;
204
+ end;
205
+
206
+ function EnsureRange(const AValue, AMin, AMax: Double): Double; assembler;
207
+ asm
208
+ if (AValue<AMin){ return AMin;
209
+ } else if (AValue>AMax){ return AMax;
210
+ } else return AValue;
211
+ end;
212
+
213
+ function RoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
214
+ var
215
+ RV : Double;
216
+
217
+ begin
218
+ RV:=IntPower(10,Digits);
219
+ Result:=Round(AValue/RV)*RV;
220
+ end;
221
+
222
+ function SimpleRoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
223
+ var
224
+ RV : Double;
225
+
226
+ begin
227
+ RV := IntPower(10, -Digits);
228
+ if AValue < 0 then
229
+ Result := Int((AValue*RV) - 0.5)/RV
230
+ else
231
+ Result := Int((AValue*RV) + 0.5)/RV;
232
+ end;
233
+
234
+ function randg(mean,stddev : float) : float;
235
+
236
+ Var
237
+ U1,S2 : Float;
238
+
239
+ begin
240
+ repeat
241
+ u1:= 2*random-1;
242
+ S2:=Sqr(U1)+sqr(2*random-1);
243
+ until s2<1;
244
+ Result:=Sqrt(-2*ln(S2)/S2)*u1*stddev+Mean;
245
+ end;
246
+
247
+
248
+ function RandomRange(const aFrom, aTo: Integer): Integer;
249
+ begin
250
+ Result:=Random(Abs(aFrom-aTo))+Min(aTo,AFrom);
251
+ end;
252
+
253
+
254
+ function RandomRange(const aFrom, aTo: NativeLargeInt): NativeLargeInt;
255
+
256
+ Var
257
+ m : NativeLargeInt;
258
+ begin
259
+ if aFrom<aTo then
260
+ M:=aFrom
261
+ else
262
+ M:=aTo;
263
+ Result:=Random(Abs(aFrom-aTo))+M;
264
+ end;
265
+
266
+ const
267
+ DZeroResolution = 1E-12;
268
+
269
+ function IsZero(const d: Double; Epsilon: Double): Boolean;
270
+ begin
271
+ if Epsilon=0 then
272
+ Epsilon:=DZeroResolution;
273
+ Result:=Abs(d)<=Epsilon;
274
+ end;
275
+
276
+ function IsZero(const d: Double): Boolean;
277
+ begin
278
+ Result:=Abs(d)<=DZeroResolution;
279
+ end;
280
+
281
+ function IsInfinite(const d: JSValue): Boolean; assembler;
282
+ asm
283
+ return (d==Infinity) || (d==-Infinity);
284
+ end;
285
+
286
+ function SameValue(const A, B: Double; Epsilon: Double): Boolean;
287
+ begin
288
+ if (Epsilon=0.0) then
289
+ Epsilon:=Max(Min(Abs(A),Abs(B))*DZeroResolution,DZeroResolution);
290
+ if (A>B) then
291
+ Result:=((A-B)<=Epsilon)
292
+ else
293
+ Result:=((B-A)<=Epsilon);
294
+ end;
295
+
296
+ function JSFloor(const A: Double): Double; external name 'Math.floor';
297
+ function JSCeil(const A: Double): Double; external name 'Math.ceil';
298
+
299
+ function Ceil(const A: Double): Integer;
300
+
301
+ begin
302
+ // TODO: add Range check ?
303
+ Result:=trunc(JSCeil(a));
304
+ end;
305
+
306
+ function Floor(const A: Double): Integer;
307
+
308
+ begin
309
+ // TODO: add Range check ?
310
+ Result:=trunc(JSFloor(a));
311
+ end;
312
+
313
+ function Ceil64(const A: Double): NativeLargeInt;
314
+
315
+ begin
316
+ Result:=trunc(JSCeil(a));
317
+ end;
318
+
319
+ function Floor64(const A: Double): NativeLargeInt;
320
+
321
+ begin
322
+ Result:=trunc(JSCeil(a));
323
+ end;
324
+
325
+ procedure Frexp(X: double; out Mantissa: double; out Exponent: integer);
326
+
327
+ begin
328
+ Exponent:=0;
329
+ if (X<>0) then
330
+ if (abs(X)<0.5) then
331
+ repeat
332
+ X:=X*2;
333
+ Dec(Exponent);
334
+ until (abs(X)>=0.5)
335
+ else
336
+ while (abs(X)>=1) do
337
+ begin
338
+ X:=X/2;
339
+ Inc(Exponent);
340
+ end;
341
+ Mantissa:=X;
342
+ end;
343
+
344
+ procedure SinCos(const A: Double; var B: Double; var C: Double);
345
+ begin
346
+ B:=Sin(A);
347
+ C:=Cos(A);
348
+ end;
349
+
350
+ function LogN(const Base,N: Double): Double;
351
+
352
+ begin
353
+ Result:=Ln(N)/Ln(Base);
354
+ end;
355
+
356
+ function lnxp1(x: double): double;
357
+
358
+ var
359
+ y: float;
360
+
361
+ begin
362
+ if (x>=4.0) then
363
+ result:=ln(1.0+x)
364
+ else
365
+ begin
366
+ y:=1.0+x;
367
+ if (y=1.0) then
368
+ result:=x
369
+ else
370
+ begin
371
+ result:=ln(y); { lnxp1(-1) = ln(0) = -Inf }
372
+ if y>0.0 then
373
+ result:=result+(x-(y-1.0))/y;
374
+ end;
375
+ end;
376
+ end;
377
+
378
+ function ldexp(x : double;const p : Integer) : double;
379
+
380
+ begin
381
+ result:=x*intpower(2.0,p);
382
+ end;
383
+
384
+
385
+ function IntPower(base: float; const exponent: Integer): double;
386
+
387
+ var
388
+ i : longint;
389
+
390
+ begin
391
+ if (base = 0.0) and (exponent = 0) then
392
+ result:=1
393
+ else
394
+ begin
395
+ i:=abs(exponent);
396
+ Result:=1.0;
397
+ while i>0 do
398
+ begin
399
+ while (i and 1)=0 do
400
+ begin
401
+ i:=i shr 1;
402
+ base:=sqr(base);
403
+ end;
404
+ i:=i-1;
405
+ Result:=Result*base;
406
+ end;
407
+ if exponent<0 then
408
+ Result:=1.0/Result;
409
+ end;
410
+ end;
411
+
412
+ procedure DivMod(Dividend: LongInt; Divisor: Word; out Result, Remainder: Word);
413
+ begin
414
+ if Dividend < 0 then
415
+ begin
416
+ Dividend:=-Dividend;
417
+ Result:=-(Dividend Div Divisor);
418
+ Remainder:=-(Dividend+(Result*Divisor));
419
+ end
420
+ else
421
+ begin
422
+ Result:=Dividend Div Divisor;
423
+ Remainder:=Dividend-(Result*Divisor);
424
+ end;
425
+ end;
426
+
427
+
428
+ procedure DivMod(Dividend: LongInt; Divisor: Word; out Result,
429
+ Remainder: SmallInt);
430
+ begin
431
+ if Dividend < 0 then
432
+ begin
433
+ Dividend:=-Dividend;
434
+ Result:=-(Dividend Div Divisor);
435
+ Remainder:=-(Dividend+(Result*Divisor));
436
+ end
437
+ else
438
+ begin
439
+ Result:=Dividend Div Divisor;
440
+ Remainder:=Dividend-(Result*Divisor);
441
+ end;
442
+ end;
443
+
444
+
445
+ procedure DivMod(Dividend: DWord; Divisor: DWord; out Result, Remainder: DWord);
446
+ begin
447
+ Result:=Dividend Div Divisor;
448
+ Remainder:=Dividend-(Result*Divisor);
449
+ end;
450
+
451
+
452
+ procedure DivMod(Dividend: LongInt; Divisor: LongInt; out Result,
453
+ Remainder: LongInt);
454
+
455
+ begin
456
+ if Dividend < 0 then
457
+ begin
458
+ Dividend:=-Dividend;
459
+ Result:=-(Dividend Div Divisor);
460
+ Remainder:=-(Dividend+(Result*Divisor));
461
+ end
462
+ else
463
+ begin
464
+ Result:=Dividend Div Divisor;
465
+ Remainder:=Dividend-(Result*Divisor);
466
+ end;
467
+ end;
468
+
469
+ { ---------------------------------------------------------------------
470
+ Angle conversion
471
+ ---------------------------------------------------------------------}
472
+ function DegToRad(deg: double): double;
473
+
474
+ begin
475
+ Result:=deg*(pi/180.0);
476
+ end;
477
+
478
+
479
+ function RadToDeg(rad: double): double;
480
+
481
+ begin
482
+ Result:=rad*(180.0/pi);
483
+ end;
484
+
485
+
486
+ function GradToRad(grad: double): double;
487
+
488
+ begin
489
+ Result:=grad*(pi/200.0);
490
+ end;
491
+
492
+
493
+ function RadToGrad(rad: double): double;
494
+
495
+ begin
496
+ Result:=rad*(200.0/pi);
497
+ end;
498
+
499
+
500
+ function DegToGrad(deg: double): double;
501
+
502
+ begin
503
+ Result:=deg*(200.0/180.0);
504
+ end;
505
+
506
+
507
+ function GradToDeg(grad: double): double;
508
+
509
+ begin
510
+ Result:=grad*(180.0/200.0);
511
+ end;
512
+
513
+
514
+ function CycleToRad(cycle: double): double;
515
+
516
+ begin
517
+ Result:=(2*pi)*cycle;
518
+ end;
519
+
520
+
521
+ function RadToCycle(rad: double): double;
522
+
523
+ begin
524
+ Result:=rad*(1/(2*pi));
525
+ end;
526
+
527
+
528
+ function DegNormalize(deg: double): double;
529
+
530
+ begin
531
+ Result:=Deg-Int(Deg/360)*360;
532
+ If (Result<0) then Result:=Result+360;
533
+ end;
534
+
535
+ function sumofsquares(const data : array of double) : double;
536
+ var
537
+ i,N : longint;
538
+
539
+ begin
540
+ N:=Length(Data);
541
+ Result:=0.0;
542
+ for i:=0 to N-1 do
543
+ Result:=Result+sqr(data[i]);
544
+ end;
545
+
546
+ function Norm(const data: array of double): double;
547
+ begin
548
+ Result:=sqrt(sumofsquares(data));
549
+ end;
550
+
551
+ { ---------------------------------------------------------------------
552
+ Statistical functions
553
+ ---------------------------------------------------------------------}
554
+
555
+ function Sum(const data: array of double): double;
556
+
557
+ var
558
+ i,N : longint;
559
+
560
+ begin
561
+ N:=Length(Data);
562
+ Result:=0.0;
563
+ for i:=0 to N-1 do
564
+ Result:=Result+data[i];
565
+ end;
566
+
567
+ function Mean(const data: array of double): double;
568
+
569
+ Var
570
+ N : integer;
571
+
572
+ begin
573
+ N:=Length(Data);
574
+ if N=0 then
575
+ Result:=0
576
+ else
577
+ Result:=Sum(Data)/N;
578
+ end;
579
+ procedure SumsAndSquares(const data: array of Double; out Sum,
580
+ SumOfSquares: double);
581
+
582
+ var
583
+ i,n : Integer;
584
+ t,s,ss: double;
585
+
586
+ begin
587
+ n:=length(Data);
588
+ ss:=0.0; // Use local vars, var is very inefficient in js
589
+ s:=0.0;
590
+ for i:=0 to N-1 do
591
+ begin
592
+ t:=data[i];
593
+ ss:=ss+sqr(t);
594
+ s:=s+t;
595
+ end;
596
+ Sum:=s;
597
+ SumOfSquares:=ss;
598
+ end;
599
+
600
+ function StdDev(const data: array of Double): float;
601
+
602
+ begin
603
+ Result:=Sqrt(Variance(Data));
604
+ end;
605
+
606
+ function Variance(const data: array of Double): double;
607
+
608
+ var
609
+ n : integer;
610
+
611
+ begin
612
+ N:=Length(Data);
613
+ If N=1 then
614
+ Result:=0
615
+ else
616
+ Result:=TotalVariance(Data)/(N-1);
617
+ end;
618
+
619
+ function TotalVariance(const data: array of Double): double;
620
+
621
+ var
622
+ S,SS : Float;
623
+ N : integer;
624
+ begin
625
+ N:=Length(Data);
626
+ If Length(Data)=1 then
627
+ Result:=0
628
+ else
629
+ begin
630
+ SumsAndSquares(Data,S,SS);
631
+ Result := SS-Sqr(S)/N;
632
+ end;
633
+ end;
634
+
635
+ procedure MeanAndStdDev(const data: array of Double; out Mean, StdDev: double);
636
+
637
+ Var
638
+ I,N : longint;
639
+ M,S : Double;
640
+
641
+ begin
642
+ N:=Length(Data);
643
+ M:=0;
644
+ S:=0;
645
+ For I:=0 to N-1 do
646
+ begin
647
+ M:=M+Data[i];
648
+ S:=S+Sqr(Data[i]);
649
+ end;
650
+ M:=M/N;
651
+ S:=(S-N*Sqr(M));
652
+ If N>1 then
653
+ S:=Sqrt(S/(N-1))
654
+ else
655
+ S:=0;
656
+ Mean:=M;
657
+ StdDev:=S;
658
+ end;
659
+
660
+ function PopNStdDev(const data : array of Double) : double;
661
+
662
+ begin
663
+ Result:=Sqrt(PopnVariance(Data));
664
+ end;
665
+
666
+ function PopNVariance(const data : array of Double) : double;
667
+
668
+ Var
669
+ N : integer;
670
+
671
+ begin
672
+ N:=Length(Data);
673
+ if N=0 then
674
+ Result:=0
675
+ else
676
+ Result:=TotalVariance(Data)/N;
677
+ end;
678
+
679
+ procedure MomentSkewKurtosis(const data: array of Double; out m1, m2, m3, m4, skew, kurtosis: double);
680
+
681
+ var
682
+ i,N: integer;
683
+ deviation, deviation2: double;
684
+ reciprocalN: float;
685
+ // Use local vars for all calculations, var is very slow
686
+ lm1, lm2, lm3, lm4, lskew, lkurtosis: double;
687
+
688
+ begin
689
+ N:=length(Data);
690
+ lm1 := 0;
691
+ reciprocalN := 1/N;
692
+ for i := 0 to N-1 do
693
+ lm1 := lm1 + data[i];
694
+ lm1 := reciprocalN * lm1;
695
+
696
+ lm2 := 0;
697
+ lm3 := 0;
698
+ lm4 := 0;
699
+ for i := 0 to N-1 do
700
+ begin
701
+ deviation := (data[i]-lm1);
702
+ deviation2 := deviation * deviation;
703
+ lm2 := lm2 + deviation2;
704
+ lm3 := lm3 + deviation2 * deviation;
705
+ lm4 := lm4 + deviation2 * deviation2;
706
+ end;
707
+ lm2 := reciprocalN * lm2;
708
+ lm3 := reciprocalN * lm3;
709
+ lm4 := reciprocalN * lm4;
710
+
711
+ lskew := lm3 / (sqrt(lm2)*lm2);
712
+ lkurtosis := lm4 / (lm2 * lm2);
713
+
714
+ m1:=lm1;
715
+ m2:=lm2;
716
+ m3:=lm3;
717
+ m4:=lm4;
718
+ skew:=lskew;
719
+ kurtosis:=lkurtosis;
720
+ end;
721
+
722
+ { ---------------------------------------------------------------------
723
+ Financial functions
724
+ ---------------------------------------------------------------------}
725
+
726
+ function FutureValue(ARate: double; NPeriods: Integer;
727
+ APayment, APresentValue: double; APaymentTime: TPaymentTime): double;
728
+ var
729
+ q, qn, factor: double;
730
+ begin
731
+ if ARate = 0 then
732
+ Result := -APresentValue - APayment * NPeriods
733
+ else begin
734
+ q := 1.0 + ARate;
735
+ qn := power(q, NPeriods);
736
+ factor := (qn - 1) / (q - 1);
737
+ if APaymentTime = ptStartOfPeriod then
738
+ factor := factor * q;
739
+ Result := -(APresentValue * qn + APayment*factor);
740
+ end;
741
+ end;
742
+
743
+ function InterestRate(NPeriods: Integer; APayment, APresentValue, AFutureValue: double;
744
+ APaymentTime: TPaymentTime): double;
745
+ { The interest rate cannot be calculated analytically. We solve the equation
746
+ numerically by means of the Newton method:
747
+ - guess value for the interest reate
748
+ - calculate at which interest rate the tangent of the curve fv(rate)
749
+ (straight line!) has the requested future vale.
750
+ - use this rate for the next iteration. }
751
+ const
752
+ DELTA = 0.001;
753
+ EPS = 1E-9; // required precision of interest rate (after typ. 6 iterations)
754
+ MAXIT = 20; // max iteration count to protect agains non-convergence
755
+ var
756
+ r1, r2, dr: double;
757
+ fv1, fv2: double;
758
+ iteration: Integer;
759
+ begin
760
+ iteration := 0;
761
+ r1 := 0.05; // inital guess
762
+ repeat
763
+ r2 := r1 + DELTA;
764
+ fv1 := FutureValue(r1, NPeriods, APayment, APresentValue, APaymentTime);
765
+ fv2 := FutureValue(r2, NPeriods, APayment, APresentValue, APaymentTime);
766
+ dr := (AFutureValue - fv1) / (fv2 - fv1) * delta; // tangent at fv(r)
767
+ r1 := r1 + dr; // next guess
768
+ inc(iteration);
769
+ until (abs(dr) < EPS) or (iteration >= MAXIT);
770
+ Result := r1;
771
+ end;
772
+
773
+ function NumberOfPeriods(ARate, APayment, APresentValue, AFutureValue: double;
774
+ APaymentTime: TPaymentTime): double;
775
+ { Solve the cash flow equation (1) for q^n and take the logarithm }
776
+ var
777
+ q, x1, x2: double;
778
+ begin
779
+ if ARate = 0 then
780
+ Result := -(APresentValue + AFutureValue) / APayment
781
+ else begin
782
+ q := 1.0 + ARate;
783
+ if APaymentTime = ptStartOfPeriod then
784
+ APayment := APayment * q;
785
+ x1 := APayment - AFutureValue * ARate;
786
+ x2 := APayment + APresentValue * ARate;
787
+ if (x2 = 0) // we have to divide by x2
788
+ or (sign(x1) * sign(x2) < 0) // the argument of the log is negative
789
+ then
790
+ Result := Infinity
791
+ else begin
792
+ Result := ln(x1/x2) / ln(q);
793
+ end;
794
+ end;
795
+ end;
796
+
797
+ function Payment(ARate: double; NPeriods: Integer;
798
+ APresentValue, AFutureValue: double; APaymentTime: TPaymentTime): double;
799
+ var
800
+ q, qn, factor: double;
801
+ begin
802
+ if ARate = 0 then
803
+ Result := -(AFutureValue + APresentValue) / NPeriods
804
+ else begin
805
+ q := 1.0 + ARate;
806
+ qn := power(q, NPeriods);
807
+ factor := (qn - 1) / (q - 1);
808
+ if APaymentTime = ptStartOfPeriod then
809
+ factor := factor * q;
810
+ Result := -(AFutureValue + APresentValue * qn) / factor;
811
+ end;
812
+ end;
813
+
814
+ function PresentValue(ARate: double; NPeriods: Integer;
815
+ APayment, AFutureValue: double; APaymentTime: TPaymentTime): double;
816
+ var
817
+ q, qn, factor: double;
818
+ begin
819
+ if ARate = 0.0 then
820
+ Result := -AFutureValue - APayment * NPeriods
821
+ else begin
822
+ q := 1.0 + ARate;
823
+ qn := power(q, NPeriods);
824
+ factor := (qn - 1) / (q - 1);
825
+ if APaymentTime = ptStartOfPeriod then
826
+ factor := factor * q;
827
+ Result := -(AFutureValue + APayment*factor) / qn;
828
+ end;
829
+ end;
830
+
831
+ { ---------------------------------------------------------------------
832
+ Miscellaneous
833
+ ---------------------------------------------------------------------}
834
+
835
+ function IfThen(val: boolean; const ifTrue: integer; const ifFalse: integer): integer;
836
+
837
+ begin
838
+ if val then result:=iftrue else result:=iffalse;
839
+ end;
840
+
841
+ function IfThen(val: boolean; const ifTrue: double; const ifFalse: double): double;
842
+
843
+ begin
844
+ if val then result:=iftrue else result:=iffalse;
845
+ end;
846
+
847
+ function CompareValue(const A, B : Integer): TValueRelationship;
848
+
849
+ begin
850
+ result:=GreaterThanValue;
851
+ if a=b then
852
+ result:=EqualsValue
853
+ else
854
+ if a<b then
855
+ result:=LessThanValue;
856
+ end;
857
+
858
+ function CompareValue(const A, B: NativeLargeInt): TValueRelationship;
859
+
860
+ begin
861
+ result:=GreaterThanValue;
862
+ if a=b then
863
+ result:=EqualsValue
864
+ else
865
+ if a<b then
866
+ result:=LessThanValue;
867
+ end;
868
+
869
+ function CompareValue(const A, B: NativeLargeUInt): TValueRelationship;
870
+
871
+ begin
872
+ result:=GreaterThanValue;
873
+ if a=b then
874
+ result:=EqualsValue
875
+ else
876
+ if a<b then
877
+ result:=LessThanValue;
878
+ end;
879
+
880
+ function CompareValue(const A, B: Double; delta: Double): TValueRelationship;
881
+ begin
882
+ result:=GreaterThanValue;
883
+ if abs(a-b)<=delta then
884
+ result:=EqualsValue
885
+ else
886
+ if a<b then
887
+ result:=LessThanValue;
888
+ end;
889
+
890
+ function MaxIntValue(const AData: array of Integer): Integer;
891
+ var
892
+ lCount: Integer;
893
+ begin
894
+ Result := AData[Low(AData)];
895
+ for lCount := Low(AData) + 1 to High(AData) do
896
+ begin
897
+ if Result < AData[lCount] then
898
+ Result := AData[lCount];
899
+ end;
900
+ end;
901
+
902
+ end.
903
+