source: src/main/java/weka/experiment/ResultMatrix.java @ 13

Last change on this file since 13 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 57.2 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * ResultMatrix.java
19 * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.experiment;
24
25import weka.core.Option;
26import weka.core.OptionHandler;
27import weka.core.RevisionHandler;
28import weka.core.Utils;
29
30import java.io.Serializable;
31import java.util.Enumeration;
32import java.util.Vector;
33
34/**
35 * This matrix is a container for the datasets and classifier setups and
36 * their statistics. Derived classes output the data in different formats.
37 * Derived classes need to implement the following methods:
38 * <ul>
39 *   <li><code>toStringMatrix()</code></li>
40 *   <li><code>toStringKey()</code></li>
41 *   <li><code>toStringHeader()</code></li>
42 *   <li><code>toStringSummary()</code></li>
43 *   <li><code>toStringRanking()</code></li>
44 * </ul>
45 *
46 *
47 * @author FracPete (fracpete at waikato dot ac dot nz)
48 * @version $Revision: 5346 $
49 * @see #toStringMatrix()
50 * @see #toStringKey()
51 * @see #toStringHeader()
52 * @see #toStringSummary()
53 * @see #toStringRanking()
54 */
55public abstract class ResultMatrix
56  implements Serializable, RevisionHandler, OptionHandler {
57
58  /** for serialization. */
59  private static final long serialVersionUID = 4487179306428209739L;
60 
61  /** tie. */
62  public final static int SIGNIFICANCE_TIE = 0;
63
64  /** win. */
65  public final static int SIGNIFICANCE_WIN = 1;
66
67  /** loss. */
68  public final static int SIGNIFICANCE_LOSS = 2;
69
70  /** tie string. */
71  public String TIE_STRING = " ";
72
73  /** win string. */
74  public String WIN_STRING = "v";
75
76  /** loss string. */
77  public String LOSS_STRING = "*";
78
79  /** the left parentheses for enumerating cols/rows. */
80  public String LEFT_PARENTHESES = "(";
81
82  /** the right parentheses for enumerating cols/rows. */
83  public String RIGHT_PARENTHESES = ")";
84
85  /** the column names. */
86  protected String[] m_ColNames = null;
87
88  /** the row names. */
89  protected String[] m_RowNames = null;
90
91  /** whether a column is hidden. */
92  protected boolean[] m_ColHidden = null;
93 
94  /** whether a row is hidden. */
95  protected boolean[] m_RowHidden = null;
96 
97  /** the significance. */
98  protected int[][] m_Significance = null;
99
100  /** the values. */
101  protected double[][] m_Mean = null;
102
103  /** the standard deviation. */
104  protected double[][] m_StdDev = null;
105
106  /** the counts for the different datasets. */
107  protected double[] m_Counts = null;
108
109  /** the standard mean precision. */
110  protected int m_MeanPrec;
111
112  /** the standard std. deviation preicision. */
113  protected int m_StdDevPrec;
114
115  /** whether std. deviations are printed as well. */
116  protected boolean m_ShowStdDev;
117
118  /** whether the average for each column should be printed. */
119  protected boolean m_ShowAverage;
120 
121  /** whether the names or numbers are output as column declarations. */
122  protected boolean m_PrintColNames;
123
124  /** whether the names or numbers are output as row declarations. */
125  protected boolean m_PrintRowNames;
126
127  /** whether a "(x)" is printed before each column name with "x" as the
128   * index. */
129  protected boolean m_EnumerateColNames;
130
131  /** whether a "(x)" is printed before each row name with "x" as the index. */
132  protected boolean m_EnumerateRowNames;
133
134  /** the size of the names of the columns. */
135  protected int m_ColNameWidth;
136
137  /** the size of the names of the rows. */
138  protected int m_RowNameWidth;
139
140  /** the size of the mean columns. */
141  protected int m_MeanWidth;
142
143  /** the size of the std dev columns. */
144  protected int m_StdDevWidth;
145
146  /** the size of the significance columns. */
147  protected int m_SignificanceWidth;
148
149  /** the size of the counts. */
150  protected int m_CountWidth;
151
152  /** contains the keys for the header. */
153  protected Vector m_HeaderKeys = null;
154
155  /** contains the values for the header. */
156  protected Vector m_HeaderValues = null;
157
158  /** the non-significant wins. */
159  protected int[][] m_NonSigWins = null;
160
161  /** the significant wins. */
162  protected int[][] m_Wins = null;
163
164  /** the wins in ranking. */
165  protected int[] m_RankingWins = null;
166
167  /** the losses in ranking. */
168  protected int[] m_RankingLosses = null;
169
170  /** the difference between wins and losses. */
171  protected int[] m_RankingDiff = null;
172
173  /** the ordering of the rows. */
174  protected int[] m_RowOrder = null;
175
176  /** the ordering of the columns. */
177  protected int[] m_ColOrder = null;
178
179  /** whether to remove the filter name from the dataaset name. */
180  protected boolean m_RemoveFilterName = false;
181 
182  /**
183   * initializes the matrix as 1x1 matrix.
184   */
185  public ResultMatrix() {
186    this(1, 1);
187  }
188 
189  /**
190   * initializes the matrix with the given dimensions.
191   *
192   * @param cols        the number of columns
193   * @param rows        the number of rows
194   */
195  public ResultMatrix(int cols, int rows) {
196    setSize(cols, rows);
197    clear();
198  }
199
200  /**
201   * initializes the matrix with the values from the given matrix.
202   *
203   * @param matrix      the matrix to get the values from
204   */
205  public ResultMatrix(ResultMatrix matrix) {
206    assign(matrix);
207  }
208 
209  /**
210   * Returns a string describing the matrix.
211   *
212   * @return            a description suitable for
213   *                    displaying in the experimenter gui
214   */
215  public abstract String globalInfo();
216
217  /**
218   * Returns an enumeration of all the available options..
219   *
220   * @return            an enumeration of all available options.
221   */
222  public Enumeration listOptions() {
223    Vector<Option>      result;
224   
225    result = new Vector<Option>();
226   
227    result.addElement(new Option(
228        "\tThe number of decimals after the decimal point for the mean.\n"
229        + "\t(default: " + getDefaultMeanPrec() + ")",
230        "mean-prec", 1, "-mean-prec <int>"));
231   
232    result.addElement(new Option(
233        "\tThe number of decimals after the decimal point for the mean.\n"
234        + "\t(default: " + getDefaultStdDevPrec() + ")",
235        "stddev-prec", 1, "-stddev-prec <int>"));
236   
237    result.addElement(new Option(
238        "\tThe maximum width for the column names (0 = optimal).\n"
239        + "\t(default: " + getDefaultColNameWidth() + ")",
240        "col-name-width", 1, "-col-name-width <int>"));
241   
242    result.addElement(new Option(
243        "\tThe maximum width for the row names (0 = optimal).\n"
244        + "\t(default: " + getDefaultRowNameWidth() + ")",
245        "row-name-width", 1, "-row-name-width <int>"));
246   
247    result.addElement(new Option(
248        "\tThe width of the mean (0 = optimal).\n"
249        + "\t(default: " + getDefaultMeanWidth() + ")",
250        "mean-width", 1, "-mean-width <int>"));
251   
252    result.addElement(new Option(
253        "\tThe width of the standard deviation (0 = optimal).\n"
254        + "\t(default: " + getDefaultStdDevWidth() + ")",
255        "stddev-width", 1, "-stddev-width <int>"));
256   
257    result.addElement(new Option(
258        "\tThe width of the significance indicator (0 = optimal).\n"
259        + "\t(default: " + getDefaultSignificanceWidth() + ")",
260        "sig-width", 1, "-sig-width <int>"));
261   
262    result.addElement(new Option(
263        "\tThe width of the counts (0 = optimal).\n"
264        + "\t(default: " + getDefaultCountWidth() + ")",
265        "count-width", 1, "-count-width <int>"));
266   
267    result.addElement(new Option(
268        "\tWhether to display the standard deviation column.\n"
269        + "\t(default: no)",
270        "show-stddev", 0, "-show-stddev"));
271   
272    result.addElement(new Option(
273        "\tWhether to show the row with averages.\n"
274        + "\t(default: no)",
275        "show-avg", 0, "-show-avg"));
276   
277    result.addElement(new Option(
278        "\tWhether to remove the classname package prefixes from the\n"
279        + "\tfilter names in datasets.\n"
280        + "\t(default: no)",
281        "remove-filter", 0, "-remove-filter"));
282   
283    result.addElement(new Option(
284        "\tWhether to output column names or just numbers representing them.\n"
285        + "\t(default: no)",
286        "print-col-names", 0, "-print-col-names"));
287   
288    result.addElement(new Option(
289        "\tWhether to output row names or just numbers representing them.\n"
290        + "\t(default: no)",
291        "print-row-names", 0, "-print-row-names"));
292   
293    result.addElement(new Option(
294        "\tWhether to enumerate the column names (prefixing them with \n"
295        + "\t'(x)', with 'x' being the index).\n"
296        + "\t(default: no)",
297        "enum-col-names", 0, "-enum-col-names"));
298   
299    result.addElement(new Option(
300        "\tWhether to enumerate the row names (prefixing them with \n"
301        + "\t'(x)', with 'x' being the index).\n"
302        + "\t(default: no)",
303        "enum-row-names", 0, "-enum-row-names"));
304   
305    return result.elements();
306  }
307
308  /**
309   * Sets the OptionHandler's options using the given list. All options
310   * will be set (or reset) during this call (i.e. incremental setting
311   * of options is not possible).
312   *
313   * @param options     the list of options as an array of strings
314   * @throws Exception  if an option is not supported
315   */
316  public void setOptions(String[] options) throws Exception {
317    String      tmpStr;
318   
319    tmpStr = Utils.getOption("mean-prec", options);
320    if (tmpStr.length() > 0)
321      setMeanPrec(Integer.parseInt(tmpStr));
322    else
323      setMeanPrec(getDefaultMeanPrec());
324   
325    tmpStr = Utils.getOption("stddev-prec", options);
326    if (tmpStr.length() > 0)
327      setStdDevPrec(Integer.parseInt(tmpStr));
328    else
329      setStdDevPrec(getDefaultStdDevPrec());
330   
331    tmpStr = Utils.getOption("col-name-width", options);
332    if (tmpStr.length() > 0)
333      setColNameWidth(Integer.parseInt(tmpStr));
334    else
335      setColNameWidth(getDefaultColNameWidth());
336   
337    tmpStr = Utils.getOption("row-name-width", options);
338    if (tmpStr.length() > 0)
339      setRowNameWidth(Integer.parseInt(tmpStr));
340    else
341      setRowNameWidth(getDefaultRowNameWidth());
342   
343    tmpStr = Utils.getOption("mean-width", options);
344    if (tmpStr.length() > 0)
345      setMeanWidth(Integer.parseInt(tmpStr));
346    else
347      setMeanWidth(getDefaultMeanWidth());
348   
349    tmpStr = Utils.getOption("stddev-width", options);
350    if (tmpStr.length() > 0)
351      setStdDevWidth(Integer.parseInt(tmpStr));
352    else
353      setStdDevWidth(getDefaultStdDevWidth());
354   
355    tmpStr = Utils.getOption("sig-width", options);
356    if (tmpStr.length() > 0)
357      setSignificanceWidth(Integer.parseInt(tmpStr));
358    else
359      setSignificanceWidth(getDefaultSignificanceWidth());
360   
361    tmpStr = Utils.getOption("count-width", options);
362    if (tmpStr.length() > 0)
363      setStdDevPrec(Integer.parseInt(tmpStr));
364    else
365      setStdDevPrec(getDefaultCountWidth());
366
367    setShowStdDev(Utils.getFlag("show-stddev", options));
368
369    setShowAverage(Utils.getFlag("show-avg", options));
370
371    setRemoveFilterName(Utils.getFlag("remove-filter", options));
372
373    setPrintColNames(Utils.getFlag("print-col-names", options));
374
375    setPrintRowNames(Utils.getFlag("print-row-names", options));
376
377    setEnumerateColNames(Utils.getFlag("enum-col-names", options));
378
379    setEnumerateRowNames(Utils.getFlag("enum-row-names", options));
380  }
381
382  /**
383   * Gets the current option settings for the OptionHandler.
384   *
385   * @return the list of current option settings as an array of strings
386   */
387  public String[] getOptions() {
388    Vector<String>      result;
389   
390    result = new Vector<String>();
391   
392    result.add("-mean-prec");
393    result.add("" + getMeanPrec());
394   
395    result.add("-stddev-prec");
396    result.add("" + getStdDevPrec());
397   
398    result.add("-col-name-width");
399    result.add("" + getColNameWidth());
400   
401    result.add("-row-name-width");
402    result.add("" + getRowNameWidth());
403   
404    result.add("-mean-width");
405    result.add("" + getMeanWidth());
406   
407    result.add("-stddev-width");
408    result.add("" + getStdDevWidth());
409   
410    result.add("-sig-width");
411    result.add("" + getSignificanceWidth());
412   
413    result.add("-count-width");
414    result.add("" + getCountWidth());
415
416    if (getShowStdDev())
417      result.add("-show-stddev");
418
419    if (getShowAverage())
420      result.add("-show-avg");
421
422    if (getRemoveFilterName())
423      result.add("-remove-filter");
424
425    if (getPrintColNames())
426      result.add("-print-col-names");
427
428    if (getPrintRowNames())
429      result.add("-print-row-names");
430
431    if (getEnumerateColNames())
432      result.add("-enum-col-names");
433
434    if (getEnumerateRowNames())
435      result.add("-enum-row-names");
436   
437    return result.toArray(new String[result.size()]);
438  }
439
440  /**
441   * returns the name of the output format.
442   *
443   * @return            the display name
444   */
445  public abstract String getDisplayName();
446
447  /**
448   * acquires the data from the given matrix.
449   *
450   * @param matrix      the matrix to get the data from
451   */
452  public void assign(ResultMatrix matrix) {
453    int         i;
454    int         n;
455   
456    setSize(matrix.getColCount(), matrix.getRowCount());
457   
458    // output parameters
459    TIE_STRING          = matrix.TIE_STRING;
460    WIN_STRING          = matrix.WIN_STRING;
461    LOSS_STRING         = matrix.LOSS_STRING;
462    LEFT_PARENTHESES    = matrix.LEFT_PARENTHESES;
463    RIGHT_PARENTHESES   = matrix.RIGHT_PARENTHESES;
464    m_MeanPrec          = matrix.m_MeanPrec;
465    m_StdDevPrec        = matrix.m_StdDevPrec;
466    m_ShowStdDev        = matrix.m_ShowStdDev;
467    m_ShowAverage       = matrix.m_ShowAverage;
468    m_PrintColNames     = matrix.m_PrintColNames;
469    m_PrintRowNames     = matrix.m_PrintRowNames;
470    m_EnumerateColNames = matrix.m_EnumerateColNames;
471    m_EnumerateRowNames = matrix.m_EnumerateRowNames;
472    m_RowNameWidth      = matrix.m_RowNameWidth;
473    m_MeanWidth         = matrix.m_MeanWidth;
474    m_StdDevWidth       = matrix.m_StdDevWidth;
475    m_SignificanceWidth = matrix.m_SignificanceWidth;
476    m_CountWidth        = matrix.m_CountWidth;
477    m_RemoveFilterName  = matrix.m_RemoveFilterName;
478   
479    // header
480    m_HeaderKeys   = (Vector) matrix.m_HeaderKeys.clone();
481    m_HeaderValues = (Vector) matrix.m_HeaderValues.clone();
482
483    // matrix
484    for (i = 0; i < matrix.m_Mean.length; i++) {
485      for (n = 0; n < matrix.m_Mean[i].length; n++) {
486        m_Mean[i][n]         = matrix.m_Mean[i][n];
487        m_StdDev[i][n]       = matrix.m_StdDev[i][n];
488        m_Significance[i][n] = matrix.m_Significance[i][n];
489      }
490    }
491
492    for (i = 0; i < matrix.m_ColNames.length; i++) {
493      m_ColNames[i]  = matrix.m_ColNames[i];
494      m_ColHidden[i] = matrix.m_ColHidden[i];
495    }
496
497    for (i = 0; i < matrix.m_RowNames.length; i++) {
498      m_RowNames[i]  = matrix.m_RowNames[i];
499      m_RowHidden[i] = matrix.m_RowHidden[i];
500    }
501
502    for (i = 0; i < matrix.m_Counts.length; i++)
503      m_Counts[i] = matrix.m_Counts[i];
504
505    // summary
506    if (matrix.m_NonSigWins != null) {
507      m_NonSigWins = new int[matrix.m_NonSigWins.length][];
508      m_Wins       = new int[matrix.m_NonSigWins.length][];
509      for (i = 0; i < matrix.m_NonSigWins.length; i++) {
510        m_NonSigWins[i] = new int[matrix.m_NonSigWins[i].length];
511        m_Wins[i]       = new int[matrix.m_NonSigWins[i].length];
512
513        for (n = 0; n < matrix.m_NonSigWins[i].length; n++) {
514          m_NonSigWins[i][n] = matrix.m_NonSigWins[i][n];
515          m_Wins[i][n]       = matrix.m_Wins[i][n];
516        }
517      }
518    }
519
520    // ranking
521    if (matrix.m_RankingWins != null) {
522      m_RankingWins   = new int[matrix.m_RankingWins.length];
523      m_RankingLosses = new int[matrix.m_RankingWins.length];
524      m_RankingDiff   = new int[matrix.m_RankingWins.length];
525      for (i = 0; i < matrix.m_RankingWins.length; i++) {
526        m_RankingWins[i]   = matrix.m_RankingWins[i];
527        m_RankingLosses[i] = matrix.m_RankingLosses[i];
528        m_RankingDiff[i]   = matrix.m_RankingDiff[i];
529      }
530    }
531  }
532
533  /**
534   * removes the stored data and the ordering, but retains the dimensions of
535   * the matrix.
536   */
537  public void clear() {
538    m_MeanPrec          = getDefaultMeanPrec();
539    m_StdDevPrec        = getDefaultStdDevPrec();
540    m_ShowStdDev        = getDefaultShowStdDev();
541    m_ShowAverage       = getDefaultShowAverage();
542    m_RemoveFilterName  = getDefaultRemoveFilterName();
543    m_PrintColNames     = getDefaultPrintColNames();
544    m_PrintRowNames     = getDefaultPrintRowNames();
545    m_EnumerateColNames = getDefaultEnumerateColNames();
546    m_EnumerateRowNames = getDefaultEnumerateRowNames();
547    m_RowNameWidth      = getDefaultRowNameWidth();
548    m_ColNameWidth      = getDefaultColNameWidth();
549    m_MeanWidth         = getDefaultMeanWidth();
550    m_StdDevWidth       = getDefaultStdDevWidth();
551    m_SignificanceWidth = getDefaultSignificanceWidth();
552    m_CountWidth        = getDefaultCountWidth();
553
554    setSize(getColCount(), getRowCount());
555  }
556
557  /**
558   * clears the content of the matrix and sets the new size.
559   *
560   * @param cols        the number of mean columns
561   * @param rows        the number of mean rows
562   */
563  public void setSize(int cols, int rows) {
564    int       i;
565    int       n;
566
567    m_ColNames     = new String[cols];
568    m_RowNames     = new String[rows];
569    m_Counts       = new double[rows];
570    m_ColHidden    = new boolean[cols];
571    m_RowHidden    = new boolean[rows];
572    m_Mean         = new double[rows][cols];
573    m_Significance = new int[rows][cols];
574    m_StdDev       = new double[rows][cols];
575    m_ColOrder     = null;
576    m_RowOrder     = null;
577
578    // NaN means that there exists no value! -> toArray()
579    for (i = 0; i < m_Mean.length; i++) {
580      for (n = 0; n < m_Mean[i].length; n++)
581        m_Mean[i][n]   = Double.NaN;
582    }
583
584    for (i = 0; i < m_ColNames.length; i++)
585      m_ColNames[i] = "col" + i;
586    for (i = 0; i < m_RowNames.length; i++)
587      m_RowNames[i] = "row" + i;
588
589    clearHeader();
590    clearSummary();
591    clearRanking();
592  }
593
594  /**
595   * sets the precision for the means.
596   *
597   * @param prec        the number of decimals
598   */
599  public void setMeanPrec(int prec) {
600    if (prec >= 0)
601      m_MeanPrec = prec;
602  }
603
604  /**
605   * returns the current precision for the means.
606   *
607   * @return            the number of decimals
608   */
609  public int getMeanPrec() {
610    return m_MeanPrec;
611  }
612
613  /**
614   * returns the default precision for the means.
615   *
616   * @return            the number of decimals
617   */
618  public int getDefaultMeanPrec() {
619    return 2;
620  }
621 
622  /**
623   * Returns the tip text for this property.
624   *
625   * @return            tip text for this property suitable for
626   *                    displaying in the experimenter gui
627   */
628  public String meanPrecTipText() {
629    return "The number of decimals after the decimal point for the mean.";
630  }
631
632  /**
633   * sets the precision for the standard deviation.
634   *
635   * @param prec        the number of decimals
636   */
637  public void setStdDevPrec(int prec) {
638    if (prec >= 0)
639      m_StdDevPrec = prec;
640  }
641
642  /**
643   * returns the current standard deviation precision.
644   *
645   * @return            the number of decimals
646   */
647  public int getStdDevPrec() {
648    return m_StdDevPrec;
649  }
650
651  /**
652   * returns the default standard deviation precision.
653   *
654   * @return            the number of decimals
655   */
656  public int getDefaultStdDevPrec() {
657    return 2;
658  }
659 
660  /**
661   * Returns the tip text for this property.
662   *
663   * @return            tip text for this property suitable for
664   *                    displaying in the experimenter gui
665   */
666  public String stdDevPrecTipText() {
667    return "The number of decimals after the decimal point for the standard deviation.";
668  }
669
670  /**
671   * sets the width for the column names (0 = optimal).
672   *
673   * @param width       the width
674   */
675  public void setColNameWidth(int width) {
676    if (width >= 0)
677      m_ColNameWidth = width;
678  }
679
680  /**
681   * returns the current width for the column names.
682   *
683   * @return            the width
684   */
685  public int getColNameWidth() {
686    return m_ColNameWidth;
687  }
688
689  /**
690   * returns the default width for the column names.
691   *
692   * @return            the width
693   */
694  public int getDefaultColNameWidth() {
695    return 0;
696  }
697 
698  /**
699   * Returns the tip text for this property.
700   *
701   * @return            tip text for this property suitable for
702   *                    displaying in the experimenter gui
703   */
704  public String colNameWidthTipText() {
705    return "The maximum width of the column names (0 = optimal).";
706  }
707
708  /**
709   * sets the width for the row names (0 = optimal).
710   *
711   * @param width       the width
712   */
713  public void setRowNameWidth(int width) {
714    if (width >= 0)
715      m_RowNameWidth = width;
716  }
717
718  /**
719   * returns the current width for the row names.
720   *
721   * @return            the width
722   */
723  public int getRowNameWidth() {
724    return m_RowNameWidth;
725  }
726
727  /**
728   * returns the default width for the row names.
729   *
730   * @return            the width
731   */
732  public int getDefaultRowNameWidth() {
733    return 0;
734  }
735 
736  /**
737   * Returns the tip text for this property.
738   *
739   * @return            tip text for this property suitable for
740   *                    displaying in the experimenter gui
741   */
742  public String rowNameWidthTipText() {
743    return "The maximum width for the row names (0 = optimal).";
744  }
745 
746  /**
747   * sets the width for the mean (0 = optimal).
748   *
749   * @param width       the width
750   */
751  public void setMeanWidth(int width) {
752    if (width >= 0)
753      m_MeanWidth = width;
754  }
755
756  /**
757   * returns the current width for the mean.
758   *
759   * @return            the width
760   */
761  public int getMeanWidth() {
762    return m_MeanWidth;
763  }
764
765  /**
766   * returns the default width for the mean.
767   *
768   * @return            the width
769   */
770  public int getDefaultMeanWidth() {
771    return 0;
772  }
773 
774  /**
775   * Returns the tip text for this property.
776   *
777   * @return            tip text for this property suitable for
778   *                    displaying in the experimenter gui
779   */
780  public String meanWidthTipText() {
781    return "The width of the mean (0 = optimal).";
782  }
783
784  /**
785   * sets the width for the std dev (0 = optimal).
786   *
787   * @param width       the width
788   */
789  public void setStdDevWidth(int width) {
790    if (width >= 0)
791      m_StdDevWidth = width;
792  }
793
794  /**
795   * returns the current width for the std dev.
796   *
797   * @return            the width
798   */
799  public int getStdDevWidth() {
800    return m_StdDevWidth;
801  }
802
803  /**
804   * returns the default width for the std dev.
805   *
806   * @return            the width
807   */
808  public int getDefaultStdDevWidth() {
809    return 0;
810  }
811 
812  /**
813   * Returns the tip text for this property.
814   *
815   * @return            tip text for this property suitable for
816   *                    displaying in the experimenter gui
817   */
818  public String stdDevWidthTipText() {
819    return "The width of the standard deviation (0 = optimal).";
820  }
821
822  /**
823   * sets the width for the significance (0 = optimal).
824   *
825   * @param width       the width
826   */
827  public void setSignificanceWidth(int width) {
828    if (width >= 0)
829      m_SignificanceWidth = width;
830  }
831
832  /**
833   * returns the current width for the significance.
834   *
835   * @return            the width
836   */
837  public int getSignificanceWidth() {
838    return m_SignificanceWidth;
839  }
840
841  /**
842   * returns the default width for the significance.
843   *
844   * @return            the width
845   */
846  public int getDefaultSignificanceWidth() {
847    return 0;
848  }
849 
850  /**
851   * Returns the tip text for this property.
852   *
853   * @return            tip text for this property suitable for
854   *                    displaying in the experimenter gui
855   */
856  public String significanceWidthTipText() {
857    return "The width of the significance indicator (0 = optimal).";
858  }
859
860  /**
861   * sets the width for the counts (0 = optimal).
862   *
863   * @param width       the width
864   */
865  public void setCountWidth(int width) {
866    if (width >= 0)
867      m_CountWidth = width;
868  }
869
870  /**
871   * returns the current width for the counts.
872   *
873   * @return            the width
874   */
875  public int getCountWidth() {
876    return m_CountWidth;
877  }
878
879  /**
880   * returns the default width for the counts.
881   *
882   * @return            the width
883   */
884  public int getDefaultCountWidth() {
885    return 0;
886  }
887 
888  /**
889   * Returns the tip text for this property.
890   *
891   * @return            tip text for this property suitable for
892   *                    displaying in the experimenter gui
893   */
894  public String countWidthTipText() {
895    return "The width of the counts (0 = optimal).";
896  }
897
898  /**
899   * sets whether to display the std deviations or not.
900   *
901   * @param show        if true then the std deviations are displayed
902   */
903  public void setShowStdDev(boolean show) {
904    m_ShowStdDev = show;
905  }
906
907  /**
908   * returns whether std deviations are displayed or not.
909   *
910   * @return            true if the std deviations are displayed
911   */
912  public boolean getShowStdDev() {
913    return m_ShowStdDev;
914  }
915
916  /**
917   * returns the default of whether std deviations are displayed or not.
918   *
919   * @return            true if the std deviations are displayed
920   */
921  public boolean getDefaultShowStdDev() {
922    return false;
923  }
924 
925  /**
926   * Returns the tip text for this property.
927   *
928   * @return            tip text for this property suitable for
929   *                    displaying in the experimenter gui
930   */
931  public String showStdDevTipText() {
932    return "Whether to display the standard deviation column.";
933  }
934
935  /**
936   * sets whether to display the average per column or not.
937   *
938   * @param show        if true then the average is displayed
939   */
940  public void setShowAverage(boolean show) {
941    m_ShowAverage = show;
942  }
943
944  /**
945   * returns whether average per column is displayed or not.
946   *
947   * @return            true if the average is displayed
948   */
949  public boolean getShowAverage() {
950    return m_ShowAverage;
951  }
952
953  /**
954   * returns the default of whether average per column is displayed or not.
955   *
956   * @return            true if the average is displayed
957   */
958  public boolean getDefaultShowAverage() {
959    return false;
960  }
961 
962  /**
963   * Returns the tip text for this property.
964   *
965   * @return            tip text for this property suitable for
966   *                    displaying in the experimenter gui
967   */
968  public String showAverageTipText() {
969    return "Whether to show the row with averages.";
970  }
971
972  /**
973   * sets whether to remove the filter classname from the dataset name.
974   *
975   * @param remove      if true then the filter classnames are shortened
976   */
977  public void setRemoveFilterName(boolean remove) {
978    m_RemoveFilterName = remove;
979  }
980
981  /**
982   * returns whether the filter classname is removed from the dataset name.
983   *
984   * @return            true if the filter classnames are shortened
985   */
986  public boolean getRemoveFilterName() {
987    return m_RemoveFilterName;
988  }
989
990  /**
991   * returns the default of whether the filter classname is removed from the
992   * dataset name.
993   *
994   * @return            true if the filter classnames are shortened
995   */
996  public boolean getDefaultRemoveFilterName() {
997    return false;
998  }
999 
1000  /**
1001   * Returns the tip text for this property.
1002   *
1003   * @return            tip text for this property suitable for
1004   *                    displaying in the experimenter gui
1005   */
1006  public String removeFilterNameTipText() {
1007    return "Whether to remove the classname package prefixes from the filter names in datasets.";
1008  }
1009
1010  /**
1011   * sets whether the column names or numbers instead are printed.
1012   * deactivating automatically sets m_EnumerateColNames to TRUE.
1013   *
1014   * @param print       if true then the names are printed instead of numbers
1015   * @see               #setEnumerateColNames(boolean)
1016   */
1017  public void setPrintColNames(boolean print) {
1018    m_PrintColNames = print;
1019    if (!print)
1020      setEnumerateColNames(true);
1021  }
1022
1023  /**
1024   * returns whether column names or numbers instead are printed.
1025   *
1026   * @return            true if names instead of numbers are printed
1027   */
1028  public boolean getPrintColNames() {
1029    return m_PrintColNames;
1030  }
1031
1032  /**
1033   * returns the default of whether column names or numbers instead are printed.
1034   *
1035   * @return            true if names instead of numbers are printed
1036   */
1037  public boolean getDefaultPrintColNames() {
1038    return true;
1039  }
1040 
1041  /**
1042   * Returns the tip text for this property.
1043   *
1044   * @return            tip text for this property suitable for
1045   *                    displaying in the experimenter gui
1046   */
1047  public String printColNamesTipText() {
1048    return "Whether to output column names or just numbers representing them.";
1049  }
1050
1051  /**
1052   * sets whether the row names or numbers instead are printed
1053   * deactivating automatically sets m_EnumerateColNames to TRUE.
1054   *
1055   * @param print       if true then names instead of numbers are printed
1056   * @see               #setEnumerateRowNames(boolean)
1057   */
1058  public void setPrintRowNames(boolean print) {
1059    m_PrintRowNames = print;
1060    if (!print)
1061      setEnumerateRowNames(true);
1062  }
1063
1064  /**
1065   * returns whether row names or numbers instead are printed.
1066   *
1067   * @return            true if names instead of numbers are printed
1068   */
1069  public boolean getPrintRowNames() {
1070    return m_PrintRowNames;
1071  }
1072
1073  /**
1074   * returns the default of whether row names or numbers instead are printed.
1075   *
1076   * @return            true if names instead of numbers are printed
1077   */
1078  public boolean getDefaultPrintRowNames() {
1079    return true;
1080  }
1081 
1082  /**
1083   * Returns the tip text for this property.
1084   *
1085   * @return            tip text for this property suitable for
1086   *                    displaying in the experimenter gui
1087   */
1088  public String printRowNamesTipText() {
1089    return "Whether to output row names or just numbers representing them.";
1090  }
1091
1092  /**
1093   * sets whether the column names are prefixed with "(x)" where "x" is
1094   * the index.
1095   *
1096   * @param enumerate   if true then the names are prefixed
1097   */
1098  public void setEnumerateColNames(boolean enumerate) {
1099    m_EnumerateColNames = enumerate;
1100  }
1101
1102  /**
1103   * returns whether column names are prefixed with the index.
1104   *
1105   * @return            true if the names are prefixed
1106   */
1107  public boolean getEnumerateColNames() {
1108    return m_EnumerateColNames;
1109  }
1110
1111  /**
1112   * returns the default of whether column names are prefixed with the index.
1113   *
1114   * @return            true if the names are prefixed
1115   */
1116  public boolean getDefaultEnumerateColNames() {
1117    return true;
1118  }
1119 
1120  /**
1121   * Returns the tip text for this property.
1122   *
1123   * @return            tip text for this property suitable for
1124   *                    displaying in the experimenter gui
1125   */
1126  public String enumerateColNamesTipText() {
1127    return "Whether to enumerate the column names (prefixing them with '(x)', with 'x' being the index).";
1128  }
1129
1130  /**
1131   * sets whether to the row names are prefixed with the index.
1132   *
1133   * @param enumerate   if true then the names will be prefixed
1134   */
1135  public void setEnumerateRowNames(boolean enumerate) {
1136    m_EnumerateRowNames = enumerate;
1137  }
1138
1139  /**
1140   * returns whether row names or prefixed with the index.
1141   *
1142   * @return            true if the names are prefixed
1143   */
1144  public boolean getEnumerateRowNames() {
1145    return m_EnumerateRowNames;
1146  }
1147
1148  /**
1149   * returns theh default of whether row names are prefixed with the index.
1150   *
1151   * @return            true if the names are prefixed
1152   */
1153  public boolean getDefaultEnumerateRowNames() {
1154    return false;
1155  }
1156 
1157  /**
1158   * Returns the tip text for this property.
1159   *
1160   * @return            tip text for this property suitable for
1161   *                    displaying in the experimenter gui
1162   */
1163  public String enumerateRowNamesTipText() {
1164    return "Whether to enumerate the row names (prefixing them with '(x)', with 'x' being the index).";
1165  }
1166
1167  /**
1168   * returns the number of columns.
1169   *
1170   * @return            the number of columns
1171   */
1172  public int getColCount() {
1173    return m_ColNames.length;
1174  }
1175
1176  /**
1177   * returns the number of visible columns.
1178   *
1179   * @return            the number of columns
1180   */
1181  public int getVisibleColCount() {
1182    int         cols;
1183    int         i;
1184   
1185    cols = 0;
1186    for (i = 0; i < getColCount(); i++) {
1187      if (!getColHidden(i))
1188        cols++;
1189    }
1190
1191    return cols;
1192  }
1193
1194  /**
1195   * returns the number of rows.
1196   *
1197   * @return            the number of rows
1198   */
1199  public int getRowCount() {
1200    return m_RowNames.length;
1201  }
1202
1203  /**
1204   * returns the number of visible rows.
1205   *
1206   * @return            the number of rows
1207   */
1208  public int getVisibleRowCount() {
1209    int         rows;
1210    int         i;
1211   
1212    rows= 0;
1213    for (i = 0; i < getRowCount(); i++) {
1214      if (!getRowHidden(i))
1215        rows++;
1216    }
1217
1218    return rows;
1219  }
1220 
1221  /**
1222   * sets the name of the column (if the index is valid).
1223   *
1224   * @param index       the index of the column
1225   * @param name        the name of the column
1226   */
1227  public void setColName(int index, String name) {
1228    if ( (index >= 0) && (index < getColCount()) )
1229      m_ColNames[index] = name;
1230  }
1231
1232  /**
1233   * returns the name of the row, if the index is valid, otherwise null.
1234   * if getPrintColNames() is FALSE then an empty string is returned or if
1235   * getEnumerateColNames() is TRUE then the 1-based index surrounded by
1236   * parentheses.
1237   *
1238   * @param index       the index of the column
1239   * @return            the name of the column
1240   * @see               #setPrintColNames(boolean)
1241   * @see               #getPrintColNames()
1242   * @see               #setEnumerateColNames(boolean)
1243   * @see               #getEnumerateColNames()
1244   */
1245  public String getColName(int index) {
1246    String        result;
1247   
1248    result = null;
1249   
1250    if ( (index >= 0) && (index < getColCount()) ) {
1251      if (getPrintColNames())
1252        result = m_ColNames[index];
1253      else
1254        result = "";
1255
1256      if (getEnumerateColNames()) {
1257        result =   LEFT_PARENTHESES
1258                 + Integer.toString(index + 1) 
1259                 + RIGHT_PARENTHESES
1260                 + " " + result;
1261        result = result.trim();
1262      }
1263    }
1264
1265    return result;
1266  }
1267
1268  /**
1269   * sets the name of the row (if the index is valid).
1270   *
1271   * @param index       the index of the row
1272   * @param name        the name of the row
1273   */
1274  public void setRowName(int index, String name) {
1275    if ( (index >= 0) && (index < getRowCount()) )
1276      m_RowNames[index] = name;
1277  }
1278
1279  /**
1280   * returns the name of the row, if the index is valid, otherwise null.
1281   * if getPrintRowNames() is FALSE then an empty string is returned or if
1282   * getEnumerateRowNames() is TRUE then the 1-based index surrounded by
1283   * parentheses.
1284   *
1285   * @param index       the index of the row
1286   * @return            the name of the row
1287   * @see               #setPrintRowNames(boolean)
1288   * @see               #getPrintRowNames()
1289   * @see               #setEnumerateRowNames(boolean)
1290   * @see               #getEnumerateRowNames()
1291   */
1292  public String getRowName(int index) {
1293    String        result;
1294   
1295    result = null;
1296   
1297    if ( (index >= 0) && (index < getRowCount()) ) {
1298      if (getPrintRowNames())
1299        result = m_RowNames[index];
1300      else
1301        result = "";
1302
1303      if (getEnumerateRowNames()) {
1304        result =   LEFT_PARENTHESES
1305                 + Integer.toString(index + 1) 
1306                 + RIGHT_PARENTHESES
1307                 + " " + result;
1308        result = result.trim();
1309      }
1310    }
1311   
1312    return result;
1313  }
1314
1315  /**
1316   * sets the hidden status of the column (if the index is valid).
1317   *
1318   * @param index       the index of the column
1319   * @param hidden      the hidden status of the column
1320   */
1321  public void setColHidden(int index, boolean hidden) {
1322    if ( (index >= 0) && (index < getColCount()) )
1323      m_ColHidden[index] = hidden;
1324  }
1325
1326  /**
1327   * returns the hidden status of the column, if the index is valid, otherwise
1328   * false.
1329   *
1330   * @param index       the index of the column
1331   * @return            true if hidden
1332   */
1333  public boolean getColHidden(int index) {
1334    if ( (index >= 0) && (index < getColCount()) )
1335      return m_ColHidden[index];
1336    else
1337      return false;
1338  }
1339
1340  /**
1341   * sets the hidden status of the row (if the index is valid).
1342   *
1343   * @param index       the index of the row
1344   * @param hidden      the hidden status of the row
1345   */
1346  public void setRowHidden(int index, boolean hidden) {
1347    if ( (index >= 0) && (index < getRowCount()) )
1348      m_RowHidden[index] = hidden;
1349  }
1350
1351  /**
1352   * returns the hidden status of the row, if the index is valid, otherwise
1353   * false.
1354   *
1355   * @param index       the index of the row
1356   * @return            true if hidden
1357   */
1358  public boolean getRowHidden(int index) {
1359    if ( (index >= 0) && (index < getRowCount()) )
1360      return m_RowHidden[index];
1361    else
1362      return false;
1363  }
1364
1365  /**
1366   * sets the count for the row (if the index is valid).
1367   *
1368   * @param index       the index of the row
1369   * @param count       the count for the row
1370   */
1371  public void setCount(int index, double count) {
1372    if ( (index >= 0) && (index < getRowCount()) )
1373      m_Counts[index] = count;
1374  }
1375
1376  /**
1377   * returns the count for the row. if the index is invalid then 0.
1378   *
1379   * @param index       the index of the row
1380   * @return            the count for the row
1381   */
1382  public double getCount(int index) {
1383    if ( (index >= 0) && (index < getRowCount()) )
1384      return m_Counts[index];
1385    else
1386      return 0;
1387  }
1388
1389  /**
1390   * sets the mean at the given position (if the position is valid).
1391   *
1392   * @param col         the column of the mean
1393   * @param row         the row of the mean
1394   * @param value       the value of the mean
1395   */
1396  public void setMean(int col, int row, double value) {
1397    if (    (col >= 0) && (col < getColCount()) 
1398         && (row >= 0) && (row < getRowCount()) )
1399      m_Mean[row][col] = value;
1400  }
1401
1402  /**
1403   * returns the mean at the given position, if the position is valid,
1404   * otherwise 0.
1405   *
1406   * @param col         the column index
1407   * @param row         the row index
1408   * @return            the mean
1409   */
1410  public double getMean(int col, int row) {
1411    if (    (col >= 0) && (col < getColCount()) 
1412         && (row >= 0) && (row < getRowCount()) )
1413      return m_Mean[row][col];
1414    else
1415      return 0;
1416  }
1417
1418  /**
1419   * returns the average of the mean at the given position, if the position is
1420   * valid, otherwise 0.
1421   *
1422   * @param col         the column index
1423   * @return            the average
1424   */
1425  public double getAverage(int col) {
1426    int       i;
1427    double    avg;
1428    int       count;
1429
1430    if ( (col >= 0) && (col < getColCount()) ) {
1431      avg   = 0;
1432      count = 0;
1433
1434      for (i = 0; i < getRowCount(); i++) {
1435        if (!Double.isNaN(getMean(col, i))) {
1436          avg += getMean(col, i);
1437          count++;
1438        }
1439      }
1440     
1441      return avg / (double) count;
1442    }
1443    else {
1444      return 0;
1445    }
1446  }
1447
1448  /**
1449   * sets the std deviation at the given position (if the position is valid).
1450   *
1451   * @param col         the column of the std. deviation
1452   * @param row         the row of the std deviation
1453   * @param value       the value of the std deviation
1454   */
1455  public void setStdDev(int col, int row, double value) {
1456    if (    (col >= 0) && (col < getColCount()) 
1457         && (row >= 0) && (row < getRowCount()) )
1458      m_StdDev[row][col] = value;
1459  }
1460
1461  /**
1462   * returns the std deviation at the given position, if the position is valid,
1463   * otherwise 0.
1464   *
1465   * @param col         the column index
1466   * @param row         the row index
1467   * @return            the std deviation
1468   */
1469  public double getStdDev(int col, int row) {
1470    if (    (col >= 0) && (col < getColCount()) 
1471         && (row >= 0) && (row < getRowCount()) )
1472      return m_StdDev[row][col];
1473    else
1474      return 0;
1475  }
1476
1477  /**
1478   * sets the significance at the given position (if the position is valid).
1479   *
1480   * @param col         the column of the significance
1481   * @param row         the row of the significance
1482   * @param value       the value of the significance
1483   */
1484  public void setSignificance(int col, int row, int value) {
1485    if (    (col >= 0) && (col < getColCount()) 
1486         && (row >= 0) && (row < getRowCount()) )
1487      m_Significance[row][col] = value;
1488  }
1489
1490  /**
1491   * returns the significance at the given position, if the position is valid,
1492   * otherwise SIGNIFICANCE_ATIE.
1493   *
1494   * @param col         the column index
1495   * @param row         the row index
1496   * @return            the indicator
1497   */
1498  public int getSignificance(int col, int row) {
1499    if (    (col >= 0) && (col < getColCount()) 
1500         && (row >= 0) && (row < getRowCount()) )
1501      return m_Significance[row][col];
1502    else
1503      return SIGNIFICANCE_TIE;
1504  }
1505
1506  /**
1507   * counts the occurrences of the given significance type in the given
1508   * column.
1509   *
1510   * @param col         the columnn to gather the information from
1511   * @param type        the significance type, WIN/TIE/LOSS
1512   * @return            the count
1513   */
1514  public int getSignificanceCount(int col, int type) {
1515    int       result;
1516    int       i;
1517
1518    result = 0;
1519
1520    if ( (col >= 0) && (col < getColCount()) ) {
1521      for (i = 0; i < getRowCount(); i++) {
1522        if (getRowHidden(i))
1523          continue;
1524
1525        // no value?
1526        if (Double.isNaN(getMean(col, i)))
1527          continue;
1528
1529        if (getSignificance(col, i) == type)
1530          result++;
1531      }
1532    }
1533
1534    return result;
1535  }
1536
1537  /**
1538   * sets the ordering of the rows, null means default.
1539   *
1540   * @param order       the new order of the rows
1541   */
1542  public void setRowOrder(int[] order) {
1543    int         i;
1544   
1545    // default order?
1546    if (order == null) {
1547      m_RowOrder = null;
1548    }
1549    else {
1550      if (order.length == getRowCount()) {
1551        m_RowOrder = new int[order.length];
1552        for (i = 0; i < order.length; i++)
1553          m_RowOrder[i] = order[i];
1554      }
1555      else {
1556        System.err.println("setRowOrder: length does not match (" 
1557            + order.length + " <> " + getRowCount() + ") - ignored!");
1558      }
1559    }
1560  }
1561
1562  /**
1563   * returns the current order of the rows, null means the default order.
1564   *
1565   * @return            the current order of the rows
1566   */
1567  public int[] getRowOrder() {
1568    return m_RowOrder;
1569  }
1570
1571  /**
1572   * returns the displayed index of the given row, depending on the order of
1573   * rows, returns -1 if index out of bounds.
1574   *
1575   * @param index       the row to get the displayed index for
1576   * @return            the real index of the row
1577   */
1578  public int getDisplayRow(int index) {
1579    if ( (index >= 0) && (index < getRowCount()) ) {
1580      if (getRowOrder() == null)
1581        return index;
1582      else
1583        return getRowOrder()[index];
1584    }
1585    else {
1586      return -1;
1587    }
1588  }
1589
1590  /**
1591   * sets the ordering of the columns, null means default.
1592   *
1593   * @param order       the new order of the columns
1594   */
1595  public void setColOrder(int[] order) {
1596    int         i;
1597   
1598    // default order?
1599    if (order == null) {
1600      m_ColOrder = null;
1601    }
1602    else {
1603      if (order.length == getColCount()) {
1604        m_ColOrder = new int[order.length];
1605        for (i = 0; i < order.length; i++)
1606          m_ColOrder[i] = order[i];
1607      }
1608      else {
1609        System.err.println("setColOrder: length does not match (" 
1610            + order.length + " <> " + getColCount() + ") - ignored!");
1611      }
1612    }
1613  }
1614
1615  /**
1616   * returns the current order of the columns, null means the default order.
1617   *
1618   * @return            the current order of the columns
1619   */
1620  public int[] getColOrder() {
1621    return m_ColOrder;
1622  }
1623
1624  /**
1625   * returns the displayed index of the given col, depending on the order of
1626   * columns, returns -1 if index out of bounds.
1627   *
1628   * @param index       the column to get the displayed index for
1629   * @return            the real index of the column
1630   */
1631  public int getDisplayCol(int index) {
1632    if ( (index >= 0) && (index < getColCount()) ) {
1633      if (getColOrder() == null)
1634        return index;
1635      else
1636        return getColOrder()[index];
1637    }
1638    else {
1639      return -1;
1640    }
1641  }
1642
1643  /**
1644   * returns the given number as string rounded to the given number of
1645   * decimals. additional necessary 0's are added.
1646   *
1647   * @param d           the number to format
1648   * @param prec        the number of decimals after the point
1649   * @return            the formatted number
1650   */
1651  protected String doubleToString(double d, int prec) {
1652    String        result;
1653    int           currentPrec;
1654    int           i;
1655
1656    result = Utils.doubleToString(d, prec);
1657
1658    // decimal point?
1659    if (result.indexOf(".") == -1)
1660      result += ".";
1661   
1662    // precision so far?
1663    currentPrec = result.length() - result.indexOf(".") - 1;
1664    for (i = currentPrec; i < prec; i++)
1665      result += "0";
1666   
1667    return result;
1668  }
1669
1670  /**
1671   * trims the given string down to the given length if longer, otherwise
1672   * leaves it unchanged. a length of "0" leaves the string always
1673   * unchanged.
1674   *
1675   * @param s           the string to trim (if too long)
1676   * @param length      the max. length (0 means infinity)
1677   * @return            the trimmed string
1678   */
1679  protected String trimString(String s, int length) {
1680    if ( (length > 0) && (s.length() > length) )
1681      return s.substring(0, length);
1682    else
1683      return s;
1684  }
1685
1686  /**
1687   * pads the given string on the right until it reaches the given length, if
1688   * longer cuts it down. if length is 0 then nothing is done.
1689   *
1690   * @param s           the string to pad
1691   * @param length      the max. length of the string
1692   * @return            the padded string
1693   */
1694  protected String padString(String s, int length) {
1695    return padString(s, length, false);
1696  }
1697
1698  /**
1699   * pads the given string until it reaches the given length, if longer cuts
1700   * it down. if length is 0 then nothing is done.
1701   *
1702   * @param s           the string to pad
1703   * @param length      the max. length of the string
1704   * @param left        whether to pad left or right
1705   * @return            the padded string
1706   */
1707  protected String padString(String s, int length, boolean left) {
1708    String      result;
1709    int         i;
1710
1711    result = s;
1712
1713    // pad with blanks
1714    for (i = s.length(); i < length; i++) {
1715      if (left)
1716        result = " " + result;
1717      else
1718        result = result + " ";
1719    }
1720     
1721    // too long?
1722    if ( (length > 0) && (result.length() > length) )
1723      result = result.substring(0, length);
1724
1725    return result;
1726  }
1727
1728  /**
1729   * returns the length of the longest cell in the given column.
1730   *
1731   * @param data        the data to base the calculation on
1732   * @param col         the column to check
1733   * @return            the maximum length
1734   */
1735  protected int getColSize(String[][] data, int col) {
1736    return getColSize(data, col, false, false);
1737  }
1738
1739  /**
1740   * returns the length of the longest cell in the given column.
1741   *
1742   * @param data        the data to base the calculation on
1743   * @param col         the column to check
1744   * @param skipFirst   whether to skip the first row
1745   * @param skipLast    whether to skip the last row
1746   * @return            the maximum length
1747   */
1748  protected int getColSize( String[][] data, int col, 
1749                            boolean skipFirst, boolean skipLast ) {
1750    int       result;
1751    int       i;
1752
1753    result = 0;
1754
1755    if ( (col >= 0) && (col < data[0].length) ) {
1756      for (i = 0; i < data.length; i++) {
1757        // skip first?
1758        if ( (i == 0) && (skipFirst) )
1759          continue;
1760
1761        // skip last?
1762        if ( (i == data.length - 1) && (skipLast) )
1763          continue;
1764       
1765        if (data[i][col].length() > result)
1766          result = data[i][col].length();
1767      }
1768    }
1769
1770    return result;
1771  }
1772
1773  /**
1774   * removes the filter classname from the given string if it should be
1775   * removed, otherwise leaves the string alone.
1776   *
1777   * @param s           the string to process
1778   * @return            the processed string
1779   * @see               #getRemoveFilterName()
1780   */
1781  protected String removeFilterName(String s) {
1782    if (getRemoveFilterName())
1783      return s.replaceAll("-weka\\.filters\\..*", "")
1784              .replaceAll("-unsupervised\\..*",   "")
1785              .replaceAll("-supervised\\..*",     "");
1786    else
1787      return s;
1788  }
1789
1790  /**
1791   * returns a 2-dimensional array with the prepared data. includes the column
1792   * and row names. hidden cols/rows are already excluded. <br>
1793   * first row: column names<br>
1794   * last  row: wins/ties/losses<br>
1795   * first col: row names<br>
1796   *
1797   * @return            the generated array
1798   */
1799  protected String[][] toArray() {
1800    int               i;
1801    int               n;
1802    int               ii;
1803    int               nn;
1804    int               x;
1805    int               y;
1806    String[][]        result;
1807    String[][]        tmpResult;
1808    int               cols;
1809    int               rows;
1810    boolean           valueExists;
1811
1812    // determine visible cols/rows
1813    rows = getVisibleRowCount();
1814    if (getShowAverage())
1815      rows++;
1816    cols = getVisibleColCount();
1817    if (getShowStdDev())
1818      cols = cols*3;   // mean + stddev + sign.
1819    else
1820      cols = cols*2;   // mean + stddev
1821
1822    result = new String[rows + 2][cols + 1];
1823
1824    // col names
1825    result[0][0] = trimString("Dataset", getRowNameWidth());
1826    x = 1;
1827    for (ii = 0; ii < getColCount(); ii++) {
1828      i = getDisplayCol(ii);
1829      if (getColHidden(i))
1830        continue;
1831     
1832      result[0][x] = trimString(
1833          removeFilterName(getColName(i)), getColNameWidth());
1834      x++;
1835      // std dev
1836      if (getShowStdDev()) {
1837        result[0][x] = "";
1838        x++;
1839      }
1840      // sign.
1841      result[0][x] = "";
1842      x++;
1843    }
1844
1845    // row names
1846    y = 1;
1847    for (ii = 0; ii < getRowCount(); ii++) {
1848      i = getDisplayRow(ii);
1849      if (!getRowHidden(i)) {
1850        result[y][0] = trimString(
1851            removeFilterName(getRowName(i)), getRowNameWidth());
1852        y++;
1853      }
1854    }
1855
1856    // fill in mean/std dev
1857    y = 1;
1858    for (ii = 0; ii < getRowCount(); ii++) {
1859      i = getDisplayRow(ii);
1860      if (getRowHidden(i))
1861        continue;
1862
1863      x = 1;
1864      for (nn = 0; nn < getColCount(); nn++) {
1865        n = getDisplayCol(nn);
1866        if (getColHidden(n))
1867          continue;
1868
1869        // do we have a value in the matrix?
1870        valueExists = (!Double.isNaN(getMean(n, i)));
1871
1872        // mean
1873        if (!valueExists)
1874          result[y][x] = "";
1875        else
1876          result[y][x] = doubleToString(getMean(n, i), getMeanPrec());
1877        x++;
1878       
1879        // stddev
1880        if (getShowStdDev()) {
1881          if (!valueExists)
1882            result[y][x] = "";
1883          else if (Double.isInfinite(getStdDev(n, i)))
1884            result[y][x] = "Inf";
1885          else
1886            result[y][x] = doubleToString(getStdDev(n, i), getStdDevPrec());
1887          x++;
1888        }
1889       
1890        // significance
1891        if (!valueExists) {
1892          result[y][x] = "";
1893        }
1894        else {
1895          switch (getSignificance(n, i)) {
1896            case SIGNIFICANCE_TIE:
1897              result[y][x] = TIE_STRING;
1898              break;
1899            case SIGNIFICANCE_WIN:
1900              result[y][x] = WIN_STRING;
1901              break;
1902            case SIGNIFICANCE_LOSS:
1903              result[y][x] = LOSS_STRING;
1904              break;
1905          }
1906        }
1907        x++;
1908      }
1909
1910      y++;
1911    }
1912
1913    // the average
1914    if (getShowAverage()) {
1915      y = result.length - 2;
1916      x = 0;
1917      result[y][0] = "Average";
1918      x++;
1919      for (ii = 0; ii < getColCount(); ii++) {
1920        i = getDisplayCol(ii);
1921        if (getColHidden(i))
1922          continue;
1923
1924        // mean-average
1925        result[y][x] = doubleToString(getAverage(i), getMeanPrec());
1926        x++;
1927
1928        // std dev.
1929        if (getShowStdDev()) {
1930          result[y][x] = "";
1931          x++;
1932        }
1933
1934        // significance
1935        result[y][x] = "";
1936        x++;
1937      }
1938    }
1939
1940    // wins/ties/losses
1941    y = result.length - 1;
1942    x = 0;
1943    result[y][0] =   LEFT_PARENTHESES
1944                   + WIN_STRING + "/" 
1945                   + TIE_STRING + "/" 
1946                   + LOSS_STRING
1947                   + RIGHT_PARENTHESES;
1948    x++;
1949    for (ii = 0; ii < getColCount(); ii++) {
1950      i = getDisplayCol(ii);
1951      if (getColHidden(i))
1952        continue;
1953
1954      // mean
1955      result[y][x] = "";
1956      x++;
1957
1958      // std dev.
1959      if (getShowStdDev()) {
1960        result[y][x] = "";
1961        x++;
1962      }
1963
1964      // significance
1965      result[y][x] =   LEFT_PARENTHESES
1966                     + getSignificanceCount(i, SIGNIFICANCE_WIN) + "/" 
1967                     + getSignificanceCount(i, SIGNIFICANCE_TIE) + "/" 
1968                     + getSignificanceCount(i, SIGNIFICANCE_LOSS) 
1969                     + RIGHT_PARENTHESES;
1970      x++;
1971    }
1972
1973    // base column has no significance -> remove these columns
1974    tmpResult = new String[result.length][result[0].length - 1];
1975
1976    x = 0;
1977    for (i = 0; i < result[0].length; i++) {
1978      // significance
1979      if (    ((i == 3) && ( getShowStdDev()))
1980           || ((i == 2) && (!getShowStdDev())) )
1981        continue;
1982     
1983      for (n = 0; n < result.length; n++)
1984        tmpResult[n][x] = result[n][i];
1985
1986      x++;
1987    }
1988    result = tmpResult;
1989
1990    return result;
1991  }
1992
1993  /**
1994   * returns true if the index (in the array produced by toArray(boolean))
1995   * is the row name.
1996   *
1997   * @param index       the row index
1998   * @return            true if index represents a row name
1999   */
2000  protected boolean isRowName(int index) {
2001    return (index == 0);
2002  }
2003
2004  /**
2005   * returns true if the index (in the array produced by toArray(boolean))
2006   * contains a mean.
2007   *
2008   * @param index       the column index
2009   * @return            true if mean column
2010   */
2011  protected boolean isMean(int index) {
2012    index--;   // dataset
2013    if (index == 0) {
2014      return true;   // base column
2015    }
2016    else {
2017      index--;   // base column
2018
2019      if (index < 0)
2020        return false;
2021     
2022      if (getShowStdDev())
2023        return (index % 3 == 1);
2024      else
2025        return (index % 2 == 0);
2026    }
2027  }
2028
2029  /**
2030   * returns true if the row index (in the array produced by toArray(boolean))
2031   * contains the average row.
2032   *
2033   * @param rowIndex    the row index
2034   * @return            true if average row
2035   */
2036  protected boolean isAverage(int rowIndex) {
2037    if (getShowAverage())
2038      return (getVisibleRowCount() + 1 == rowIndex);
2039    else
2040      return false;
2041  }
2042
2043  /**
2044   * returns true if the index (in the array produced by toArray(boolean))
2045   * contains a std deviation.
2046   *
2047   * @param index       the column index
2048   * @return            true if std dev column
2049   */
2050  protected boolean isStdDev(int index) {
2051    index--;   // dataset
2052    index--;   // base column
2053
2054    if (getShowStdDev()) {
2055      if (index == 0) {
2056        return true;   // stddev of base column
2057      }
2058      else {
2059        index--;   // stddev of base column
2060
2061        if (index < 0)
2062          return false;
2063     
2064        return (index % 3 == 1);
2065      }
2066    }
2067    else
2068      return false;
2069  }
2070
2071  /**
2072   * returns true if the index (in the array produced by toArray(boolean))
2073   * contains a significance column.
2074   *
2075   * @param index       the column index
2076   * @return            true if significance column
2077   */
2078  protected boolean isSignificance(int index) {
2079    index--;   // dataset
2080    index--;   // base column
2081    if (getShowStdDev()) {
2082      index--;   // stddev of base column
2083
2084      if (index < 0)
2085        return false;
2086     
2087      return (index % 3 == 2);
2088    }
2089    else {
2090      if (index < 0)
2091        return false;
2092     
2093      return (index % 2 == 1);
2094    }
2095  }
2096
2097  /**
2098   * returns the matrix as a string.
2099   *
2100   * @return            the matrix as string
2101   */
2102  public abstract String toStringMatrix();
2103
2104  /**
2105   * returns the matrix as a string.
2106   *
2107   * @return            the matrix as string
2108   * @see               #toStringMatrix()
2109   */
2110  public String toString() {
2111    return toStringMatrix();
2112  }
2113
2114  /**
2115   * removes all the header information.
2116   */
2117  public void clearHeader() {
2118    m_HeaderKeys   = new Vector();
2119    m_HeaderValues = new Vector();
2120  }
2121
2122  /**
2123   * adds the key-value pair to the header.
2124   *
2125   * @param key         the name of the header value
2126   * @param value       the value of the header value
2127   */
2128  public void addHeader(String key, String value) {
2129    int         pos;
2130   
2131    pos = m_HeaderKeys.indexOf(key);
2132    if (pos > -1) {
2133      m_HeaderValues.set(pos, value);
2134    }
2135    else {
2136      m_HeaderKeys.add(key);
2137      m_HeaderValues.add(value);
2138    }
2139  }
2140
2141  /**
2142   * returns the value associated with the given key, null if if cannot be
2143   * found.
2144   *
2145   * @param key         the key to retrieve the value for
2146   * @return            the associated value
2147   */
2148  public String getHeader(String key) {
2149    int       pos;
2150
2151    pos = m_HeaderKeys.indexOf(key);
2152    if (pos == 0)
2153      return null;
2154    else
2155      return (String) m_HeaderKeys.get(pos);
2156  }
2157
2158  /**
2159   * returns an enumeration of the header keys.
2160   *
2161   * @return            all stored keys
2162   */
2163  public Enumeration headerKeys() {
2164    return m_HeaderKeys.elements();
2165  }
2166 
2167  /**
2168   * returns the header of the matrix as a string.
2169   *
2170   * @return            the header as string
2171   * @see               #m_HeaderKeys
2172   * @see               #m_HeaderValues
2173   */
2174  public abstract String toStringHeader();
2175
2176  /**
2177   * returns returns a key for all the col names, for better readability if
2178   * the names got cut off.
2179   *
2180   * @return            the key
2181   */
2182  public abstract String toStringKey();
2183
2184  /**
2185   * clears the current summary data.
2186   */
2187  public void clearSummary() {
2188    m_NonSigWins = null;
2189    m_Wins       = null;
2190  }
2191
2192  /**
2193   * sets the non-significant and significant wins of the resultsets.
2194   *
2195   * @param nonSigWins      the non-significant wins
2196   * @param wins         the significant wins
2197   */
2198  public void setSummary(int[][] nonSigWins, int[][] wins) {
2199    int         i;
2200    int         n;
2201   
2202    m_NonSigWins = new int[nonSigWins.length][nonSigWins[0].length];
2203    m_Wins       = new int[wins.length][wins[0].length];
2204
2205    for (i = 0; i < m_NonSigWins.length; i++) {
2206      for (n = 0; n < m_NonSigWins[i].length; n++) {
2207        m_NonSigWins[i][n] = nonSigWins[i][n];
2208        m_Wins[i][n]       = wins[i][n];
2209      }
2210    }
2211  }
2212
2213  /**
2214   * returns the character representation of the given column.
2215   *
2216   * @param col         the column index
2217   * @return            the title of the column
2218   */
2219  protected String getSummaryTitle(int col) {
2220    return "" + (char) ((int) 'a' + col % 26);
2221  }
2222
2223  /**
2224   * returns the summary as string.
2225   *
2226   * @return            the summary
2227   */
2228  public abstract String toStringSummary();
2229
2230  /**
2231   * clears the currently stored ranking data.
2232   */
2233  public void clearRanking() {
2234    m_RankingWins   = null;
2235    m_RankingLosses = null;
2236    m_RankingDiff   = null;
2237  }
2238
2239  /**
2240   * sets the ranking data based on the wins.
2241   *
2242   * @param wins      the wins
2243   */
2244  public void setRanking(int[][] wins) {
2245    int         i;
2246    int         j;
2247   
2248    m_RankingWins   = new int[wins.length];
2249    m_RankingLosses = new int[wins.length];
2250    m_RankingDiff   = new int[wins.length];
2251
2252    for (i = 0; i < wins.length; i++) {
2253      for (j = 0; j < wins[i].length; j++) {
2254        m_RankingWins[j]   += wins[i][j];
2255        m_RankingDiff[j]   += wins[i][j];
2256        m_RankingLosses[i] += wins[i][j];
2257        m_RankingDiff[i]   -= wins[i][j];
2258      }
2259    }
2260  }
2261
2262  /**
2263   * returns the ranking in a string representation.
2264   *
2265   * @return            the ranking
2266   */
2267  public abstract String toStringRanking();
2268}
Note: See TracBrowser for help on using the repository browser.