Float64Gene.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-1.5.0).
003  * Copyright (c) 2007-2013 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
019  */
020 package org.jenetics;
021 
022 import java.io.IOException;
023 import java.io.ObjectInputStream;
024 import java.io.ObjectOutputStream;
025 import java.util.Random;
026 
027 import javolution.context.ObjectFactory;
028 import javolution.xml.XMLFormat;
029 import javolution.xml.stream.XMLStreamException;
030 
031 import org.jscience.mathematics.number.Float64;
032 import org.jscience.mathematics.structure.GroupMultiplicative;
033 
034 import org.jenetics.util.Function;
035 import org.jenetics.util.RandomRegistry;
036 import org.jenetics.util.math;
037 
038 /**
039  * Implementation of the NumberGene which holds a 64 bit floating point number.
040  *
041  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
042  @since 1.0
043  @version 1.2 &mdash; <em>$Date: 2013-08-30 $</em>
044  */
045 public final class Float64Gene
046     extends NumberGene<Float64, Float64Gene>
047     implements GroupMultiplicative<Float64Gene>
048 {
049     private static final long serialVersionUID = 1L;
050 
051     Float64Gene() {
052     }
053 
054     @Override
055     protected Float64 box(final java.lang.Number value) {
056         return Float64.valueOf(value.doubleValue());
057     }
058 
059     public Float64Gene divide(final Float64Gene gene) {
060         return newInstance(_value.divide(gene._value));
061     }
062 
063     @Override
064     public Float64Gene inverse() {
065         return newInstance(_value.inverse());
066     }
067 
068     @Override
069     public Float64Gene mean(final Float64Gene that) {
070         return newInstance(
071             _value.doubleValue()  +
072             (that._value.doubleValue() - _value.doubleValue())/2.0
073         );
074     }
075 
076 
077     /* *************************************************************************
078      *  Property access methods
079      * ************************************************************************/
080 
081     /**
082      * Converter for accessing the value from a given number gene.
083      */
084     public static final Function<Float64Gene, Float64> Allele =
085         new Function<Float64Gene, Float64>() {
086             @Override public Float64 apply(final Float64Gene value) {
087                 return value._value;
088             }
089         };
090 
091     /**
092      * Converter for accessing the allele from a given number gene.
093      */
094     public static final Function<Float64Gene, Float64> Value = Allele;
095 
096     /**
097      * Converter for accessing the allowed minimum from a given number gene.
098      */
099     public static final Function<Float64Gene, Float64> Min =
100         new Function<Float64Gene, Float64>() {
101             @Override public Float64 apply(final Float64Gene value) {
102                 return value._min;
103             }
104         };
105 
106     /**
107      * Converter for accessing the allowed minimum from a given number gene.
108      */
109     public static final Function<Float64Gene, Float64> Max =
110         new Function<Float64Gene, Float64>() {
111             @Override public Float64 apply(final Float64Gene value) {
112                 return value._max;
113             }
114         };
115 
116     /* *************************************************************************
117      *  Factory methods
118      * ************************************************************************/
119 
120     /**
121      * Create a new valid, <em>random</em> gene.
122      */
123     @Override
124     public Float64Gene newInstance() {
125         return valueOf(_min, _max);
126     }
127 
128     /**
129      * Create a new Float64Gene with the same limits and the given value.
130      *
131      @param value the value of the new {@code NumberGene}.
132      @return the new {@code NumberGene}.
133      */
134     public Float64Gene newInstance(final double value) {
135         return valueOf(Float64.valueOf(value), _min, _max);
136     }
137 
138     @Override
139     public Float64Gene newInstance(final Float64 value) {
140         return valueOf(value, _min, _max);
141     }
142 
143 
144     /* *************************************************************************
145      *  Static object creation methods
146      * ************************************************************************/
147 
148     private static final ObjectFactory<Float64Gene> FACTORY =
149         new ObjectFactory<Float64Gene>() {
150             @Override protected Float64Gene create() {
151                 return new Float64Gene();
152             }
153         };
154 
155     /**
156      * Create a new random {@code Float64Gene} with the given value and the
157      * given range. If the {@code value} isn't within the interval [min, max),
158      * no exception is thrown. In this case the method
159      {@link Float64Gene#isValid()} returns {@code false}.
160      *
161      @param value the value of the gene.
162      @param min the minimal valid value of this gene (inclusively).
163      @param max the maximal valid value of this gene (exclusively).
164      @return the new created gene with the given {@code value}.
165      */
166     public static Float64Gene valueOf(
167         final double value,
168         final double min,
169         final double max
170     ) {
171         return valueOf(
172             Float64.valueOf(value),
173             Float64.valueOf(min),
174             Float64.valueOf(max)
175         );
176     }
177 
178     /**
179      * Create a new random {@code Float64Gene} with the given value and the
180      * given range. If the {@code value} isn't within the interval [min, max),
181      * no exception is thrown. In this case the method
182      {@link Float64Gene#isValid()} returns {@code false}.
183      *
184      @param value the value of the gene.
185      @param min the minimal valid value of this gene (inclusively).
186      @param max the maximal valid value of this gene (exclusively).
187      @return the new created gene with the given {@code value}.
188      @throws NullPointerException if one of the arguments is {@code null}.
189      */
190     public static Float64Gene valueOf(
191         final Float64 value,
192         final Float64 min,
193         final Float64 max
194     ) {
195         final Float64Gene gene = FACTORY.object();
196         gene.set(value, min, max);
197         return gene;
198     }
199 
200     /**
201      * Create a new random {@code Float64Gene}. It is guaranteed that the value
202      * of the {@code Float64Gene} lies in the interval [min, max).
203      *
204      @param min the minimal valid value of this gene (inclusively).
205      @param max the maximal valid value of this gene (exclusively).
206      @return the new created gene.
207      */
208     public static Float64Gene valueOf(final double min, final double max) {
209         return valueOf(Float64.valueOf(min), Float64.valueOf(max));
210     }
211 
212     /**
213      * Create a new random {@code Float64Gene}. It is guaranteed that the value
214      * of the {@code Float64Gene} lies in the interval [min, max).
215      *
216      @param min the minimal valid value of this gene (inclusively).
217      @param max the maximal valid value of this gene (exclusively).
218      @return the new created gene.
219      @throws NullPointerException if one of the arguments is {@code null}.
220      */
221     public static Float64Gene valueOf(
222         final Float64 min,
223         final Float64 max
224     ) {
225         final Random random = RandomRegistry.getRandom();
226         final Float64 value = Float64.valueOf(
227             math.random.nextDouble(random, min.doubleValue(), max.doubleValue())
228         );
229 
230         return valueOf(value, min, max);
231     }
232 
233 
234     /* *************************************************************************
235      *  XML object serialization
236      * ************************************************************************/
237 
238     static final XMLFormat<Float64Gene>
239     XML = new XMLFormat<Float64Gene>(Float64Gene.class)
240     {
241         private static final String MIN = "min";
242         private static final String MAX = "max";
243 
244         @Override
245         public Float64Gene newInstance(
246             final Class<Float64Gene> cls, final InputElement element
247         )
248             throws XMLStreamException
249         {
250             final double min = element.getAttribute(MIN, 0.0);
251             final double max = element.getAttribute(MAX, 1.0);
252             final double value = element.<Double>getNext();
253             return Float64Gene.valueOf(value, min, max);
254         }
255         @Override
256         public void write(final Float64Gene gene, final OutputElement element)
257             throws XMLStreamException
258         {
259             element.setAttribute(MIN, gene.getMin().doubleValue());
260             element.setAttribute(MAX, gene.getMax().doubleValue());
261             element.add(gene.getAllele().doubleValue());
262         }
263         @Override
264         public void read(final InputElement element, final Float64Gene gene) {
265         }
266     };
267 
268     /* *************************************************************************
269      *  Java object serialization
270      * ************************************************************************/
271 
272     private void writeObject(final ObjectOutputStream out)
273         throws IOException
274     {
275         out.defaultWriteObject();
276 
277         out.writeDouble(_value.doubleValue());
278         out.writeDouble(_min.doubleValue());
279         out.writeDouble(_max.doubleValue());
280     }
281 
282     private void readObject(final ObjectInputStream in)
283         throws IOException, ClassNotFoundException
284     {
285         in.defaultReadObject();
286 
287         set(
288             Float64.valueOf(in.readDouble()),
289             Float64.valueOf(in.readDouble()),
290             Float64.valueOf(in.readDouble())
291         );
292     }
293 
294 }
295 
296 
297