~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/tachart/tamath.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
{
 
2
 
 
3
 *****************************************************************************
 
4
 *                                                                           *
 
5
 *  See the file COPYING.modifiedLGPL.txt, 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
 
 
14
 Authors: Alexander Klenin, Werner Pamler
 
15
 
 
16
}
 
17
unit TAMath;
 
18
 
 
19
{$H+}
 
20
 
 
21
interface
 
22
 
 
23
uses
 
24
  Classes, SysUtils; 
 
25
 
 
26
function CumulNormDistr(AX: Double): Double;
 
27
function InvCumulNormDistr(AX: Double): Double;
 
28
 
 
29
procedure EnsureOrder(var A, B: Integer); overload; inline;
 
30
procedure EnsureOrder(var A, B: Double); overload; inline;
 
31
 
 
32
procedure ExpandRange(var ALo, AHi: Double; ACoeff: Double);
 
33
 
 
34
function InRangeUlps(AX, ALo, AHi: Double; AMaxUlps: Word): Boolean;
 
35
 
 
36
function SafeInfinity: Double; inline;
 
37
function SafeInRange(AValue, ABound1, ABound2: Double): Boolean;
 
38
function SafeMin(A, B: Double): Double;
 
39
function SafeNan: Double; inline;
 
40
 
 
41
implementation
 
42
 
 
43
uses
 
44
  Math, spe, TAChartUtils;
 
45
 
 
46
function Ulps(AX: Double): Int64; forward;
 
47
 
 
48
// Cumulative normal distribution
 
49
// x = -INF ... INF --> Result = 0 ... 1
 
50
function CumulNormDistr(AX: Double): Double;
 
51
begin
 
52
  if AX > 0 then
 
53
    Result := (speerf(AX / Sqrt(2)) + 1) * 0.5
 
54
  else if AX < 0 then
 
55
    Result := (1 - speerf(-AX / Sqrt(2))) * 0.5
 
56
  else
 
57
    Result := 0;
 
58
end;
 
59
 
 
60
// Inverse cumulative normal distribution.
 
61
// x = 0 ... 1 --> Result = -INF ... +INF
 
62
// Algorithm by Peter John Acklam.
 
63
// http://home.online.no/~pjacklam/notes/invnorm/index.html
 
64
function InvCumulNormDistr(AX: Double): Double;
 
65
const
 
66
  A: array[1..6] of Double = (
 
67
    -3.969683028665376e+01,
 
68
    +2.209460984245205e+02,
 
69
    -2.759285104469687e+02,
 
70
    +1.383577518672690e+02,
 
71
    -3.066479806614716e+01,
 
72
    +2.506628277459239e+00
 
73
  );
 
74
  B: array[1..5] of Double = (
 
75
    -5.447609879822406e+01,
 
76
    +1.615858368580409e+02,
 
77
    -1.556989798598866e+02,
 
78
    +6.680131188771972e+01,
 
79
    -1.328068155288572e+01
 
80
  );
 
81
  C: array[1..6] of Double = (
 
82
    -7.784894002430293e-03,
 
83
    -3.223964580411365e-01,
 
84
    -2.400758277161838e+00,
 
85
    -2.549732539343734e+00,
 
86
    +4.374664141464968e+00,
 
87
    +2.938163982698783e+00
 
88
  );
 
89
  D: array[1..4] of Double = (
 
90
    +7.784695709041462e-03,
 
91
    +3.224671290700398e-01,
 
92
    +2.445134137142996e+00,
 
93
    +3.754408661907416e+00
 
94
  );
 
95
  // Switching points between regions.
 
96
  P_LOW = 0.02425;
 
97
  P_HIGH = 1 - P_LOW;
 
98
var
 
99
  q, r: Extended;
 
100
begin
 
101
  if AX <= 0 then
 
102
    Result := NegInfinity
 
103
  else if AX < P_LOW then begin
 
