math.pp 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2005 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {
  12. This unit is an equivalent to the Delphi math unit
  13. (with some improvements)
  14. What's to do:
  15. o some statistical functions
  16. o all financial functions
  17. o optimizations
  18. }
  19. {$MODE objfpc}
  20. {$inline on }
  21. {$GOTO on}
  22. unit math;
  23. interface
  24. {$ifndef FPUNONE}
  25. uses
  26. sysutils;
  27. { Ranges of the IEEE floating point types, including denormals }
  28. {$ifdef FPC_HAS_TYPE_SINGLE}
  29. const
  30. MinSingle = 1.5e-45;
  31. MaxSingle = 3.4e+38;
  32. {$endif FPC_HAS_TYPE_SINGLE}
  33. {$ifdef FPC_HAS_TYPE_DOUBLE}
  34. const
  35. MinDouble = 5.0e-324;
  36. MaxDouble = 1.7e+308;
  37. {$endif FPC_HAS_TYPE_DOUBLE}
  38. {$ifdef FPC_HAS_TYPE_EXTENDED}
  39. const
  40. MinExtended = 3.4e-4932;
  41. MaxExtended = 1.1e+4932;
  42. {$endif FPC_HAS_TYPE_EXTENDED}
  43. {$ifdef FPC_HAS_TYPE_COMP}
  44. const
  45. MinComp = -9.223372036854775807e+18;
  46. MaxComp = 9.223372036854775807e+18;
  47. {$endif FPC_HAS_TYPE_COMP}
  48. { the original delphi functions use extended as argument, }
  49. { but I would prefer double, because 8 bytes is a very }
  50. { natural size for the processor }
  51. { WARNING : changing float type will }
  52. { break all assembler code PM }
  53. {$ifdef FPC_HAS_TYPE_FLOAT128}
  54. type
  55. float = float128;
  56. const
  57. MinFloat = MinFloat128;
  58. MaxFloat = MaxFloat128;
  59. {$else FPC_HAS_TYPE_FLOAT128}
  60. {$ifdef FPC_HAS_TYPE_EXTENDED}
  61. type
  62. float = extended;
  63. const
  64. MinFloat = MinExtended;
  65. MaxFloat = MaxExtended;
  66. {$else FPC_HAS_TYPE_EXTENDED}
  67. {$ifdef FPC_HAS_TYPE_DOUBLE}
  68. type
  69. float = double;
  70. const
  71. MinFloat = MinDouble;
  72. MaxFloat = MaxDouble;
  73. {$else FPC_HAS_TYPE_DOUBLE}
  74. {$ifdef FPC_HAS_TYPE_SINGLE}
  75. type
  76. float = single;
  77. const
  78. MinFloat = MinSingle;
  79. MaxFloat = MaxSingle;
  80. {$else FPC_HAS_TYPE_SINGLE}
  81. {$fatal At least one floating point type must be supported}
  82. {$endif FPC_HAS_TYPE_SINGLE}
  83. {$endif FPC_HAS_TYPE_DOUBLE}
  84. {$endif FPC_HAS_TYPE_EXTENDED}
  85. {$endif FPC_HAS_TYPE_FLOAT128}
  86. type
  87. PFloat = ^Float;
  88. PInteger = ObjPas.PInteger;
  89. tpaymenttime = (ptendofperiod,ptstartofperiod);
  90. einvalidargument = class(ematherror);
  91. TValueRelationship = -1..1;
  92. const
  93. EqualsValue = 0;
  94. LessThanValue = Low(TValueRelationship);
  95. GreaterThanValue = High(TValueRelationship);
  96. {$ifopt R+}
  97. {$define RangeCheckWasOn}
  98. {$R-}
  99. {$endif opt R+}
  100. {$ifopt Q+}
  101. {$define OverflowCheckWasOn}
  102. {$Q-}
  103. {$endif opt Q+}
  104. NaN = 0.0/0.0;
  105. Infinity = 1.0/0.0;
  106. NegInfinity = -1.0/0.0;
  107. {$ifdef RangeCheckWasOn}
  108. {$R+}
  109. {$undef RangeCheckWasOn}
  110. {$endif}
  111. {$ifdef OverflowCheckWasOn}
  112. {$Q+}
  113. {$undef OverflowCheckWasOn}
  114. {$endif}
  115. { Min/max determination }
  116. function MinIntValue(const Data: array of Integer): Integer;
  117. function MaxIntValue(const Data: array of Integer): Integer;
  118. { Extra, not present in Delphi, but used frequently }
  119. function Min(a, b: Integer): Integer;inline; overload;
  120. function Max(a, b: Integer): Integer;inline; overload;
  121. { this causes more trouble than it solves
  122. function Min(a, b: Cardinal): Cardinal; overload;
  123. function Max(a, b: Cardinal): Cardinal; overload;
  124. }
  125. function Min(a, b: Int64): Int64;inline; overload;
  126. function Max(a, b: Int64): Int64;inline; overload;
  127. {$ifdef FPC_HAS_TYPE_SINGLE}
  128. function Min(a, b: Single): Single;inline; overload;
  129. function Max(a, b: Single): Single;inline; overload;
  130. {$endif FPC_HAS_TYPE_SINGLE}
  131. {$ifdef FPC_HAS_TYPE_DOUBLE}
  132. function Min(a, b: Double): Double;inline; overload;
  133. function Max(a, b: Double): Double;inline; overload;
  134. {$endif FPC_HAS_TYPE_DOUBLE}
  135. {$ifdef FPC_HAS_TYPE_EXTENDED}
  136. function Min(a, b: Extended): Extended;inline; overload;
  137. function Max(a, b: Extended): Extended;inline; overload;
  138. {$endif FPC_HAS_TYPE_EXTENDED}
  139. function InRange(const AValue, AMin, AMax: Integer): Boolean;inline; overload;
  140. function InRange(const AValue, AMin, AMax: Int64): Boolean;inline; overload;
  141. {$ifdef FPC_HAS_TYPE_DOUBLE}
  142. function InRange(const AValue, AMin, AMax: Double): Boolean;inline; overload;
  143. {$endif FPC_HAS_TYPE_DOUBLE}
  144. function EnsureRange(const AValue, AMin, AMax: Integer): Integer;inline; overload;
  145. function EnsureRange(const AValue, AMin, AMax: Int64): Int64;inline; overload;
  146. {$ifdef FPC_HAS_TYPE_DOUBLE}
  147. function EnsureRange(const AValue, AMin, AMax: Double): Double;inline; overload;
  148. {$endif FPC_HAS_TYPE_DOUBLE}
  149. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
  150. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
  151. procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);
  152. procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);
  153. // Sign functions
  154. Type
  155. TValueSign = -1..1;
  156. const
  157. NegativeValue = Low(TValueSign);
  158. ZeroValue = 0;
  159. PositiveValue = High(TValueSign);
  160. function Sign(const AValue: Integer): TValueSign;inline; overload;
  161. function Sign(const AValue: Int64): TValueSign;inline; overload;
  162. {$ifdef FPC_HAS_TYPE_SINGLE}
  163. function Sign(const AValue: Single): TValueSign;inline; overload;
  164. {$endif}
  165. function Sign(const AValue: Double): TValueSign;inline; overload;
  166. {$ifdef FPC_HAS_TYPE_EXTENDED}
  167. function Sign(const AValue: Extended): TValueSign;inline; overload;
  168. {$endif}
  169. function IsZero(const A: Single; Epsilon: Single): Boolean; overload;
  170. function IsZero(const A: Single): Boolean;inline; overload;
  171. {$ifdef FPC_HAS_TYPE_DOUBLE}
  172. function IsZero(const A: Double; Epsilon: Double): Boolean; overload;
  173. function IsZero(const A: Double): Boolean;inline; overload;
  174. {$endif FPC_HAS_TYPE_DOUBLE}
  175. {$ifdef FPC_HAS_TYPE_EXTENDED}
  176. function IsZero(const A: Extended; Epsilon: Extended): Boolean; overload;
  177. function IsZero(const A: Extended): Boolean;inline; overload;
  178. {$endif FPC_HAS_TYPE_EXTENDED}
  179. function IsNan(const d : Double): Boolean; overload;
  180. function IsInfinite(const d : Double): Boolean;
  181. {$ifdef FPC_HAS_TYPE_EXTENDED}
  182. function SameValue(const A, B: Extended): Boolean;inline; overload;
  183. {$endif}
  184. {$ifdef FPC_HAS_TYPE_DOUBLE}
  185. function SameValue(const A, B: Double): Boolean;inline; overload;
  186. {$endif}
  187. function SameValue(const A, B: Single): Boolean;inline; overload;
  188. {$ifdef FPC_HAS_TYPE_EXTENDED}
  189. function SameValue(const A, B: Extended; Epsilon: Extended): Boolean; overload;
  190. {$endif}
  191. {$ifdef FPC_HAS_TYPE_DOUBLE}
  192. function SameValue(const A, B: Double; Epsilon: Double): Boolean; overload;
  193. {$endif}
  194. function SameValue(const A, B: Single; Epsilon: Single): Boolean; overload;
  195. type
  196. TRoundToRange = -37..37;
  197. {$ifdef FPC_HAS_TYPE_DOUBLE}
  198. function RoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
  199. {$endif}
  200. {$ifdef FPC_HAS_TYPE_EXTENDED}
  201. function RoundTo(const AVAlue: Extended; const Digits: TRoundToRange): Extended;
  202. {$endif}
  203. {$ifdef FPC_HAS_TYPE_SINGLE}
  204. function RoundTo(const AValue: Single; const Digits: TRoundToRange): Single;
  205. {$endif}
  206. {$ifdef FPC_HAS_TYPE_SINGLE}
  207. function SimpleRoundTo(const AValue: Single; const Digits: TRoundToRange = -2): Single;
  208. {$endif}
  209. {$ifdef FPC_HAS_TYPE_DOUBLE}
  210. function SimpleRoundTo(const AValue: Double; const Digits: TRoundToRange = -2): Double;
  211. {$endif}
  212. {$ifdef FPC_HAS_TYPE_EXTENDED}
  213. function SimpleRoundTo(const AValue: Extended; const Digits: TRoundToRange = -2): Extended;
  214. {$endif}
  215. { angle conversion }
  216. function degtorad(deg : float) : float;
  217. function radtodeg(rad : float) : float;
  218. function gradtorad(grad : float) : float;
  219. function radtograd(rad : float) : float;
  220. function degtograd(deg : float) : float;
  221. function gradtodeg(grad : float) : float;
  222. { one cycle are 2*Pi rad }
  223. function cycletorad(cycle : float) : float;
  224. function radtocycle(rad : float) : float;
  225. { trigoniometric functions }
  226. function tan(x : float) : float;
  227. function cotan(x : float) : float;
  228. function cot(x : float) : float; inline;
  229. procedure sincos(theta : float;out sinus,cosinus : float);
  230. function secant(x : float) : float; inline;
  231. function cosecant(x : float) : float; inline;
  232. function sec(x : float) : float; inline;
  233. function csc(x : float) : float; inline;
  234. { inverse functions }
  235. function arccos(x : float) : float;
  236. function arcsin(x : float) : float;
  237. { calculates arctan(y/x) and returns an angle in the correct quadrant }
  238. function arctan2(y,x : float) : float;
  239. { hyperbolic functions }
  240. function cosh(x : float) : float;
  241. function sinh(x : float) : float;
  242. function tanh(x : float) : float;
  243. { area functions }
  244. { delphi names: }
  245. function arccosh(x : float) : float;
  246. function arcsinh(x : float) : float;
  247. function arctanh(x : float) : float;
  248. { IMHO the function should be called as follows (FK) }
  249. function arcosh(x : float) : float;
  250. function arsinh(x : float) : float;
  251. function artanh(x : float) : float;
  252. { triangle functions }
  253. { returns the length of the hypotenuse of a right triangle }
  254. { if x and y are the other sides }
  255. function hypot(x,y : float) : float;
  256. { logarithm functions }
  257. function log10(x : float) : float;
  258. function log2(x : float) : float;
  259. function logn(n,x : float) : float;
  260. { returns natural logarithm of x+1 }
  261. function lnxp1(x : float) : float;
  262. { exponential functions }
  263. function power(base,exponent : float) : float;
  264. { base^exponent }
  265. function intpower(base : float;const exponent : Integer) : float;
  266. operator ** (bas,expo : float) e: float; inline;
  267. operator ** (bas,expo : int64) i: int64; inline;
  268. { number converting }
  269. { rounds x towards positive infinity }
  270. function ceil(x : float) : Integer;
  271. { rounds x towards negative infinity }
  272. function floor(x : float) : Integer;
  273. { misc. functions }
  274. { splits x into mantissa and exponent (to base 2) }
  275. procedure Frexp(X: float; var Mantissa: float; var Exponent: integer);
  276. { returns x*(2^p) }
  277. function ldexp(x : float; const p : Integer) : float;
  278. { statistical functions }
  279. {$ifdef FPC_HAS_TYPE_SINGLE}
  280. function mean(const data : array of Single) : float;
  281. function sum(const data : array of Single) : float;
  282. function mean(const data : PSingle; Const N : longint) : float;
  283. function sum(const data : PSingle; Const N : Longint) : float;
  284. {$endif FPC_HAS_TYPE_SINGLE}
  285. {$ifdef FPC_HAS_TYPE_DOUBLE}
  286. function mean(const data : array of double) : float;
  287. function sum(const data : array of double) : float;
  288. function mean(const data : PDouble; Const N : longint) : float;
  289. function sum(const data : PDouble; Const N : Longint) : float;
  290. {$endif FPC_HAS_TYPE_DOUBLE}
  291. {$ifdef FPC_HAS_TYPE_EXTENDED}
  292. function mean(const data : array of Extended) : float;
  293. function sum(const data : array of Extended) : float;
  294. function mean(const data : PExtended; Const N : longint) : float;
  295. function sum(const data : PExtended; Const N : Longint) : float;
  296. {$endif FPC_HAS_TYPE_EXTENDED}
  297. function sumInt(const data : PInt64;Const N : longint) : Int64;
  298. function sumInt(const data : array of Int64) : Int64;
  299. {$ifdef FPC_HAS_TYPE_SINGLE}
  300. function sumofsquares(const data : array of Single) : float;
  301. function sumofsquares(const data : PSingle; Const N : Integer) : float;
  302. { calculates the sum and the sum of squares of data }
  303. procedure sumsandsquares(const data : array of Single;
  304. var sum,sumofsquares : float);
  305. procedure sumsandsquares(const data : PSingle; Const N : Integer;
  306. var sum,sumofsquares : float);
  307. {$endif FPC_HAS_TYPE_SINGLE}
  308. {$ifdef FPC_HAS_TYPE_DOUBLE}
  309. function sumofsquares(const data : array of double) : float;
  310. function sumofsquares(const data : PDouble; Const N : Integer) : float;
  311. { calculates the sum and the sum of squares of data }
  312. procedure sumsandsquares(const data : array of Double;
  313. var sum,sumofsquares : float);
  314. procedure sumsandsquares(const data : PDouble; Const N : Integer;
  315. var sum,sumofsquares : float);
  316. {$endif FPC_HAS_TYPE_DOUBLE}
  317. {$ifdef FPC_HAS_TYPE_EXTENDED}
  318. function sumofsquares(const data : array of Extended) : float;
  319. function sumofsquares(const data : PExtended; Const N : Integer) : float;
  320. { calculates the sum and the sum of squares of data }
  321. procedure sumsandsquares(const data : array of Extended;
  322. var sum,sumofsquares : float);
  323. procedure sumsandsquares(const data : PExtended; Const N : Integer;
  324. var sum,sumofsquares : float);
  325. {$endif FPC_HAS_TYPE_EXTENDED}
  326. {$ifdef FPC_HAS_TYPE_SINGLE}
  327. function minvalue(const data : array of Single) : Single;
  328. function minvalue(const data : PSingle; Const N : Integer) : Single;
  329. function maxvalue(const data : array of Single) : Single;
  330. function maxvalue(const data : PSingle; Const N : Integer) : Single;
  331. {$endif FPC_HAS_TYPE_SINGLE}
  332. {$ifdef FPC_HAS_TYPE_DOUBLE}
  333. function minvalue(const data : array of Double) : Double;
  334. function minvalue(const data : PDouble; Const N : Integer) : Double;
  335. function maxvalue(const data : array of Double) : Double;
  336. function maxvalue(const data : PDouble; Const N : Integer) : Double;
  337. {$endif FPC_HAS_TYPE_DOUBLE}
  338. {$ifdef FPC_HAS_TYPE_EXTENDED}
  339. function minvalue(const data : array of Extended) : Extended;
  340. function minvalue(const data : PExtended; Const N : Integer) : Extended;
  341. function maxvalue(const data : array of Extended) : Extended;
  342. function maxvalue(const data : PExtended; Const N : Integer) : Extended;
  343. {$endif FPC_HAS_TYPE_EXTENDED}
  344. function minvalue(const data : array of integer) : Integer;
  345. function MinValue(const Data : PInteger; Const N : Integer): Integer;
  346. function maxvalue(const data : array of integer) : Integer;
  347. function maxvalue(const data : PInteger; Const N : Integer) : Integer;
  348. { returns random values with gaussian distribution }
  349. function randg(mean,stddev : float) : float;
  350. function RandomRange(const aFrom, aTo: Integer): Integer;
  351. {$ifdef FPC_HAS_TYPE_SINGLE}
  352. { calculates the standard deviation }
  353. function stddev(const data : array of Single) : float;
  354. function stddev(const data : PSingle; Const N : Integer) : float;
  355. { calculates the mean and stddev }
  356. procedure meanandstddev(const data : array of Single;
  357. var mean,stddev : float);
  358. procedure meanandstddev(const data : PSingle;
  359. Const N : Longint;var mean,stddev : float);
  360. function variance(const data : array of Single) : float;
  361. function totalvariance(const data : array of Single) : float;
  362. function variance(const data : PSingle; Const N : Integer) : float;
  363. function totalvariance(const data : PSingle; Const N : Integer) : float;
  364. { I don't know what the following functions do: }
  365. function popnstddev(const data : array of Single) : float;
  366. function popnstddev(const data : PSingle; Const N : Integer) : float;
  367. function popnvariance(const data : PSingle; Const N : Integer) : float;
  368. function popnvariance(const data : array of Single) : float;
  369. procedure momentskewkurtosis(const data : array of Single;
  370. out m1,m2,m3,m4,skew,kurtosis : float);
  371. procedure momentskewkurtosis(const data : PSingle; Const N : Integer;
  372. out m1,m2,m3,m4,skew,kurtosis : float);
  373. { geometrical function }
  374. { returns the euclidean L2 norm }
  375. function norm(const data : array of Single) : float;
  376. function norm(const data : PSingle; Const N : Integer) : float;
  377. {$endif FPC_HAS_TYPE_SINGLE}
  378. {$ifdef FPC_HAS_TYPE_DOUBLE}
  379. { calculates the standard deviation }
  380. function stddev(const data : array of Double) : float;
  381. function stddev(const data : PDouble; Const N : Integer) : float;
  382. { calculates the mean and stddev }
  383. procedure meanandstddev(const data : array of Double;
  384. var mean,stddev : float);
  385. procedure meanandstddev(const data : PDouble;
  386. Const N : Longint;var mean,stddev : float);
  387. function variance(const data : array of Double) : float;
  388. function totalvariance(const data : array of Double) : float;
  389. function variance(const data : PDouble; Const N : Integer) : float;
  390. function totalvariance(const data : PDouble; Const N : Integer) : float;
  391. { I don't know what the following functions do: }
  392. function popnstddev(const data : array of Double) : float;
  393. function popnstddev(const data : PDouble; Const N : Integer) : float;
  394. function popnvariance(const data : PDouble; Const N : Integer) : float;
  395. function popnvariance(const data : array of Double) : float;
  396. procedure momentskewkurtosis(const data : array of Double;
  397. out m1,m2,m3,m4,skew,kurtosis : float);
  398. procedure momentskewkurtosis(const data : PDouble; Const N : Integer;
  399. out m1,m2,m3,m4,skew,kurtosis : float);
  400. { geometrical function }
  401. { returns the euclidean L2 norm }
  402. function norm(const data : array of double) : float;
  403. function norm(const data : PDouble; Const N : Integer) : float;
  404. {$endif FPC_HAS_TYPE_DOUBLE}
  405. {$ifdef FPC_HAS_TYPE_EXTENDED}
  406. { calculates the standard deviation }
  407. function stddev(const data : array of Extended) : float;
  408. function stddev(const data : PExtended; Const N : Integer) : float;
  409. { calculates the mean and stddev }
  410. procedure meanandstddev(const data : array of Extended;
  411. var mean,stddev : float);
  412. procedure meanandstddev(const data : PExtended;
  413. Const N : Longint;var mean,stddev : float);
  414. function variance(const data : array of Extended) : float;
  415. function totalvariance(const data : array of Extended) : float;
  416. function variance(const data : PExtended; Const N : Integer) : float;
  417. function totalvariance(const data : PExtended; Const N : Integer) : float;
  418. { I don't know what the following functions do: }
  419. function popnstddev(const data : array of Extended) : float;
  420. function popnstddev(const data : PExtended; Const N : Integer) : float;
  421. function popnvariance(const data : PExtended; Const N : Integer) : float;
  422. function popnvariance(const data : array of Extended) : float;
  423. procedure momentskewkurtosis(const data : array of Extended;
  424. out m1,m2,m3,m4,skew,kurtosis : float);
  425. procedure momentskewkurtosis(const data : PExtended; Const N : Integer;
  426. out m1,m2,m3,m4,skew,kurtosis : float);
  427. { geometrical function }
  428. { returns the euclidean L2 norm }
  429. function norm(const data : array of Extended) : float;
  430. function norm(const data : PExtended; Const N : Integer) : float;
  431. {$endif FPC_HAS_TYPE_EXTENDED}
  432. function ifthen(val:boolean;const iftrue:integer; const iffalse:integer= 0) :integer; inline; overload;
  433. function ifthen(val:boolean;const iftrue:int64 ; const iffalse:int64 = 0) :int64; inline; overload;
  434. function ifthen(val:boolean;const iftrue:double ; const iffalse:double =0.0):double; inline; overload;
  435. function CompareValue ( const A, B : Integer) : TValueRelationship; inline;
  436. function CompareValue ( const A, B : Int64) : TValueRelationship; inline;
  437. function CompareValue ( const A, B : QWord) : TValueRelationship; inline;
  438. {$ifdef FPC_HAS_TYPE_SINGLE}
  439. function CompareValue ( const A, B : Single; delta : Single = 0.0 ) : TValueRelationship; inline;
  440. {$endif}
  441. {$ifdef FPC_HAS_TYPE_DOUBLE}
  442. function CompareValue ( const A, B : Double; delta : Double = 0.0) : TValueRelationship; inline;
  443. {$endif}
  444. {$ifdef FPC_HAS_TYPE_EXTENDED}
  445. function CompareValue ( const A, B : Extended; delta : Extended = 0.0 ) : TValueRelationship; inline;
  446. {$endif}
  447. function RandomFrom(const AValues: array of Double): Double; overload;
  448. function RandomFrom(const AValues: array of Integer): Integer; overload;
  449. function RandomFrom(const AValues: array of Int64): Int64; overload;
  450. { include cpu specific stuff }
  451. {$i mathuh.inc}
  452. implementation
  453. { include cpu specific stuff }
  454. {$i mathu.inc}
  455. ResourceString
  456. SMathError = 'Math Error : %s';
  457. SInvalidArgument = 'Invalid argument';
  458. Procedure DoMathError(Const S : String);
  459. begin
  460. Raise EMathError.CreateFmt(SMathError,[S]);
  461. end;
  462. Procedure InvalidArgument;
  463. begin
  464. Raise EInvalidArgument.Create(SInvalidArgument);
  465. end;
  466. function Sign(const AValue: Integer): TValueSign;inline;
  467. begin
  468. If Avalue<0 then
  469. Result:=NegativeValue
  470. else If Avalue>0 then
  471. Result:=PositiveValue
  472. else
  473. Result:=ZeroValue;
  474. end;
  475. function Sign(const AValue: Int64): TValueSign;inline;
  476. begin
  477. If Avalue<0 then
  478. Result:=NegativeValue
  479. else If Avalue>0 then
  480. Result:=PositiveValue
  481. else
  482. Result:=ZeroValue;
  483. end;
  484. {$ifdef FPC_HAS_TYPE_SINGLE}
  485. function Sign(const AValue: Single): TValueSign;inline;
  486. begin
  487. If Avalue<0.0 then
  488. Result:=NegativeValue
  489. else If Avalue>0.0 then
  490. Result:=PositiveValue
  491. else
  492. Result:=ZeroValue;
  493. end;
  494. {$endif}
  495. function Sign(const AValue: Double): TValueSign;inline;
  496. begin
  497. If Avalue<0.0 then
  498. Result:=NegativeValue
  499. else If Avalue>0.0 then
  500. Result:=PositiveValue
  501. else
  502. Result:=ZeroValue;
  503. end;
  504. {$ifdef FPC_HAS_TYPE_EXTENDED}
  505. function Sign(const AValue: Extended): TValueSign;inline;
  506. begin
  507. If Avalue<0.0 then
  508. Result:=NegativeValue
  509. else If Avalue>0.0 then
  510. Result:=PositiveValue
  511. else
  512. Result:=ZeroValue;
  513. end;
  514. {$endif}
  515. function degtorad(deg : float) : float;
  516. begin
  517. degtorad:=deg*(pi/180.0);
  518. end;
  519. function radtodeg(rad : float) : float;
  520. begin
  521. radtodeg:=rad*(180.0/pi);
  522. end;
  523. function gradtorad(grad : float) : float;
  524. begin
  525. gradtorad:=grad*(pi/200.0);
  526. end;
  527. function radtograd(rad : float) : float;
  528. begin
  529. radtograd:=rad*(200.0/pi);
  530. end;
  531. function degtograd(deg : float) : float;
  532. begin
  533. degtograd:=deg*(200.0/180.0);
  534. end;
  535. function gradtodeg(grad : float) : float;
  536. begin
  537. gradtodeg:=grad*(180.0/200.0);
  538. end;
  539. function cycletorad(cycle : float) : float;
  540. begin
  541. cycletorad:=(2*pi)*cycle;
  542. end;
  543. function radtocycle(rad : float) : float;
  544. begin
  545. { avoid division }
  546. radtocycle:=rad*(1/(2*pi));
  547. end;
  548. {$ifndef FPC_MATH_HAS_TAN}
  549. function tan(x : float) : float;
  550. var
  551. _sin,_cos : float;
  552. begin
  553. sincos(x,_sin,_cos);
  554. tan:=_sin/_cos;
  555. end;
  556. {$endif FPC_MATH_HAS_TAN}
  557. {$ifndef FPC_MATH_HAS_COTAN}
  558. function cotan(x : float) : float;
  559. var
  560. _sin,_cos : float;
  561. begin
  562. sincos(x,_sin,_cos);
  563. cotan:=_cos/_sin;
  564. end;
  565. {$endif FPC_MATH_HAS_COTAN}
  566. function cot(x : float) : float; inline;
  567. begin
  568. cot := cotan(x);
  569. end;
  570. {$ifndef FPC_MATH_HAS_SINCOS}
  571. procedure sincos(theta : float;out sinus,cosinus : float);
  572. begin
  573. sinus:=sin(theta);
  574. cosinus:=cos(theta);
  575. end;
  576. {$endif FPC_MATH_HAS_SINCOS}
  577. function secant(x : float) : float; inline;
  578. begin
  579. secant := 1 / cos(x);
  580. end;
  581. function cosecant(x : float) : float; inline;
  582. begin
  583. cosecant := 1 / sin(x);
  584. end;
  585. function sec(x : float) : float; inline;
  586. begin
  587. sec := secant(x);
  588. end;
  589. function csc(x : float) : float; inline;
  590. begin
  591. csc := cosecant(x);
  592. end;
  593. { ArcSin and ArcCos from Arjan van Dijk ([email protected]) }
  594. function arcsin(x : float) : float;
  595. begin
  596. if abs(x) > 1 then InvalidArgument
  597. else if abs(x) < 0.5 then
  598. arcsin := arctan(x/sqrt(1-sqr(x)))
  599. else
  600. arcsin := sign(x) * (pi*0.5 - arctan(sqrt(1 / sqr(x) - 1)));
  601. end;
  602. function Arccos(x : Float) : Float;
  603. begin
  604. arccos := pi*0.5 - arcsin(x);
  605. end;
  606. {$ifndef FPC_MATH_HAS_ARCTAN2}
  607. function arctan2(y,x : float) : float;
  608. begin
  609. if (x=0) then
  610. begin
  611. if y=0 then
  612. arctan2:=0.0
  613. else if y>0 then
  614. arctan2:=pi/2
  615. else if y<0 then
  616. arctan2:=-pi/2;
  617. end
  618. else
  619. ArcTan2:=ArcTan(y/x);
  620. if x<0.0 then
  621. ArcTan2:=ArcTan2+pi;
  622. if ArcTan2>pi then
  623. ArcTan2:=ArcTan2-2*pi;
  624. end;
  625. {$endif FPC_MATH_HAS_ARCTAN2}
  626. function cosh(x : float) : float;
  627. var
  628. temp : float;
  629. begin
  630. temp:=exp(x);
  631. cosh:=0.5*(temp+1.0/temp);
  632. end;
  633. function sinh(x : float) : float;
  634. var
  635. temp : float;
  636. begin
  637. temp:=exp(x);
  638. sinh:=0.5*(temp-1.0/temp);
  639. end;
  640. Const MaxTanh = 5678.22249441322; // Ln(MaxExtended)/2
  641. function tanh(x : float) : float;
  642. var Temp : float;
  643. begin
  644. if x>MaxTanh then exit(1.0)
  645. else if x<-MaxTanh then exit (-1.0);
  646. temp:=exp(-2*x);
  647. tanh:=(1-temp)/(1+temp)
  648. end;
  649. function arccosh(x : float) : float;
  650. begin
  651. arccosh:=arcosh(x);
  652. end;
  653. function arcsinh(x : float) : float;
  654. begin
  655. arcsinh:=arsinh(x);
  656. end;
  657. function arctanh(x : float) : float;
  658. begin
  659. if x>1 then InvalidArgument;
  660. arctanh:=artanh(x);
  661. end;
  662. function arcosh(x : float) : float;
  663. begin
  664. if x<1 then InvalidArgument;
  665. arcosh:=Ln(x+Sqrt(x*x-1));
  666. end;
  667. function arsinh(x : float) : float;
  668. begin
  669. arsinh:=Ln(x+Sqrt(1+x*x));
  670. end;
  671. function artanh(x : float) : float;
  672. begin
  673. If abs(x)>1 then InvalidArgument;
  674. artanh:=(Ln((1+x)/(1-x)))*0.5;
  675. end;
  676. function hypot(x,y : float) : float;
  677. begin
  678. hypot:=Sqrt(x*x+y*y)
  679. end;
  680. function log10(x : float) : float;
  681. begin
  682. log10:=ln(x)/ln(10);
  683. end;
  684. function log2(x : float) : float;
  685. begin
  686. log2:=ln(x)/ln(2)
  687. end;
  688. function logn(n,x : float) : float;
  689. begin
  690. if n<0 then InvalidArgument;
  691. logn:=ln(x)/ln(n);
  692. end;
  693. function lnxp1(x : float) : float;
  694. begin
  695. if x<-1 then
  696. InvalidArgument;
  697. lnxp1:=ln(1+x);
  698. end;
  699. function power(base,exponent : float) : float;
  700. begin
  701. if Exponent=0.0 then
  702. if base <> 0.0 then
  703. result:=1.0
  704. else
  705. InvalidArgument
  706. else if (base=0.0) and (exponent>0.0) then
  707. result:=0.0
  708. else if (abs(exponent)<=maxint) and (frac(exponent)=0.0) then
  709. result:=intpower(base,trunc(exponent))
  710. else if base>0.0 then
  711. result:=exp(exponent * ln (base))
  712. else
  713. InvalidArgument;
  714. end;
  715. function intpower(base : float;const exponent : Integer) : float;
  716. var
  717. i : longint;
  718. begin
  719. if (base = 0.0) and (exponent = 0) then
  720. InvalidArgument;
  721. i:=abs(exponent);
  722. intpower:=1.0;
  723. while i>0 do
  724. begin
  725. while (i and 1)=0 do
  726. begin
  727. i:=i shr 1;
  728. base:=sqr(base);
  729. end;
  730. i:=i-1;
  731. intpower:=intpower*base;
  732. end;
  733. if exponent<0 then
  734. intpower:=1.0/intpower;
  735. end;
  736. operator ** (bas,expo : float) e: float; inline;
  737. begin
  738. e:=power(bas,expo);
  739. end;
  740. operator ** (bas,expo : int64) i: int64; inline;
  741. begin
  742. i:=round(intpower(bas,expo));
  743. end;
  744. function ceil(x : float) : integer;
  745. begin
  746. Ceil:=Trunc(x);
  747. If Frac(x)>0 then
  748. Ceil:=Ceil+1;
  749. end;
  750. function floor(x : float) : integer;
  751. begin
  752. Floor:=Trunc(x);
  753. If Frac(x)<0 then
  754. Floor := Floor-1;
  755. end;
  756. procedure Frexp(X: float; var Mantissa: float; var Exponent: integer);
  757. begin
  758. Exponent:=0;
  759. if (X<>0) then
  760. if (abs(X)<0.5) then
  761. repeat
  762. X:=X*2;
  763. Dec(Exponent);
  764. until (abs(X)>=0.5)
  765. else
  766. while (abs(X)>=1) do
  767. begin
  768. X:=X/2;
  769. Inc(Exponent);
  770. end;
  771. Mantissa:=X;
  772. end;
  773. function ldexp(x : float;const p : Integer) : float;
  774. begin
  775. ldexp:=x*intpower(2.0,p);
  776. end;
  777. {$ifdef FPC_HAS_TYPE_SINGLE}
  778. function mean(const data : array of Single) : float;
  779. begin
  780. Result:=Mean(PSingle(@data[0]),High(Data)+1);
  781. end;
  782. function mean(const data : PSingle; Const N : longint) : float;
  783. begin
  784. mean:=sum(Data,N);
  785. mean:=mean/N;
  786. end;
  787. function sum(const data : array of Single) : float;
  788. begin
  789. Result:=Sum(PSingle(@Data[0]),High(Data)+1);
  790. end;
  791. function sum(const data : PSingle;Const N : longint) : float;
  792. var
  793. i : longint;
  794. begin
  795. sum:=0.0;
  796. for i:=0 to N-1 do
  797. sum:=sum+data[i];
  798. end;
  799. {$endif FPC_HAS_TYPE_SINGLE}
  800. {$ifdef FPC_HAS_TYPE_DOUBLE}
  801. function mean(const data : array of Double) : float;
  802. begin
  803. Result:=Mean(PDouble(@data[0]),High(Data)+1);
  804. end;
  805. function mean(const data : PDouble; Const N : longint) : float;
  806. begin
  807. mean:=sum(Data,N);
  808. mean:=mean/N;
  809. end;
  810. function sum(const data : array of Double) : float;
  811. begin
  812. Result:=Sum(PDouble(@Data[0]),High(Data)+1);
  813. end;
  814. function sum(const data : PDouble;Const N : longint) : float;
  815. var
  816. i : longint;
  817. begin
  818. sum:=0.0;
  819. for i:=0 to N-1 do
  820. sum:=sum+data[i];
  821. end;
  822. {$endif FPC_HAS_TYPE_DOUBLE}
  823. {$ifdef FPC_HAS_TYPE_EXTENDED}
  824. function mean(const data : array of Extended) : float;
  825. begin
  826. Result:=Mean(PExtended(@data[0]),High(Data)+1);
  827. end;
  828. function mean(const data : PExtended; Const N : longint) : float;
  829. begin
  830. mean:=sum(Data,N);
  831. mean:=mean/N;
  832. end;
  833. function sum(const data : array of Extended) : float;
  834. begin
  835. Result:=Sum(PExtended(@Data[0]),High(Data)+1);
  836. end;
  837. function sum(const data : PExtended;Const N : longint) : float;
  838. var
  839. i : longint;
  840. begin
  841. sum:=0.0;
  842. for i:=0 to N-1 do
  843. sum:=sum+data[i];
  844. end;
  845. {$endif FPC_HAS_TYPE_EXTENDED}
  846. function sumInt(const data : PInt64;Const N : longint) : Int64;
  847. var
  848. i : longint;
  849. begin
  850. sumInt:=0;
  851. for i:=0 to N-1 do
  852. sumInt:=sumInt+data[i];
  853. end;
  854. function sumInt(const data : array of Int64) : Int64;
  855. begin
  856. Result:=SumInt(@Data[0],High(Data)+1);
  857. end;
  858. {$ifdef FPC_HAS_TYPE_SINGLE}
  859. function sumofsquares(const data : array of Single) : float;
  860. begin
  861. Result:=sumofsquares(PSingle(@data[0]),High(Data)+1);
  862. end;
  863. function sumofsquares(const data : PSingle; Const N : Integer) : float;
  864. var
  865. i : longint;
  866. begin
  867. sumofsquares:=0.0;
  868. for i:=0 to N-1 do
  869. sumofsquares:=sumofsquares+sqr(data[i]);
  870. end;
  871. procedure sumsandsquares(const data : array of Single;
  872. var sum,sumofsquares : float);
  873. begin
  874. sumsandsquares (PSingle(@Data[0]),High(Data)+1,Sum,sumofsquares);
  875. end;
  876. procedure sumsandsquares(const data : PSingle; Const N : Integer;
  877. var sum,sumofsquares : float);
  878. var
  879. i : Integer;
  880. temp : float;
  881. begin
  882. sumofsquares:=0.0;
  883. sum:=0.0;
  884. for i:=0 to N-1 do
  885. begin
  886. temp:=data[i];
  887. sumofsquares:=sumofsquares+sqr(temp);
  888. sum:=sum+temp;
  889. end;
  890. end;
  891. {$endif FPC_HAS_TYPE_SINGLE}
  892. {$ifdef FPC_HAS_TYPE_DOUBLE}
  893. function sumofsquares(const data : array of Double) : float;
  894. begin
  895. Result:=sumofsquares(PDouble(@data[0]),High(Data)+1);
  896. end;
  897. function sumofsquares(const data : PDouble; Const N : Integer) : float;
  898. var
  899. i : longint;
  900. begin
  901. sumofsquares:=0.0;
  902. for i:=0 to N-1 do
  903. sumofsquares:=sumofsquares+sqr(data[i]);
  904. end;
  905. procedure sumsandsquares(const data : array of Double;
  906. var sum,sumofsquares : float);
  907. begin
  908. sumsandsquares (PDouble(@Data[0]),High(Data)+1,Sum,sumofsquares);
  909. end;
  910. procedure sumsandsquares(const data : PDouble; Const N : Integer;
  911. var sum,sumofsquares : float);
  912. var
  913. i : Integer;
  914. temp : float;
  915. begin
  916. sumofsquares:=0.0;
  917. sum:=0.0;
  918. for i:=0 to N-1 do
  919. begin
  920. temp:=data[i];
  921. sumofsquares:=sumofsquares+sqr(temp);
  922. sum:=sum+temp;
  923. end;
  924. end;
  925. {$endif FPC_HAS_TYPE_DOUBLE}
  926. {$ifdef FPC_HAS_TYPE_EXTENDED}
  927. function sumofsquares(const data : array of Extended) : float;
  928. begin
  929. Result:=sumofsquares(PExtended(@data[0]),High(Data)+1);
  930. end;
  931. function sumofsquares(const data : PExtended; Const N : Integer) : float;
  932. var
  933. i : longint;
  934. begin
  935. sumofsquares:=0.0;
  936. for i:=0 to N-1 do
  937. sumofsquares:=sumofsquares+sqr(data[i]);
  938. end;
  939. procedure sumsandsquares(const data : array of Extended;
  940. var sum,sumofsquares : float);
  941. begin
  942. sumsandsquares (PExtended(@Data[0]),High(Data)+1,Sum,sumofsquares);
  943. end;
  944. procedure sumsandsquares(const data : PExtended; Const N : Integer;
  945. var sum,sumofsquares : float);
  946. var
  947. i : Integer;
  948. temp : float;
  949. begin
  950. sumofsquares:=0.0;
  951. sum:=0.0;
  952. for i:=0 to N-1 do
  953. begin
  954. temp:=data[i];
  955. sumofsquares:=sumofsquares+sqr(temp);
  956. sum:=sum+temp;
  957. end;
  958. end;
  959. {$endif FPC_HAS_TYPE_EXTENDED}
  960. function randg(mean,stddev : float) : float;
  961. Var U1,S2 : Float;
  962. begin
  963. repeat
  964. u1:= 2*random-1;
  965. S2:=Sqr(U1)+sqr(2*random-1);
  966. until s2<1;
  967. randg:=Sqrt(-2*ln(S2)/S2)*u1*stddev+Mean;
  968. end;
  969. function RandomRange(const aFrom, aTo: Integer): Integer;
  970. begin
  971. Result:=Random(Abs(aFrom-aTo))+Min(aTo,AFrom);
  972. end;
  973. {$ifdef FPC_HAS_TYPE_SINGLE}
  974. function stddev(const data : array of Single) : float;
  975. begin
  976. Result:=Stddev(PSingle(@Data[0]),High(Data)+1)
  977. end;
  978. function stddev(const data : PSingle; Const N : Integer) : float;
  979. begin
  980. StdDev:=Sqrt(Variance(Data,N));
  981. end;
  982. procedure meanandstddev(const data : array of Single;
  983. var mean,stddev : float);
  984. begin
  985. Meanandstddev(PSingle(@Data[0]),High(Data)+1,Mean,stddev);
  986. end;
  987. procedure meanandstddev(const data : PSingle;
  988. Const N : Longint;var mean,stddev : float);
  989. Var I : longint;
  990. begin
  991. Mean:=0;
  992. StdDev:=0;
  993. For I:=0 to N-1 do
  994. begin
  995. Mean:=Mean+Data[i];
  996. StdDev:=StdDev+Sqr(Data[i]);
  997. end;
  998. Mean:=Mean/N;
  999. StdDev:=(StdDev-N*Sqr(Mean));
  1000. If N>1 then
  1001. StdDev:=Sqrt(Stddev/(N-1))
  1002. else
  1003. StdDev:=0;
  1004. end;
  1005. function variance(const data : array of Single) : float;
  1006. begin
  1007. Variance:=Variance(PSingle(@Data[0]),High(Data)+1);
  1008. end;
  1009. function variance(const data : PSingle; Const N : Integer) : float;
  1010. begin
  1011. If N=1 then
  1012. Result:=0
  1013. else
  1014. Result:=TotalVariance(Data,N)/(N-1);
  1015. end;
  1016. function totalvariance(const data : array of Single) : float;
  1017. begin
  1018. Result:=TotalVariance(PSingle(@Data[0]),High(Data)+1);
  1019. end;
  1020. function totalvariance(const data : PSingle;Const N : Integer) : float;
  1021. var S,SS : Float;
  1022. begin
  1023. If N=1 then
  1024. Result:=0
  1025. else
  1026. begin
  1027. SumsAndSquares(Data,N,S,SS);
  1028. Result := SS-Sqr(S)/N;
  1029. end;
  1030. end;
  1031. function popnstddev(const data : array of Single) : float;
  1032. begin
  1033. PopnStdDev:=Sqrt(PopnVariance(PSingle(@Data[0]),High(Data)+1));
  1034. end;
  1035. function popnstddev(const data : PSingle; Const N : Integer) : float;
  1036. begin
  1037. PopnStdDev:=Sqrt(PopnVariance(Data,N));
  1038. end;
  1039. function popnvariance(const data : array of Single) : float;
  1040. begin
  1041. popnvariance:=popnvariance(PSingle(@data[0]),high(Data)+1);
  1042. end;
  1043. function popnvariance(const data : PSingle; Const N : Integer) : float;
  1044. begin
  1045. PopnVariance:=TotalVariance(Data,N)/N;
  1046. end;
  1047. procedure momentskewkurtosis(const data : array of single;
  1048. out m1,m2,m3,m4,skew,kurtosis : float);
  1049. begin
  1050. momentskewkurtosis(PSingle(@Data[0]),High(Data)+1,m1,m2,m3,m4,skew,kurtosis);
  1051. end;
  1052. procedure momentskewkurtosis(
  1053. const data: pSingle;
  1054. Const N: integer;
  1055. out m1: float;
  1056. out m2: float;
  1057. out m3: float;
  1058. out m4: float;
  1059. out skew: float;
  1060. out kurtosis: float
  1061. );
  1062. var
  1063. i: integer;
  1064. value : psingle;
  1065. deviation, deviation2: single;
  1066. reciprocalN: float;
  1067. begin
  1068. m1 := 0;
  1069. reciprocalN := 1/N;
  1070. value := data;
  1071. for i := 0 to N-1 do
  1072. begin
  1073. m1 := m1 + value^;
  1074. inc(value);
  1075. end;
  1076. m1 := reciprocalN * m1;
  1077. m2 := 0;
  1078. m3 := 0;
  1079. m4 := 0;
  1080. value := data;
  1081. for i := 0 to N-1 do
  1082. begin
  1083. deviation := (value^-m1);
  1084. deviation2 := deviation * deviation;
  1085. m2 := m2 + deviation2;
  1086. m3 := m3 + deviation2 * deviation;
  1087. m4 := m4 + deviation2 * deviation2;
  1088. inc(value);
  1089. end;
  1090. m2 := reciprocalN * m2;
  1091. m3 := reciprocalN * m3;
  1092. m4 := reciprocalN * m4;
  1093. skew := m3 / (sqrt(m2)*m2);
  1094. kurtosis := m4 / (m2 * m2);
  1095. end;
  1096. function norm(const data : array of Single) : float;
  1097. begin
  1098. norm:=Norm(PSingle(@data[0]),High(Data)+1);
  1099. end;
  1100. function norm(const data : PSingle; Const N : Integer) : float;
  1101. begin
  1102. norm:=sqrt(sumofsquares(data,N));
  1103. end;
  1104. {$endif FPC_HAS_TYPE_SINGLE}
  1105. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1106. function stddev(const data : array of Double) : float;
  1107. begin
  1108. Result:=Stddev(PDouble(@Data[0]),High(Data)+1)
  1109. end;
  1110. function stddev(const data : PDouble; Const N : Integer) : float;
  1111. begin
  1112. StdDev:=Sqrt(Variance(Data,N));
  1113. end;
  1114. procedure meanandstddev(const data : array of Double;
  1115. var mean,stddev : float);
  1116. begin
  1117. Meanandstddev(PDouble(@Data[0]),High(Data)+1,Mean,stddev);
  1118. end;
  1119. procedure meanandstddev(const data : PDouble;
  1120. Const N : Longint;var mean,stddev : float);
  1121. Var I : longint;
  1122. begin
  1123. Mean:=0;
  1124. StdDev:=0;
  1125. For I:=0 to N-1 do
  1126. begin
  1127. Mean:=Mean+Data[i];
  1128. StdDev:=StdDev+Sqr(Data[i]);
  1129. end;
  1130. Mean:=Mean/N;
  1131. StdDev:=(StdDev-N*Sqr(Mean));
  1132. If N>1 then
  1133. StdDev:=Sqrt(Stddev/(N-1))
  1134. else
  1135. StdDev:=0;
  1136. end;
  1137. function variance(const data : array of Double) : float;
  1138. begin
  1139. Variance:=Variance(PDouble(@Data[0]),High(Data)+1);
  1140. end;
  1141. function variance(const data : PDouble; Const N : Integer) : float;
  1142. begin
  1143. If N=1 then
  1144. Result:=0
  1145. else
  1146. Result:=TotalVariance(Data,N)/(N-1);
  1147. end;
  1148. function totalvariance(const data : array of Double) : float;
  1149. begin
  1150. Result:=TotalVariance(PDouble(@Data[0]),High(Data)+1);
  1151. end;
  1152. function totalvariance(const data : PDouble;Const N : Integer) : float;
  1153. var S,SS : Float;
  1154. begin
  1155. If N=1 then
  1156. Result:=0
  1157. else
  1158. begin
  1159. SumsAndSquares(Data,N,S,SS);
  1160. Result := SS-Sqr(S)/N;
  1161. end;
  1162. end;
  1163. function popnstddev(const data : array of Double) : float;
  1164. begin
  1165. PopnStdDev:=Sqrt(PopnVariance(PDouble(@Data[0]),High(Data)+1));
  1166. end;
  1167. function popnstddev(const data : PDouble; Const N : Integer) : float;
  1168. begin
  1169. PopnStdDev:=Sqrt(PopnVariance(Data,N));
  1170. end;
  1171. function popnvariance(const data : array of Double) : float;
  1172. begin
  1173. popnvariance:=popnvariance(PDouble(@data[0]),high(Data)+1);
  1174. end;
  1175. function popnvariance(const data : PDouble; Const N : Integer) : float;
  1176. begin
  1177. PopnVariance:=TotalVariance(Data,N)/N;
  1178. end;
  1179. procedure momentskewkurtosis(const data : array of Double;
  1180. out m1,m2,m3,m4,skew,kurtosis : float);
  1181. begin
  1182. momentskewkurtosis(PDouble(@Data[0]),High(Data)+1,m1,m2,m3,m4,skew,kurtosis);
  1183. end;
  1184. procedure momentskewkurtosis(
  1185. const data: pdouble;
  1186. Const N: integer;
  1187. out m1: float;
  1188. out m2: float;
  1189. out m3: float;
  1190. out m4: float;
  1191. out skew: float;
  1192. out kurtosis: float
  1193. );
  1194. var
  1195. i: integer;
  1196. value : pdouble;
  1197. deviation, deviation2: double;
  1198. reciprocalN: float;
  1199. begin
  1200. m1 := 0;
  1201. reciprocalN := 1/N;
  1202. value := data;
  1203. for i := 0 to N-1 do
  1204. begin
  1205. m1 := m1 + value^;
  1206. inc(value);
  1207. end;
  1208. m1 := reciprocalN * m1;
  1209. m2 := 0;
  1210. m3 := 0;
  1211. m4 := 0;
  1212. value := data;
  1213. for i := 0 to N-1 do
  1214. begin
  1215. deviation := (value^-m1);
  1216. deviation2 := deviation * deviation;
  1217. m2 := m2 + deviation2;
  1218. m3 := m3 + deviation2 * deviation;
  1219. m4 := m4 + deviation2 * deviation2;
  1220. inc(value);
  1221. end;
  1222. m2 := reciprocalN * m2;
  1223. m3 := reciprocalN * m3;
  1224. m4 := reciprocalN * m4;
  1225. skew := m3 / (sqrt(m2)*m2);
  1226. kurtosis := m4 / (m2 * m2);
  1227. end;
  1228. function norm(const data : array of Double) : float;
  1229. begin
  1230. norm:=Norm(PDouble(@data[0]),High(Data)+1);
  1231. end;
  1232. function norm(const data : PDouble; Const N : Integer) : float;
  1233. begin
  1234. norm:=sqrt(sumofsquares(data,N));
  1235. end;
  1236. {$endif FPC_HAS_TYPE_DOUBLE}
  1237. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1238. function stddev(const data : array of Extended) : float;
  1239. begin
  1240. Result:=Stddev(PExtended(@Data[0]),High(Data)+1)
  1241. end;
  1242. function stddev(const data : PExtended; Const N : Integer) : float;
  1243. begin
  1244. StdDev:=Sqrt(Variance(Data,N));
  1245. end;
  1246. procedure meanandstddev(const data : array of Extended;
  1247. var mean,stddev : float);
  1248. begin
  1249. Meanandstddev(PExtended(@Data[0]),High(Data)+1,Mean,stddev);
  1250. end;
  1251. procedure meanandstddev(const data : PExtended;
  1252. Const N : Longint;var mean,stddev : float);
  1253. Var I : longint;
  1254. begin
  1255. Mean:=0;
  1256. StdDev:=0;
  1257. For I:=0 to N-1 do
  1258. begin
  1259. Mean:=Mean+Data[i];
  1260. StdDev:=StdDev+Sqr(Data[i]);
  1261. end;
  1262. Mean:=Mean/N;
  1263. StdDev:=(StdDev-N*Sqr(Mean));
  1264. If N>1 then
  1265. StdDev:=Sqrt(Stddev/(N-1))
  1266. else
  1267. StdDev:=0;
  1268. end;
  1269. function variance(const data : array of Extended) : float;
  1270. begin
  1271. Variance:=Variance(PExtended(@Data[0]),High(Data)+1);
  1272. end;
  1273. function variance(const data : PExtended; Const N : Integer) : float;
  1274. begin
  1275. If N=1 then
  1276. Result:=0
  1277. else
  1278. Result:=TotalVariance(Data,N)/(N-1);
  1279. end;
  1280. function totalvariance(const data : array of Extended) : float;
  1281. begin
  1282. Result:=TotalVariance(PExtended(@Data[0]),High(Data)+1);
  1283. end;
  1284. function totalvariance(const data : PExtended;Const N : Integer) : float;
  1285. var S,SS : Float;
  1286. begin
  1287. If N=1 then
  1288. Result:=0
  1289. else
  1290. begin
  1291. SumsAndSquares(Data,N,S,SS);
  1292. Result := SS-Sqr(S)/N;
  1293. end;
  1294. end;
  1295. function popnstddev(const data : array of Extended) : float;
  1296. begin
  1297. PopnStdDev:=Sqrt(PopnVariance(PExtended(@Data[0]),High(Data)+1));
  1298. end;
  1299. function popnstddev(const data : PExtended; Const N : Integer) : float;
  1300. begin
  1301. PopnStdDev:=Sqrt(PopnVariance(Data,N));
  1302. end;
  1303. function popnvariance(const data : array of Extended) : float;
  1304. begin
  1305. popnvariance:=popnvariance(PExtended(@data[0]),high(Data)+1);
  1306. end;
  1307. function popnvariance(const data : PExtended; Const N : Integer) : float;
  1308. begin
  1309. PopnVariance:=TotalVariance(Data,N)/N;
  1310. end;
  1311. procedure momentskewkurtosis(const data : array of Extended;
  1312. out m1,m2,m3,m4,skew,kurtosis : float);
  1313. begin
  1314. momentskewkurtosis(PExtended(@Data[0]),High(Data)+1,m1,m2,m3,m4,skew,kurtosis);
  1315. end;
  1316. procedure momentskewkurtosis(
  1317. const data: pExtended;
  1318. Const N: integer;
  1319. out m1: float;
  1320. out m2: float;
  1321. out m3: float;
  1322. out m4: float;
  1323. out skew: float;
  1324. out kurtosis: float
  1325. );
  1326. var
  1327. i: integer;
  1328. value : pextended;
  1329. deviation, deviation2: extended;
  1330. reciprocalN: float;
  1331. begin
  1332. m1 := 0;
  1333. reciprocalN := 1/N;
  1334. value := data;
  1335. for i := 0 to N-1 do
  1336. begin
  1337. m1 := m1 + value^;
  1338. inc(value);
  1339. end;
  1340. m1 := reciprocalN * m1;
  1341. m2 := 0;
  1342. m3 := 0;
  1343. m4 := 0;
  1344. value := data;
  1345. for i := 0 to N-1 do
  1346. begin
  1347. deviation := (value^-m1);
  1348. deviation2 := deviation * deviation;
  1349. m2 := m2 + deviation2;
  1350. m3 := m3 + deviation2 * deviation;
  1351. m4 := m4 + deviation2 * deviation2;
  1352. inc(value);
  1353. end;
  1354. m2 := reciprocalN * m2;
  1355. m3 := reciprocalN * m3;
  1356. m4 := reciprocalN * m4;
  1357. skew := m3 / (sqrt(m2)*m2);
  1358. kurtosis := m4 / (m2 * m2);
  1359. end;
  1360. function norm(const data : array of Extended) : float;
  1361. begin
  1362. norm:=Norm(PExtended(@data[0]),High(Data)+1);
  1363. end;
  1364. function norm(const data : PExtended; Const N : Integer) : float;
  1365. begin
  1366. norm:=sqrt(sumofsquares(data,N));
  1367. end;
  1368. {$endif FPC_HAS_TYPE_EXTENDED}
  1369. function MinIntValue(const Data: array of Integer): Integer;
  1370. var
  1371. I: Integer;
  1372. begin
  1373. Result := Data[Low(Data)];
  1374. For I := Succ(Low(Data)) To High(Data) Do
  1375. If Data[I] < Result Then Result := Data[I];
  1376. end;
  1377. function MaxIntValue(const Data: array of Integer): Integer;
  1378. var
  1379. I: Integer;
  1380. begin
  1381. Result := Data[Low(Data)];
  1382. For I := Succ(Low(Data)) To High(Data) Do
  1383. If Data[I] > Result Then Result := Data[I];
  1384. end;
  1385. function MinValue(const Data: array of Integer): Integer;
  1386. begin
  1387. Result:=MinValue(Pinteger(@Data[0]),High(Data)+1)
  1388. end;
  1389. function MinValue(const Data: PInteger; Const N : Integer): Integer;
  1390. var
  1391. I: Integer;
  1392. begin
  1393. Result := Data[0];
  1394. For I := 1 To N-1 do
  1395. If Data[I] < Result Then Result := Data[I];
  1396. end;
  1397. function MaxValue(const Data: array of Integer): Integer;
  1398. begin
  1399. Result:=MaxValue(PInteger(@Data[0]),High(Data)+1)
  1400. end;
  1401. function maxvalue(const data : PInteger; Const N : Integer) : Integer;
  1402. var
  1403. i : longint;
  1404. begin
  1405. { get an initial value }
  1406. maxvalue:=data[0];
  1407. for i:=1 to N-1 do
  1408. if data[i]>maxvalue then
  1409. maxvalue:=data[i];
  1410. end;
  1411. {$ifdef FPC_HAS_TYPE_SINGLE}
  1412. function minvalue(const data : array of Single) : Single;
  1413. begin
  1414. Result:=minvalue(PSingle(@data[0]),High(Data)+1);
  1415. end;
  1416. function minvalue(const data : PSingle; Const N : Integer) : Single;
  1417. var
  1418. i : longint;
  1419. begin
  1420. { get an initial value }
  1421. minvalue:=data[0];
  1422. for i:=1 to N-1 do
  1423. if data[i]<minvalue then
  1424. minvalue:=data[i];
  1425. end;
  1426. function maxvalue(const data : array of Single) : Single;
  1427. begin
  1428. Result:=maxvalue(PSingle(@data[0]),High(Data)+1);
  1429. end;
  1430. function maxvalue(const data : PSingle; Const N : Integer) : Single;
  1431. var
  1432. i : longint;
  1433. begin
  1434. { get an initial value }
  1435. maxvalue:=data[0];
  1436. for i:=1 to N-1 do
  1437. if data[i]>maxvalue then
  1438. maxvalue:=data[i];
  1439. end;
  1440. {$endif FPC_HAS_TYPE_SINGLE}
  1441. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1442. function minvalue(const data : array of Double) : Double;
  1443. begin
  1444. Result:=minvalue(PDouble(@data[0]),High(Data)+1);
  1445. end;
  1446. function minvalue(const data : PDouble; Const N : Integer) : Double;
  1447. var
  1448. i : longint;
  1449. begin
  1450. { get an initial value }
  1451. minvalue:=data[0];
  1452. for i:=1 to N-1 do
  1453. if data[i]<minvalue then
  1454. minvalue:=data[i];
  1455. end;
  1456. function maxvalue(const data : array of Double) : Double;
  1457. begin
  1458. Result:=maxvalue(PDouble(@data[0]),High(Data)+1);
  1459. end;
  1460. function maxvalue(const data : PDouble; Const N : Integer) : Double;
  1461. var
  1462. i : longint;
  1463. begin
  1464. { get an initial value }
  1465. maxvalue:=data[0];
  1466. for i:=1 to N-1 do
  1467. if data[i]>maxvalue then
  1468. maxvalue:=data[i];
  1469. end;
  1470. {$endif FPC_HAS_TYPE_DOUBLE}
  1471. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1472. function minvalue(const data : array of Extended) : Extended;
  1473. begin
  1474. Result:=minvalue(PExtended(@data[0]),High(Data)+1);
  1475. end;
  1476. function minvalue(const data : PExtended; Const N : Integer) : Extended;
  1477. var
  1478. i : longint;
  1479. begin
  1480. { get an initial value }
  1481. minvalue:=data[0];
  1482. for i:=1 to N-1 do
  1483. if data[i]<minvalue then
  1484. minvalue:=data[i];
  1485. end;
  1486. function maxvalue(const data : array of Extended) : Extended;
  1487. begin
  1488. Result:=maxvalue(PExtended(@data[0]),High(Data)+1);
  1489. end;
  1490. function maxvalue(const data : PExtended; Const N : Integer) : Extended;
  1491. var
  1492. i : longint;
  1493. begin
  1494. { get an initial value }
  1495. maxvalue:=data[0];
  1496. for i:=1 to N-1 do
  1497. if data[i]>maxvalue then
  1498. maxvalue:=data[i];
  1499. end;
  1500. {$endif FPC_HAS_TYPE_EXTENDED}
  1501. function Min(a, b: Integer): Integer;inline;
  1502. begin
  1503. if a < b then
  1504. Result := a
  1505. else
  1506. Result := b;
  1507. end;
  1508. function Max(a, b: Integer): Integer;inline;
  1509. begin
  1510. if a > b then
  1511. Result := a
  1512. else
  1513. Result := b;
  1514. end;
  1515. {
  1516. function Min(a, b: Cardinal): Cardinal;inline;
  1517. begin
  1518. if a < b then
  1519. Result := a
  1520. else
  1521. Result := b;
  1522. end;
  1523. function Max(a, b: Cardinal): Cardinal;inline;
  1524. begin
  1525. if a > b then
  1526. Result := a
  1527. else
  1528. Result := b;
  1529. end;
  1530. }
  1531. function Min(a, b: Int64): Int64;inline;
  1532. begin
  1533. if a < b then
  1534. Result := a
  1535. else
  1536. Result := b;
  1537. end;
  1538. function Max(a, b: Int64): Int64;inline;
  1539. begin
  1540. if a > b then
  1541. Result := a
  1542. else
  1543. Result := b;
  1544. end;
  1545. {$ifdef FPC_HAS_TYPE_SINGLE}
  1546. function Min(a, b: Single): Single;inline;
  1547. begin
  1548. if a < b then
  1549. Result := a
  1550. else
  1551. Result := b;
  1552. end;
  1553. function Max(a, b: Single): Single;inline;
  1554. begin
  1555. if a > b then
  1556. Result := a
  1557. else
  1558. Result := b;
  1559. end;
  1560. {$endif FPC_HAS_TYPE_SINGLE}
  1561. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1562. function Min(a, b: Double): Double;inline;
  1563. begin
  1564. if a < b then
  1565. Result := a
  1566. else
  1567. Result := b;
  1568. end;
  1569. function Max(a, b: Double): Double;inline;
  1570. begin
  1571. if a > b then
  1572. Result := a
  1573. else
  1574. Result := b;
  1575. end;
  1576. {$endif FPC_HAS_TYPE_DOUBLE}
  1577. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1578. function Min(a, b: Extended): Extended;inline;
  1579. begin
  1580. if a < b then
  1581. Result := a
  1582. else
  1583. Result := b;
  1584. end;
  1585. function Max(a, b: Extended): Extended;inline;
  1586. begin
  1587. if a > b then
  1588. Result := a
  1589. else
  1590. Result := b;
  1591. end;
  1592. {$endif FPC_HAS_TYPE_EXTENDED}
  1593. function InRange(const AValue, AMin, AMax: Integer): Boolean;inline;
  1594. begin
  1595. Result:=(AValue>=AMin) and (AValue<=AMax);
  1596. end;
  1597. function InRange(const AValue, AMin, AMax: Int64): Boolean;inline;
  1598. begin
  1599. Result:=(AValue>=AMin) and (AValue<=AMax);
  1600. end;
  1601. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1602. function InRange(const AValue, AMin, AMax: Double): Boolean;inline;
  1603. begin
  1604. Result:=(AValue>=AMin) and (AValue<=AMax);
  1605. end;
  1606. {$endif FPC_HAS_TYPE_DOUBLE}
  1607. function EnsureRange(const AValue, AMin, AMax: Integer): Integer;inline;
  1608. begin
  1609. Result:=AValue;
  1610. If Result<AMin then
  1611. Result:=AMin
  1612. else if Result>AMax then
  1613. Result:=AMax;
  1614. end;
  1615. function EnsureRange(const AValue, AMin, AMax: Int64): Int64;inline;
  1616. begin
  1617. Result:=AValue;
  1618. If Result<AMin then
  1619. Result:=AMin
  1620. else if Result>AMax then
  1621. Result:=AMax;
  1622. end;
  1623. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1624. function EnsureRange(const AValue, AMin, AMax: Double): Double;inline;
  1625. begin
  1626. Result:=AValue;
  1627. If Result<AMin then
  1628. Result:=AMin
  1629. else if Result>AMax then
  1630. Result:=AMax;
  1631. end;
  1632. {$endif FPC_HAS_TYPE_DOUBLE}
  1633. Const
  1634. EZeroResolution = 1E-16;
  1635. DZeroResolution = 1E-12;
  1636. SZeroResolution = 1E-4;
  1637. function IsZero(const A: Single; Epsilon: Single): Boolean;
  1638. begin
  1639. if (Epsilon=0) then
  1640. Epsilon:=SZeroResolution;
  1641. Result:=Abs(A)<=Epsilon;
  1642. end;
  1643. function IsZero(const A: Single): Boolean;inline;
  1644. begin
  1645. Result:=IsZero(A,single(SZeroResolution));
  1646. end;
  1647. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1648. function IsZero(const A: Double; Epsilon: Double): Boolean;
  1649. begin
  1650. if (Epsilon=0) then
  1651. Epsilon:=DZeroResolution;
  1652. Result:=Abs(A)<=Epsilon;
  1653. end;
  1654. function IsZero(const A: Double): Boolean;inline;
  1655. begin
  1656. Result:=IsZero(A,DZeroResolution);
  1657. end;
  1658. {$endif FPC_HAS_TYPE_DOUBLE}
  1659. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1660. function IsZero(const A: Extended; Epsilon: Extended): Boolean;
  1661. begin
  1662. if (Epsilon=0) then
  1663. Epsilon:=EZeroResolution;
  1664. Result:=Abs(A)<=Epsilon;
  1665. end;
  1666. function IsZero(const A: Extended): Boolean;inline;
  1667. begin
  1668. Result:=IsZero(A,EZeroResolution);
  1669. end;
  1670. {$endif FPC_HAS_TYPE_EXTENDED}
  1671. type
  1672. TSplitDouble = packed record
  1673. cards: Array[0..1] of cardinal;
  1674. end;
  1675. function IsNan(const d : Double): Boolean;
  1676. var
  1677. fraczero, expMaximal: boolean;
  1678. begin
  1679. {$if defined(FPC_BIG_ENDIAN) or defined(FPC_DOUBLE_HILO_SWAPPED)}
  1680. expMaximal := ((TSplitDouble(d).cards[0] shr 20) and $7ff) = 2047;
  1681. fraczero:= (TSplitDouble(d).cards[0] and $fffff = 0) and
  1682. (TSplitDouble(d).cards[1] = 0);
  1683. {$else FPC_BIG_ENDIAN}
  1684. expMaximal := ((TSplitDouble(d).cards[1] shr 20) and $7ff) = 2047;
  1685. fraczero := (TSplitDouble(d).cards[1] and $fffff = 0) and
  1686. (TSplitDouble(d).cards[0] = 0);
  1687. {$endif FPC_BIG_ENDIAN}
  1688. Result:=expMaximal and not(fraczero);
  1689. end;
  1690. function IsInfinite(const d : Double): Boolean;
  1691. var
  1692. fraczero, expMaximal: boolean;
  1693. begin
  1694. {$if defined(FPC_BIG_ENDIAN) or defined(FPC_DOUBLE_HILO_SWAPPED)}
  1695. expMaximal := ((TSplitDouble(d).cards[0] shr 20) and $7ff) = 2047;
  1696. fraczero:= (TSplitDouble(d).cards[0] and $fffff = 0) and
  1697. (TSplitDouble(d).cards[1] = 0);
  1698. {$else FPC_BIG_ENDIAN}
  1699. expMaximal := ((TSplitDouble(d).cards[1] shr 20) and $7ff) = 2047;
  1700. fraczero := (TSplitDouble(d).cards[1] and $fffff = 0) and
  1701. (TSplitDouble(d).cards[0] = 0);
  1702. {$endif FPC_BIG_ENDIAN}
  1703. Result:=expMaximal and fraczero;
  1704. end;
  1705. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1706. function SameValue(const A, B: Extended; Epsilon: Extended): Boolean;
  1707. begin
  1708. if (Epsilon=0) then
  1709. Epsilon:=Max(Min(Abs(A),Abs(B))*EZeroResolution,EZeroResolution);
  1710. if (A>B) then
  1711. Result:=((A-B)<=Epsilon)
  1712. else
  1713. Result:=((B-A)<=Epsilon);
  1714. end;
  1715. function SameValue(const A, B: Extended): Boolean;inline;
  1716. begin
  1717. Result:=SameValue(A,B,0);
  1718. end;
  1719. {$endif FPC_HAS_TYPE_EXTENDED}
  1720. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1721. function SameValue(const A, B: Double): Boolean;inline;
  1722. begin
  1723. Result:=SameValue(A,B,0);
  1724. end;
  1725. function SameValue(const A, B: Double; Epsilon: Double): Boolean;
  1726. begin
  1727. if (Epsilon=0) then
  1728. Epsilon:=Max(Min(Abs(A),Abs(B))*DZeroResolution,DZeroResolution);
  1729. if (A>B) then
  1730. Result:=((A-B)<=Epsilon)
  1731. else
  1732. Result:=((B-A)<=Epsilon);
  1733. end;
  1734. {$endif FPC_HAS_TYPE_DOUBLE}
  1735. function SameValue(const A, B: Single): Boolean;inline;
  1736. begin
  1737. Result:=SameValue(A,B,0);
  1738. end;
  1739. function SameValue(const A, B: Single; Epsilon: Single): Boolean;
  1740. begin
  1741. if (Epsilon=0) then
  1742. Epsilon:=Max(Min(Abs(A),Abs(B))*SZeroResolution,SZeroResolution);
  1743. if (A>B) then
  1744. Result:=((A-B)<=Epsilon)
  1745. else
  1746. Result:=((B-A)<=Epsilon);
  1747. end;
  1748. // Some CPUs probably allow a faster way of doing this in a single operation...
  1749. // There weshould define FPC_MATH_HAS_CPUDIVMOD in the header mathuh.inc and implement it using asm.
  1750. {$ifndef FPC_MATH_HAS_DIVMOD}
  1751. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: Word);
  1752. begin
  1753. Result:=Dividend Div Divisor;
  1754. Remainder:=Dividend -(Result*Divisor);
  1755. end;
  1756. procedure DivMod(Dividend: Integer; Divisor: Word; var Result, Remainder: SmallInt);
  1757. var
  1758. UnsignedResult: Word absolute Result;
  1759. UnsignedRemainder: Word absolute Remainder;
  1760. begin
  1761. DivMod(Dividend, Divisor, UnsignedResult, UnsignedRemainder);
  1762. end;
  1763. procedure DivMod(Dividend: DWord; Divisor: DWord; var Result, Remainder: DWord);
  1764. begin
  1765. Result:=Dividend Div Divisor;
  1766. Remainder:=Dividend -(Result*Divisor);
  1767. end;
  1768. procedure DivMod(Dividend: Integer; Divisor: Integer; var Result, Remainder: Integer);
  1769. var
  1770. UnsignedResult: DWord absolute Result;
  1771. UnsignedRemainder: DWord absolute Remainder;
  1772. begin
  1773. DivMod(Dividend, Divisor, UnsignedResult, UnsignedRemainder);
  1774. end;
  1775. {$endif FPC_MATH_HAS_DIVMOD}
  1776. function ifthen(val:boolean;const iftrue:integer; const iffalse:integer= 0) :integer;
  1777. begin
  1778. if val then result:=iftrue else result:=iffalse;
  1779. end;
  1780. function ifthen(val:boolean;const iftrue:int64 ; const iffalse:int64 = 0) :int64;
  1781. begin
  1782. if val then result:=iftrue else result:=iffalse;
  1783. end;
  1784. function ifthen(val:boolean;const iftrue:double ; const iffalse:double =0.0):double;
  1785. begin
  1786. if val then result:=iftrue else result:=iffalse;
  1787. end;
  1788. // dilemma here. asm can do the two comparisons in one go?
  1789. // but pascal is portable and can be i inline;ed. Ah well, we need purepascal's anyway:
  1790. function CompareValue ( const A, B : Integer) : TValueRelationship;
  1791. begin
  1792. result:=GreaterThanValue;
  1793. if a=b then
  1794. result:=EqualsValue
  1795. else
  1796. if a<b then
  1797. result:=LessThanValue;
  1798. end;
  1799. function CompareValue ( const A, B : Int64) : TValueRelationship;
  1800. begin
  1801. result:=GreaterThanValue;
  1802. if a=b then
  1803. result:=EqualsValue
  1804. else
  1805. if a<b then
  1806. result:=LessThanValue;
  1807. end;
  1808. function CompareValue ( const A, B : QWord) : TValueRelationship;
  1809. begin
  1810. result:=GreaterThanValue;
  1811. if a=b then
  1812. result:=EqualsValue
  1813. else
  1814. if a<b then
  1815. result:=LessThanValue;
  1816. end;
  1817. {$ifdef FPC_HAS_TYPE_SINGLE}
  1818. function CompareValue ( const A, B : Single; delta : Single = 0.0) : TValueRelationship;
  1819. begin
  1820. result:=GreaterThanValue;
  1821. if abs(a-b)<=delta then
  1822. result:=EqualsValue
  1823. else
  1824. if a<b then
  1825. result:=LessThanValue;
  1826. end;
  1827. {$endif}
  1828. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1829. function CompareValue ( const A, B : Double; delta : Double = 0.0) : TValueRelationship;
  1830. begin
  1831. result:=GreaterThanValue;
  1832. if abs(a-b)<=delta then
  1833. result:=EqualsValue
  1834. else
  1835. if a<b then
  1836. result:=LessThanValue;
  1837. end;
  1838. {$endif}
  1839. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1840. function CompareValue ( const A, B : Extended; delta : Extended = 0.0) : TValueRelationship;
  1841. begin
  1842. result:=GreaterThanValue;
  1843. if abs(a-b)<=delta then
  1844. result:=EqualsValue
  1845. else
  1846. if a<b then
  1847. result:=LessThanValue;
  1848. end;
  1849. {$endif}
  1850. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1851. function RoundTo(const AValue: Double; const Digits: TRoundToRange): Double;
  1852. var
  1853. RV : Double;
  1854. begin
  1855. RV:=IntPower(10,Digits);
  1856. Result:=Round(AValue/RV)*RV;
  1857. end;
  1858. {$endif}
  1859. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1860. function RoundTo(const AVAlue: Extended; const Digits: TRoundToRange): Extended;
  1861. var
  1862. RV : Extended;
  1863. begin
  1864. RV:=IntPower(10,Digits);
  1865. Result:=Round(AValue/RV)*RV;
  1866. end;
  1867. {$endif}
  1868. {$ifdef FPC_HAS_TYPE_SINGLE}
  1869. function RoundTo(const AValue: Single; const Digits: TRoundToRange): Single;
  1870. var
  1871. RV : Single;
  1872. begin
  1873. RV:=IntPower(10,Digits);
  1874. Result:=Round(AValue/RV)*RV;
  1875. end;
  1876. {$endif}
  1877. {$ifdef FPC_HAS_TYPE_SINGLE}
  1878. function SimpleRoundTo(const AValue: Single; const Digits: TRoundToRange = -2): Single;
  1879. var
  1880. RV : Single;
  1881. begin
  1882. RV := IntPower(10, -Digits);
  1883. if AValue < 0 then
  1884. Result := Trunc((AValue*RV) - 0.5)/RV
  1885. else
  1886. Result := Trunc((AValue*RV) + 0.5)/RV;
  1887. end;
  1888. {$endif}
  1889. {$ifdef FPC_HAS_TYPE_DOUBLE}
  1890. function SimpleRoundTo(const AValue: Double; const Digits: TRoundToRange = -2): Double;
  1891. var
  1892. RV : Double;
  1893. begin
  1894. RV := IntPower(10, -Digits);
  1895. if AValue < 0 then
  1896. Result := Trunc((AValue*RV) - 0.5)/RV
  1897. else
  1898. Result := Trunc((AValue*RV) + 0.5)/RV;
  1899. end;
  1900. {$endif}
  1901. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1902. function SimpleRoundTo(const AValue: Extended; const Digits: TRoundToRange = -2): Extended;
  1903. var
  1904. RV : Extended;
  1905. begin
  1906. RV := IntPower(10, -Digits);
  1907. if AValue < 0 then
  1908. Result := Trunc((AValue*RV) - 0.5)/RV
  1909. else
  1910. Result := Trunc((AValue*RV) + 0.5)/RV;
  1911. end;
  1912. {$endif}
  1913. function RandomFrom(const AValues: array of Double): Double; overload;
  1914. begin
  1915. result:=AValues[random(High(AValues)+1)];
  1916. end;
  1917. function RandomFrom(const AValues: array of Integer): Integer; overload;
  1918. begin
  1919. result:=AValues[random(High(AValues)+1)];
  1920. end;
  1921. function RandomFrom(const AValues: array of Int64): Int64; overload;
  1922. begin
  1923. result:=AValues[random(High(AValues)+1)];
  1924. end;
  1925. {$else}
  1926. implementation
  1927. {$endif FPUNONE}
  1928. end.