001 /*
002 * Java Genetic Algorithm Library (jenetics-3.7.0).
003 * Copyright (c) 2007-2016 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.tool.trial;
021
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024
025 import java.io.Serializable;
026 import java.util.Arrays;
027 import java.util.stream.DoubleStream;
028
029 import javax.xml.bind.annotation.XmlAccessType;
030 import javax.xml.bind.annotation.XmlAccessorType;
031 import javax.xml.bind.annotation.XmlList;
032 import javax.xml.bind.annotation.XmlRootElement;
033 import javax.xml.bind.annotation.XmlType;
034 import javax.xml.bind.annotation.adapters.XmlAdapter;
035 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
036
037 /**
038 * The sample class contains the results of one test run of all parameters. This
039 * class is <i>mutable</i> and <b>not</b> thread safe.
040 *
041 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
042 * @version 3.4
043 * @since 3.4
044 */
045 @XmlJavaTypeAdapter(Sample.Model.Adapter.class)
046 public final class Sample implements Serializable {
047
048 private static final long serialVersionUID = 1L;
049
050 private final double[] _values;
051
052 private Sample(final double[] values) {
053 _values = requireNonNull(values);
054 }
055
056 /**
057 * Return the number of {@code double} <i>slots</i> the {@code Sample} class
058 * stores.
059 *
060 * @return the number of {@code double} <i>slots</i>
061 */
062 public int size() {
063 return _values.length;
064 }
065
066 /**
067 * Insert the given value at the next free <i>slot</i> (position).
068 *
069 * @param value the value to insert
070 * @throws IndexOutOfBoundsException if all sample values has been set
071 * @throws IllegalArgumentException if the given value is not a number,
072 * {@code Double.isNaN(value)} returns {@code true}
073 */
074 void add(final double value) {
075 if (Double.isNaN(value)) {
076 throw new IllegalArgumentException();
077 }
078
079 _values[nextIndex()] = value;
080 }
081
082 /**
083 * Return the index of the next free {@code double} <i>slot</i>. If all
084 * <i>slots</i> are occupied, {@code -1} is returned.
085 *
086 * @return the index of the next free {@code double} <i>slot</i>, or
087 * {@code -1} if all <i>slots</i> are occupied
088 */
089 public int nextIndex() {
090 int index = -1;
091 for (int i = 0; i < _values.length && index == -1; ++i) {
092 if (Double.isNaN(_values[i])) {
093 index = i;
094 }
095 }
096
097 return index;
098 }
099
100 /**
101 * Test whether all sample <i>slots</i> are occupied.
102 *
103 * @return {@code true} if all sample <i>slots</i> are occupied,
104 * {@code false} otherwise
105 */
106 public boolean isFull() {
107 return nextIndex() == -1;
108 }
109
110 /**
111 * Return the sample {@code double} values (slots).
112 *
113 * @return the sample {@code double} values (slots).
114 */
115 public double[] values() {
116 return _values.clone();
117 }
118
119 /**
120 * Returns a sequential {@link DoubleStream} with the <i>slot</i> values of
121 * this {@code Sample} object.
122 *
123 * @return a {@code DoubleStream} for the sample values
124 */
125 public DoubleStream stream() {
126 return Arrays.stream(_values);
127 }
128
129 /**
130 * Return the <i>slot</i> value at the given position.
131 *
132 * @param index the value index
133 * @return the sample value at the given {@code index}
134 * @throws IndexOutOfBoundsException if the {@code index} is out of range
135 * {@code (index < 0 || index >= size())}
136 */
137 public double get(final int index) {
138 return _values[index];
139 }
140
141 /**
142 * Create a new {@code Sample} object, with all slots available, with the
143 * same size as {@code this} one.
144 *
145 * @return a new empty {@code Sample} object
146 */
147 public Sample newSample() {
148 return of(size());
149 }
150
151 @Override
152 public int hashCode() {
153 return Arrays.hashCode(_values);
154 }
155
156 @Override
157 public boolean equals(final Object obj) {
158 return obj instanceof Sample &&
159 Arrays.equals(_values, ((Sample)obj)._values);
160 }
161
162 @Override
163 public String toString() {
164 return Arrays.toString(_values);
165 }
166
167 /**
168 * Create a new {@code Sample} object with the {@code values}.
169 *
170 * @param values the slot values of the created {@code Sample} object
171 * @return a new {@code Sample} object with the {@code values}
172 * @throws IllegalArgumentException if the length of the given {@code values}
173 * is zero
174 */
175 public static Sample of(final double[] values) {
176 if (values.length == 0) {
177 throw new IllegalArgumentException(
178 "The given values must not be empty."
179 );
180 }
181
182 return new Sample(values);
183 }
184
185 /**
186 * Create a new {@code Sample} object of the given {@code length}.
187 *
188 * @param length the length of the new {@code Sample} object
189 * @return a new {@code Sample} object of the given {@code length}
190 * @throws IllegalArgumentException if the given {@code length} is smaller
191 * then one
192 */
193 public static Sample of(final int length) {
194 if (length < 1) {
195 throw new IllegalArgumentException(format(
196 "Length must not be smaller than one, but was %d.", length
197 ));
198 }
199
200 final double[] values = new double[length];
201 Arrays.fill(values, Double.NaN);
202 return of(values);
203 }
204
205
206 /* *************************************************************************
207 * JAXB object serialization
208 * ************************************************************************/
209
210 @XmlRootElement(name = "sample")
211 @XmlType(name = "org.jenetics.tool.trial.Sample")
212 @XmlAccessorType(XmlAccessType.FIELD)
213 static final class Model {
214
215 @XmlList
216 public double[] sample;
217
218 public static final class Adapter extends XmlAdapter<Model, Sample> {
219 @Override
220 public Model marshal(final Sample sample) {
221 final Model model = new Model();
222 model.sample = sample._values;
223 return model;
224 }
225
226 @Override
227 public Sample unmarshal(final Model model) {
228 return Sample.of(model.sample);
229 }
230 }
231 }
232
233 }
|