source: tags/MetisMQIDemo/src/main/java/weka/datagenerators/classifiers/regression/Expression.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: 11.6 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 * Expression.java
19 * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.datagenerators.classifiers.regression;
24
25import weka.core.Attribute;
26import weka.core.FastVector;
27import weka.core.Instance;
28import weka.core.DenseInstance;
29import weka.core.Instances;
30import weka.core.Option;
31import weka.core.RevisionUtils;
32import weka.core.Utils;
33import weka.filters.unsupervised.attribute.AddExpression;
34
35import java.util.Enumeration;
36import java.util.Random;
37import java.util.Vector;
38
39/**
40 <!-- globalinfo-start -->
41 * A data generator for generating y according to a given expression out of randomly generated x.<br/>
42 * E.g., the mexican hat can be generated like this:<br/>
43 *    sin(abs(a1)) / abs(a1)<br/>
44 * In addition to this function, the amplitude can be changed and gaussian noise can be added.
45 * <p/>
46 <!-- globalinfo-end -->
47 *
48 <!-- options-start -->
49 * Valid options are: <p/>
50 *
51 * <pre> -h
52 *  Prints this help.</pre>
53 *
54 * <pre> -o &lt;file&gt;
55 *  The name of the output file, otherwise the generated data is
56 *  printed to stdout.</pre>
57 *
58 * <pre> -r &lt;name&gt;
59 *  The name of the relation.</pre>
60 *
61 * <pre> -d
62 *  Whether to print debug informations.</pre>
63 *
64 * <pre> -S
65 *  The seed for random function (default 1)</pre>
66 *
67 * <pre> -n &lt;num&gt;
68 *  The number of examples to generate (default 100)</pre>
69 *
70 * <pre> -A &lt;num&gt;
71 *  The amplitude multiplier (default 1.0).</pre>
72 *
73 * <pre> -R &lt;num&gt;..&lt;num&gt;
74 *  The range x is randomly drawn from (default -10.0..10.0).</pre>
75 *
76 * <pre> -N &lt;num&gt;
77 *  The noise rate (default 0.0).</pre>
78 *
79 * <pre> -V &lt;num&gt;
80 *  The noise variance (default 1.0).</pre>
81 *
82 * <pre> -E &lt;expression&gt;
83 *  The expression to use for generating y out of x
84 *  (default sin(abs(a1)) / abs(a1)).</pre>
85 *
86 <!-- options-end -->
87 *
88 * @author  FracPete (fracpete at waikato dot ac dot nz)
89 * @version $Revision: 5987 $
90 * @see     AddExpression
91 * @see     MexicanHat
92 */
93
94public class Expression
95  extends MexicanHat {
96
97  /** for serialization */
98  static final long serialVersionUID = -4237047357682277211L; 
99 
100  /** the expression for computing y */
101  protected String m_Expression;
102
103  /** the filter for generating y out of x */
104  protected AddExpression m_Filter;
105
106  /** the input data structure for the filter */
107  protected Instances m_RawData;
108 
109  /**
110   * initializes the generator
111   */
112  public Expression() {
113    super();
114
115    setExpression(defaultExpression());
116  }
117 
118  /**
119   * Returns a string describing this data generator.
120   *
121   * @return a description of the data generator suitable for
122   * displaying in the explorer/experimenter gui
123   */
124  public String globalInfo() {
125    return 
126        "A data generator for generating y according to a given expression "
127        + "out of randomly generated x.\n"
128        + "E.g., the mexican hat can be generated like this:\n"
129        + "   sin(abs(a1)) / abs(a1)\n"
130        + "In addition to this function, the amplitude can be changed and "
131        + "gaussian noise can be added.";
132  }
133
134  /**
135   * Returns an enumeration describing the available options.
136   *
137   * @return an enumeration of all the available options
138   */
139  public Enumeration listOptions() {
140    Vector result = enumToVector(super.listOptions());
141
142    result.addElement(new Option(
143              "\tThe expression to use for generating y out of x \n"
144              + "\t(default " + defaultExpression() + ").",
145              "E", 1, "-E <expression>"));
146
147    return result.elements();
148  }
149 
150  /**
151   * Parses a list of options for this object. <p/>
152   *
153   <!-- options-start -->
154   * Valid options are: <p/>
155   *
156   * <pre> -h
157   *  Prints this help.</pre>
158   *
159   * <pre> -o &lt;file&gt;
160   *  The name of the output file, otherwise the generated data is
161   *  printed to stdout.</pre>
162   *
163   * <pre> -r &lt;name&gt;
164   *  The name of the relation.</pre>
165   *
166   * <pre> -d
167   *  Whether to print debug informations.</pre>
168   *
169   * <pre> -S
170   *  The seed for random function (default 1)</pre>
171   *
172   * <pre> -n &lt;num&gt;
173   *  The number of examples to generate (default 100)</pre>
174   *
175   * <pre> -A &lt;num&gt;
176   *  The amplitude multiplier (default 1.0).</pre>
177   *
178   * <pre> -R &lt;num&gt;..&lt;num&gt;
179   *  The range x is randomly drawn from (default -10.0..10.0).</pre>
180   *
181   * <pre> -N &lt;num&gt;
182   *  The noise rate (default 0.0).</pre>
183   *
184   * <pre> -V &lt;num&gt;
185   *  The noise variance (default 1.0).</pre>
186   *
187   * <pre> -E &lt;expression&gt;
188   *  The expression to use for generating y out of x
189   *  (default sin(abs(a1)) / abs(a1)).</pre>
190   *
191   <!-- options-end -->
192   *
193   * @param options the list of options as an array of strings
194   * @exception Exception if an option is not supported
195   */
196  public void setOptions(String[] options) throws Exception {
197    String        tmpStr;
198   
199    super.setOptions(options);
200
201    tmpStr = Utils.getOption('E', options);
202    if (tmpStr.length() != 0)
203      setExpression(tmpStr);
204    else
205      setExpression(defaultExpression());
206  }
207
208  /**
209   * Gets the current settings of the datagenerator BIRCHCluster.
210   *
211   * @return an array of strings suitable for passing to setOptions
212   */
213  public String[] getOptions() {
214    Vector        result;
215    String[]      options;
216    int           i;
217   
218    result  = new Vector();
219    options = super.getOptions();
220    for (i = 0; i < options.length; i++)
221      result.add(options[i]);
222   
223    result.add("-E"); 
224    result.add("" + getExpression());
225   
226    return (String[]) result.toArray(new String[result.size()]);
227  }
228 
229  /**
230   * Returns the tip text for this property
231   *
232   * @return tip text for this property suitable for
233   *         displaying in the explorer/experimenter gui
234   */
235  public String amplitudeTipText() {
236    return "The amplitude to multiply the y value with.";
237  }
238
239  /**
240   * returns the default expression
241   *
242   * @return the default expression
243   */
244  protected String defaultExpression() {
245    return "sin(abs(a1)) / abs(a1)";
246  }
247
248  /**
249   * Gets the mathematical expression for generating y out of x
250   *
251   * @return the expression for computing y
252   */
253  public String getExpression() { 
254    return m_Expression; 
255  }
256 
257  /**
258   * Sets the mathematical expression to generate y out of x.
259   *
260   * @param value the expression for computing y
261   */
262  public void setExpression(String value) {
263    if (value.length() != 0)
264      m_Expression = value;
265    else
266      throw new IllegalArgumentException(
267          "An expression has to be provided!");
268  }
269 
270  /**
271   * Returns the tip text for this property
272   *
273   * @return tip text for this property suitable for
274   *         displaying in the explorer/experimenter gui
275   */
276  public String expressionTipText() {
277    return "The expression for generating y out of x.";
278  }
279
280  /**
281   * Return if single mode is set for the given data generator
282   * mode depends on option setting and or generator type.
283   *
284   * @return single mode flag
285   * @throws Exception if mode is not set yet
286   */
287  public boolean getSingleModeFlag() throws Exception {
288    return true;
289  }
290
291  /**
292   * Initializes the format for the dataset produced.
293   * Must be called before the generateExample or generateExamples
294   * methods are used.
295   * Re-initializes the random number generator with the given seed.
296   *
297   * @return the format for the dataset
298   * @throws Exception if the generating of the format failed
299   * @see  #getSeed()
300   */
301  public Instances defineDataFormat() throws Exception {
302    FastVector      atts;
303
304    // initialize input format
305    atts = new FastVector();
306    atts.addElement(new Attribute("x"));
307   
308    m_RawData = new Instances(getRelationNameToUse(), atts, 0);
309
310    m_Filter = new AddExpression();
311    m_Filter.setName("y");
312    m_Filter.setExpression(getExpression());
313    m_Filter.setInputFormat(m_RawData);
314
315    return super.defineDataFormat();
316  }
317
318  /**
319   * Generates one example of the dataset.
320   *
321   * @return the generated example
322   * @throws Exception if the format of the dataset is not yet defined
323   * @throws Exception if the generator only works with generateExamples
324   * which means in non single mode
325   */
326  public Instance generateExample() throws Exception {
327    Instance    result;
328    Random      rand;
329    double      x;
330    double      y;
331    double[]    atts;
332    Instance    inst;
333
334    result = null;
335    rand   = getRandom();
336
337    if (m_DatasetFormat == null)
338      throw new Exception("Dataset format not defined.");
339
340    // random x
341    x = rand.nextDouble();
342    // fit into range
343    x = x * (getMaxRange() - getMinRange()) + getMinRange();
344   
345    // generate y
346    atts    = new double[1];
347    atts[0] = x;
348    inst    = new DenseInstance(1.0, atts);
349    m_Filter.input(inst);
350    m_Filter.batchFinished();
351    inst = m_Filter.output();
352   
353    // noise
354    y = inst.value(1) + getAmplitude() 
355            * m_NoiseRandom.nextGaussian() 
356            * getNoiseRate() * getNoiseVariance();
357
358    // generate attributes
359    atts = new double[m_DatasetFormat.numAttributes()];
360   
361    atts[0] = x;
362    atts[1] = y;
363    result = new DenseInstance(1.0, atts);
364
365    // dataset reference
366    result.setDataset(m_DatasetFormat);
367   
368    return result;
369  }
370
371  /**
372   * Generates all examples of the dataset. Re-initializes the random number
373   * generator with the given seed, before generating instances.
374   *
375   * @return the generated dataset
376   * @throws Exception if the format of the dataset is not yet defined
377   * @throws Exception if the generator only works with generateExample,
378   * which means in single mode
379   * @see   #getSeed()
380   */
381  public Instances generateExamples() throws Exception {
382    Instances       result;
383    int             i;
384
385    result   = new Instances(m_DatasetFormat, 0);
386    m_Random = new Random(getSeed());
387
388    for (i = 0; i < getNumExamplesAct(); i++)
389      result.add(generateExample());
390   
391    return result;
392  }
393
394  /**
395   * Generates a comment string that documentates the data generator.
396   * By default this string is added at the beginning of the produced output
397   * as ARFF file type, next after the options.
398   *
399   * @return string contains info about the generated rules
400   */
401  public String generateStart () {
402    return "";
403  }
404
405  /**
406   * Generates a comment string that documentats the data generator.
407   * By default this string is added at the end of theproduces output
408   * as ARFF file type.
409   *
410   * @return string contains info about the generated rules
411   * @throws Exception if the generating of the documentaion fails
412   */
413  public String generateFinished() throws Exception {
414    return "";
415  }
416 
417  /**
418   * Returns the revision string.
419   *
420   * @return            the revision
421   */
422  public String getRevision() {
423    return RevisionUtils.extract("$Revision: 5987 $");
424  }
425
426  /**
427   * Main method for testing this class.
428   *
429   * @param args should contain arguments for the data producer:
430   */
431  public static void main(String[] args) {
432    runDataGenerator(new Expression(), args);
433  }
434}
435
Note: See TracBrowser for help on using the repository browser.