Improve tests in Mathematics

refs #53
This commit is contained in:
Fabian Becker 2015-12-11 12:14:35 +01:00
parent 02a7b74415
commit bb04ff2231
6 changed files with 93 additions and 38 deletions

View File

@ -2,7 +2,7 @@ package eva2.optimization.individuals;
/** /**
* This interface gives access to a real-valued genotype and should * This interface gives access to a real-valued genotype and should
* only be used by mutation and crossover operators. Onyl exception are * only be used by mutation and crossover operators. Only exception are
* data type specific optimization strategies like PSO or DE. * data type specific optimization strategies like PSO or DE.
*/ */
public interface InterfaceESIndividual { public interface InterfaceESIndividual {

View File

@ -24,7 +24,7 @@ public class MOSONoConvert implements InterfaceMOSOConverter, java.io.Serializab
/** /**
* This method takes a population of individuals with an array of * This method takes a population of individuals with an array of
* fitness values and calculates a single fitness value to replace * fitness values and calculates a single fitness value to replace
* the former fitness array. Please note: The orignal fitness values * the former fitness array. Please note: The original fitness values
* are lost this way, so please use the individual.setData() method * are lost this way, so please use the individual.setData() method
* if you still want to access the original fitness values. * if you still want to access the original fitness values.
* *

View File

@ -198,7 +198,7 @@ public class StatisticalEvaluation {
double[] dat = job1.getDoubleDataColumn(field); double[] dat = job1.getDoubleDataColumn(field);
double median = Double.NaN; double median = Double.NaN;
if (dat != null) { if (dat != null) {
median = Mathematics.median2(dat, true); median = Mathematics.median(dat, true);
median = StatisticalEvaluation.formatOutput(median); median = StatisticalEvaluation.formatOutput(median);
} }

View File

@ -475,8 +475,9 @@ public final class Mathematics {
* Check whether the given value lies within the interval in every * Check whether the given value lies within the interval in every
* dimension. * dimension.
* *
* @param x * @param v Value
* @param range * @param lower Lower bound
* @param upper Upper bound
* @return true if the vector lies within the range, else false * @return true if the vector lies within the range, else false
*/ */
public static boolean isInRange(double v, double lower, double upper) { public static boolean isInRange(double v, double lower, double upper) {
@ -507,8 +508,8 @@ public final class Mathematics {
* @return * @return
*/ */
public static boolean isValidVec(double[][] d) { public static boolean isValidVec(double[][] d) {
for (int i = 0; i < d.length; i++) { for (double[] vec : d) {
if (!isValidVector(d[i])) { if (!isValidVector(vec)) {
return false; return false;
} }
} }
@ -621,16 +622,18 @@ public final class Mathematics {
in = x; in = x;
} }
if (in.length == 1) { Arrays.sort(in);
if (in.length == 0) {
return Double.NaN;
} else if (in.length == 1) {
return in[0]; return in[0];
} else if (in.length == 2) { } else if (in.length == 2) {
return (in[0] + in[1]) / 2.; return (in[0] + in[1]) / 2.;
} else { } else {
Arrays.sort(in); if (in.length % 2 == 1) {
if (in.length % 2 != 0) { return in[in.length / 2];
return in[(in.length - 1) / 2];
} else { } else {
return (in[in.length / 2] + in[(in.length / 2) + 1]) / 2.; return (in[in.length / 2 - 1] + in[in.length / 2]) / 2.;
} }
} }
} }
@ -663,21 +666,6 @@ public final class Mathematics {
} }
} }
public static double median2(double[] vector, boolean clone) {
double[] in;
if (clone) {
in = vector.clone();
} else {
in = vector;
}
if (in.length == 0) {
return 0;
}
Arrays.sort(in);
return in[(int) Math.floor(((double) in.length) / 2.0)];
}
public static double variance(double[] vector) { public static double variance(double[] vector) {
double mean = Mathematics.mean(vector); double mean = Mathematics.mean(vector);
double result = 0.0; double result = 0.0;
@ -787,7 +775,7 @@ public final class Mathematics {
} }
/** /**
* Normalize the given vector to an euclidian length of 1. * Normalize the given vector to a euclidean length of 1.
* *
* @param v * @param v
* @return * @return
@ -797,7 +785,7 @@ public final class Mathematics {
} }
/** /**
* Normalize the given vector to an euclidian length of 1. * Normalize the given vector to a euclidean length of 1.
* *
* @param v * @param v
* @return * @return
@ -943,7 +931,7 @@ public final class Mathematics {
if ((val + step) < min) { if ((val + step) < min) {
return (2 * min - val - step); return (2 * min - val - step);
} }
return (val += step); return val + step;
} }
/** /**
@ -954,7 +942,7 @@ public final class Mathematics {
* *
* @param x A vector * @param x A vector
* @param y The reference vector * @param y The reference vector
* @param def The default value to be use to avoid division by zero. * @param def The default value to be used to avoid division by zero.
* @return The relative distance of x to y. * @return The relative distance of x to y.
* @throws Exception * @throws Exception
*/ */
@ -1183,7 +1171,6 @@ public final class Mathematics {
* @return the sum of the elements * @return the sum of the elements
*/ */
public static int sum(int[] ints) { public static int sum(int[] ints) {
int sum = 0; int sum = 0;
for (int value : ints) { for (int value : ints) {
@ -1208,8 +1195,8 @@ public final class Mathematics {
/** /**
* Add each entry of a vector with a scalar in a result vector. * Add each entry of a vector with a scalar in a result vector.
* *
* @param s * @param s Scalar
* @param v * @param v Vector
* @return * @return
*/ */
public static void svAdd(double s, double[] v, double[] res) { public static void svAdd(double s, double[] v, double[] res) {

View File

@ -0,0 +1,12 @@
<html>
<head>
<title>Differential Evolution - DE</title>
</head>
<body>
<h1 align="center">Differential Evolution - DE</h1>
<center>
</center><br>
Description of DE.
<br>
</body>
</html>

View File

@ -2,7 +2,10 @@ package eva2.tools.math;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class MathematicsTest { public class MathematicsTest {
@ -26,6 +29,9 @@ public class MathematicsTest {
public void testMean() throws Exception { public void testMean() throws Exception {
double[] vals = {2.0,3.05,4.9,7.8,12.7}; double[] vals = {2.0,3.05,4.9,7.8,12.7};
assertEquals(6.09, Mathematics.mean(vals), 0.0); assertEquals(6.09, Mathematics.mean(vals), 0.0);
// Empty vector
assertEquals(0.0, Mathematics.mean(new double[]{}), 0.0);
} }
@Test @Test
@ -57,12 +63,29 @@ public class MathematicsTest {
@Test @Test
public void testMedian() throws Exception { public void testMedian() throws Exception {
// Handle empty case
assertEquals(Double.NaN, Mathematics.median(new double[]{}, true), 0.0);
} // Median of single element array
assertEquals(2.4, Mathematics.median(new double[]{2.4}, true), 10E-6);
@Test // Median of two element array
public void testMedian2() throws Exception { assertEquals(5.0, Mathematics.median(new double[]{2.5, 7.5}, true), 10E-6);
// Median of even length array
double[] values = {9.8, 7.8, 8.6, 5.6, 3.2, 10.9};
assertEquals(8.2, Mathematics.median(values, true), 10E-6);
// Median of odd length array
double[] values2 = {9.8, 7.8, 5.6, 3.2, 10.9};
assertEquals(7.8, Mathematics.median(values2, false), 10E-6);
// Median while preserving original array
double[] unsortedValues = {5.2, 3.4};
double[] unsortedValues2 = {5.2, 3.4};
Mathematics.median(unsortedValues, true);
assertTrue(Arrays.equals(unsortedValues, unsortedValues2));
} }
@Test @Test
@ -103,11 +126,23 @@ public class MathematicsTest {
@Test @Test
public void testSum() throws Exception { public void testSum() throws Exception {
// Array of doubles
double[] values = {1.9,2.8,3.7,4.6,5.5}; double[] values = {1.9,2.8,3.7,4.6,5.5};
assertEquals(18.5, Mathematics.sum(values), 0.0); assertEquals(18.5, Mathematics.sum(values), 0.0);
// Array of ints
int[] intValues = {1,9,2,8,3,7,4,6,5};
assertEquals(45, Mathematics.sum(intValues));
} }
@Test
public void testNorm() throws Exception {
double[] values = {3.0, 4.0};
assertEquals(5.0, Mathematics.norm(values), 0.0);
}
@Test @Test
public void testScale() throws Exception { public void testScale() throws Exception {
@ -120,4 +155,25 @@ public class MathematicsTest {
assertEquals(-4.05593, Mathematics.tTestEqSizeEqVar(values1, values2), 0.00001); assertEquals(-4.05593, Mathematics.tTestEqSizeEqVar(values1, values2), 0.00001);
} }
@Test
public void testProduct() throws Exception {
double[] values = {3.0, 4.0, 5.0};
assertEquals(60.0, Mathematics.product(values), 0.0);
}
@Test
public void testIsInRange() throws Exception {
// Single dimension
assertTrue(Mathematics.isInRange(4.9, 1.2, 7.6));
assertFalse(Mathematics.isInRange(0.0, 1.2, 3.4));
// Multidimensional
double[][] ranges = {{1.2, 7.6}, {1.2, 3.4}};
assertTrue(Mathematics.isInRange(new double[]{4.9, 2.2}, ranges));
assertFalse(Mathematics.isInRange(new double[]{9.9, 2.2}, ranges));
}
} }