unit specials; interface Uses Declarations; function SortArray(Const VaiArrayOfInteger: TArrayOfInteger; Const VadArrayO fdouble: TArrayOfDouble): TArrayOfInteger; procedure VarAdd(Var VdVarValue: Double; Const VdAddValue: Double); procedure VarMultiply(Var VdVarValue: Double; Const VdMultiplyValue: Double); function IsTrue(VsString: String): Boolean; function IsArrayNotEmpty(Const VadArray: TArrayOfDouble): Boolean; function GetArrayOfDoubleSum(Const VadArray: TArrayOfDouble): Double; procedure GetArrayOfDoubleMinMax(Const VadArray: TArrayOfDouble; Var VdMin, VdMax: Double); procedure GetArrayOfIntegerMinMax(Const VaiArray: TArrayOfInteger; Var ViMin, ViMax: Integer); procedure GetArrayOfArrayOfDoubleMinMax(Const VaiArray: TArrayOfArrayOfDouble; Var VdMin, VdMax: Double); function HoursInYear(ViYear: Integer): Integer; function IsLeapYear(ViYear: Integer): Boolean; function TrimFromSemiColon(VsString: String): String; function TrimBlanks(VsString: String): String; procedure TestMessage(VvMessage: Variant); procedure OkMessage(VsMessage: String); function YesNoCancelMessage(VsQuestion: String): Integer; function YesNoMessage(VsQuestion: String): Integer; Procedure SortShell( a: array of integer); Function Pearsn(x,y: array of double; Var Rc: Double) : Boolea n; Function StringToCaseSelect(Selector: string; CaseList: array of string): Integer; Function InvCumNorm(const p: double): double; Function ClipboardToFile(sFileName : string) : Boolean; Function RoundUp(X: Double): Integer; Function RoundDn(X: Double): Integer; function LargestInt(i1,i2: Integer): Integer; function SmallestInt(i1,i2: Integer): Integer; function LargestFloat(i1,i2: Double): Double; function SmallestFloat(i1,i2: Double): Double; implementation Uses Windows, Math, Sysutils, Dialogs, Clipbrd, StrUtils, Progress; {function obtained from P. J. Acklam, http://home.online.no/~pjacklam/notes/invnorm/index.html} function InvCumNorm(const p: Double): Double; {Coefficients in rational approximations} const a: array[1..6] of double=( -3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01,
2.506628277459239e+00 ); const b: array[1..5] of double =( -5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01 ); const c: array[1..6] of double=( -7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00, -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00 ); const d: array[1..4] of double=( 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00 ); {Define break-points} const p_low = 0.02425; const p_high = 1 - p_low; {const infinity=1.7e308; // maximum size of double} q, r: Extended; Result := 0; if ((p<=0) or (p>=1)) then raise Einvalidargument.create('Inverse Cum Norm argument must be in range 0<p<1'); {Rational approximation for lower region.} if ((0 < p) and (p< p_low)) then q := sqrt(-2*ln(p)); result := (((((c[1]*q+c[2])*q+c[3])*q+c[4])*q+c[5])*q+c[6]) / ((((d[1]*q+d[2])*q+d[3])*q+d[4])*q+1); {Rational approximation for central region.} if (p_low <= p) and (p <= p_high ) then q := p - 0.5 ; r := q*q ; result := (((((a[1]*r+a[2])*r+a[3])*r+a[4])*r+a[5])*r+a[6])*q / (((((b[1]*r+b[2])*r+b[3])*r+b[4])*r+b[5])*r+1) ; {Rational approximation for upper region.} if ((p_high < p) and (p < 1)) then q := sqrt(-2*ln(1-p)); result := -(((((c[1]*q+c[2])*q+c[3])*q+c[4])*q+c[5])*q+c[6]) / ((((d[1]*q+d[2])*q+d[3])*q+d[4])*q+1) ; procedure OkMessage(VsMessage: String); MessageDlg(VsMessage, mtinformation, [mbok], 0);
procedure TestMessage(VvMessage: Variant); MessageDlg(VvMessage, mtinformation, [mbok], 0); function YesNoCancelMessage(VsQuestion: String): Integer; Result := MessageDlg(VsQuestion, mtconfirmation, [mbyes, mbno, mbcancel], 0); function YesNoMessage(VsQuestion: String): Integer; Result := MessageDlg(VsQuestion, mtconfirmation, [mbyes, mbno], 0); {Pearse correlation} Function pearsn(x,y: array of double; Var Rc: Double) : Boolean; //PROCEDURE pearsn(x,y: nparray; n: integer; VAR r,prob,z: real); //CONST // dtiny = 1.0e-20; VAR j,n: integer; yt,xt,t,syy,sxy,sxx,df,ay,ax: double; BEGIN SetProgressMark('Computing Correlation'); n:=length(x); if n <> 0 then Result := True Exit; ax := 0.0; ay := 0.0; FOR j := 0 TO n-1 DO BEGIN ax := ax+x[j]; ay := ay+y[j]; END; ax := ax/n; ay := ay/n; sxx := 0.0; syy := 0.0; sxy := 0.0; FOR j := 0 TO n-1 DO BEGIN xt := x[j]-ax; yt := y[j]-ay; sxx := sxx+sqr(xt); syy := syy+sqr(yt); sxy := sxy+xt*yt; END; if sqrt(sxx*syy) <> 0 then Rc := sxy/sqrt(sxx*syy) // z := 0.5*ln(((1.0+r)+tiny)/((1.0-r)+tiny));
// df := n-2; // t := r*sqrt(df/(((1.0-r)+tiny)*((1.0+r)+tiny))); // prob := betai(0.5*df,0.5,df/(df+sqr(t))) (* prob := erfcc(abs(z*sqrt(n-1.0))/1.4142136) *) END; {Famous shell array sort} Procedure SortShell( a: Array of Integer); bis, i, j, k: LongInt; h: integer; bis := High(a); k := bis shr 1;// div 2 while k > 0 do for i := 0 to bis - k do j := i; while (j >= 0) and (a[j] > a[j + k]) do h := a[j]; a[j] := a[j + k]; a[j + k] := h; if j > k then Dec(j, k) j := 0; // {end while] // { end for} k := k shr 1; // div 2 // {end while} End; {So that a string may be used in a Case statement} function StringToCaseSelect(Selector : string; CaseList: array of string): Integer; cnt: integer; Result:=-1; for cnt:=0 to Length(CaseList)-1 do if CompareText(Selector, CaseList[cnt]) = 0 then Result:=cnt; Break; function ClipboardToFile(sFileName : string) : Boolean; ps1, ps2 : PChar; dwlen : DWord; tf : TextFile; hdata : THandle; with Clipboard do
try Open; if(hasformat(cf_text)) then hdata := GetClipboardData(CF_TEXT) ; ps1 := GlobalLock(hData) ; dwlen := GlobalSize(hData) ; ps2 := StrAlloc(1 + dwlen) ; StrLCopy(ps2,ps1,dwLen) ; GlobalUnlock(hData) ; AssignFile(tf, sfilename) ; // Erase(tf) ; ReWrite(tf) ; Write(tf,ps2) ; CloseFile(tf) ; StrDispose(ps2) ; Result := True; finally Close; {Returns -1, 0 or 1 according to the sign of the argument} function Sgn(X: Double): Integer; if X < 0 then Result := -1 if X = 0 then Result := 0 Result := 1; {Returns the first integer less than or equal to a given number in absolute value (sign is preserved). RoundDn(3.7) = 3 RoundDn(-3.7) = -3} function RoundDn(X: Double): Integer; Result := Trunc(Int(X)); {Returns the first integer greater than or equal to a given number in absolute value (sign is preserved). RoundUp(3.3) = 4 RoundUp(-3.3) = -4} function RoundUp(X: Double): Integer; Result := Trunc(Int(X)) + Sgn(Frac(X)); function LargestInt(i1,i2: Integer): Integer; if i1 > i2 then Result := i1 Result := i2; function SmallestInt(i1,i2: Integer): Integer;
if i1 < i2 then Result := i1 Result := i2; function LargestFloat(i1,i2: Double): Double; if i1 > i2 then Result := i1 Result := i2; function SmallestFloat(i1,i2: Double): Double; if i1 < i2 then Result := i1 Result := i2; function TrimBlanks(VsString: String): String; Result := StringReplace(VsString,' ','',[rfreplaceall, rfignorecase]); function TrimFromSemiColon(VsString: String): String; ipos: Integer; ipos := AnsiPos(';',VsString); if ipos <> 0 then Result := AnsiLeftStr(VsString,iPos-1) Result := VsString; function IsLeapYear(ViYear: Integer): Boolean; Result := (ViYear Mod 4 = 0) and ((ViYear Mod 100 <> 0) or ((ViYear Mod 100 = 0) and (ViYear Mod 400 = 0))); function HoursInYear(ViYear: Integer): Integer; // if not IsLeapYear(ViYear) then Result := 8760 // // Result := 8784; function IsTrue(VsString: String): Boolean; if UpperCase(VsString) = 'TRUE' then Result := True
procedure GetArrayOfDoubleMinMax(Const VadArray: TArrayOfDouble; Var VdMin, VdMax: Double); if Length(VadArray) <> 0 then VdMin := MinValue(VadArray); VdMax := MaxValue(VadArray); end VdMin := 0; VdMax := 0; function GetArrayOfDoubleSum(Const VadArray: TArrayOfDouble): Double; i: Integer; Res ult := 0; for i := 0 to Length(VadArray)-1 do Result := Result + VadArray[i]; procedure GetArrayOfIntegerMinMax(Const VaiArray: TArrayOfInteger; Var ViMin, ViMax: Integer); ViMin := MinIntValue(VaiArray); ViMax := MaxIntValue(VaiArray); procedure GetArrayOfArrayOfDoubleMinMax(Const VaiArray: TArrayOfArrayOfDouble; Var VdMin, VdMax: Double); i: Integer; VdMinTmp, VdMaxTmp: Double; VdMin := MinValue(VaiArray[0]); VdMax := MaxValue(VaiArray[0]); for i := 1 to Length(VaiArray)-1 do VdMinTmp := MinValue(VaiArray[i]); if VdMinTmp < VdMin then VdMin := VdMinTmp; VdMaxTmp := MaxValue(VaiArray[i]); if VdMaxTmp > VdMax then VdMax := VdMaxTmp; function IsArrayNotEmpty(Const VadArray: TArrayOfDouble): Boolean; if Length(VadArray) <> 0 then Result := True procedure VarMultiply(Var VdVarValue: Double; Const VdMultiplyValue: Double);
VdVarValue := VdVarValue * VdMultiplyValue; procedure VarAdd(Var VdVarValue: Double; Const VdAddValue: Double); VdVarValue := VdVarValue + VdAddValue; function CloneArrayOfInteger(VaiArr: TArrayOfInteger): TArrayOfInteger; i: Integer; SetLength(Res ult,length(vaiarr) ); for i := 0 to Length(VaiArr)-1 do Result[i] := VaiArr[i]; function CloneArrayOfDouble(VadArr: TArrayOfDouble): TArrayOfDouble; i: Integer; SetLength(Res ult,length(vadarr) ); for i := 0 to Length(VadArr)-1 do Result[i] := VadArr[i]; function SortArray(Const VaiArrayOfInteger: TArrayOfInteger; Const VadArrayOfDouble: TArrayOfDouble): TArrayOfInteger; a, b: Integer; dvalue: Double; ivalue: Integer; adarraytemp: TArrayOfDouble; aiarraysort, aiarraytemp: TArrayOfInteger; aiarraytemp := CloneArrayOfInteger(VaiArrayOfInteger); adarraytemp := CloneArrayOfDouble(VadArrayOfDouble); SetLength(Result,Length(VaiArrayOfInteger)); SetLength(aiArraySort,Length(VaiArrayOfInteger)); for a := 0 to Length(adArrayTemp)-2 do for b := a + 1 to Length(adArrayTemp)-1 do if adarraytemp[b] < adarraytemp[a] then // swap dvalue := adarraytemp[a]; ivalue := aiarraytemp[a]; adarraytemp[a]:= adarraytemp[b]; aiarraytemp[a]:= aiarraytemp[b]; adarraytemp[b]:= dvalue; aiarraytemp[b]:= ivalue; for a := 0 to Length(Result)-1 do for b := 0 to Length(Result)-1 do if VaiArrayOfInteger[a] = aiarraytemp[b] then aiarraysort[a] := b; for a := 0 to Length(Result)-1 do Result[aiArraySort[a]] := a;
end.