1 18 19 package org.apache.jmeter.visualizers; 20 21 import org.apache.jorphan.logging.LoggingManager; 22 import org.apache.log.Logger; 23 24 25 30 31 97 public class Spline3 98 { 99 transient private static Logger log = LoggingManager.getLoggerForClass(); 100 101 protected float[][] _coefficients; 102 protected float[][] _A; 103 protected float[] _B; 104 protected float[] _r; 105 protected float[] _rS; 106 protected int _m; protected int _n; final static protected float DEFAULT_PRECISION = (float) 1E-1; 109 final static protected int DEFAULT_MAX_ITERATIONS = 100; 110 protected float _minPrecision = DEFAULT_PRECISION; 111 protected int _maxIterations = DEFAULT_MAX_ITERATIONS; 112 113 121 public Spline3(float[] r) 122 { 123 int n = r.length; 124 125 this._m = n; 127 this._r = new float[n]; 129 for (int i = 0; i < n; i++) 130 { 131 _r[i] = r[i]; 132 } 133 this._n = n - 2; 136 try 138 { 139 long startTime = System.currentTimeMillis(); 140 141 this.interpolation(); 142 if (log.isDebugEnabled()) 143 { 144 long endTime = System.currentTimeMillis(); 145 long elapsedTime = endTime - startTime; 146 147 log.debug("New Spline curve interpolated in "); 148 log.debug(elapsedTime + " ms"); 149 } 150 } 151 catch (Exception e) 152 { 153 log.error("Error when interpolating : ", e); 154 } 155 156 } 157 158 162 protected void interpolation() 163 { 164 _rS = new float[_m]; 166 _B = new float[_n]; 167 _A = new float[_n][_n]; 168 _coefficients = new float[_n + 1][4]; 169 int i = 0, j = 0; 171 172 for (i = 0; i < _n; i++) 174 { 175 _B[i] = 0; 176 for (j = 0; j < _n; j++) 177 { 178 _A[i][j] = 0; 179 } 180 for (j = 0; j < 4; j++) 181 { 182 _coefficients[i][j] = 0; 183 } 184 } 185 for (i = 0; i < _n; i++) 186 { 187 _rS[i] = 0; 188 } 189 for (i = 0; i < _n; i++) 191 { 192 _A[i][i] = 4; 193 } 194 for (i = 1; i < _n; i++) 196 { 197 _A[i][i - 1] = 1; 198 _A[i - 1][i] = 1; 199 } 200 for (i = 0; i < _n; i++) 202 { 203 _B[i] = 6 * (_r[i + 2] - 2 * _r[i + 1] + _r[i]); 204 } 205 this.jacobi(); for (i = 0; i < _n + 1; i++) 209 { 210 _coefficients[i][0] = _r[i]; 212 _coefficients[i][1] = _r[i + 1] - _r[i] 214 - (_rS[i + 1] + 2 * _rS[i]) / 6; 215 _coefficients[i][2] = _rS[i] / 2; 217 _coefficients[i][3] = (_rS[i + 1] - _rS[i]) / 6; 219 } 220 } 221 222 229 protected void jacobi() 230 { 231 int i = 0, j = 0, iterations = 0; 233 float[] newX = new float[_n]; 235 float[] oldX = new float[_n]; 236 237 if (!converge()) 239 { 240 if (log.isDebugEnabled()) 241 { 242 log.debug( 243 "Warning : equation system resolving is unstable"); 244 } 245 } 246 for (i = 0; i < _n; i++) 248 { 249 newX[i] = 0; 250 oldX[i] = 0; 251 } 252 while ((this.precision(oldX, newX) > this._minPrecision) 254 && (iterations < this._maxIterations)) 255 { 256 for (i = 0; i < _n; i++) 257 { 258 oldX[i] = newX[i]; 259 } 260 for (i = 0; i < _n; i++) 261 { 262 newX[i] = _B[i]; 263 for (j = 0; j < i; j++) 264 { 265 newX[i] = newX[i] - (_A[i][j] * oldX[j]); 266 } 267 for (j = i + 1; j < _n; j++) 268 { 269 newX[i] = newX[i] - (_A[i][j] * oldX[j]); 270 } 271 newX[i] = newX[i] / _A[i][i]; 272 } 273 iterations++; 274 } 275 if (this.precision(oldX, newX) < this._minPrecision) 276 { 277 if (log.isDebugEnabled()) 278 { 279 log.debug("Minimal precision ("); 280 log.debug(this._minPrecision + ") reached after "); 281 log.debug(iterations + " iterations"); 282 } 283 } 284 else if (iterations > this._maxIterations) 285 { 286 if (log.isDebugEnabled()) 287 { 288 log.debug("Maximal number of iterations ("); 289 log.debug(this._maxIterations + ") reached"); 290 log.debug("Warning : precision is only "); 291 log.debug("" + this.precision(oldX, newX)); 292 log.debug(", divergence is possible"); 293 } 294 } 295 for (i = 0; i < _n; i++) 296 { 297 _rS[i + 1] = newX[i]; 298 } 299 } 300 301 305 protected boolean converge() 306 { 307 boolean converge = true; 308 int i = 0, j = 0; 309 float lineSum = 0F; 310 311 for (i = 0; i < _n; i++) 312 { 313 if (converge) 314 { 315 lineSum = 0; 316 for (j = 0; j < _n; j++) 317 { 318 lineSum = lineSum + Math.abs(_A[i][j]); 319 } 320 lineSum = lineSum - Math.abs(_A[i][i]); 321 if (lineSum > Math.abs(_A[i][i])) 322 { 323 converge = false; 324 } 325 } 326 } 327 return converge; 328 } 329 330 333 protected float precision(float[] oldX, float[] newX) 334 { 335 float N = 0F, D = 0F, erreur = 0F; 336 int i = 0; 337 338 for (i = 0; i < _n; i++) 339 { 340 N = N + Math.abs(newX[i] - oldX[i]); 341 D = D + Math.abs(newX[i]); 342 } 343 if (D != 0F) 344 { 345 erreur = N / D; 346 } 347 else 348 { 349 erreur = Float.MAX_VALUE; 350 } 351 return erreur; 352 } 353 354 359 public float value(float t) 360 { 361 int i = 0, splineNumber = 0; 362 float abscissa = 0F, result = 0F; 363 364 if ((t < 0) || (t > (_m - 1))) 366 { 367 if (log.isDebugEnabled()) 368 { 369 log.debug( 370 "Warning : abscissa " 371 + t 372 + " out of bounds [0, " 373 + (_m - 1) 374 + "]"); 375 } 376 if (t < 0) 378 { 379 t = 0; 380 } 381 else 382 { 383 t = _m - 1; 384 } 385 } 386 splineNumber = (int) Math.floor(t); 388 if (t == (_m - 1)) 389 { 390 splineNumber--; 393 } 394 abscissa = t - splineNumber; 397 for (i = 0; i < 4; i++) 399 { 400 result = result * abscissa; 401 result = result + _coefficients[splineNumber][3 - i]; 402 } 403 return result; 404 } 405 406 409 public void debugCheck() 410 { 411 int i = 0; 412 413 for (i = 0; i < _m; i++) 414 { 415 log.info("Point " + i + " : "); 416 log.info(_r[i] + " =? " + value(i)); 417 } 418 } 419 420 429 public int[] getPlots(int width, int height) 430 { 431 int[] plot = new int[width]; 432 float[] y = new float[width]; 434 float max = java.lang.Integer.MIN_VALUE; 435 float min = java.lang.Integer.MAX_VALUE; 436 437 for (int i = 0; i < width; i++) 438 { 439 y[i] = value(((float) i) * (_m - 1) / width); 440 if (y[i] < min) 441 { 442 min = y[i]; 443 } 444 445 if (y[i] > max) 446 { 447 max = y[i]; 448 } 449 } 450 if (min < 0) 451 { 452 min = 0; } 454 for (int i = 0; i < width; i++) 456 { 457 plot[i] = 458 (int) Math.round(((y[i] - min) * (height - 1)) / (max - min)); 459 } 460 return plot; 461 } 462 463 public void setPrecision(float precision) 464 { 465 this._minPrecision = precision; 466 } 467 468 public float getPrecision() 469 { 470 return this._minPrecision; 471 } 472 473 public void setToDefaultPrecision() 474 { 475 this._minPrecision = DEFAULT_PRECISION; 476 } 477 478 public float getDefaultPrecision() 479 { 480 return DEFAULT_PRECISION; 481 } 482 483 public void setMaxIterations(int iterations) 484 { 485 this._maxIterations = iterations; 486 } 487 488 public int getMaxIterations() 489 { 490 return this._maxIterations; 491 } 492 493 public void setToDefaultMaxIterations() 494 { 495 this._maxIterations = DEFAULT_MAX_ITERATIONS; 496 } 497 498 public int getDefaultMaxIterations() 499 { 500 return DEFAULT_MAX_ITERATIONS; 501 } 502 503 } 504 505 | Popular Tags |