Java tutorial
/* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * ResultMatrix.java * Copyright (C) 2005-2012 University of Waikato, Hamilton, New Zealand * */ package weka.experiment; import java.io.Serializable; import java.util.Enumeration; import java.util.Vector; import weka.core.Option; import weka.core.OptionHandler; import weka.core.RevisionHandler; import weka.core.Utils; /** * This matrix is a container for the datasets and classifier setups and their * statistics. Derived classes output the data in different formats. Derived * classes need to implement the following methods: * <ul> * <li><code>toStringMatrix()</code></li> * <li><code>toStringKey()</code></li> * <li><code>toStringHeader()</code></li> * <li><code>toStringSummary()</code></li> * <li><code>toStringRanking()</code></li> * </ul> * * * @author FracPete (fracpete at waikato dot ac dot nz) * @version $Revision$ * @see #toStringMatrix() * @see #toStringKey() * @see #toStringHeader() * @see #toStringSummary() * @see #toStringRanking() */ public abstract class ResultMatrix implements Serializable, RevisionHandler, OptionHandler { /** for serialization. */ private static final long serialVersionUID = 4487179306428209739L; /** tie. */ public final static int SIGNIFICANCE_TIE = 0; /** win. */ public final static int SIGNIFICANCE_WIN = 1; /** loss. */ public final static int SIGNIFICANCE_LOSS = 2; /** tie string. */ public String TIE_STRING = " "; /** win string. */ public String WIN_STRING = "v"; /** loss string. */ public String LOSS_STRING = "*"; /** the left parentheses for enumerating cols/rows. */ public String LEFT_PARENTHESES = "("; /** the right parentheses for enumerating cols/rows. */ public String RIGHT_PARENTHESES = ")"; /** the column names. */ protected String[] m_ColNames = null; /** the row names. */ protected String[] m_RowNames = null; /** whether a column is hidden. */ protected boolean[] m_ColHidden = null; /** whether a row is hidden. */ protected boolean[] m_RowHidden = null; /** the significance. */ protected int[][] m_Significance = null; /** the values. */ protected double[][] m_Mean = null; /** the standard deviation. */ protected double[][] m_StdDev = null; /** the counts for the different datasets. */ protected double[] m_Counts = null; /** the standard mean precision. */ protected int m_MeanPrec; /** the standard std. deviation preicision. */ protected int m_StdDevPrec; /** whether std. deviations are printed as well. */ protected boolean m_ShowStdDev; /** whether the average for each column should be printed. */ protected boolean m_ShowAverage; /** whether the names or numbers are output as column declarations. */ protected boolean m_PrintColNames; /** whether the names or numbers are output as row declarations. */ protected boolean m_PrintRowNames; /** * whether a "(x)" is printed before each column name with "x" as the index. */ protected boolean m_EnumerateColNames; /** whether a "(x)" is printed before each row name with "x" as the index. */ protected boolean m_EnumerateRowNames; /** the size of the names of the columns. */ protected int m_ColNameWidth; /** the size of the names of the rows. */ protected int m_RowNameWidth; /** the size of the mean columns. */ protected int m_MeanWidth; /** the size of the std dev columns. */ protected int m_StdDevWidth; /** the size of the significance columns. */ protected int m_SignificanceWidth; /** the size of the counts. */ protected int m_CountWidth; /** contains the keys for the header. */ protected Vector<String> m_HeaderKeys = null; /** contains the values for the header. */ protected Vector<String> m_HeaderValues = null; /** the non-significant wins. */ protected int[][] m_NonSigWins = null; /** the significant wins. */ protected int[][] m_Wins = null; /** the wins in ranking. */ protected int[] m_RankingWins = null; /** the losses in ranking. */ protected int[] m_RankingLosses = null; /** the difference between wins and losses. */ protected int[] m_RankingDiff = null; /** the ordering of the rows. */ protected int[] m_RowOrder = null; /** the ordering of the columns. */ protected int[] m_ColOrder = null; /** whether to remove the filter name from the dataaset name. */ protected boolean m_RemoveFilterName = false; /** * initializes the matrix as 1x1 matrix. */ public ResultMatrix() { this(1, 1); } /** * initializes the matrix with the given dimensions. * * @param cols the number of columns * @param rows the number of rows */ public ResultMatrix(int cols, int rows) { setSize(cols, rows); clear(); } /** * initializes the matrix with the values from the given matrix. * * @param matrix the matrix to get the values from */ public ResultMatrix(ResultMatrix matrix) { assign(matrix); } /** * Returns a string describing the matrix. * * @return a description suitable for displaying in the experimenter gui */ public abstract String globalInfo(); /** * Returns an enumeration of all the available options.. * * @return an enumeration of all available options. */ @Override public Enumeration<Option> listOptions() { Vector<Option> result; result = new Vector<Option>(); result.addElement(new Option("\tThe number of decimals after the decimal point for the mean.\n" + "\t(default: " + getDefaultMeanPrec() + ")", "mean-prec", 1, "-mean-prec <int>")); result.addElement(new Option("\tThe number of decimals after the decimal point for the mean.\n" + "\t(default: " + getDefaultStdDevPrec() + ")", "stddev-prec", 1, "-stddev-prec <int>")); result.addElement(new Option("\tThe maximum width for the column names (0 = optimal).\n" + "\t(default: " + getDefaultColNameWidth() + ")", "col-name-width", 1, "-col-name-width <int>")); result.addElement(new Option("\tThe maximum width for the row names (0 = optimal).\n" + "\t(default: " + getDefaultRowNameWidth() + ")", "row-name-width", 1, "-row-name-width <int>")); result.addElement(new Option( "\tThe width of the mean (0 = optimal).\n" + "\t(default: " + getDefaultMeanWidth() + ")", "mean-width", 1, "-mean-width <int>")); result.addElement(new Option("\tThe width of the standard deviation (0 = optimal).\n" + "\t(default: " + getDefaultStdDevWidth() + ")", "stddev-width", 1, "-stddev-width <int>")); result.addElement(new Option("\tThe width of the significance indicator (0 = optimal).\n" + "\t(default: " + getDefaultSignificanceWidth() + ")", "sig-width", 1, "-sig-width <int>")); result.addElement(new Option( "\tThe width of the counts (0 = optimal).\n" + "\t(default: " + getDefaultCountWidth() + ")", "count-width", 1, "-count-width <int>")); result.addElement(new Option("\tWhether to display the standard deviation column.\n" + "\t(default: no)", "show-stddev", 0, "-show-stddev")); result.addElement(new Option("\tWhether to show the row with averages.\n" + "\t(default: no)", "show-avg", 0, "-show-avg")); result.addElement(new Option("\tWhether to remove the classname package prefixes from the\n" + "\tfilter names in datasets.\n" + "\t(default: no)", "remove-filter", 0, "-remove-filter")); result.addElement(new Option( "\tWhether to output column names or just numbers representing them.\n" + "\t(default: no)", "print-col-names", 0, "-print-col-names")); result.addElement( new Option("\tWhether to output row names or just numbers representing them.\n" + "\t(default: no)", "print-row-names", 0, "-print-row-names")); result.addElement(new Option( "\tWhether to enumerate the column names (prefixing them with \n" + "\t'(x)', with 'x' being the index).\n" + "\t(default: no)", "enum-col-names", 0, "-enum-col-names")); result.addElement(new Option( "\tWhether to enumerate the row names (prefixing them with \n" + "\t'(x)', with 'x' being the index).\n" + "\t(default: no)", "enum-row-names", 0, "-enum-row-names")); return result.elements(); } /** * Sets the OptionHandler's options using the given list. All options will be * set (or reset) during this call (i.e. incremental setting of options is not * possible). * * @param options the list of options as an array of strings * @throws Exception if an option is not supported */ @Override public void setOptions(String[] options) throws Exception { String tmpStr; tmpStr = Utils.getOption("mean-prec", options); if (tmpStr.length() > 0) { setMeanPrec(Integer.parseInt(tmpStr)); } else { setMeanPrec(getDefaultMeanPrec()); } tmpStr = Utils.getOption("stddev-prec", options); if (tmpStr.length() > 0) { setStdDevPrec(Integer.parseInt(tmpStr)); } else { setStdDevPrec(getDefaultStdDevPrec()); } tmpStr = Utils.getOption("col-name-width", options); if (tmpStr.length() > 0) { setColNameWidth(Integer.parseInt(tmpStr)); } else { setColNameWidth(getDefaultColNameWidth()); } tmpStr = Utils.getOption("row-name-width", options); if (tmpStr.length() > 0) { setRowNameWidth(Integer.parseInt(tmpStr)); } else { setRowNameWidth(getDefaultRowNameWidth()); } tmpStr = Utils.getOption("mean-width", options); if (tmpStr.length() > 0) { setMeanWidth(Integer.parseInt(tmpStr)); } else { setMeanWidth(getDefaultMeanWidth()); } tmpStr = Utils.getOption("stddev-width", options); if (tmpStr.length() > 0) { setStdDevWidth(Integer.parseInt(tmpStr)); } else { setStdDevWidth(getDefaultStdDevWidth()); } tmpStr = Utils.getOption("sig-width", options); if (tmpStr.length() > 0) { setSignificanceWidth(Integer.parseInt(tmpStr)); } else { setSignificanceWidth(getDefaultSignificanceWidth()); } tmpStr = Utils.getOption("count-width", options); if (tmpStr.length() > 0) { setStdDevPrec(Integer.parseInt(tmpStr)); } else { setStdDevPrec(getDefaultCountWidth()); } setShowStdDev(Utils.getFlag("show-stddev", options)); setShowAverage(Utils.getFlag("show-avg", options)); setRemoveFilterName(Utils.getFlag("remove-filter", options)); setEnumerateColNames(Utils.getFlag("enum-col-names", options)); setEnumerateRowNames(Utils.getFlag("enum-row-names", options)); setPrintColNames(Utils.getFlag("print-col-names", options)); setPrintRowNames(Utils.getFlag("print-row-names", options)); } /** * Gets the current option settings for the OptionHandler. * * @return the list of current option settings as an array of strings */ @Override public String[] getOptions() { Vector<String> result; result = new Vector<String>(); result.add("-mean-prec"); result.add("" + getMeanPrec()); result.add("-stddev-prec"); result.add("" + getStdDevPrec()); result.add("-col-name-width"); result.add("" + getColNameWidth()); result.add("-row-name-width"); result.add("" + getRowNameWidth()); result.add("-mean-width"); result.add("" + getMeanWidth()); result.add("-stddev-width"); result.add("" + getStdDevWidth()); result.add("-sig-width"); result.add("" + getSignificanceWidth()); result.add("-count-width"); result.add("" + getCountWidth()); if (getShowStdDev()) { result.add("-show-stddev"); } if (getShowAverage()) { result.add("-show-avg"); } if (getRemoveFilterName()) { result.add("-remove-filter"); } if (getPrintColNames()) { result.add("-print-col-names"); } if (getPrintRowNames()) { result.add("-print-row-names"); } if (getEnumerateColNames()) { result.add("-enum-col-names"); } if (getEnumerateRowNames()) { result.add("-enum-row-names"); } return result.toArray(new String[result.size()]); } /** * returns the name of the output format. * * @return the display name */ public abstract String getDisplayName(); /** * acquires the data from the given matrix. * * @param matrix the matrix to get the data from */ @SuppressWarnings("unchecked") public void assign(ResultMatrix matrix) { int i; int n; setSize(matrix.getColCount(), matrix.getRowCount()); // output parameters TIE_STRING = matrix.TIE_STRING; WIN_STRING = matrix.WIN_STRING; LOSS_STRING = matrix.LOSS_STRING; LEFT_PARENTHESES = matrix.LEFT_PARENTHESES; RIGHT_PARENTHESES = matrix.RIGHT_PARENTHESES; m_MeanPrec = matrix.m_MeanPrec; m_StdDevPrec = matrix.m_StdDevPrec; m_ShowStdDev = matrix.m_ShowStdDev; m_ShowAverage = matrix.m_ShowAverage; m_PrintColNames = matrix.m_PrintColNames; m_PrintRowNames = matrix.m_PrintRowNames; m_EnumerateColNames = matrix.m_EnumerateColNames; m_EnumerateRowNames = matrix.m_EnumerateRowNames; m_RowNameWidth = matrix.m_RowNameWidth; m_MeanWidth = matrix.m_MeanWidth; m_StdDevWidth = matrix.m_StdDevWidth; m_SignificanceWidth = matrix.m_SignificanceWidth; m_CountWidth = matrix.m_CountWidth; m_RemoveFilterName = matrix.m_RemoveFilterName; // header m_HeaderKeys = (Vector<String>) matrix.m_HeaderKeys.clone(); m_HeaderValues = (Vector<String>) matrix.m_HeaderValues.clone(); // matrix for (i = 0; i < matrix.m_Mean.length; i++) { for (n = 0; n < matrix.m_Mean[i].length; n++) { m_Mean[i][n] = matrix.m_Mean[i][n]; m_StdDev[i][n] = matrix.m_StdDev[i][n]; m_Significance[i][n] = matrix.m_Significance[i][n]; } } for (i = 0; i < matrix.m_ColNames.length; i++) { m_ColNames[i] = matrix.m_ColNames[i]; m_ColHidden[i] = matrix.m_ColHidden[i]; } for (i = 0; i < matrix.m_RowNames.length; i++) { m_RowNames[i] = matrix.m_RowNames[i]; m_RowHidden[i] = matrix.m_RowHidden[i]; } for (i = 0; i < matrix.m_Counts.length; i++) { m_Counts[i] = matrix.m_Counts[i]; } // summary if (matrix.m_NonSigWins != null) { m_NonSigWins = new int[matrix.m_NonSigWins.length][]; m_Wins = new int[matrix.m_NonSigWins.length][]; for (i = 0; i < matrix.m_NonSigWins.length; i++) { m_NonSigWins[i] = new int[matrix.m_NonSigWins[i].length]; m_Wins[i] = new int[matrix.m_NonSigWins[i].length]; for (n = 0; n < matrix.m_NonSigWins[i].length; n++) { m_NonSigWins[i][n] = matrix.m_NonSigWins[i][n]; m_Wins[i][n] = matrix.m_Wins[i][n]; } } } // ranking if (matrix.m_RankingWins != null) { m_RankingWins = new int[matrix.m_RankingWins.length]; m_RankingLosses = new int[matrix.m_RankingWins.length]; m_RankingDiff = new int[matrix.m_RankingWins.length]; for (i = 0; i < matrix.m_RankingWins.length; i++) { m_RankingWins[i] = matrix.m_RankingWins[i]; m_RankingLosses[i] = matrix.m_RankingLosses[i]; m_RankingDiff[i] = matrix.m_RankingDiff[i]; } } } /** * removes the stored data and the ordering, but retains the dimensions of the * matrix. */ public void clear() { m_MeanPrec = getDefaultMeanPrec(); m_StdDevPrec = getDefaultStdDevPrec(); m_ShowStdDev = getDefaultShowStdDev(); m_ShowAverage = getDefaultShowAverage(); m_RemoveFilterName = getDefaultRemoveFilterName(); m_PrintColNames = getDefaultPrintColNames(); m_PrintRowNames = getDefaultPrintRowNames(); m_EnumerateColNames = getDefaultEnumerateColNames(); m_EnumerateRowNames = getDefaultEnumerateRowNames(); m_RowNameWidth = getDefaultRowNameWidth(); m_ColNameWidth = getDefaultColNameWidth(); m_MeanWidth = getDefaultMeanWidth(); m_StdDevWidth = getDefaultStdDevWidth(); m_SignificanceWidth = getDefaultSignificanceWidth(); m_CountWidth = getDefaultCountWidth(); setSize(getColCount(), getRowCount()); } /** * clears the content of the matrix and sets the new size. * * @param cols the number of mean columns * @param rows the number of mean rows */ public void setSize(int cols, int rows) { int i; int n; m_ColNames = new String[cols]; m_RowNames = new String[rows]; m_Counts = new double[rows]; m_ColHidden = new boolean[cols]; m_RowHidden = new boolean[rows]; m_Mean = new double[rows][cols]; m_Significance = new int[rows][cols]; m_StdDev = new double[rows][cols]; m_ColOrder = null; m_RowOrder = null; // NaN means that there exists no value! -> toArray() for (i = 0; i < m_Mean.length; i++) { for (n = 0; n < m_Mean[i].length; n++) { m_Mean[i][n] = Double.NaN; } } for (i = 0; i < m_ColNames.length; i++) { m_ColNames[i] = "col" + i; } for (i = 0; i < m_RowNames.length; i++) { m_RowNames[i] = "row" + i; } clearHeader(); clearSummary(); clearRanking(); } /** * sets the precision for the means. * * @param prec the number of decimals */ public void setMeanPrec(int prec) { if (prec >= 0) { m_MeanPrec = prec; } } /** * returns the current precision for the means. * * @return the number of decimals */ public int getMeanPrec() { return m_MeanPrec; } /** * returns the default precision for the means. * * @return the number of decimals */ public int getDefaultMeanPrec() { return 2; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String meanPrecTipText() { return "The number of decimals after the decimal point for the mean."; } /** * sets the precision for the standard deviation. * * @param prec the number of decimals */ public void setStdDevPrec(int prec) { if (prec >= 0) { m_StdDevPrec = prec; } } /** * returns the current standard deviation precision. * * @return the number of decimals */ public int getStdDevPrec() { return m_StdDevPrec; } /** * returns the default standard deviation precision. * * @return the number of decimals */ public int getDefaultStdDevPrec() { return 2; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String stdDevPrecTipText() { return "The number of decimals after the decimal point for the standard deviation."; } /** * sets the width for the column names (0 = optimal). * * @param width the width */ public void setColNameWidth(int width) { if (width >= 0) { m_ColNameWidth = width; } } /** * returns the current width for the column names. * * @return the width */ public int getColNameWidth() { return m_ColNameWidth; } /** * returns the default width for the column names. * * @return the width */ public int getDefaultColNameWidth() { return 0; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String colNameWidthTipText() { return "The maximum width of the column names (0 = optimal)."; } /** * sets the width for the row names (0 = optimal). * * @param width the width */ public void setRowNameWidth(int width) { if (width >= 0) { m_RowNameWidth = width; } } /** * returns the current width for the row names. * * @return the width */ public int getRowNameWidth() { return m_RowNameWidth; } /** * returns the default width for the row names. * * @return the width */ public int getDefaultRowNameWidth() { return 0; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String rowNameWidthTipText() { return "The maximum width for the row names (0 = optimal)."; } /** * sets the width for the mean (0 = optimal). * * @param width the width */ public void setMeanWidth(int width) { if (width >= 0) { m_MeanWidth = width; } } /** * returns the current width for the mean. * * @return the width */ public int getMeanWidth() { return m_MeanWidth; } /** * returns the default width for the mean. * * @return the width */ public int getDefaultMeanWidth() { return 0; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String meanWidthTipText() { return "The width of the mean (0 = optimal)."; } /** * sets the width for the std dev (0 = optimal). * * @param width the width */ public void setStdDevWidth(int width) { if (width >= 0) { m_StdDevWidth = width; } } /** * returns the current width for the std dev. * * @return the width */ public int getStdDevWidth() { return m_StdDevWidth; } /** * returns the default width for the std dev. * * @return the width */ public int getDefaultStdDevWidth() { return 0; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String stdDevWidthTipText() { return "The width of the standard deviation (0 = optimal)."; } /** * sets the width for the significance (0 = optimal). * * @param width the width */ public void setSignificanceWidth(int width) { if (width >= 0) { m_SignificanceWidth = width; } } /** * returns the current width for the significance. * * @return the width */ public int getSignificanceWidth() { return m_SignificanceWidth; } /** * returns the default width for the significance. * * @return the width */ public int getDefaultSignificanceWidth() { return 0; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String significanceWidthTipText() { return "The width of the significance indicator (0 = optimal)."; } /** * sets the width for the counts (0 = optimal). * * @param width the width */ public void setCountWidth(int width) { if (width >= 0) { m_CountWidth = width; } } /** * returns the current width for the counts. * * @return the width */ public int getCountWidth() { return m_CountWidth; } /** * returns the default width for the counts. * * @return the width */ public int getDefaultCountWidth() { return 0; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String countWidthTipText() { return "The width of the counts (0 = optimal)."; } /** * sets whether to display the std deviations or not. * * @param show if true then the std deviations are displayed */ public void setShowStdDev(boolean show) { m_ShowStdDev = show; } /** * returns whether std deviations are displayed or not. * * @return true if the std deviations are displayed */ public boolean getShowStdDev() { return m_ShowStdDev; } /** * returns the default of whether std deviations are displayed or not. * * @return true if the std deviations are displayed */ public boolean getDefaultShowStdDev() { return false; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String showStdDevTipText() { return "Whether to display the standard deviation column."; } /** * sets whether to display the average per column or not. * * @param show if true then the average is displayed */ public void setShowAverage(boolean show) { m_ShowAverage = show; } /** * returns whether average per column is displayed or not. * * @return true if the average is displayed */ public boolean getShowAverage() { return m_ShowAverage; } /** * returns the default of whether average per column is displayed or not. * * @return true if the average is displayed */ public boolean getDefaultShowAverage() { return false; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String showAverageTipText() { return "Whether to show the row with averages."; } /** * sets whether to remove the filter classname from the dataset name. * * @param remove if true then the filter classnames are shortened */ public void setRemoveFilterName(boolean remove) { m_RemoveFilterName = remove; } /** * returns whether the filter classname is removed from the dataset name. * * @return true if the filter classnames are shortened */ public boolean getRemoveFilterName() { return m_RemoveFilterName; } /** * returns the default of whether the filter classname is removed from the * dataset name. * * @return true if the filter classnames are shortened */ public boolean getDefaultRemoveFilterName() { return false; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String removeFilterNameTipText() { return "Whether to remove the classname package prefixes from the filter names in datasets."; } /** * sets whether the column names or numbers instead are printed. deactivating * automatically sets m_EnumerateColNames to TRUE. * * @param print if true then the names are printed instead of numbers * @see #setEnumerateColNames(boolean) */ public void setPrintColNames(boolean print) { m_PrintColNames = print; if (!print) { setEnumerateColNames(true); } } /** * returns whether column names or numbers instead are printed. * * @return true if names instead of numbers are printed */ public boolean getPrintColNames() { return m_PrintColNames; } /** * returns the default of whether column names or numbers instead are printed. * * @return true if names instead of numbers are printed */ public boolean getDefaultPrintColNames() { return true; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String printColNamesTipText() { return "Whether to output column names or just numbers representing them."; } /** * sets whether the row names or numbers instead are printed deactivating * automatically sets m_EnumerateColNames to TRUE. * * @param print if true then names instead of numbers are printed * @see #setEnumerateRowNames(boolean) */ public void setPrintRowNames(boolean print) { m_PrintRowNames = print; if (!print) { setEnumerateRowNames(true); } } /** * returns whether row names or numbers instead are printed. * * @return true if names instead of numbers are printed */ public boolean getPrintRowNames() { return m_PrintRowNames; } /** * returns the default of whether row names or numbers instead are printed. * * @return true if names instead of numbers are printed */ public boolean getDefaultPrintRowNames() { return true; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String printRowNamesTipText() { return "Whether to output row names or just numbers representing them."; } /** * sets whether the column names are prefixed with "(x)" where "x" is the * index. * * @param enumerate if true then the names are prefixed */ public void setEnumerateColNames(boolean enumerate) { m_EnumerateColNames = enumerate; } /** * returns whether column names are prefixed with the index. * * @return true if the names are prefixed */ public boolean getEnumerateColNames() { return m_EnumerateColNames; } /** * returns the default of whether column names are prefixed with the index. * * @return true if the names are prefixed */ public boolean getDefaultEnumerateColNames() { return true; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String enumerateColNamesTipText() { return "Whether to enumerate the column names (prefixing them with '(x)', with 'x' being the index)."; } /** * sets whether to the row names are prefixed with the index. * * @param enumerate if true then the names will be prefixed */ public void setEnumerateRowNames(boolean enumerate) { m_EnumerateRowNames = enumerate; } /** * returns whether row names or prefixed with the index. * * @return true if the names are prefixed */ public boolean getEnumerateRowNames() { return m_EnumerateRowNames; } /** * returns theh default of whether row names are prefixed with the index. * * @return true if the names are prefixed */ public boolean getDefaultEnumerateRowNames() { return false; } /** * Returns the tip text for this property. * * @return tip text for this property suitable for displaying in the * experimenter gui */ public String enumerateRowNamesTipText() { return "Whether to enumerate the row names (prefixing them with '(x)', with 'x' being the index)."; } /** * returns the number of columns. * * @return the number of columns */ public int getColCount() { return m_ColNames.length; } /** * returns the number of visible columns. * * @return the number of columns */ public int getVisibleColCount() { int cols; int i; cols = 0; for (i = 0; i < getColCount(); i++) { if (!getColHidden(i)) { cols++; } } return cols; } /** * returns the number of rows. * * @return the number of rows */ public int getRowCount() { return m_RowNames.length; } /** * returns the number of visible rows. * * @return the number of rows */ public int getVisibleRowCount() { int rows; int i; rows = 0; for (i = 0; i < getRowCount(); i++) { if (!getRowHidden(i)) { rows++; } } return rows; } /** * sets the name of the column (if the index is valid). * * @param index the index of the column * @param name the name of the column */ public void setColName(int index, String name) { if ((index >= 0) && (index < getColCount())) { m_ColNames[index] = name; } } /** * returns the name of the row, if the index is valid, otherwise null. if * getPrintColNames() is FALSE then an empty string is returned or if * getEnumerateColNames() is TRUE then the 1-based index surrounded by * parentheses. * * @param index the index of the column * @return the name of the column * @see #setPrintColNames(boolean) * @see #getPrintColNames() * @see #setEnumerateColNames(boolean) * @see #getEnumerateColNames() */ public String getColName(int index) { String result; result = null; if ((index >= 0) && (index < getColCount())) { if (getPrintColNames()) { result = m_ColNames[index]; } else { result = ""; } if (getEnumerateColNames()) { result = LEFT_PARENTHESES + Integer.toString(index + 1) + RIGHT_PARENTHESES + " " + result; result = result.trim(); } } return result; } /** * sets the name of the row (if the index is valid). * * @param index the index of the row * @param name the name of the row */ public void setRowName(int index, String name) { if ((index >= 0) && (index < getRowCount())) { m_RowNames[index] = name; } } /** * returns the name of the row, if the index is valid, otherwise null. if * getPrintRowNames() is FALSE then an empty string is returned or if * getEnumerateRowNames() is TRUE then the 1-based index surrounded by * parentheses. * * @param index the index of the row * @return the name of the row * @see #setPrintRowNames(boolean) * @see #getPrintRowNames() * @see #setEnumerateRowNames(boolean) * @see #getEnumerateRowNames() */ public String getRowName(int index) { String result; result = null; if ((index >= 0) && (index < getRowCount())) { if (getPrintRowNames()) { result = m_RowNames[index]; } else { result = ""; } if (getEnumerateRowNames()) { result = LEFT_PARENTHESES + Integer.toString(index + 1) + RIGHT_PARENTHESES + " " + result; result = result.trim(); } } return result; } /** * sets the hidden status of the column (if the index is valid). * * @param index the index of the column * @param hidden the hidden status of the column */ public void setColHidden(int index, boolean hidden) { if ((index >= 0) && (index < getColCount())) { m_ColHidden[index] = hidden; } } /** * returns the hidden status of the column, if the index is valid, otherwise * false. * * @param index the index of the column * @return true if hidden */ public boolean getColHidden(int index) { if ((index >= 0) && (index < getColCount())) { return m_ColHidden[index]; } else { return false; } } /** * sets the hidden status of the row (if the index is valid). * * @param index the index of the row * @param hidden the hidden status of the row */ public void setRowHidden(int index, boolean hidden) { if ((index >= 0) && (index < getRowCount())) { m_RowHidden[index] = hidden; } } /** * returns the hidden status of the row, if the index is valid, otherwise * false. * * @param index the index of the row * @return true if hidden */ public boolean getRowHidden(int index) { if ((index >= 0) && (index < getRowCount())) { return m_RowHidden[index]; } else { return false; } } /** * sets the count for the row (if the index is valid). * * @param index the index of the row * @param count the count for the row */ public void setCount(int index, double count) { if ((index >= 0) && (index < getRowCount())) { m_Counts[index] = count; } } /** * returns the count for the row. if the index is invalid then 0. * * @param index the index of the row * @return the count for the row */ public double getCount(int index) { if ((index >= 0) && (index < getRowCount())) { return m_Counts[index]; } else { return 0; } } /** * sets the mean at the given position (if the position is valid). * * @param col the column of the mean * @param row the row of the mean * @param value the value of the mean */ public void setMean(int col, int row, double value) { if ((col >= 0) && (col < getColCount()) && (row >= 0) && (row < getRowCount())) { m_Mean[row][col] = value; } } /** * returns the mean at the given position, if the position is valid, otherwise * 0. * * @param col the column index * @param row the row index * @return the mean */ public double getMean(int col, int row) { if ((col >= 0) && (col < getColCount()) && (row >= 0) && (row < getRowCount())) { return m_Mean[row][col]; } else { return 0; } } /** * returns the average of the mean at the given position, if the position is * valid, otherwise 0. * * @param col the column index * @return the average */ public double getAverage(int col) { int i; double avg; int count; if ((col >= 0) && (col < getColCount())) { avg = 0; count = 0; for (i = 0; i < getRowCount(); i++) { if (!Double.isNaN(getMean(col, i))) { avg += getMean(col, i); count++; } } return avg / count; } else { return 0; } } /** * sets the std deviation at the given position (if the position is valid). * * @param col the column of the std. deviation * @param row the row of the std deviation * @param value the value of the std deviation */ public void setStdDev(int col, int row, double value) { if ((col >= 0) && (col < getColCount()) && (row >= 0) && (row < getRowCount())) { m_StdDev[row][col] = value; } } /** * returns the std deviation at the given position, if the position is valid, * otherwise 0. * * @param col the column index * @param row the row index * @return the std deviation */ public double getStdDev(int col, int row) { if ((col >= 0) && (col < getColCount()) && (row >= 0) && (row < getRowCount())) { return m_StdDev[row][col]; } else { return 0; } } /** * sets the significance at the given position (if the position is valid). * * @param col the column of the significance * @param row the row of the significance * @param value the value of the significance */ public void setSignificance(int col, int row, int value) { if ((col >= 0) && (col < getColCount()) && (row >= 0) && (row < getRowCount())) { m_Significance[row][col] = value; } } /** * returns the significance at the given position, if the position is valid, * otherwise SIGNIFICANCE_ATIE. * * @param col the column index * @param row the row index * @return the indicator */ public int getSignificance(int col, int row) { if ((col >= 0) && (col < getColCount()) && (row >= 0) && (row < getRowCount())) { return m_Significance[row][col]; } else { return SIGNIFICANCE_TIE; } } /** * counts the occurrences of the given significance type in the given column. * * @param col the columnn to gather the information from * @param type the significance type, WIN/TIE/LOSS * @return the count */ public int getSignificanceCount(int col, int type) { int result; int i; result = 0; if ((col >= 0) && (col < getColCount())) { for (i = 0; i < getRowCount(); i++) { if (getRowHidden(i)) { continue; } // no value? if (Double.isNaN(getMean(col, i))) { continue; } if (getSignificance(col, i) == type) { result++; } } } return result; } /** * sets the ordering of the rows, null means default. * * @param order the new order of the rows */ public void setRowOrder(int[] order) { int i; // default order? if (order == null) { m_RowOrder = null; } else { if (order.length == getRowCount()) { m_RowOrder = new int[order.length]; for (i = 0; i < order.length; i++) { m_RowOrder[i] = order[i]; } } else { System.err.println("setRowOrder: length does not match (" + order.length + " <> " + getRowCount() + ") - ignored!"); } } } /** * returns the current order of the rows, null means the default order. * * @return the current order of the rows */ public int[] getRowOrder() { return m_RowOrder; } /** * returns the displayed index of the given row, depending on the order of * rows, returns -1 if index out of bounds. * * @param index the row to get the displayed index for * @return the real index of the row */ public int getDisplayRow(int index) { if ((index >= 0) && (index < getRowCount())) { if (getRowOrder() == null) { return index; } else { return getRowOrder()[index]; } } else { return -1; } } /** * sets the ordering of the columns, null means default. * * @param order the new order of the columns */ public void setColOrder(int[] order) { int i; // default order? if (order == null) { m_ColOrder = null; } else { if (order.length == getColCount()) { m_ColOrder = new int[order.length]; for (i = 0; i < order.length; i++) { m_ColOrder[i] = order[i]; } } else { System.err.println("setColOrder: length does not match (" + order.length + " <> " + getColCount() + ") - ignored!"); } } } /** * returns the current order of the columns, null means the default order. * * @return the current order of the columns */ public int[] getColOrder() { return m_ColOrder; } /** * returns the displayed index of the given col, depending on the order of * columns, returns -1 if index out of bounds. * * @param index the column to get the displayed index for * @return the real index of the column */ public int getDisplayCol(int index) { if ((index >= 0) && (index < getColCount())) { if (getColOrder() == null) { return index; } else { return getColOrder()[index]; } } else { return -1; } } /** * returns the given number as string rounded to the given number of decimals. * additional necessary 0's are added. * * @param d the number to format * @param prec the number of decimals after the point * @return the formatted number */ protected String doubleToString(double d, int prec) { String result; int currentPrec; int i; result = Utils.doubleToString(d, prec); if (prec <= 0 || Double.isInfinite(d) || Double.isNaN(d)) { return result; } // decimal point? if (result.indexOf(".") == -1) { result += "."; } // precision so far? currentPrec = result.length() - result.indexOf(".") - 1; for (i = currentPrec; i < prec; i++) { result += "0"; } return result; } /** * trims the given string down to the given length if longer, otherwise leaves * it unchanged. a length of "0" leaves the string always unchanged. * * @param s the string to trim (if too long) * @param length the max. length (0 means infinity) * @return the trimmed string */ protected String trimString(String s, int length) { if ((length > 0) && (s.length() > length)) { return s.substring(0, length); } else { return s; } } /** * pads the given string on the right until it reaches the given length, if * longer cuts it down. if length is 0 then nothing is done. * * @param s the string to pad * @param length the max. length of the string * @return the padded string */ protected String padString(String s, int length) { return padString(s, length, false); } /** * pads the given string until it reaches the given length, if longer cuts it * down. if length is 0 then nothing is done. * * @param s the string to pad * @param length the max. length of the string * @param left whether to pad left or right * @return the padded string */ protected String padString(String s, int length, boolean left) { String result; int i; result = s; // pad with blanks for (i = s.length(); i < length; i++) { if (left) { result = " " + result; } else { result = result + " "; } } // too long? if ((length > 0) && (result.length() > length)) { result = result.substring(0, length); } return result; } /** * returns the length of the longest cell in the given column. * * @param data the data to base the calculation on * @param col the column to check * @return the maximum length */ protected int getColSize(String[][] data, int col) { return getColSize(data, col, false, false); } /** * returns the length of the longest cell in the given column. * * @param data the data to base the calculation on * @param col the column to check * @param skipFirst whether to skip the first row * @param skipLast whether to skip the last row * @return the maximum length */ protected int getColSize(String[][] data, int col, boolean skipFirst, boolean skipLast) { int result; int i; result = 0; if ((col >= 0) && (col < data[0].length)) { for (i = 0; i < data.length; i++) { // skip first? if ((i == 0) && (skipFirst)) { continue; } // skip last? if ((i == data.length - 1) && (skipLast)) { continue; } if (data[i][col].length() > result) { result = data[i][col].length(); } } } return result; } /** * removes the filter classname from the given string if it should be removed, * otherwise leaves the string alone. * * @param s the string to process * @return the processed string * @see #getRemoveFilterName() */ protected String removeFilterName(String s) { if (getRemoveFilterName()) { return s.replaceAll("-weka\\.filters\\..*", "").replaceAll("-unsupervised\\..*", "") .replaceAll("-supervised\\..*", ""); } else { return s; } } /** * returns a 2-dimensional array with the prepared data. includes the column * and row names. hidden cols/rows are already excluded. <br> * first row: column names<br> * last row: wins/ties/losses<br> * first col: row names<br> * * @return the generated array */ protected String[][] toArray() { int i; int n; int ii; int nn; int x; int y; String[][] result; String[][] tmpResult; int cols; int rows; boolean valueExists; // determine visible cols/rows rows = getVisibleRowCount(); if (getShowAverage()) { rows++; } cols = getVisibleColCount(); if (getShowStdDev()) { cols = cols * 3; // mean + stddev + sign. } else { cols = cols * 2; // mean + stddev } result = new String[rows + 2][cols + 1]; // col names result[0][0] = trimString("Dataset", getRowNameWidth()); x = 1; for (ii = 0; ii < getColCount(); ii++) { i = getDisplayCol(ii); if (getColHidden(i)) { continue; } result[0][x] = trimString(removeFilterName(getColName(i)), getColNameWidth()); x++; // std dev if (getShowStdDev()) { result[0][x] = ""; x++; } // sign. result[0][x] = ""; x++; } // row names y = 1; for (ii = 0; ii < getRowCount(); ii++) { i = getDisplayRow(ii); if (!getRowHidden(i)) { result[y][0] = trimString(removeFilterName(getRowName(i)), getRowNameWidth()); y++; } } // fill in mean/std dev y = 1; for (ii = 0; ii < getRowCount(); ii++) { i = getDisplayRow(ii); if (getRowHidden(i)) { continue; } x = 1; for (nn = 0; nn < getColCount(); nn++) { n = getDisplayCol(nn); if (getColHidden(n)) { continue; } // do we have a value in the matrix? valueExists = (!Double.isNaN(getMean(n, i))); // mean if (!valueExists) { result[y][x] = ""; } else { result[y][x] = doubleToString(getMean(n, i), getMeanPrec()); } x++; // stddev if (getShowStdDev()) { if (!valueExists) { result[y][x] = ""; } else if (Double.isInfinite(getStdDev(n, i))) { result[y][x] = "Inf"; } else { result[y][x] = doubleToString(getStdDev(n, i), getStdDevPrec()); } x++; } // significance if (!valueExists) { result[y][x] = ""; } else { switch (getSignificance(n, i)) { case SIGNIFICANCE_TIE: result[y][x] = TIE_STRING; break; case SIGNIFICANCE_WIN: result[y][x] = WIN_STRING; break; case SIGNIFICANCE_LOSS: result[y][x] = LOSS_STRING; break; } } x++; } y++; } // the average if (getShowAverage()) { y = result.length - 2; x = 0; result[y][0] = "Average"; x++; for (ii = 0; ii < getColCount(); ii++) { i = getDisplayCol(ii); if (getColHidden(i)) { continue; } // mean-average result[y][x] = doubleToString(getAverage(i), getMeanPrec()); x++; // std dev. if (getShowStdDev()) { result[y][x] = ""; x++; } // significance result[y][x] = ""; x++; } } // wins/ties/losses y = result.length - 1; x = 0; result[y][0] = LEFT_PARENTHESES + WIN_STRING + "/" + TIE_STRING + "/" + LOSS_STRING + RIGHT_PARENTHESES; x++; for (ii = 0; ii < getColCount(); ii++) { i = getDisplayCol(ii); if (getColHidden(i)) { continue; } // mean result[y][x] = ""; x++; // std dev. if (getShowStdDev()) { result[y][x] = ""; x++; } // significance result[y][x] = LEFT_PARENTHESES + getSignificanceCount(i, SIGNIFICANCE_WIN) + "/" + getSignificanceCount(i, SIGNIFICANCE_TIE) + "/" + getSignificanceCount(i, SIGNIFICANCE_LOSS) + RIGHT_PARENTHESES; x++; } // base column has no significance -> remove these columns tmpResult = new String[result.length][result[0].length - 1]; x = 0; for (i = 0; i < result[0].length; i++) { // significance if (((i == 3) && (getShowStdDev())) || ((i == 2) && (!getShowStdDev()))) { continue; } for (n = 0; n < result.length; n++) { tmpResult[n][x] = result[n][i]; } x++; } result = tmpResult; return result; } /** * returns true if the index (in the array produced by toArray(boolean)) is * the row name. * * @param index the row index * @return true if index represents a row name */ protected boolean isRowName(int index) { return (index == 0); } /** * returns true if the index (in the array produced by toArray(boolean)) * contains a mean. * * @param index the column index * @return true if mean column */ protected boolean isMean(int index) { index--; // dataset if (index == 0) { return true; // base column } else { index--; // base column if (index < 0) { return false; } if (getShowStdDev()) { return (index % 3 == 1); } else { return (index % 2 == 0); } } } /** * returns true if the row index (in the array produced by toArray(boolean)) * contains the average row. * * @param rowIndex the row index * @return true if average row */ protected boolean isAverage(int rowIndex) { if (getShowAverage()) { return (getVisibleRowCount() + 1 == rowIndex); } else { return false; } } /** * returns true if the index (in the array produced by toArray(boolean)) * contains a std deviation. * * @param index the column index * @return true if std dev column */ protected boolean isStdDev(int index) { index--; // dataset index--; // base column if (getShowStdDev()) { if (index == 0) { return true; // stddev of base column } else { index--; // stddev of base column if (index < 0) { return false; } return (index % 3 == 1); } } else { return false; } } /** * returns true if the index (in the array produced by toArray(boolean)) * contains a significance column. * * @param index the column index * @return true if significance column */ protected boolean isSignificance(int index) { index--; // dataset index--; // base column if (getShowStdDev()) { index--; // stddev of base column if (index < 0) { return false; } return (index % 3 == 2); } else { if (index < 0) { return false; } return (index % 2 == 1); } } /** * returns the matrix as a string. * * @return the matrix as string */ public abstract String toStringMatrix(); /** * returns the matrix as a string. * * @return the matrix as string * @see #toStringMatrix() */ @Override public String toString() { return toStringMatrix(); } /** * removes all the header information. */ public void clearHeader() { m_HeaderKeys = new Vector<String>(); m_HeaderValues = new Vector<String>(); } /** * adds the key-value pair to the header. * * @param key the name of the header value * @param value the value of the header value */ public void addHeader(String key, String value) { int pos; pos = m_HeaderKeys.indexOf(key); if (pos > -1) { m_HeaderValues.set(pos, value); } else { m_HeaderKeys.add(key); m_HeaderValues.add(value); } } /** * returns the value associated with the given key, null if if cannot be * found. * * @param key the key to retrieve the value for * @return the associated value */ public String getHeader(String key) { int pos; pos = m_HeaderKeys.indexOf(key); if (pos == 0) { return null; } else { return m_HeaderKeys.get(pos); } } /** * returns an enumeration of the header keys. * * @return all stored keys */ public Enumeration<String> headerKeys() { return m_HeaderKeys.elements(); } /** * returns the header of the matrix as a string. * * @return the header as string * @see #m_HeaderKeys * @see #m_HeaderValues */ public abstract String toStringHeader(); /** * returns returns a key for all the col names, for better readability if the * names got cut off. * * @return the key */ public abstract String toStringKey(); /** * clears the current summary data. */ public void clearSummary() { m_NonSigWins = null; m_Wins = null; } /** * sets the non-significant and significant wins of the resultsets. * * @param nonSigWins the non-significant wins * @param wins the significant wins */ public void setSummary(int[][] nonSigWins, int[][] wins) { int i; int n; m_NonSigWins = new int[nonSigWins.length][nonSigWins[0].length]; m_Wins = new int[wins.length][wins[0].length]; for (i = 0; i < m_NonSigWins.length; i++) { for (n = 0; n < m_NonSigWins[i].length; n++) { m_NonSigWins[i][n] = nonSigWins[i][n]; m_Wins[i][n] = wins[i][n]; } } } /** * returns the character representation of the given column. * * @param col the column index * @return the title of the column */ protected String getSummaryTitle(int col) { return "" + (char) ('a' + col % 26); } /** * returns the summary as string. * * @return the summary */ public abstract String toStringSummary(); /** * clears the currently stored ranking data. */ public void clearRanking() { m_RankingWins = null; m_RankingLosses = null; m_RankingDiff = null; } /** * sets the ranking data based on the wins. * * @param wins the wins */ public void setRanking(int[][] wins) { int i; int j; m_RankingWins = new int[wins.length]; m_RankingLosses = new int[wins.length]; m_RankingDiff = new int[wins.length]; for (i = 0; i < wins.length; i++) { for (j = 0; j < wins[i].length; j++) { m_RankingWins[j] += wins[i][j]; m_RankingDiff[j] += wins[i][j]; m_RankingLosses[i] += wins[i][j]; m_RankingDiff[i] -= wins[i][j]; } } } /** * returns the ranking in a string representation. * * @return the ranking */ public abstract String toStringRanking(); }