source: branches/MetisMQI/src/main/java/weka/datagenerators/clusterers/SubspaceClusterDefinition.java

Last change on this file was 29, checked in by gnappo, 15 years ago

Taggata versione per la demo e aggiunto branch.

File size: 24.4 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 * SubspaceClusterDefinition.java
19 * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.datagenerators.clusterers;
24
25import weka.core.Option;
26import weka.core.Range;
27import weka.core.RevisionUtils;
28import weka.core.SelectedTag;
29import weka.core.Utils;
30import weka.datagenerators.ClusterDefinition;
31import weka.datagenerators.ClusterGenerator;
32
33import java.util.Enumeration;
34import java.util.Random;
35import java.util.StringTokenizer;
36import java.util.Vector;
37
38/**
39 <!-- globalinfo-start -->
40 * A single cluster for the SubspaceCluster datagenerator
41 * <p/>
42 <!-- globalinfo-end -->
43 *
44 <!-- options-start -->
45 * Valid options are: <p/>
46 *
47 * <pre> -A &lt;range&gt;
48 *  Generates randomly distributed instances in the cluster.</pre>
49 *
50 * <pre> -U &lt;range&gt;
51 *  Generates uniformly distributed instances in the cluster.</pre>
52 *
53 * <pre> -G &lt;range&gt;
54 *  Generates gaussian distributed instances in the cluster.</pre>
55 *
56 * <pre> -D &lt;num&gt;,&lt;num&gt;
57 *  The attribute min/max (-A and -U) or mean/stddev (-G) for
58 *  the cluster.</pre>
59 *
60 * <pre> -N &lt;num&gt;..&lt;num&gt;
61 *  The range of number of instances per cluster (default 1..50).</pre>
62 *
63 * <pre> -I
64 *  Uses integer instead of continuous values (default continuous).</pre>
65 *
66 <!-- options-end -->
67 *
68 * @author  Gabi Schmidberger (gabi@cs.waikato.ac.nz)
69 * @author  FracPete (fracpete at waikato dot ac dot nz)
70 * @version $Revision: 1.5 $
71 * @see SubspaceCluster
72 */
73public class SubspaceClusterDefinition 
74  extends ClusterDefinition {
75
76  /** for serialization */
77  static final long serialVersionUID = 3135678125044007231L;
78 
79  /** cluster type */
80  protected int m_clustertype;
81
82  /** cluster subtypes */
83  protected int m_clustersubtype;
84
85  /** number of attributes the cluster is defined for */
86  protected int m_numClusterAttributes;
87
88  /** number of instances for this cluster */
89  protected int m_numInstances;
90
91  /** minimal number of instances for this cluster */
92  protected int m_MinInstNum;
93
94  /** maximal number of instances for this cluster */
95  protected int m_MaxInstNum;
96
97  /** range of atttributes */
98  protected Range m_AttrIndexRange;
99
100  /** attributes of this cluster */
101  protected boolean[] m_attributes;
102
103  /** global indices of the attributes of the cluster */
104  protected int[] m_attrIndices;
105
106  /** ranges of each attribute (min); not used if gaussian */
107  protected double[] m_minValue;
108
109  /** ranges of each attribute (max); not used if gaussian */
110  protected double[] m_maxValue;
111
112  /** mean ; only used if gaussian */
113  protected double[] m_meanValue;
114 
115  /** standarddev; only used if gaussian */
116  protected double[] m_stddevValue;
117
118  /**
119   * initializes the cluster, without a parent cluster (necessary for GOE)
120   */
121  public SubspaceClusterDefinition() {
122    super();
123  }
124
125  /**
126   * initializes the cluster with default values
127   *
128   * @param parent    the datagenerator this cluster belongs to
129   */
130  public SubspaceClusterDefinition(ClusterGenerator parent) {
131    super(parent);
132  }
133
134  /**
135   * sets the default values
136   *
137   * @throws Exception if setting of defaults fails
138   */
139  protected void setDefaults() throws Exception {
140    setClusterType(defaultClusterType());
141    setClusterSubType(defaultClusterSubType());
142    setMinInstNum(defaultMinInstNum());
143    setMaxInstNum(defaultMaxInstNum());
144    setAttrIndexRange(defaultAttrIndexRange());
145    m_numClusterAttributes = 1;
146    setValuesList(defaultValuesList());
147  }
148
149 
150  /**
151   * Returns a string describing this data generator.
152   *
153   * @return a description of the data generator suitable for
154   * displaying in the explorer/experimenter gui
155   */
156  public String globalInfo() {
157    return "A single cluster for the SubspaceCluster datagenerator";
158  }
159  /**
160   * Returns an enumeration describing the available options.
161   *
162   * @return an enumeration of all the available options
163   */
164  public Enumeration listOptions() {
165    Vector result = new Vector();
166
167    result.addElement(new Option(
168          "\tGenerates randomly distributed instances in the cluster.",
169          "A", 1, "-A <range>"));
170
171    result.addElement(new Option(
172          "\tGenerates uniformly distributed instances in the cluster.",
173          "U", 1, "-U <range>"));
174
175    result.addElement(new Option(
176          "\tGenerates gaussian distributed instances in the cluster.",
177          "G", 1, "-G <range>"));
178
179    result.addElement(new Option(
180          "\tThe attribute min/max (-A and -U) or mean/stddev (-G) for\n"
181          + "\tthe cluster.",
182          "D", 1, "-D <num>,<num>"));
183
184    result.addElement(new Option(
185          "\tThe range of number of instances per cluster (default "
186          + defaultMinInstNum() + ".." + defaultMaxInstNum() + ").",
187          "N", 1, "-N <num>..<num>"));
188
189    result.addElement(new Option(
190          "\tUses integer instead of continuous values (default continuous).",
191          "I", 0, "-I"));
192
193    return result.elements();
194  }
195
196  /**
197   * Parses a list of options for this object. <p/>
198   *
199   <!-- options-start -->
200   * Valid options are: <p/>
201   *
202   * <pre> -A &lt;range&gt;
203   *  Generates randomly distributed instances in the cluster.</pre>
204   *
205   * <pre> -U &lt;range&gt;
206   *  Generates uniformly distributed instances in the cluster.</pre>
207   *
208   * <pre> -G &lt;range&gt;
209   *  Generates gaussian distributed instances in the cluster.</pre>
210   *
211   * <pre> -D &lt;num&gt;,&lt;num&gt;
212   *  The attribute min/max (-A and -U) or mean/stddev (-G) for
213   *  the cluster.</pre>
214   *
215   * <pre> -N &lt;num&gt;..&lt;num&gt;
216   *  The range of number of instances per cluster (default 1..50).</pre>
217   *
218   * <pre> -I
219   *  Uses integer instead of continuous values (default continuous).</pre>
220   *
221   <!-- options-end -->
222   *
223   * @param options the list of options as an array of strings
224   * @throws Exception if an option is not supported
225   */
226  public void setOptions(String[] options) throws Exception {
227    String        tmpStr;
228    String        fromToStr;
229    int           typeCount;
230
231    typeCount = 0;
232    fromToStr = "";
233
234    tmpStr = Utils.getOption('A', options);
235    if (tmpStr.length() != 0) {
236      fromToStr = tmpStr;
237      setClusterType(
238          new SelectedTag(
239            SubspaceCluster.UNIFORM_RANDOM, SubspaceCluster.TAGS_CLUSTERTYPE));
240      typeCount++;
241    }
242
243    tmpStr = Utils.getOption('U', options);
244    if (tmpStr.length() != 0) {
245      fromToStr = tmpStr;
246      setClusterType(
247          new SelectedTag(
248            SubspaceCluster.TOTAL_UNIFORM, SubspaceCluster.TAGS_CLUSTERTYPE));
249      typeCount++;
250    }
251
252    tmpStr = Utils.getOption('G', options);
253    if (tmpStr.length() != 0) {
254      fromToStr = tmpStr;
255      setClusterType(
256          new SelectedTag(
257            SubspaceCluster.GAUSSIAN, SubspaceCluster.TAGS_CLUSTERTYPE));
258      typeCount++;
259    }
260
261    // default is uniform/random
262    if (typeCount == 0)
263      setClusterType(
264          new SelectedTag(
265            SubspaceCluster.UNIFORM_RANDOM, SubspaceCluster.TAGS_CLUSTERTYPE));
266    else if (typeCount > 1)
267      throw new Exception("Only one cluster type can be specified!");
268
269    setAttrIndexRange(fromToStr);
270   
271    tmpStr = Utils.getOption('D', options);
272    if (isGaussian()) {
273      if (tmpStr.length() != 0)
274        setMeanStddev(tmpStr);
275      else
276        setMeanStddev(defaultMeanStddev());
277    }
278    else {
279      if (tmpStr.length() != 0)
280        setValuesList(tmpStr);
281      else
282        setValuesList(defaultValuesList());
283    }
284
285    tmpStr = Utils.getOption('N', options);
286    if (tmpStr.length() != 0)
287      setInstNums(tmpStr);
288    else
289      setInstNums(defaultMinInstNum() + ".." + defaultMaxInstNum());
290
291    if (Utils.getFlag('I', options))
292      setClusterSubType(
293          new SelectedTag(
294            SubspaceCluster.INTEGER, SubspaceCluster.TAGS_CLUSTERSUBTYPE));
295    else
296      setClusterSubType(
297          new SelectedTag(
298            SubspaceCluster.CONTINUOUS, SubspaceCluster.TAGS_CLUSTERSUBTYPE));
299  }
300
301  /**
302   * Gets the current settings of the datagenerator BIRCHCluster.
303   *
304   * @return an array of strings suitable for passing to setOptions
305   */
306  public String[] getOptions() {
307    Vector        result;
308
309    result  = new Vector();
310
311    if (isRandom()) {
312      result.add("-A");
313      result.add("" + getAttrIndexRange());
314      result.add("-D");
315      result.add("" + getValuesList());
316    }
317    else if (isUniform()) {
318      result.add("-U");
319      result.add("" + getAttrIndexRange());
320      result.add("-D");
321      result.add("" + getValuesList());
322    }
323    else if (isGaussian()) {
324      result.add("-G");
325      result.add("" + getAttrIndexRange());
326      result.add("-D");
327      result.add("" + getMeanStddev());
328    }
329
330    result.add("-N"); 
331    result.add("" + getInstNums());
332
333    if (m_clustersubtype == SubspaceCluster.INTEGER)
334      result.add("-I");
335
336    return (String[]) result.toArray(new String[result.size()]);
337  }
338
339  /**
340   * Make a string from the attribues list.
341   *
342   * @return the attributes as string
343   */
344  public String attributesToString() {
345    StringBuffer text = new StringBuffer();
346    int j = 0;
347    for (int i = 0; i < m_attributes.length; i++) {
348      if (m_attributes[i]) {
349        if (isGaussian()) {
350          text.append(" Attribute: " + i);
351          text.append(" Mean: "+ m_meanValue[j]);
352          text.append(" StdDev: "+m_stddevValue[j]+"\n%");
353        } 
354        else {
355          text.append(" Attribute: " + i);
356          text.append(" Range: "+ m_minValue[j]);
357          text.append(" - "+m_maxValue[j]+"\n%");
358        }
359        j++;
360      }
361    }
362    return text.toString();
363  }
364
365  /**
366   * Make a string from the cluster features.
367   *
368   * @return the cluster features as string
369   */
370  public String toString() {
371    StringBuffer text = new StringBuffer();
372    text.append("attributes " + attributesToString() + "\n");
373    text.append("number of instances " + getInstNums()); 
374    return text.toString();
375  }
376
377  /**
378   * sets the parent datagenerator this cluster belongs to
379   * @param parent      the parent datagenerator
380   */
381  public void setParent(SubspaceCluster parent) {
382    super.setParent(parent);
383    m_AttrIndexRange.setUpper(getParent().getNumAttributes());
384  }
385
386  /**
387   * returns the default attribute index range
388   *
389   * @return the default attribute index range
390   */
391  protected String defaultAttrIndexRange() {
392    return "1";
393  }
394
395  /**
396   * Sets which attributes are used in the cluster
397   * attributes among the selection will be discretized.
398   *
399   * @param rangeList a string representing the list of attributes. Since
400   * the string will typically come from a user, attributes are indexed from
401   * 1. <br/>
402   * eg: first-3,5,6-last
403   */
404  public void setAttrIndexRange(String rangeList) {
405    m_numClusterAttributes = 0; 
406    if (m_AttrIndexRange == null)
407      m_AttrIndexRange = new Range();
408    m_AttrIndexRange.setRanges(rangeList);
409
410    if (getParent() != null) {
411      m_AttrIndexRange.setUpper(getParent().getNumAttributes());
412      m_attributes = new boolean [getParent().getNumAttributes()];
413      for (int i = 0; i < m_attributes.length; i++) {
414        if (m_AttrIndexRange.isInRange(i)) {
415          m_numClusterAttributes++;
416          m_attributes[i] = true; 
417        } 
418        else {
419          m_attributes[i] = false; 
420        }
421      }
422
423      //store translation from attr in cluster to attr in whole dataset
424      m_attrIndices = new int[m_numClusterAttributes];
425      int clusterI = -1;
426      for (int i = 0; i < m_attributes.length; i++) {
427        if (m_AttrIndexRange.isInRange(i)) {
428          clusterI++;
429          m_attrIndices[clusterI] = i;
430        }
431      }
432    }
433  }
434
435  /**
436   * returns the attribute range(s).
437   *
438   * @return the attribute range(s).
439   */
440  public String getAttrIndexRange() {
441    return m_AttrIndexRange.getRanges();
442  }
443 
444  /**
445   * Returns the tip text for this property
446   * @return tip text for this property suitable for
447   * displaying in the explorer/experimenter gui
448   */
449  public String attrIndexRangeTipText() {
450    return "The attribute range(s).";
451  }
452
453  public boolean[] getAttributes() {
454    return m_attributes;
455  }
456
457  public double[] getMinValue() {
458    return m_minValue;
459  }
460
461  public double[] getMaxValue() {
462    return m_maxValue;
463  }
464
465  public double[] getMeanValue() {
466    return m_meanValue;
467  }
468
469  public double[] getStddevValue() {
470    return m_stddevValue;
471  }
472
473  public int getNumInstances () { 
474    return m_numInstances; 
475  }
476
477  /**
478   * returns the default cluster type
479   *
480   * @return the default cluster type
481   */
482  protected SelectedTag defaultClusterType() {
483    return new SelectedTag(
484        SubspaceCluster.UNIFORM_RANDOM, SubspaceCluster.TAGS_CLUSTERTYPE);
485  }
486 
487  /**
488   * Gets the cluster type.
489   *
490   * @return the cluster type
491   * @see SubspaceCluster#TAGS_CLUSTERTYPE
492   */
493  public SelectedTag getClusterType() {
494    return new SelectedTag(m_clustertype, SubspaceCluster.TAGS_CLUSTERTYPE);
495  }
496 
497  /**
498   * Sets the cluster type.
499   *
500   * @param value the new cluster type.
501   * @see SubspaceCluster#TAGS_CLUSTERTYPE
502   */
503  public void setClusterType(SelectedTag value) {
504    if (value.getTags() == SubspaceCluster.TAGS_CLUSTERTYPE)
505      m_clustertype = value.getSelectedTag().getID();
506  }
507 
508  /**
509   * Returns the tip text for this property
510   * @return tip text for this property suitable for
511   * displaying in the explorer/experimenter gui
512   */
513  public String clusterTypeTipText() {
514    return "The type of cluster to use.";
515  }
516
517  /**
518   * returns the default cluster sub type
519   *
520   * @return the default cluster sub type
521   */
522  protected SelectedTag defaultClusterSubType() {
523    return new SelectedTag(
524        SubspaceCluster.CONTINUOUS, SubspaceCluster.TAGS_CLUSTERSUBTYPE);
525  }
526 
527  /**
528   * Gets the cluster sub type.
529   *
530   * @return the cluster sub type
531   * @see SubspaceCluster#TAGS_CLUSTERSUBTYPE
532   */
533  public SelectedTag getClusterSubType() {
534    return new SelectedTag(
535                  m_clustersubtype, SubspaceCluster.TAGS_CLUSTERSUBTYPE);
536  }
537 
538  /**
539   * Sets the cluster sub type.
540   *
541   * @param value the new cluster sub type.
542   * @see SubspaceCluster#TAGS_CLUSTERSUBTYPE
543   */
544  public void setClusterSubType(SelectedTag value) {
545    if (value.getTags() == SubspaceCluster.TAGS_CLUSTERSUBTYPE)
546      m_clustersubtype = value.getSelectedTag().getID();
547  }
548 
549  /**
550   * Returns the tip text for this property
551   * @return tip text for this property suitable for
552   * displaying in the explorer/experimenter gui
553   */
554  public String clusterSubTypeTipText() {
555    return "The sub-type of cluster to use.";
556  }
557
558  /**
559   * checks, whether cluster type is random
560   *
561   * @return true if cluster type is random
562   */
563  public boolean isRandom() {
564    return (m_clustertype == SubspaceCluster.UNIFORM_RANDOM);
565  }
566
567  /**
568   * checks, whether cluster type is uniform
569   *
570   * @return true if cluster type is uniform
571   */
572  public boolean isUniform() {
573    return (m_clustertype == SubspaceCluster.TOTAL_UNIFORM);
574  }
575
576  /**
577   * checks, whether cluster type is gaussian
578   *
579   * @return true if cluster type is gaussian
580   */
581  public boolean isGaussian() {
582    return (m_clustertype == SubspaceCluster.GAUSSIAN);
583  }
584
585  /**
586   * checks, whether cluster sub type is continuous
587   *
588   * @return true if cluster sub type is continuous
589   */
590  public boolean isContinuous() {
591    return (m_clustertype == SubspaceCluster.CONTINUOUS);
592  }
593
594  /**
595   * checks, whether cluster sub type is integer
596   *
597   * @return true if cluster sub type is integer
598   */
599  public boolean isInteger() {
600    return (m_clustertype == SubspaceCluster.INTEGER);
601  }
602
603  /**
604   * Sets the upper and lower boundary for instances for this cluster.
605   *
606   * @param fromTo  the string containing the upper and lower boundary for
607   *                instances per cluster separated by ..
608   */
609  protected void setInstNums(String fromTo) {
610    int i = fromTo.indexOf("..");
611    if (i == -1) 
612      i = fromTo.length();
613    String from = fromTo.substring(0, i);
614    m_MinInstNum = Integer.parseInt(from);
615    if (i < fromTo.length()) {
616      String to = fromTo.substring(i + 2, fromTo.length());
617      m_MaxInstNum = Integer.parseInt(to);
618    } 
619    else {
620      m_MaxInstNum = m_MinInstNum;
621    }
622  }
623
624  /**
625   * Get a string with the  upper and lower boundary for the
626   * number of instances for this cluster.
627   *
628   * @return the string containing the upper and lower boundary for
629   * instances per cluster separated by ..
630   */
631  protected String getInstNums() {
632    String text = new String(""+m_MinInstNum+".."+m_MaxInstNum);
633    return text;
634  }
635 
636  /**
637   * Returns the tip text for this property
638   * @return tip text for this property suitable for
639   * displaying in the explorer/experimenter gui
640   */
641  protected String instNumsTipText() {
642    return "The lower and upper boundary for the number of instances in this cluster.";
643  }
644
645  /**
646   * returns the default min number of instances
647   *
648   * @return the default min number of instances
649   */
650  protected int defaultMinInstNum() {
651    return 1;
652  }
653
654  /**
655   * Gets the lower boundary for instances per cluster.
656   *
657   * @return the the lower boundary for instances per cluster
658   */
659  public int getMinInstNum() { 
660    return m_MinInstNum; 
661  }
662 
663  /**
664   * Sets the lower boundary for instances per cluster.
665   *
666   * @param newMinInstNum new lower boundary for instances per cluster
667   */
668  public void setMinInstNum(int newMinInstNum) {
669    m_MinInstNum = newMinInstNum;
670  }
671 
672  /**
673   * Returns the tip text for this property
674   *
675   * @return tip text for this property suitable for
676   *         displaying in the explorer/experimenter gui
677   */
678  public String minInstNumTipText() {
679    return "The lower boundary for instances per cluster.";
680  }
681
682  /**
683   * returns the default max number of instances
684   *
685   * @return the default max number of instances
686   */
687  protected int defaultMaxInstNum() {
688    return 50;
689  }
690
691  /**
692   * Gets the upper boundary for instances per cluster.
693   *
694   * @return the upper boundary for instances per cluster
695   */
696  public int getMaxInstNum() { 
697    return m_MaxInstNum; 
698  }
699 
700  /**
701   * Sets the upper boundary for instances per cluster.
702   *
703   * @param newMaxInstNum new upper boundary for instances per cluster
704   */
705  public void setMaxInstNum(int newMaxInstNum) {
706    m_MaxInstNum = newMaxInstNum;
707  }
708 
709  /**
710   * Returns the tip text for this property
711   *
712   * @return tip text for this property suitable for
713   *         displaying in the explorer/experimenter gui
714   */
715  public String maxInstNumTipText() {
716    return "The upper boundary for instances per cluster.";
717  }
718
719  /**
720   * Sets the real number of instances for this cluster.
721   *
722   * @param r random number generator
723   */
724  public void setNumInstances(Random r) {
725    if (m_MaxInstNum > m_MinInstNum)
726      m_numInstances = (int)(r.nextDouble() 
727                       * (m_MaxInstNum - m_MinInstNum) + m_MinInstNum);
728    else
729      m_numInstances =  m_MinInstNum;
730  }
731
732  /**
733   * returns the default values list
734   *
735   * @return the default values list
736   */
737  protected String defaultValuesList() {
738    return "1,10";
739  }
740
741  /**
742   * Sets the ranges for each attribute.
743   *
744   * @param fromToList the string containing the upper and lower boundary for
745   * instances per cluster separated by ..
746   * @throws Exception if values are not correct in number or value
747   */
748  public void setValuesList(String fromToList) throws Exception {
749    m_minValue = new double [m_numClusterAttributes];
750    m_maxValue = new double [m_numClusterAttributes];
751    setValuesList(fromToList, m_minValue, m_maxValue, "D");
752    SubspaceCluster parent = (SubspaceCluster) getParent();
753
754    for (int i = 0; i < m_numClusterAttributes; i++) {
755      if (m_minValue[i] > m_maxValue[i])
756        throw new Exception("Min must be smaller than max.");
757
758      if (getParent() != null) {
759        // boolean values are only 0.0 and 1.0
760        if (parent.isBoolean(m_attrIndices[i])) {
761          parent.getNumValues()[m_attrIndices[i]] = 2;
762          if (((m_minValue[i] != 0.0) && (m_minValue[i] != 1.0)) ||
763              ((m_maxValue[i] != 0.0) && (m_maxValue[i] != 1.0)))
764            throw new Exception("Ranges for boolean must be 0 or 1 only.");
765        }
766
767        if (parent.isNominal(m_attrIndices[i])) {
768          // nominal values: attributes range might have to be enlarged
769          double rest = m_minValue[i] - Math.rint(m_minValue[i]);
770          if (rest != 0.0) 
771            throw new Exception(" Ranges for nominal must be integer"); 
772          rest = m_maxValue[i] - Math.rint(m_maxValue[i]);
773          if (rest != 0.0) 
774            throw new Exception("Ranges for nominal must be integer"); 
775          if (m_minValue[i] < 0.0) 
776            throw new Exception("Range for nominal must start with number 0.0 or higher");
777          if (m_maxValue[i] + 1 > parent.getNumValues()[m_attrIndices[i]]) {
778            // add new values to attribute
779            // (actual format is not yet defined)
780            parent.getNumValues()[m_attrIndices[i]] = (int)m_maxValue[i] + 1;
781          }
782        }
783      }
784    }
785  }
786
787  /**
788   * returns the range for each attribute as string
789   */
790  public String getValuesList() {
791    String        result;
792    int           i;
793
794    result = "";
795
796    if (m_minValue != null) {
797      for (i = 0; i < m_minValue.length; i++) {
798        if (i > 0)
799          result += ",";
800        result += "" + m_minValue[i] + "," + m_maxValue[i];
801      }
802    }
803
804    return result;
805  }
806 
807  /**
808   * Returns the tip text for this property
809   * @return tip text for this property suitable for
810   * displaying in the explorer/experimenter gui
811   */
812  public String valuesListTipText() {
813    return "The range for each each attribute as string.";
814  }
815
816  /**
817   * returns the default mean/stddev list
818   */
819  protected String defaultMeanStddev() {
820    return "0,1.0";
821  }
822
823  /**
824   * Sets mean and standarddeviation.
825   *
826   * @param meanstddev the string containing the upper and lower boundary for
827   * instances per cluster separated by ..
828   * @throws Exception if values are not correct in number or value
829   */
830  public void setMeanStddev(String meanstddev) throws Exception {
831    m_meanValue   = new double [m_numClusterAttributes];
832    m_stddevValue = new double [m_numClusterAttributes];
833    setValuesList(meanstddev, m_meanValue, m_stddevValue, "D");
834  }
835
836  /**
837   * returns the current mean/stddev setup
838   */
839  public String getMeanStddev() {
840    String        result;
841    int           i;
842
843    result = "";
844
845    if (m_meanValue != null) {
846      for (i = 0; i < m_meanValue.length; i++) {
847        if (i > 0)
848          result += ",";
849        result += "" + m_meanValue[i] + "," + m_stddevValue[i];
850      }
851    }
852
853    return result;
854  }
855 
856  /**
857   * Returns the tip text for this property
858   * @return tip text for this property suitable for
859   * displaying in the explorer/experimenter gui
860   */
861  public String meanStddevTipText() {
862    return "The mean and stddev, in case of gaussian.";
863  }
864
865  /**
866   * Sets the ranges for each attribute.
867   *
868   * @param fromToList the string containing the upper and lower boundary for
869   * instances per cluster separated by ..
870   * @param first the "from's"
871   * @param second the "to's"
872   * @param optionLetter the option, from which the list came
873   * @throws Exception if values are not correct in number or value
874   */
875  public void setValuesList(String fromToList, double[] first, double[] second, 
876      String optionLetter) throws Exception {
877
878    StringTokenizer     tok;
879    int                 index;
880   
881    tok = new StringTokenizer(fromToList, ",");
882    if (tok.countTokens() != first.length + second.length)
883      throw new Exception(
884          "Wrong number of values for option '-" + optionLetter + "'.");
885
886    index = 0;
887    while (tok.hasMoreTokens()) {
888      first[index]  = Double.parseDouble(tok.nextToken());
889      second[index] = Double.parseDouble(tok.nextToken());
890      index++;
891    }
892  }
893 
894  /**
895   * Returns the revision string.
896   *
897   * @return            the revision
898   */
899  public String getRevision() {
900    return RevisionUtils.extract("$Revision: 1.5 $");
901  }
902}
Note: See TracBrowser for help on using the repository browser.