104
    // Rational approximation for lower region.
 
105
    q := Sqrt(-2 * Ln(AX));
 
106
    Result :=
 
107
      (((((C[1] * q + C[2]) * q + C[3]) * q + C[4]) * q + C[5]) * q + C[6]) /
 
108
      ((((D[1] * q + D[2]) * q + D[3]) * q + D[4]) * q + 1);
 
109
  end
 
110
  else if AX <= P_HIGH then begin
 
111
    // Rational approximation for central region.
 
112
    q := AX - 0.5 ;
 
113
    r := q * q ;
 
114
    Result :=
 
115
      (((((A[1] * r + A[2]) * r + A[3]) * r + A[4]) * r + A[5]) * r + A[6]) * q /
 
116
      (((((B[1] * r + B[2]) * r + B[3]) * r + B[4]) * r + B[5]) * r + 1);
 
117
  end
 
118
  else if AX < 1 then begin
 
119
    // Rational approximation for upper region.
 
120
    q := Sqrt(-2 * Ln(1 - AX));
 
121
    Result :=
 
122
      -(((((C[1] * q + C[2]) * q + C[3]) * q + C[4]) * q + C[5]) * q + C[6]) /
 
123
      ((((D[1] * q + D[2]) * q + D[3]) * q + D[4]) * q + 1);
 
124
  end else
 
125
    Result := SafeInfinity;
 
126
end;
 
127
 
 
128
procedure EnsureOrder(var A, B: Integer); overload; inline;
 
129
begin
 
130
  if A > B then
 
131
    Exchange(A, B);
 
132
end;
 
133
 
 
134
procedure EnsureOrder(var A, B: Double); overload; inline;
 
135
begin
 
136
  if A > B then
 
137
    Exchange(A, B);
 
138
end;
 
139
 
 
140
procedure ExpandRange(var ALo, AHi: Double; ACoeff: Double);
 
141
var
 
142
  d: Double;
 
143
begin
 
144
  if IsInfinite(ALo) or IsInfinite(AHi) then exit;
 
145
  d := AHi - ALo;
 
146
  ALo -= d * ACoeff;
 
147
  AHi += d * ACoeff;
 
148
end;
 
149
 
 
150
function InRangeUlps(AX, ALo, AHi: Double; AMaxUlps: Word): Boolean;
 
151
begin
 
152
  Result := InRange(Ulps(AX), Ulps(ALo) - AMaxUlps, Ulps(AHi) + AMaxUlps);
 
153
end;
 
154
 
 
155
function SafeInfinity: Double;
 
156
begin
 
157
  {$PUSH}{$R-}{$Q-}
 
158
  Result := Infinity;
 
159
  {$POP}
 
160
end;
 
161
 
 
162
function SafeInRange(AValue, ABound1, ABound2: Double): Boolean;
 
163
begin
 
164
  EnsureOrder(ABound1, ABound2);
 
165
  Result := InRange(AValue, ABound1, ABound2);
 
166
end;
 
167
 
 
168
function SafeMin(A, B: Double): Double;
 
169
begin
 
170
  if IsNan(A) then
 
171
    Result := B
 
172
  else if IsNan(B) then
 
173
    Result := A
 
174
  else if A < B then
 
175
    Result := A
 
176
  else
 
177
    Result := B;
 
178
end;
 
179
 
 
180
function SafeNan: Double;
 
181
begin
 
182
  {$PUSH}{$R-}{$Q-}
 
183
  Result := NaN;
 
184
  {$POP}
 
185
end;
 
186
 
 
187
// Convert double value to integer 2's complement representation.
 
188
// Difference between resulting integers can be interpreted as distance in ulps.
 
189
function Ulps(AX: Double): Int64; inline;
 
190
begin
 
191
  Result := Int64(AX);
 
192
  if Result < 0 then
 
193
    Result := (1 shl 63) - Result;
 
194
end;
 
195
 
 
196
end.
 
197