SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
NI1.java
1/*
2 * Class: NI1
3 * Description:
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Université de Montréal
7 * Organization: DIRO, Université de Montréal
8 * @author Nabil Channouf
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.probdistmulti.norta;
26
27import umontreal.ssj.probdist.*;
28
45public class NI1 extends NortaInitDisc {
46 private double tolerance; /*
47 * Desired accuracy for the root-finder algorithm (epsilon in paragraph
48 * "Method NI1" of section 3 in the paper).
49 */
50
57 public NI1(double rX, DiscreteDistributionInt dist1, DiscreteDistributionInt dist2, double tr, double tolerance) {
58 super(rX, dist1, dist2, tr);
59 this.tolerance = tolerance;
61 }
62
66 public double computeCorr() {
67 final double ITMAX = 100; // Maximum number of iterations
68 final double EPS = 1.0e-15; // Machine accuracy
69 double b; /*
70 * Latest iterate and closest approximation of the root (the returned solution
71 * at the end).
72 */
73 double a; // Previous iterate (previous value of b).
74 double c; /*
75 * Previous or older iterate so that f(b) and f(c) have opposite signs (may
76 * coincide with a).
77 */
78 double fa, fb, fc; /*
79 * Evaluations of the function f at points a, b and c.
80 */
81 double tolerance1; /*
82 * Final tolerance wich involves the machine accuracy and the initial desired
83 * tolerance (epsilon).
84 */
89 double x1, x2; // Left and right endpoints of initial search interval
90 double pp, q, rrr, s; /*
91 * Parameters to compute inverse quadratic interpolation.
92 */
93 double xm; // Bisection point.
94 double min1, min2; /*
95 * Criterias to check whether inverse quadratic interpolation can be performed
96 * or not.
97 */
98 double e = 0.0, d = 0.0; /*
99 * Parameters to specify bounding interval and whether bisection or inverse
100 * quadratic interpolation was performed at one iteration before the last one.
101 */
102 // Precompute constants.
103 double cc = rX * sd1 * sd2;
104 double ccc = cc + mu1 * mu2;
105
106 if (rX == 0)
107 return 0.0;
108 if (rX > 0) { // Orient the search and initialize a, b, c
109 x1 = 0.0;
110 x2 = 1.0;
111 a = x1;
112 b = x2;
113 c = x2;
114 fa = -cc;
115 fb = integ(b) - ccc;
116 } else {
117 x1 = -1.0;
118 x2 = 0.0;
119 a = x1;
120 b = x2;
121 c = x2;
122 fa = integ(a) - ccc;
123 fb = -cc;
124 }
125 fc = fb;
126
127 for (int i = 1; i <= ITMAX; i++) { // Begin the search
128 if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) {
129 // Rename a, b, c and adjust bounding interval d
130 c = a;
131 fc = fa;
132 e = d = b - a;
133 }
134 if (Math.abs(fc) < Math.abs(fb)) {
135 a = b;
136 b = c;
137 c = a;
138 fa = fb;
139 fb = fc;
140 fc = fa;
141 }
142
143 // Convergence check
144 tolerance1 = 2.0 * EPS * Math.abs(b) + 0.5 * tolerance;
145 xm = 0.5 * (c - b);
146 if (Math.abs(xm) <= tolerance1 || fb == 0.0)
147 return b;
148
149 if (Math.abs(e) >= tolerance1 && Math.abs(fa) > Math.abs(fb)) {
150 s = fb / fa; // Attempt inverse quadratic interpolation
151 if (a == c) {
152 pp = 2.0 * xm * s;
153 q = 1.0 - s;
154 } else {
155 q = fa / fc;
156 rrr = fb / fc;
157 pp = s * (2.0 * xm * q * (q - rrr) - (b - a) * (rrr - 1.0));
158 q = (q - 1.0) * (rrr - 1.0) * (s - 1.0);
159 }
160 if (pp > 0.0)
161 q = -q; // Check whether in bounds
162 pp = Math.abs(pp);
163 min1 = 3.0 * xm * q - Math.abs(tolerance1 * q);
164 min2 = Math.abs(e * q);
165 if (2.0 * pp < (min1 < min2 ? min1 : min2)) {
166 e = d; // Accept interpolation
167 d = pp / q;
168 } else { // Interpolation failed, use bisection
169 d = xm;
170 e = d;
171 }
172 } else { // Bounds decreasing too slowly, use bisection
173 d = xm;
174 e = d;
175 }
176 a = b; // a becomes the best trial
177 fa = fb;
178 if (Math.abs(d) > tolerance1)
179 b += d; // Evaluate the new trial root
180 else {
181 if (xm > 0)
182 b += Math.abs(tolerance1);
183 else
184 b += -Math.abs(tolerance1);
185 }
186 fb = integ(b) - ccc;
187 }
188
189 return b;
190 }
191
192 public String toString() {
193 String desc = super.toString();
194 desc += "tolerance : " + tolerance + "\n";
195 return desc;
196 }
197
198}
Classes implementing discrete distributions over the integers should inherit from this class.
NI1(double rX, DiscreteDistributionInt dist1, DiscreteDistributionInt dist2, double tr, double tolerance)
Constructor with the target rank correlation rX, the two discrete marginals dist1 and dist2,...
Definition NI1.java:57
double computeCorr()
Computes and returns the correlation using the algorithm NI1.
Definition NI1.java:66
NortaInitDisc(double rX, DiscreteDistributionInt dist1, DiscreteDistributionInt dist2, double tr)
Constructor with the target rank correlation rX, the two discrete marginals dist1 and dist2 and the p...
void computeParams()
Computes the following inputs of each marginal distribution:
double integ(double r)
Computes the function.