SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
HistogramSeriesCollection.java
1/*
2 * Class: HistogramSeriesCollection
3 * Description:
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
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.charts;
26
27import umontreal.ssj.stat.*;
28import umontreal.ssj.util.Num;
29
30import org.jfree.chart.renderer.xy.XYBarRenderer;
31import org.jfree.data.statistics.HistogramBin;
32
33import cern.colt.list.DoubleArrayList;
34
35import java.util.Locale;
36import java.util.Formatter;
37import java.util.List;
38import java.util.ListIterator;
39import java.awt.Color;
40
54 protected boolean[] filled; // fill flag for each series
55 protected double[] lineWidth; // sets line width
56 protected int numBin = 20; // default number of bins
57
58 private int calcNumBins(int n) {
59 // set the number of bins
60 int numbins = (int) Math.ceil(1.0 + Num.log2(n));
61 if (n > 5000)
62 numbins *= 2;
63 return numbins;
64 }
65
66 private double[] countersToArray(TallyHistogram hist) {
67 final int nb = hist.getNumBins();
68 final double binwidth = (hist.getB() - hist.getA()) / nb;
69 int[] count = hist.getCounters();
70 int sum = 0;
71 for (int i = 1; i <= nb; i++)
72 sum += count[i];
73 double[] data = new double[sum];
74
75 double h, base;
76 int k = 0;
77 for (int i = 1; i <= nb; i++) {
78 h = binwidth;
79 base = hist.getA() + (i - 1) * binwidth;
80 if (count[i] > 0)
81 h /= count[i];
82 if (i == nb) {
83 for (int j = 0; j < count[i]; j++)
84 data[k++] = hist.getB() - j * h;
85 } else {
86 for (int j = 0; j < count[i]; j++)
87 data[k++] = base + j * h;
88 }
89 }
90 return data;
91 }
92
97 renderer = new XYBarRenderer();
98 seriesCollection = new CustomHistogramDataset();
99 }
100
109 public HistogramSeriesCollection(double[]... data) {
110 seriesCollection = new CustomHistogramDataset();
111 renderer = new XYBarRenderer();
112 CustomHistogramDataset tempSeriesCollection = (CustomHistogramDataset) seriesCollection;
113 for (int i = 0; i < data.length; i++) {
114 numBin = calcNumBins(data[i].length);
115 tempSeriesCollection.addSeries(i, data[i], numBin);
116 }
117
118 // set default colors
119 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
120 renderer.setSeriesPaint(i, getDefaultColor(i));
121 }
122
123 // set default plot style
124 filled = new boolean[seriesCollection.getSeriesCount()];
125 lineWidth = new double[seriesCollection.getSeriesCount()];
126 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
127 filled[i] = false;
128 lineWidth[i] = 0.5;
129 setFilled(i, false);
130 }
131 }
132
142 public HistogramSeriesCollection(double[] data, int numPoints) {
143 seriesCollection = new CustomHistogramDataset();
144 renderer = new XYBarRenderer();
145 CustomHistogramDataset tempSeriesCollection = (CustomHistogramDataset) seriesCollection;
146 numBin = calcNumBins(numPoints);
147 tempSeriesCollection.addSeries(0, data, numPoints, numBin);
148
149 // set default colors
150 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
151 renderer.setSeriesPaint(i, getDefaultColor(i));
152 }
153
154 // set default plot style
155 filled = new boolean[seriesCollection.getSeriesCount()];
156 lineWidth = new double[seriesCollection.getSeriesCount()];
157 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
158 filled[i] = false;
159 lineWidth[i] = 0.5;
160 setFilled(i, false);
161 }
162 }
163
172 public HistogramSeriesCollection(DoubleArrayList... data) {
173 seriesCollection = new CustomHistogramDataset();
174 renderer = new XYBarRenderer();
175 CustomHistogramDataset tempSeriesCollection = (CustomHistogramDataset) seriesCollection;
176
177 for (int i = 0; i < data.length; i++) {
178 numBin = calcNumBins(data[i].size());
179 tempSeriesCollection.addSeries(i, data[i].elements(), data[i].size(), numBin);
180 }
181
182 // set default colors
183 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
184 renderer.setSeriesPaint(i, getDefaultColor(i));
185 }
186
187 // set default plot style
188 filled = new boolean[seriesCollection.getSeriesCount()];
189 lineWidth = new double[seriesCollection.getSeriesCount()];
190 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
191 filled[i] = false;
192 lineWidth[i] = 0.5;
193 setFilled(i, false);
194 }
195 }
196
206 seriesCollection = new CustomHistogramDataset();
207 renderer = new XYBarRenderer();
208 CustomHistogramDataset tempSeriesCollection = (CustomHistogramDataset) seriesCollection;
209
210 double h;
211 for (int i = 0; i < tallies.length; i++) {
212 // Scott's formula
213 h = 3.5 * tallies[i].standardDeviation() / Math.pow(tallies[i].numberObs(), 1.0 / 3.0);
214 numBin = (int) ((tallies[i].max() - tallies[i].min()) / (1.5 * h));
215 tempSeriesCollection.addSeries(i, tallies[i].getArray(), tallies[i].numberObs(), numBin, tallies[i].min(),
216 tallies[i].max());
217 }
218
219 // set default colors
220 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
221 renderer.setSeriesPaint(i, getDefaultColor(i));
222 }
223
224 // set default plot style
225 filled = new boolean[seriesCollection.getSeriesCount()];
226 lineWidth = new double[seriesCollection.getSeriesCount()];
227 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
228 filled[i] = false;
229 lineWidth[i] = 0.5;
230 setFilled(i, false);
231 }
232 }
233
244 seriesCollection = new CustomHistogramDataset();
245 renderer = new XYBarRenderer();
246 CustomHistogramDataset tempSeriesCollection = (CustomHistogramDataset) seriesCollection;
247
248 double[] data;
249 for (int i = 0; i < tallies.length; i++) {
250 data = countersToArray(tallies[i]);
251 tempSeriesCollection.addSeries(i, data, data.length, tallies[i].getNumBins(), tallies[i].getA(),
252 tallies[i].getB());
253 }
254
255 // set default colors
256 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
257 renderer.setSeriesPaint(i, getDefaultColor(i));
258 }
259
260 // set default plot style
261 filled = new boolean[seriesCollection.getSeriesCount()];
262 lineWidth = new double[seriesCollection.getSeriesCount()];
263 for (int i = 0; i < tempSeriesCollection.getSeriesCount(); i++) {
264 filled[i] = false;
265 lineWidth[i] = 0.5;
266 setFilled(i, false);
267 }
268 }
269
278 renderer = new XYBarRenderer();
279 seriesCollection = data;
280
281 // set default colors
282 for (int i = 0; i < data.getSeriesCount(); i++) {
283 renderer.setSeriesPaint(i, getDefaultColor(i));
284 }
285
286 // set default plot style
287 filled = new boolean[seriesCollection.getSeriesCount()];
288 lineWidth = new double[seriesCollection.getSeriesCount()];
289 for (int i = 0; i < data.getSeriesCount(); i++) {
290 filled[i] = false;
291 lineWidth[i] = 0.5;
292 setFilled(i, false);
293 }
294 }
295
299
306 public int add(double[] data) {
307 return add(data, data.length);
308 }
309
318 public int add(double[] data, int numPoints) {
319 CustomHistogramDataset tempSeriesCollection = (CustomHistogramDataset) seriesCollection;
320 tempSeriesCollection.addSeries(tempSeriesCollection.getSeriesCount(), data, numPoints, numBin);
321
322 boolean[] newFilled = new boolean[seriesCollection.getSeriesCount()];
323 double[] newLineWidth = new double[seriesCollection.getSeriesCount()];
324
325 // color
326 int j = seriesCollection.getSeriesCount() - 1;
327 renderer.setSeriesPaint(j, getDefaultColor(j));
328 newFilled[j] = false;
329 newLineWidth[j] = 0.5;
330
331 for (j = 0; j < seriesCollection.getSeriesCount() - 1; j++) {
332 newFilled[j] = filled[j];
333 newLineWidth[j] = lineWidth[j];
334 }
335
336 filled = newFilled;
337 lineWidth = newLineWidth;
338
339 return seriesCollection.getSeriesCount() - 1;
340 }
341
349 public int add(DoubleArrayList observationSet) {
350 return add(observationSet.elements(), observationSet.size());
351 }
352
360 public int add(TallyStore tally) {
361 return add(tally.getArray(), tally.numberObs());
362 }
363
371 return (CustomHistogramDataset) seriesCollection;
372 }
373
384 public List getBins(int series) {
385 return ((CustomHistogramDataset) seriesCollection).getBins(series);
386 }
387
398 public void setBins(int series, int bins) {
399 ((CustomHistogramDataset) seriesCollection).setBins(series, bins);
400 }
401
415 public void setBins(int series, int bins, double minimum, double maximum) {
416 ((CustomHistogramDataset) seriesCollection).setBins(series, bins, minimum, maximum);
417 }
418
429 public void setBins(int series, HistogramBin[] binsTable) {
430 ((CustomHistogramDataset) seriesCollection).setBins(series, binsTable);
431 }
432
443 public List getValuesList(int series) {
444 return ((CustomHistogramDataset) seriesCollection).getValuesList(series);
445 }
446
457 public double[] getValues(int series) {
458 return ((CustomHistogramDataset) seriesCollection).getValues(series);
459 }
460
468 public void setValues(int series, List valuesList) {
469 ((CustomHistogramDataset) seriesCollection).setValues(series, valuesList);
470 }
471
479 public void setValues(int series, double[] values) {
480 ((CustomHistogramDataset) seriesCollection).setValues(series, values);
481 }
482
486
490
497 public boolean getFilled(int series) {
498 return filled[series];
499 }
500
509 public void setFilled(int series, boolean filled) {
510 this.filled[series] = filled;
511 }
512
517 public double getMargin() {
518 return ((XYBarRenderer) renderer).getMargin();
519 }
520
527 public void setMargin(double margin) {
528 ((XYBarRenderer) renderer).setMargin(margin);
529 }
530
536 public double getOutlineWidth(int series) {
537 return lineWidth[series];
538 }
539
546 public void setOutlineWidth(int series, double outline) {
547 this.lineWidth[series] = outline;
548 }
549
550 public String toLatex(double XScale, double YScale, double XShift, double YShift, double xmin, double xmax,
551 double ymin, double ymax) {
552
553 // Calcule les bornes reelles du graphique, en prenant en compte la position des
554 // axes
555 xmin = Math.min(XShift, xmin);
556 xmax = Math.max(XShift, xmax);
557 ymin = Math.min(YShift, ymin);
558 ymax = Math.max(YShift, ymax);
559
560 CustomHistogramDataset tempSeriesCollection = (CustomHistogramDataset) seriesCollection;
561 Formatter formatter = new Formatter(Locale.US);
562 double var;
563 double margin = ((XYBarRenderer) renderer).getMargin();
564
565 for (int i = tempSeriesCollection.getSeriesCount() - 1; i >= 0; i--) {
566 List temp = tempSeriesCollection.getBins(i);
567 ListIterator iter = temp.listIterator();
568
569 Color color = (Color) renderer.getSeriesPaint(i);
570 String colorString = detectXColorClassic(color);
571 if (colorString == null) {
572 colorString = "color" + i;
573 formatter.format("\\definecolor{%s}{rgb}{%.2f, %.2f, %.2f}%n", colorString, color.getRed() / 255.0,
574 color.getGreen() / 255.0, color.getBlue() / 255.0);
575 }
576
577 HistogramBin currentBin = null;
578 while (iter.hasNext()) {
579 double currentMargin;
580 currentBin = (HistogramBin) iter.next();
581 currentMargin = ((margin * (currentBin.getEndBoundary() - currentBin.getStartBoundary()))) * XScale;
582 if ((currentBin.getStartBoundary() >= xmin && currentBin.getStartBoundary() <= xmax)
583 && (currentBin.getCount() >= ymin && currentBin.getCount() <= ymax)) {
584 var = Math.min(currentBin.getEndBoundary(), xmax);
585 if (filled[i]) {
586 formatter.format(
587 "\\filldraw [line width=%.2fpt, opacity=%.2f, color=%s] ([xshift=%.4f] %.4f, %.4f) rectangle ([xshift=-%.4f] %.4f, %.4f); %%%n",
588 lineWidth[i], (color.getAlpha() / 255.0), colorString, currentMargin,
589 (currentBin.getStartBoundary() - XShift) * XScale, 0.0, currentMargin, (var - XShift) * XScale,
590 (currentBin.getCount() - YShift) * YScale);
591 } else {
592 formatter.format(
593 "\\draw [line width=%.2fpt, color=%s] ([xshift=%.4f] %.4f, %.4f) rectangle ([xshift=-%.4f] %.4f, %.4f); %%%n",
594 lineWidth[i], colorString, currentMargin, (currentBin.getStartBoundary() - XShift) * XScale,
595 0.0, currentMargin, (var - XShift) * XScale, (currentBin.getCount() - YShift) * YScale);
596 }
597 } else if ((currentBin.getStartBoundary() >= xmin && currentBin.getStartBoundary() <= xmax)
598 && (currentBin.getCount() >= ymin && currentBin.getCount() > ymax)) { // Cas ou notre rectangle ne
599 // peut pas etre affiche en
600 // entier (trop haut)
601 var = Math.min(currentBin.getEndBoundary(), xmax);
602 if (filled[i]) {
603 formatter.format(
604 "\\filldraw [line width=%.2fpt, opacity=%.2f, color=%s] ([xshift=%.4f] %.4f, %.4f) rectangle ([xshift=-%.4f] %.4f, %.4f); %%%n",
605 lineWidth[i], (color.getAlpha() / 255.0), colorString, currentMargin,
606 (currentBin.getStartBoundary() - XShift) * XScale, 0.0, currentMargin, (var - XShift) * XScale,
607 (ymax - YShift) * YScale);
608 formatter.format(
609 "\\draw [line width=%.2fpt, color=%s, style=dotted] ([xshift=%.4f] %.4f, %.4f) rectangle ([yshift=3mm, xshift=-%.4f] %.4f, %.4f); %%%n",
610 lineWidth[i], colorString, currentMargin, (currentBin.getStartBoundary() - XShift) * XScale,
611 (ymax - YShift) * YScale, currentMargin, (var - XShift) * XScale, (ymax - YShift) * YScale);
612 } else {
613 formatter.format(
614 "\\draw [line width=%.2fpt, color=%s] ([xshift=%.4f] %.4f, %.4f) rectangle ([xshift=-%.4f] %.4f, %.4f); %%%n",
615 lineWidth[i], colorString, currentMargin, (currentBin.getStartBoundary() - XShift) * XScale,
616 0.0, currentMargin, (var - XShift) * XScale, (ymax - YShift) * YScale);
617
618 formatter.format(
619 "\\draw [line width=%.2fpt, color=%s, style=dotted] ([xshift=%.4f] %.4f, %.4f) rectangle ([yshift=3mm, xshift=-%.4f] %.4f, %.4f); %%%n",
620 lineWidth[i], colorString, currentMargin, (currentBin.getStartBoundary() - XShift) * XScale,
621 (ymax - YShift) * YScale, currentMargin, (var - XShift) * XScale, (ymax - YShift) * YScale);
622 }
623 }
624 }
625 }
626 return formatter.toString();
627 }
628}
629
A dataset that can be used for creating histograms.
void addSeries(Comparable key, double values[], int bins)
Adds a series to the dataset, using the specified number of bins.
int getSeriesCount()
Returns the number of series in the dataset.
List getBins(int series)
Returns the bins for a series.
List getBins(int series)
Returns the bins for a series.
CustomHistogramDataset getSeriesCollection()
Returns the CustomHistogramDataset object associated with the current variable.
int add(double[] data, int numPoints)
Adds a data series into the series collection.
void setBins(int series, HistogramBin[] binsTable)
Links bins given by table binsTable to a series.
double getMargin()
Returns the margin which is a percentage amount by which the bars are trimmed.
void setMargin(double margin)
Sets the margin which is a percentage amount by which the bars are trimmed for all series.
void setBins(int series, int bins)
Sets bins periodic bins from the observation minimum values to the observation maximum value for a se...
void setValues(int series, List valuesList)
Sets a new values set to a series from a List variable.
HistogramSeriesCollection()
Creates a new HistogramSeriesCollection instance with empty dataset.
boolean getFilled(int series)
Returns the filled flag associated with the series-th data series.
void setValues(int series, double[] values)
Sets a new values set to a series from a table.
void setOutlineWidth(int series, double outline)
Sets the outline width in pt.
void setBins(int series, int bins, double minimum, double maximum)
Sets bins periodic bins from minimum to maximum for a series.
int add(double[] data)
Adds a data series into the series collection.
List getValuesList(int series)
Returns the values for a series.
double[] getValues(int series)
Returns the values for a series.
double getOutlineWidth(int series)
Returns the outline width in pt.
void setFilled(int series, boolean filled)
Sets the filled flag.
String toLatex(double XScale, double YScale, double XShift, double YShift, double xmin, double xmax, double ymin, double ymax)
Formats and returns a string containing a LaTeX-compatible source code which represents this data ser...
int add(DoubleArrayList observationSet)
Adds a data series into the series collection.
HistogramSeriesCollection(TallyStore... tallies)
Creates a new HistogramSeriesCollection instance with default parameters and given data.
HistogramSeriesCollection(DoubleArrayList... data)
Creates a new HistogramSeriesCollection.
HistogramSeriesCollection(double[]... data)
Creates a new HistogramSeriesCollection instance with given data series.
HistogramSeriesCollection(double[] data, int numPoints)
Creates a new HistogramSeriesCollection instance with the given data series data.
HistogramSeriesCollection(CustomHistogramDataset data)
Creates a new HistogramSeriesCollection instance.
HistogramSeriesCollection(TallyHistogram... tallies)
Creates a new HistogramSeriesCollection instance with default parameters and given data.
int add(TallyStore tally)
Adds a data series into the series collection.
static Color getDefaultColor(int index)
Gives the default color associated with a series.
static String detectXColorClassic(Color color)
Converts a java Color object into a friendly and readable LaTeX/xcolor string.
int getNumBins()
Returns the number of bins .
int[] getCounters()
Returns the array of bin counters.
double getA()
Returns the left boundary of the interval .
double getB()
Returns the right boundary of the interval .
This class is a variant of Tally for which the individual observations are stored in a list implement...
double[] getArray()
Returns the observations stored in this probe.
int numberObs()
Returns the number of observations given to this probe since its last initialization.
Definition Tally.java:143
This class provides various constants and methods to compute numerical quantities such as factorials,...
Definition Num.java:35
static double log2(double x)
Returns x .
Definition Num.java:405