Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Random/3.3/NormalRandomAdder.cs @ 3402

Last change on this file since 3402 was 2524, checked in by swagner, 15 years ago

Removed plugin HeuristicLab.Constraints (#804)

File size: 6.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Random {
30  /// <summary>
31  /// Normally distributed random number generator that adds the generated value to the existing value
32  /// in the specified scope.
33  /// </summary>
34  [EmptyStorableClass]
35  public class NormalRandomAdder : OperatorBase {
36    private static int MAX_NUMBER_OF_TRIES = 100;
37
38    /// <inheritdoc select="summary"/>
39    public override string Description {
40      get {
41        return @"Samples a normally distributed (mu, sigma * shakingFactor) random variable and adds the result to variable 'Value'.
42       
43If a constraint for the allowed range of 'Value' is defined and the result of the operation would be smaller then
44the smallest allowed value then 'Value' is set to the lower bound and vice versa for the upper bound.";
45      }
46    }
47
48    /// <summary>
49    /// Gets or sets the value for µ.
50    /// </summary>
51    /// <remarks>Gets or sets the variable with the name <c>Mu</c> through the method
52    /// <see cref="OperatorBase.GetVariable"/> of class <see cref="OperatorBase"/>.</remarks>
53    public double Mu {
54      get { return ((DoubleData)GetVariable("Mu").Value).Data; }
55      set { ((DoubleData)GetVariable("Mu").Value).Data = value; }
56    }
57    /// <summary>
58    /// Gets or sets the value for sigma.
59    /// </summary>
60    /// <remarks>Gets or sets the variable with the name <c>Sigma</c> through the method
61    /// <see cref="OperatorBase.GetVariable"/> of class <see cref="OperatorBase"/>.</remarks>
62    public double Sigma {
63      get { return ((DoubleData)GetVariable("Sigma").Value).Data; }
64      set { ((DoubleData)GetVariable("Sigma").Value).Data = value; }
65    }
66
67    /// <summary>
68    /// Initializes a new instance of <see cref="NormalRandomAdder"/> with five variable infos
69    /// (<c>Mu</c>, <c>Sigma</c>, <c>Value</c>, <c>ShakingFactor</c> and <c>Random</c>).
70    /// </summary>
71    public NormalRandomAdder() {
72      AddVariableInfo(new VariableInfo("Mu", "Parameter mu of the normal distribution", typeof(DoubleData), VariableKind.None));
73      GetVariableInfo("Mu").Local = true;
74      AddVariable(new Variable("Mu", new DoubleData(0.0)));
75
76      AddVariableInfo(new VariableInfo("Sigma", "Parameter sigma of the normal distribution", typeof(DoubleData), VariableKind.None));
77      GetVariableInfo("Sigma").Local = true;
78      AddVariable(new Variable("Sigma", new DoubleData(1.0)));
79
80      AddVariableInfo(new VariableInfo("Value", "The value to manipulate (actual type is one of: IntData, DoubleData, ConstrainedIntData, ConstrainedDoubleData)", typeof(IObjectData), VariableKind.In));
81      AddVariableInfo(new VariableInfo("ShakingFactor", "Determines the force of the shaking factor (effective sigma = sigma * shakingFactor)", typeof(DoubleData), VariableKind.In));
82      AddVariableInfo(new VariableInfo("Random", "The random generator to use", typeof(MersenneTwister), VariableKind.In));
83    }
84
85    /// <summary>
86    /// Generates a new normally distributed random number and adds it to the specified value in the
87    /// given <paramref name="scope"/>.
88    /// </summary>
89    /// <param name="scope">The scope where to add the generated random number.</param>
90    /// <returns><c>null</c>.</returns>
91    public override IOperation Apply(IScope scope) {
92      IObjectData value = GetVariableValue<IObjectData>("Value", scope, false);
93      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
94      double factor = GetVariableValue<DoubleData>("ShakingFactor", scope, true).Data;
95      double mu = GetVariableValue<DoubleData>("Mu", scope, true).Data;
96      double sigma = GetVariableValue<DoubleData>("Sigma", scope, true).Data;
97      NormalDistributedRandom normal = new NormalDistributedRandom(mt, mu, sigma * factor);
98
99      AddNormal(value, normal);
100      return null;
101    }
102
103    private void AddNormal(IObjectData value, NormalDistributedRandom normal) {
104      // dispatch manually based on dynamic type
105      if (value is IntData)
106        AddNormal((IntData)value, normal);
107      else if (value is DoubleData)
108        AddNormal((DoubleData)value, normal);
109      else throw new InvalidOperationException("Can't handle type " + value.GetType().Name);
110    }
111    /// <summary>
112    /// Generates a new double random number and adds it to the value of
113    /// the given <paramref name="data"/>.
114    /// </summary>
115    /// <param name="data">The double object where to add the random number.</param>
116    /// <param name="normal">The continuous, normally distributed random variable.</param>
117    public void AddNormal(DoubleData data, NormalDistributedRandom normal) {
118      data.Data += normal.NextDouble();
119    }
120
121    /// <summary>
122    /// Generates a new int random number and adds it to value of the given <paramref name="data"/>.
123    /// </summary>
124    /// <param name="data">The int object where to add the random number.</param>
125    /// <param name="normal">The continuous, normally distributed random variable.</param>
126    public void AddNormal(IntData data, NormalDistributedRandom normal) {
127      data.Data = (int)Math.Round(data.Data + normal.NextDouble());
128    }
129  }
130}
Note: See TracBrowser for help on using the repository browser.