Skip to content
Snippets Groups Projects
Commit edb7307f authored by Koen Wermer's avatar Koen Wermer
Browse files

added a modified version of Iterator.java for use with daikon and added...

added a modified version of Iterator.java for use with daikon and added results for the mutation test on this class
parent 98b928a6
No related branches found
No related tags found
No related merge requests found
......@@ -3,11 +3,24 @@ module Daikon where
import Control.Monad
import System.FilePath(joinPath)
import System.Directory
import Data.List
testNr :: Int
testNr = 1
source, pathDir, packageDir, methodName :: String
source = "GradientFunction"
pathDir = "org/apache/commons/math3/analysis/differentiation"
methodName = "value"
source = case testNr of
1 -> "Iterator"
2 -> "GradientFunction"
3 -> "BaseSecantSolver"
pathDir = case testNr of
1 -> "org/apache/commons/math3/util"
2 -> "org/apache/commons/math3/analysis/differentiation"
3 -> "org/apache/commons/math3/analysis/solvers"
methodName = case testNr of
1 -> "hasNext"
2 -> "value"
3 -> "doSolve"
packageDir = map (\c -> if c == '/' then '.' else c) pathDir
......@@ -16,20 +29,28 @@ createDaikonScript :: IO ()
createDaikonScript = do
writeFile scriptName ("#!/bin/sh\nHOME=\"T3Daikon\"\nSOURCE=\"" ++ source ++ "\"\nPATHDIR=\"" ++ pathDir ++ "\"\nPACKAGEDIR=\"" ++ packageDir ++ "\"\nMETHODNAME=\"" ++ methodName ++ "\"\n\n")
mutationFolders <- listDirectory (joinPath ["..", source ++ " mutants"])
mutationFolders <- listDirectory (joinPath ["..", "daikon " ++ source ++ " mutants"])
checkMutants (length mutationFolders)
appendFile scriptName "read -p \"Press enter to continue\""
scriptName :: FilePath
scriptName = joinPath["..", "Daikon check inv " ++ source ++ ".sh"]
scriptName = joinPath["..", "Daikon check inv " ++ source ++ " " ++ methodName ++ ".sh"]
-- Adds the code to check the mutants
checkMutants :: Int -> IO ()
checkMutants 0 = return ()
checkMutants n = do
appendFile scriptName ("echo \"compiling mutation " ++ show n ++ "..\"\njavac -cp \".;wlp/Tests/\" -d \"wlp/Tests\" \"$SOURCE mutants/" ++ show n ++ "/$PATHDIR/$SOURCE.java\"\n\n")
appendFile scriptName ("echo \"generating test suite\"\njava -cp \".;$HOME/KWT3daikon.jar;$HOME/libs/T3.jar;$HOME/libs/T3Daikon.jar;wlp/tests\" MyT3Daikon.Generator wlp/tests $PACKAGEDIR.$SOURCE $METHODNAME 50 1000 \"Daikon test suites/$SOURCE\"\n\n")
appendFile scriptName ("echo \"compiling mutation " ++ show n ++ "..\"\njavac -cp \".;wlp/Tests/\" -d \"wlp/Tests\" \"daikon $SOURCE mutants/" ++ show n ++ "/$PATHDIR/$SOURCE.java\"\n\n")
appendFile scriptName ("echo \"checking invariants " ++ show n ++ "..\"\njava -cp \".;$HOME/KWT3daikon.jar;$HOME/libs/T3.jar;$HOME/libs/T3Daikon.jar;wlp/Tests\" MyT3Daikon.Miner -check \"Daikon test suites/$SOURCE.tr\" $METHODNAME \"Daikon invariants/$SOURCE\"\n\n")
checkMutants (n-1)
\ No newline at end of file
checkMutants (n-1)
-- Renames mutant directories by subtracting a value from the mutant number
renameMutants :: Int -> IO ()
renameMutants n = do
let mutantsPath = joinPath ["..", "daikon " ++ source ++ " mutants"]
mutationFolders <- listDirectory (mutantsPath)
mapM_ (\old -> renameDirectory (joinPath [mutantsPath, show old]) (joinPath [mutantsPath, show (old - n)])) (sort (map read mutationFolders :: [Int]))
\ No newline at end of file
iterator:
5 mutations with error found: 2, 3, 4, 5, 32
4 mutations with error found not detected by wlp: 2, 3, 4, 5
2 mutations with unterminated calls: 1 and 31
1 mutation stuck in a loop: 35
\ No newline at end of file
......@@ -30,7 +30,12 @@ public class Iterator {
/**
* Simple constructor.
*/
private Iterator() {
public Iterator(int[] keys, double[] values, byte[] states, int count) {
this.keys = keys;
this.values = values;
this.states = states;
this.count = count;
// preserve the modification this.count of the map to detect concurrent modifications later
this.referenceCount = this.count;
......
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.analysis.solvers;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.exception.ConvergenceException;
import org.apache.commons.math3.exception.MathInternalError;
import org.apache.commons.math3.exception.NoBracketingException;
import org.apache.commons.math3.exception.NotStrictlyPositiveException;
import org.apache.commons.math3.exception.NullArgumentException;
import org.apache.commons.math3.exception.NumberIsTooLargeException;
import org.apache.commons.math3.exception.util.LocalizedFormats;
import org.apache.commons.math3.util.FastMath;
/**
* Base class for all bracketing <em>Secant</em>-based methods for root-finding
* (approximating a zero of a univariate real function).
*
* <p>Implementation of the {@link RegulaFalsiSolver <em>Regula Falsi</em>} and
* {@link IllinoisSolver <em>Illinois</em>} methods is based on the
* following article: M. Dowell and P. Jarratt,
* <em>A modified regula falsi method for computing the root of an
* equation</em>, BIT Numerical Mathematics, volume 11, number 2,
* pages 168-174, Springer, 1971.</p>
*
* <p>Implementation of the {@link PegasusSolver <em>Pegasus</em>} method is
* based on the following article: M. Dowell and P. Jarratt,
* <em>The "Pegasus" method for computing the root of an equation</em>,
* BIT Numerical Mathematics, volume 12, number 4, pages 503-508, Springer,
* 1972.</p>
*
* <p>The {@link SecantSolver <em>Secant</em>} method is <em>not</em> a
* bracketing method, so it is not implemented here. It has a separate
* implementation.</p>
*
* @since 3.0
*/
public abstract class BaseSecantSolver
extends AbstractUnivariateSolver
implements BracketedUnivariateSolver<UnivariateFunction> {
/** Default absolute accuracy. */
protected static final double DEFAULT_ABSOLUTE_ACCURACY = 1e-6;
/** The kinds of solutions that the algorithm may accept. */
private AllowedSolution allowed;
/** The <em>Secant</em>-based root-finding method to use. */
private final Method method;
/**
* Construct a solver.
*
* @param absoluteAccuracy Absolute accuracy.
* @param method <em>Secant</em>-based root-finding method to use.
*/
protected BaseSecantSolver(final double absoluteAccuracy, final Method method1) {
super(absoluteAccuracy);
this.allowed = AllowedSolution.ANY_SIDE;
this.method = method1;
}
/**
* Construct a solver.
*
* @param relativeAccuracy Relative accuracy.
* @param absoluteAccuracy Absolute accuracy.
* @param method <em>Secant</em>-based root-finding method to use.
*/
protected BaseSecantSolver(final double relativeAccuracy,
final double absoluteAccuracy1,
final Method method2) {
super(relativeAccuracy, absoluteAccuracy1);
this.allowed = AllowedSolution.ANY_SIDE;
this.method = method2;
}
/**
* Construct a solver.
*
* @param relativeAccuracy Maximum relative error.
* @param absoluteAccuracy Maximum absolute error.
* @param functionValueAccuracy Maximum function value error.
* @param method <em>Secant</em>-based root-finding method to use
*/
protected BaseSecantSolver(final double relativeAccuracy2,
final double absoluteAccuracy2,
final double functionValueAccuracy,
final Method method3) {
super(relativeAccuracy2, absoluteAccuracy2, functionValueAccuracy);
this.allowed = AllowedSolution.ANY_SIDE;
this.method = method3;
}
protected final double doSolve()
throws ConvergenceException {
// Get initial solution
double x0 = getMin();
double x1 = getMax();
double f0 = computeObjectiveValue(x0);
double f1 = computeObjectiveValue(x1);
// If one of the bounds is the exact root, return it. Since these are
// not under-approximations or over-approximations, we can return them
// regardless of the allowed solutions.
if (f0 == 0.0) {
return x0;
}
if (f1 == 0.0) {
return x1;
}
// Verify bracketing of initial solution.
verifyBracketing(x0, x1);
// Get accuracies.
final double ftol = getFunctionValueAccuracy();
final double atol = getAbsoluteAccuracy();
final double rtol = getRelativeAccuracy();
// Keep track of inverted intervals, meaning that the left bound is
// larger than the right bound.
boolean inverted = false;
// Keep finding better approximations.
while (true) {
// Calculate the next approximation.
final double x = x1 - ((f1 * (x1 - x0)) / (f1 - f0));
final double fx = computeObjectiveValue(x);
// If the new approximation is the exact root, return it. Since
// this is not an under-approximation or an over-approximation,
// we can return it regardless of the allowed solutions.
if (fx == 0.0) {
return x;
}
// Update the bounds with the new approximation.
if (f1 * fx < 0) {
// The value of x1 has switched to the other bound, thus inverting
// the interval.
x0 = x1;
f0 = f1;
inverted = !inverted;
} else {
switch (this.method) {
case ILLINOIS:
f0 *= 0.5;
break;
case PEGASUS:
f0 *= f1 / (f1 + fx);
break;
case REGULA_FALSI:
// Detect early that algorithm is stuck, instead of waiting
// for the maximum number of iterations to be exceeded.
if (x == x1) {
throw new ConvergenceException();
}
break;
default:
// Should never happen.
throw new MathInternalError();
}
}
// Update from [x0, x1] to [x0, x].
x1 = x;
f1 = fx;
// If the function value of the last approximation is too small,
// given the function value accuracy, then we can't get closer to
// the root than we already are.
if (FastMath.abs(f1) <= ftol) {
switch (this.allowed) {
case ANY_SIDE:
return x1;
case LEFT_SIDE:
if (inverted) {
return x1;
}
break;
case RIGHT_SIDE:
if (!inverted) {
return x1;
}
break;
case BELOW_SIDE:
if (f1 <= 0) {
return x1;
}
break;
case ABOVE_SIDE:
if (f1 >= 0) {
return x1;
}
break;
default:
throw new MathInternalError();
}
}
// If the current interval is within the given accuracies, we
// are satisfied with the current approximation.
if (FastMath.abs(x1 - x0) < FastMath.max(rtol * FastMath.abs(x1),
atol)) {
switch (this.allowed) {
case ANY_SIDE:
return x1;
case LEFT_SIDE:
return inverted ? x1 : x0;
case RIGHT_SIDE:
return inverted ? x0 : x1;
case BELOW_SIDE:
return (f1 <= 0) ? x1 : x0;
case ABOVE_SIDE:
return (f1 >= 0) ? x1 : x0;
default:
throw new MathInternalError();
}
}
}
}
protected enum Method {
REGULA_FALSI,
ILLINOIS,
PEGASUS;
}
//
// UnivariateSolverUtils
//
public static double midpoint(double a, double b) {
return (a + b) * 0.5;
}
public static boolean isBracketing(UnivariateFunction function1,
final double lower1,
final double upper1)
throws NullArgumentException {
if (function1 == null) {
throw new NullArgumentException(LocalizedFormats.FUNCTION);
}
final double fLo = function1.value(lower1);
final double fHi = function1.value(upper1);
return (fLo >= 0 && fHi <= 0) || (fLo <= 0 && fHi >= 0);
}
public static boolean isSequence1(final double start,
final double mid,
final double end) {
return (start < mid) && (mid < end);
}
public static void verifyInterval1(final double lower2,
final double upper2)
throws NumberIsTooLargeException {
if (lower2 >= upper2) {
throw new NumberIsTooLargeException(LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
lower2, upper2, false);
}
}
public static void verifySequence1(final double lower3,
final double initial,
final double upper3)
throws NumberIsTooLargeException {
verifyInterval1(lower3, initial);
verifyInterval1(initial, upper3);
}
public static void verifyBracketing(UnivariateFunction function2,
final double lower4,
final double upper4)
throws NullArgumentException,
NoBracketingException {
if (function2 == null) {
throw new NullArgumentException(LocalizedFormats.FUNCTION);
}
verifyInterval1(lower4, upper4);
if (!isBracketing(function2, lower4, upper4)) {
throw new NoBracketingException(lower4, upper4,
function2.value(lower4),
function2.value(upper4));
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.analysis.differentiation;
import org.apache.commons.math3.analysis.MultivariateVectorFunction;
/** Class representing the gradient of a multivariate function.
* <p>
* The vectorial components of the function represent the derivatives
* with respect to each function parameters.
* </p>
* @since 3.1
*/
public class GradientFunction implements MultivariateVectorFunction {
/** Underlying real-valued function. */
private final MultivariateDifferentiableFunction f;
/** Simple constructor.
* @param f underlying real-valued function
*/
public GradientFunction(final MultivariateDifferentiableFunction f1) {
this.f = f1;
}
/** {@inheritDoc} */
public double[] value(double[] point) {
// set up parameters
final DerivativeStructure[] dsX = new DerivativeStructure[point.length];
for (int i = 0; i < point.length; ++i) {
dsX[i] = new DerivativeStructure(point.length, 1, i, point[i]);
}
// compute the derivatives
final DerivativeStructure dsY = this.f.value(dsX);
// extract the gradient
final double[] y = new double[point.length];
final int[] orders = new int[point.length];
for (int j = 0; j < point.length; ++j) {
orders[j] = 1;
y[j] = dsY.getPartialDerivative(orders);
orders[j] = 0;
}
return y;
}
}
// Copied from OpenIntToDoubleHashMap.java
package org.apache.commons.math3.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;
/** Iterator class for the map. */
public class Iterator {
protected static final byte FULL = 1;
private int[] keys;
private double[] values;
private byte[] states;
private int count;
/** Reference modification this.count. */
private final int referenceCount;
/** Index of current element. */
private int current;
/** Index of next element. */
private int next;
/**
* Simple constructor.
*/
private Iterator() {
// preserve the modification this.count of the map to detect concurrent modifications later
this.referenceCount = this.count;
// initialize this.current index
this.next = -1;
try {
this.advance();
} catch (NoSuchElementException nsee) { // NOPMD
// ignored
}
}
/**
* Check if there is a this.next element in the map.
* @return true if there is a this.next element
*/
public boolean hasNext() {
return this.next >= 0;
}
/**
* Get the key of this.current entry.
* @return key of this.current entry
* @exception ConcurrentModificationException if the map is modified during iteration
* @exception NoSuchElementException if there is no element left in the map
*/
public int key()
throws ConcurrentModificationException, NoSuchElementException {
if (this.referenceCount != this.count) {
throw new ConcurrentModificationException();
}
if (this.current < 0) {
throw new NoSuchElementException();
}
return this.keys[this.current];
}
/**
* Get the value of this.current entry.
* @return value of this.current entry
* @exception ConcurrentModificationException if the map is modified during iteration
* @exception NoSuchElementException if there is no element left in the map
*/
public double value()
throws ConcurrentModificationException, NoSuchElementException {
if (this.referenceCount != this.count) {
throw new ConcurrentModificationException();
}
if (this.current < 0) {
throw new NoSuchElementException();
}
return this.values[this.current];
}
/**
* Advance iterator one step further.
* @exception ConcurrentModificationException if the map is modified during iteration
* @exception NoSuchElementException if there is no element left in the map
*/
public void advance()
throws ConcurrentModificationException, NoSuchElementException {
if (this.referenceCount != this.count) {
throw new ConcurrentModificationException();
}
// advance on step
this.current = this.next;
// prepare this.next step
try {
while (this.states[++this.next] != this.FULL) { // NOPMD
// nothing to do
}
} catch (ArrayIndexOutOfBoundsException e) {
this.next = -2;
if (this.current < 0) {
throw new NoSuchElementException();
}
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment