Procházet zdrojové kódy

Merge pull request #650 from jplag/feature/floatToDouble

Migration from float to double
Timur Sağlam před 4 roky
rodič
revize
bc87bdf2b2
36 změnil soubory, kde provedl 465 přidání a 449 odebrání
  1. 6 6
      jplag.cli/src/main/java/de/jplag/CommandLineArgument.java
  2. 1 1
      jplag.cli/src/test/java/de/jplag/cli/ClusteringTest.java
  3. 1 1
      jplag.cli/src/test/java/de/jplag/cli/CommandLineInterfaceTest.java
  4. 8 8
      jplag.cli/src/test/java/de/jplag/cli/SimiliarityThresholdTest.java
  5. 2 2
      jplag.endtoend-testing/src/main/java/de/jplag/endtoend/model/ExpectedResult.java
  6. 15 8
      jplag.endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndSuiteTest.java
  7. 236 236
      jplag.endtoend-testing/src/test/resources/results/java/sortAlgo.json
  8. 19 19
      jplag/src/main/java/de/jplag/JPlagComparison.java
  9. 4 4
      jplag/src/main/java/de/jplag/JPlagResult.java
  10. 11 11
      jplag/src/main/java/de/jplag/clustering/Cluster.java
  11. 3 3
      jplag/src/main/java/de/jplag/clustering/ClusteringAdapter.java
  12. 1 1
      jplag/src/main/java/de/jplag/clustering/ClusteringFactory.java
  13. 16 16
      jplag/src/main/java/de/jplag/clustering/ClusteringOptions.java
  14. 27 21
      jplag/src/main/java/de/jplag/clustering/ClusteringResult.java
  15. 3 3
      jplag/src/main/java/de/jplag/clustering/algorithm/AgglomerativeClustering.java
  16. 9 9
      jplag/src/main/java/de/jplag/clustering/algorithm/InterClusterSimilarity.java
  17. 1 2
      jplag/src/main/java/de/jplag/clustering/algorithm/SpectralClustering.java
  18. 2 2
      jplag/src/main/java/de/jplag/clustering/preprocessors/PercentileThresholdProcessor.java
  19. 6 6
      jplag/src/main/java/de/jplag/options/JPlagOptions.java
  20. 9 9
      jplag/src/main/java/de/jplag/options/SimilarityMetric.java
  21. 1 1
      jplag/src/main/java/de/jplag/reporting/reportobject/mapper/MetricMapper.java
  22. 1 1
      jplag/src/main/java/de/jplag/reporting/reportobject/model/Cluster.java
  23. 1 1
      jplag/src/main/java/de/jplag/reporting/reportobject/model/ComparisonReport.java
  24. 1 1
      jplag/src/main/java/de/jplag/reporting/reportobject/model/TopComparison.java
  25. 1 1
      jplag/src/test/java/de/jplag/BaseCodeTest.java
  26. 14 14
      jplag/src/test/java/de/jplag/NormalComparisonTest.java
  27. 13 13
      jplag/src/test/java/de/jplag/ParallelComparisonTest.java
  28. 1 1
      jplag/src/test/java/de/jplag/TestBase.java
  29. 1 1
      jplag/src/test/java/de/jplag/clustering/ClusteringAdapterTest.java
  30. 11 11
      jplag/src/test/java/de/jplag/clustering/ClusteringResultTest.java
  31. 6 6
      jplag/src/test/java/de/jplag/clustering/algorithm/ClusteringData.java
  32. 5 7
      jplag/src/test/java/de/jplag/clustering/preprocessors/PercentilePreprocessorTest.java
  33. 10 6
      jplag/src/test/java/de/jplag/clustering/preprocessors/PreprocessingTestBase.java
  34. 6 6
      jplag/src/test/java/de/jplag/reporting/reportobject/mapper/ClusteringResultMapperTest.java
  35. 9 7
      jplag/src/test/java/de/jplag/reporting/reportobject/mapper/MetricMapperTest.java
  36. 4 4
      jplag/src/test/java/de/jplag/special/VolumeTest.java

+ 6 - 6
jplag.cli/src/main/java/de/jplag/CommandLineArgument.java

@@ -48,7 +48,7 @@ public enum CommandLineArgument {
     SUFFIXES(new Builder("-p", String.class).argumentGroup(ADVANCED_GROUP)),
     SUFFIXES(new Builder("-p", String.class).argumentGroup(ADVANCED_GROUP)),
     EXCLUDE_FILE(new Builder("-x", String.class).argumentGroup(ADVANCED_GROUP)),
     EXCLUDE_FILE(new Builder("-x", String.class).argumentGroup(ADVANCED_GROUP)),
     MIN_TOKEN_MATCH("-t", Integer.class),
     MIN_TOKEN_MATCH("-t", Integer.class),
-    SIMILARITY_THRESHOLD(new Builder("-m", Float.class).defaultsTo(DEFAULT_SIMILARITY_THRESHOLD).argumentGroup(ADVANCED_GROUP)),
+    SIMILARITY_THRESHOLD(new Builder("-m", Double.class).defaultsTo(DEFAULT_SIMILARITY_THRESHOLD).argumentGroup(ADVANCED_GROUP)),
     SHOWN_COMPARISONS(new Builder("-n", Integer.class).defaultsTo(DEFAULT_SHOWN_COMPARISONS)),
     SHOWN_COMPARISONS(new Builder("-n", Integer.class).defaultsTo(DEFAULT_SHOWN_COMPARISONS)),
     RESULT_FOLDER(new Builder("-r", String.class).defaultsTo("result")),
     RESULT_FOLDER(new Builder("-r", String.class).defaultsTo("result")),
     COMPARISON_MODE(new Builder("-c", String.class).defaultsTo(DEFAULT_COMPARISON_MODE.getName()).choices(ComparisonMode.allNames())),
     COMPARISON_MODE(new Builder("-c", String.class).defaultsTo(DEFAULT_COMPARISON_MODE.getName()).choices(ComparisonMode.allNames())),
@@ -60,10 +60,10 @@ public enum CommandLineArgument {
             new Builder("--cluster-metric", SimilarityMetric.class).argumentGroup(CLUSTERING_GROUP_NAME)
             new Builder("--cluster-metric", SimilarityMetric.class).argumentGroup(CLUSTERING_GROUP_NAME)
                     .defaultsTo(new ClusteringOptions().similarityMetric())),
                     .defaultsTo(new ClusteringOptions().similarityMetric())),
     CLUSTER_SPECTRAL_BANDWIDTH(
     CLUSTER_SPECTRAL_BANDWIDTH(
-            new Builder("--cluster-spectral-bandwidth", Float.class).metaVar("bandwidth")
+            new Builder("--cluster-spectral-bandwidth", Double.class).metaVar("bandwidth")
                     .defaultsTo(new ClusteringOptions().spectralKernelBandwidth()).hidden()),
                     .defaultsTo(new ClusteringOptions().spectralKernelBandwidth()).hidden()),
     CLUSTER_SPECTRAL_NOISE(
     CLUSTER_SPECTRAL_NOISE(
-            new Builder("--cluster-spectral-noise", Float.class).metaVar("noise")
+            new Builder("--cluster-spectral-noise", Double.class).metaVar("noise")
                     .defaultsTo(new ClusteringOptions().spectralGaussianProcessVariance()).hidden()),
                     .defaultsTo(new ClusteringOptions().spectralGaussianProcessVariance()).hidden()),
     CLUSTER_SPECTRAL_MIN_RUNS(
     CLUSTER_SPECTRAL_MIN_RUNS(
             new Builder("--cluster-spectral-min-runs", Integer.class).metaVar("min").defaultsTo(new ClusteringOptions().spectralMinRuns()).hidden()),
             new Builder("--cluster-spectral-min-runs", Integer.class).metaVar("min").defaultsTo(new ClusteringOptions().spectralMinRuns()).hidden()),
@@ -73,15 +73,15 @@ public enum CommandLineArgument {
             new Builder("--cluster-spectral-kmeans-interations", Integer.class).metaVar("iterations")
             new Builder("--cluster-spectral-kmeans-interations", Integer.class).metaVar("iterations")
                     .defaultsTo(new ClusteringOptions().spectralMaxKMeansIterationPerRun()).hidden()),
                     .defaultsTo(new ClusteringOptions().spectralMaxKMeansIterationPerRun()).hidden()),
     CLUSTER_AGGLOMERATIVE_THRESHOLD(
     CLUSTER_AGGLOMERATIVE_THRESHOLD(
-            new Builder("--cluster-agglomerative-threshold", Float.class).metaVar("threshold")
+            new Builder("--cluster-agglomerative-threshold", Double.class).metaVar("threshold")
                     .defaultsTo(new ClusteringOptions().agglomerativeThreshold()).hidden()),
                     .defaultsTo(new ClusteringOptions().agglomerativeThreshold()).hidden()),
     CLUSTER_AGGLOMERATIVE_INTER_CLUSTER_SIMILARITY(
     CLUSTER_AGGLOMERATIVE_INTER_CLUSTER_SIMILARITY(
             new Builder("--cluster-agglomerative-inter-cluster-similarity", InterClusterSimilarity.class)
             new Builder("--cluster-agglomerative-inter-cluster-similarity", InterClusterSimilarity.class)
                     .defaultsTo(new ClusteringOptions().agglomerativeInterClusterSimilarity()).hidden()),
                     .defaultsTo(new ClusteringOptions().agglomerativeInterClusterSimilarity()).hidden()),
     CLUSTER_PREPROCESSING_NONE(new Builder("--cluster-pp-none", Boolean.class).action(Arguments.storeTrue()).hidden()),
     CLUSTER_PREPROCESSING_NONE(new Builder("--cluster-pp-none", Boolean.class).action(Arguments.storeTrue()).hidden()),
     CLUSTER_PREPROCESSING_CDF(new Builder("--cluster-pp-cdf", Boolean.class).action(Arguments.storeTrue()).hidden()),
     CLUSTER_PREPROCESSING_CDF(new Builder("--cluster-pp-cdf", Boolean.class).action(Arguments.storeTrue()).hidden()),
-    CLUSTER_PREPROCESSING_PERCENTILE(new Builder("--cluster-pp-percentile", Float.class).metaVar("percentile").hidden()),
-    CLUSTER_PREPROCESSING_THRESHOLD(new Builder("--cluster-pp-threshold", Float.class).metaVar("threshold").hidden());
+    CLUSTER_PREPROCESSING_PERCENTILE(new Builder("--cluster-pp-percentile", Double.class).metaVar("percentile").hidden()),
+    CLUSTER_PREPROCESSING_THRESHOLD(new Builder("--cluster-pp-threshold", Double.class).metaVar("threshold").hidden());
 
 
     /**
     /**
      * The identifier of the default {@link Language}.
      * The identifier of the default {@link Language}.

+ 1 - 1
jplag.cli/src/test/java/de/jplag/cli/ClusteringTest.java

@@ -26,7 +26,7 @@ class ClusteringTest extends CommandLineInterfaceTest {
 
 
     @Test
     @Test
     void parsePercentilePreProcessor() {
     void parsePercentilePreProcessor() {
-        String argument = buildArgument(CommandLineArgument.CLUSTER_PREPROCESSING_PERCENTILE, Float.toString(0.5f));
+        String argument = buildArgument(CommandLineArgument.CLUSTER_PREPROCESSING_PERCENTILE, Double.toString(0.5));
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
         assertEquals(Preprocessing.PERCENTILE, options.clusteringOptions().preprocessor());
         assertEquals(Preprocessing.PERCENTILE, options.clusteringOptions().preprocessor());
         assertEquals(0.5, options.clusteringOptions().preprocessorPercentile(), EPSILON);
         assertEquals(0.5, options.clusteringOptions().preprocessorPercentile(), EPSILON);

+ 1 - 1
jplag.cli/src/test/java/de/jplag/cli/CommandLineInterfaceTest.java

@@ -19,7 +19,7 @@ import de.jplag.options.JPlagOptions;
  */
  */
 public abstract class CommandLineInterfaceTest {
 public abstract class CommandLineInterfaceTest {
     protected static final String CURRENT_DIRECTORY = ".";
     protected static final String CURRENT_DIRECTORY = ".";
-    protected static final float DELTA = 0.0001f;
+    protected static final double DELTA = 1E-5;
 
 
     protected CLI cli;
     protected CLI cli;
     protected Namespace namespace;
     protected Namespace namespace;

+ 8 - 8
jplag.cli/src/test/java/de/jplag/cli/SimiliarityThresholdTest.java

@@ -18,29 +18,29 @@ class SimiliarityThresholdTest extends CommandLineInterfaceTest {
 
 
     @Test
     @Test
     void testInvalidThreshold() throws Exception {
     void testInvalidThreshold() throws Exception {
-        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, "Not a float...");
+        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, "Not a Double...");
         int statusCode = catchSystemExit(() -> buildOptionsFromCLI(argument, CURRENT_DIRECTORY));
         int statusCode = catchSystemExit(() -> buildOptionsFromCLI(argument, CURRENT_DIRECTORY));
-        assertEquals(1, statusCode);
+        assertEquals(1.0, statusCode);
     }
     }
 
 
     @Test
     @Test
     void testLowerBound() {
     void testLowerBound() {
-        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, Float.toString(-1f));
+        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, Double.toString(-1.0));
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
-        assertEquals(0f, options.similarityThreshold(), DELTA);
+        assertEquals(0.0, options.similarityThreshold(), DELTA);
     }
     }
 
 
     @Test
     @Test
     void testUpperBound() {
     void testUpperBound() {
-        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, Float.toString(101f));
+        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, Double.toString(101.0));
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
-        assertEquals(100f, options.similarityThreshold(), DELTA);
+        assertEquals(100.0, options.similarityThreshold(), DELTA);
     }
     }
 
 
     @Test
     @Test
     void testValidThreshold() {
     void testValidThreshold() {
-        float expectedValue = 50f;
-        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, Float.toString(expectedValue));
+        double expectedValue = 50.0;
+        String argument = buildArgument(CommandLineArgument.SIMILARITY_THRESHOLD, Double.toString(expectedValue));
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
         buildOptionsFromCLI(argument, CURRENT_DIRECTORY);
         assertEquals(expectedValue, options.similarityThreshold(), DELTA);
         assertEquals(expectedValue, options.similarityThreshold(), DELTA);
     }
     }

+ 2 - 2
jplag.endtoend-testing/src/main/java/de/jplag/endtoend/model/ExpectedResult.java

@@ -7,6 +7,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
  * which can be found at https://github.com/jplag/JPlag/issues/548 Here this object is used for serialization and
  * which can be found at https://github.com/jplag/JPlag/issues/548 Here this object is used for serialization and
  * deserialization of the information from json to object or object to json.
  * deserialization of the information from json to object or object to json.
  */
  */
-public record ExpectedResult(@JsonProperty("minimal_similarity") float resultSimilarityMinimum,
-        @JsonProperty("maximum_similarity") float resultSimilarityMaximum, @JsonProperty("matched_token_number") int resultMatchedTokenNumber) {
+public record ExpectedResult(@JsonProperty("minimal_similarity") double resultSimilarityMinimum,
+        @JsonProperty("maximum_similarity") double resultSimilarityMaximum, @JsonProperty("matched_token_number") int resultMatchedTokenNumber) {
 }
 }

+ 15 - 8
jplag.endtoend-testing/src/test/java/de/jplag/endtoend/EndToEndSuiteTest.java

@@ -26,7 +26,9 @@ import de.jplag.LanguageLoader;
 import de.jplag.endtoend.helper.FileHelper;
 import de.jplag.endtoend.helper.FileHelper;
 import de.jplag.endtoend.helper.JsonHelper;
 import de.jplag.endtoend.helper.JsonHelper;
 import de.jplag.endtoend.helper.TestSuiteHelper;
 import de.jplag.endtoend.helper.TestSuiteHelper;
-import de.jplag.endtoend.model.*;
+import de.jplag.endtoend.model.ExpectedResult;
+import de.jplag.endtoend.model.Options;
+import de.jplag.endtoend.model.ResultDescription;
 import de.jplag.exceptions.ExitException;
 import de.jplag.exceptions.ExitException;
 import de.jplag.options.JPlagOptions;
 import de.jplag.options.JPlagOptions;
 
 
@@ -36,8 +38,9 @@ import de.jplag.options.JPlagOptions;
  * original class. The results are compared with the results from previous tests and changes are detected.
  * original class. The results are compared with the results from previous tests and changes are detected.
  */
  */
 public class EndToEndSuiteTest {
 public class EndToEndSuiteTest {
+    private static final double EPSILON = 1E-8;
     // Language -> directory names and Paths
     // Language -> directory names and Paths
-    private Map<String, Map<String, Path>> LanguageToTestCaseMapper;
+    private Map<String, Map<String, Path>> languageToTestCaseMapper;
 
 
     private List<Options> options;
     private List<Options> options;
 
 
@@ -47,7 +50,7 @@ public class EndToEndSuiteTest {
 
 
     public EndToEndSuiteTest() throws IOException {
     public EndToEndSuiteTest() throws IOException {
         // Loading the test resources
         // Loading the test resources
-        LanguageToTestCaseMapper = TestSuiteHelper.getAllLanguageResources();
+        languageToTestCaseMapper = TestSuiteHelper.getAllLanguageResources();
         // creating the temporary lists for the test run
         // creating the temporary lists for the test run
         validationErrors = new ArrayList<>();
         validationErrors = new ArrayList<>();
         temporaryResultList = new HashMap<>();
         temporaryResultList = new HashMap<>();
@@ -82,7 +85,7 @@ public class EndToEndSuiteTest {
      */
      */
     @TestFactory
     @TestFactory
     Collection<DynamicTest> dynamicOverAllTest() throws IOException {
     Collection<DynamicTest> dynamicOverAllTest() throws IOException {
-        for (Entry<String, Map<String, Path>> languageMap : LanguageToTestCaseMapper.entrySet()) {
+        for (Entry<String, Map<String, Path>> languageMap : languageToTestCaseMapper.entrySet()) {
             String currentLanguageIdentifier = languageMap.getKey();
             String currentLanguageIdentifier = languageMap.getKey();
             for (Entry<String, Path> languagePaths : languageMap.getValue().entrySet()) {
             for (Entry<String, Path> languagePaths : languageMap.getValue().entrySet()) {
                 String[] fileNames = FileHelper.loadAllTestFileNames(languagePaths.getValue());
                 String[] fileNames = FileHelper.loadAllTestFileNames(languagePaths.getValue());
@@ -154,20 +157,20 @@ public class EndToEndSuiteTest {
             String identifier = TestSuiteHelper.getTestIdentifier(jPlagComparison);
             String identifier = TestSuiteHelper.getTestIdentifier(jPlagComparison);
             addToTemporaryResultMap(directoryName, options, jPlagComparison, languageIdentifier);
             addToTemporaryResultMap(directoryName, options, jPlagComparison, languageIdentifier);
 
 
-            assertNotNull(currentResultDescription, "No stored result could be found for the current LanguageOption! " + options.toString());
+            assertNotNull(currentResultDescription, "No stored result could be found for the current LanguageOption! " + options);
 
 
             ExpectedResult result = currentResultDescription.getExpectedResultByIdentifier(TestSuiteHelper.getTestIdentifier(jPlagComparison));
             ExpectedResult result = currentResultDescription.getExpectedResultByIdentifier(TestSuiteHelper.getTestIdentifier(jPlagComparison));
             assertNotNull(result, "No stored result could be found for the identifier! " + identifier);
             assertNotNull(result, "No stored result could be found for the identifier! " + identifier);
 
 
-            if (Float.compare(result.resultSimilarityMinimum(), jPlagComparison.minimalSimilarity()) != 0) {
+            if (areDoublesDifferent(result.resultSimilarityMinimum(), jPlagComparison.minimalSimilarity())) {
                 addToValidationErrors("minimalSimilarity", String.valueOf(result.resultSimilarityMinimum()),
                 addToValidationErrors("minimalSimilarity", String.valueOf(result.resultSimilarityMinimum()),
                         String.valueOf(jPlagComparison.minimalSimilarity()));
                         String.valueOf(jPlagComparison.minimalSimilarity()));
             }
             }
-            if (Float.compare(result.resultSimilarityMaximum(), jPlagComparison.maximalSimilarity()) != 0) {
+            if (areDoublesDifferent(result.resultSimilarityMaximum(), jPlagComparison.maximalSimilarity())) {
                 addToValidationErrors("maximalSimilarity", String.valueOf(result.resultSimilarityMaximum()),
                 addToValidationErrors("maximalSimilarity", String.valueOf(result.resultSimilarityMaximum()),
                         String.valueOf(jPlagComparison.maximalSimilarity()));
                         String.valueOf(jPlagComparison.maximalSimilarity()));
             }
             }
-            if (Integer.compare(result.resultMatchedTokenNumber(), jPlagComparison.getNumberOfMatchedTokens()) != 0) {
+            if (result.resultMatchedTokenNumber() != jPlagComparison.getNumberOfMatchedTokens()) {
                 addToValidationErrors("numberOfMatchedTokens", String.valueOf(result.resultMatchedTokenNumber()),
                 addToValidationErrors("numberOfMatchedTokens", String.valueOf(result.resultMatchedTokenNumber()),
                         String.valueOf(jPlagComparison.getNumberOfMatchedTokens()));
                         String.valueOf(jPlagComparison.getNumberOfMatchedTokens()));
             }
             }
@@ -176,6 +179,10 @@ public class EndToEndSuiteTest {
         }
         }
     }
     }
 
 
+    private boolean areDoublesDifferent(double d1, double d2) {
+        return Math.abs(d1 - d2) >= EPSILON;
+    }
+
     /**
     /**
      * Creates the display message for failed tests
      * Creates the display message for failed tests
      * @param valueName Name of the failed test object
      * @param valueName Name of the failed test object

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 236 - 236
jplag.endtoend-testing/src/test/resources/results/java/sortAlgo.json


+ 19 - 19
jplag/src/main/java/de/jplag/JPlagComparison.java

@@ -103,24 +103,24 @@ public class JPlagComparison { // FIXME TS: contains a lot of code duplication
     /**
     /**
      * @return Maximum similarity in percent of both submissions.
      * @return Maximum similarity in percent of both submissions.
      */
      */
-    public final float maximalSimilarity() {
+    public final double maximalSimilarity() {
         return Math.max(similarityOfFirst(), similarityOfSecond());
         return Math.max(similarityOfFirst(), similarityOfSecond());
     }
     }
 
 
     /**
     /**
      * @return Minimum similarity in percent of both submissions.
      * @return Minimum similarity in percent of both submissions.
      */
      */
-    public final float minimalSimilarity() {
+    public final double minimalSimilarity() {
         return Math.min(similarityOfFirst(), similarityOfSecond());
         return Math.min(similarityOfFirst(), similarityOfSecond());
     }
     }
 
 
     /**
     /**
      * @return Similarity in percent (what percentage of tokens across both submissions are matched).
      * @return Similarity in percent (what percentage of tokens across both submissions are matched).
      */
      */
-    public final float similarity() {
+    public final double similarity() {
         boolean subtractBaseCode = firstSubmission.hasBaseCodeMatches() && secondSubmission.hasBaseCodeMatches();
         boolean subtractBaseCode = firstSubmission.hasBaseCodeMatches() && secondSubmission.hasBaseCodeMatches();
-        float sa = firstSubmission.getSimilarityDivisor(subtractBaseCode);
-        float sb = secondSubmission.getSimilarityDivisor(subtractBaseCode);
+        double sa = firstSubmission.getSimilarityDivisor(subtractBaseCode);
+        double sb = secondSubmission.getSimilarityDivisor(subtractBaseCode);
         return (200 * getNumberOfMatchedTokens()) / (sa + sb);
         return (200 * getNumberOfMatchedTokens()) / (sa + sb);
     }
     }
 
 
@@ -128,39 +128,39 @@ public class JPlagComparison { // FIXME TS: contains a lot of code duplication
      * @return Similarity in percent for the first submission (what percent of the first submission is similar to the
      * @return Similarity in percent for the first submission (what percent of the first submission is similar to the
      * second).
      * second).
      */
      */
-    public final float similarityOfFirst() {
+    public final double similarityOfFirst() {
         int divisor = firstSubmission.getSimilarityDivisor(true);
         int divisor = firstSubmission.getSimilarityDivisor(true);
-        return (divisor == 0 ? 0f : (getNumberOfMatchedTokens() * 100 / (float) divisor));
+        return (divisor == 0 ? 0 : (getNumberOfMatchedTokens() * 100 / (double) divisor));
     }
     }
 
 
     /**
     /**
      * @return Similarity in percent for the second submission (what percent of the second submission is similar to the
      * @return Similarity in percent for the second submission (what percent of the second submission is similar to the
      * first).
      * first).
      */
      */
-    public final float similarityOfSecond() {
+    public final double similarityOfSecond() {
         int divisor = secondSubmission.getSimilarityDivisor(true);
         int divisor = secondSubmission.getSimilarityDivisor(true);
-        return (divisor == 0 ? 0f : (getNumberOfMatchedTokens() * 100 / (float) divisor));
+        return (divisor == 0 ? 0 : (getNumberOfMatchedTokens() * 100 / (double) divisor));
     }
     }
 
 
     /**
     /**
      * @return Similarity in percent rounded down to the nearest tenth.
      * @return Similarity in percent rounded down to the nearest tenth.
      */
      */
-    public final float roundedSimilarity() {
-        return ((int) (similarity() * ROUNDING_FACTOR)) / (float) ROUNDING_FACTOR;
+    public final double roundedSimilarity() {
+        return ((int) (similarity() * ROUNDING_FACTOR)) / (double) ROUNDING_FACTOR;
     }
     }
 
 
     /**
     /**
      * @return Similarity of the first submission to the basecode in percent rounded down to the nearest tenth.
      * @return Similarity of the first submission to the basecode in percent rounded down to the nearest tenth.
      */
      */
-    public final float basecodeSimilarityOfFirst() {
-        return ((int) (firstBasecodeSimilarity() * ROUNDING_FACTOR)) / (float) ROUNDING_FACTOR;
+    public final double basecodeSimilarityOfFirst() {
+        return ((int) (firstBasecodeSimilarity() * ROUNDING_FACTOR)) / (double) ROUNDING_FACTOR;
     }
     }
 
 
     /**
     /**
      * @return Similarity of the second submission to the basecode in percent rounded down to the nearest tenth.
      * @return Similarity of the second submission to the basecode in percent rounded down to the nearest tenth.
      */
      */
-    public final float basecodeSimilarityOfSecond() {
-        return ((int) (secondBasecodeSimilarity() * ROUNDING_FACTOR)) / (float) ROUNDING_FACTOR;
+    public final double basecodeSimilarityOfSecond() {
+        return ((int) (secondBasecodeSimilarity() * ROUNDING_FACTOR)) / (double) ROUNDING_FACTOR;
     }
     }
 
 
     @Override
     @Override
@@ -168,14 +168,14 @@ public class JPlagComparison { // FIXME TS: contains a lot of code duplication
         return firstSubmission.getName() + " <-> " + secondSubmission.getName();
         return firstSubmission.getName() + " <-> " + secondSubmission.getName();
     }
     }
 
 
-    private float firstBasecodeSimilarity() {
-        float sa = firstSubmission.getSimilarityDivisor(false);
+    private double firstBasecodeSimilarity() {
+        double sa = firstSubmission.getSimilarityDivisor(false);
         JPlagComparison firstBaseCodeMatches = firstSubmission.getBaseCodeComparison();
         JPlagComparison firstBaseCodeMatches = firstSubmission.getBaseCodeComparison();
         return firstBaseCodeMatches.getNumberOfMatchedTokens() * 100 / sa;
         return firstBaseCodeMatches.getNumberOfMatchedTokens() * 100 / sa;
     }
     }
 
 
-    private float secondBasecodeSimilarity() {
-        float sb = secondSubmission.getSimilarityDivisor(false);
+    private double secondBasecodeSimilarity() {
+        double sb = secondSubmission.getSimilarityDivisor(false);
         JPlagComparison secondBaseCodeMatches = secondSubmission.getBaseCodeComparison();
         JPlagComparison secondBaseCodeMatches = secondSubmission.getBaseCodeComparison();
         return secondBaseCodeMatches.getNumberOfMatchedTokens() * 100 / sb;
         return secondBaseCodeMatches.getNumberOfMatchedTokens() * 100 / sb;
     }
     }

+ 4 - 4
jplag/src/main/java/de/jplag/JPlagResult.java

@@ -1,7 +1,7 @@
 package de.jplag;
 package de.jplag;
 
 
 import java.util.List;
 import java.util.List;
-import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
 
 
 import de.jplag.clustering.ClusteringResult;
 import de.jplag.clustering.ClusteringResult;
 import de.jplag.options.JPlagOptions;
 import de.jplag.options.JPlagOptions;
@@ -31,7 +31,7 @@ public class JPlagResult {
         this.durationInMillis = durationInMillis;
         this.durationInMillis = durationInMillis;
         this.options = options;
         this.options = options;
         similarityDistribution = calculateSimilarityDistribution(comparisons);
         similarityDistribution = calculateSimilarityDistribution(comparisons);
-        comparisons.sort((first, second) -> Float.compare(second.similarity(), first.similarity())); // Sort by percentage (descending).
+        comparisons.sort((first, second) -> Double.compare(second.similarity(), first.similarity())); // Sort by percentage (descending).
     }
     }
 
 
     /**
     /**
@@ -134,11 +134,11 @@ public class JPlagResult {
         return calculateDistributionFor(comparisons, JPlagComparison::similarity);
         return calculateDistributionFor(comparisons, JPlagComparison::similarity);
     }
     }
 
 
-    private int[] calculateDistributionFor(List<JPlagComparison> comparisons, Function<JPlagComparison, Float> similarityExtractor) {
+    private int[] calculateDistributionFor(List<JPlagComparison> comparisons, ToDoubleFunction<JPlagComparison> similarityExtractor) {
         int[] similarityDistribution = new int[SIMILARITY_DISTRIBUTION_SIZE];
         int[] similarityDistribution = new int[SIMILARITY_DISTRIBUTION_SIZE];
         int similarityDistributionBucketSize = 100 / SIMILARITY_DISTRIBUTION_SIZE;
         int similarityDistributionBucketSize = 100 / SIMILARITY_DISTRIBUTION_SIZE;
         for (JPlagComparison comparison : comparisons) {
         for (JPlagComparison comparison : comparisons) {
-            float similarity = similarityExtractor.apply(comparison); // extract similarity in percent: 0f <= similarity <= 100f
+            double similarity = similarityExtractor.applyAsDouble(comparison); // extract similarity in percent: 0f <= similarity <= 100f
             int index = (int) (similarity / similarityDistributionBucketSize); // divide similarity by bucket size to find index of correct bucket.
             int index = (int) (similarity / similarityDistributionBucketSize); // divide similarity by bucket size to find index of correct bucket.
             index = Math.min(index, SIMILARITY_DISTRIBUTION_SIZE - 1);// index is out of bounds when similarity is 100%. decrease by one to count
             index = Math.min(index, SIMILARITY_DISTRIBUTION_SIZE - 1);// index is out of bounds when similarity is 100%. decrease by one to count
                                                                       // towards the highest value bucket
                                                                       // towards the highest value bucket

+ 11 - 11
jplag/src/main/java/de/jplag/clustering/Cluster.java

@@ -11,17 +11,17 @@ import java.util.function.BiFunction;
  */
  */
 public class Cluster<T> {
 public class Cluster<T> {
 
 
-    private final float communityStrength;
+    private final double communityStrength;
     private final Collection<T> members;
     private final Collection<T> members;
     private ClusteringResult<T> clusteringResult = null;
     private ClusteringResult<T> clusteringResult = null;
-    private final float averageSimilarity;
+    private final double averageSimilarity;
 
 
     /**
     /**
      * @param members Members of the cluster.
      * @param members Members of the cluster.
      * @param communityStrength A metric of how strongly the members of this cluster are connected.
      * @param communityStrength A metric of how strongly the members of this cluster are connected.
      * @param averageSimilarity The average similarity between all tuple comparisons of the members in this cluster.
      * @param averageSimilarity The average similarity between all tuple comparisons of the members in this cluster.
      */
      */
-    public Cluster(Collection<T> members, float communityStrength, float averageSimilarity) {
+    public Cluster(Collection<T> members, double communityStrength, double averageSimilarity) {
         this.members = new ArrayList<>(members);
         this.members = new ArrayList<>(members);
         this.communityStrength = communityStrength;
         this.communityStrength = communityStrength;
         this.averageSimilarity = averageSimilarity;
         this.averageSimilarity = averageSimilarity;
@@ -37,7 +37,7 @@ public class Cluster<T> {
     /**
     /**
      * @return average similarity between all tuple comparisons of the members in this cluster.
      * @return average similarity between all tuple comparisons of the members in this cluster.
      */
      */
-    public float getAverageSimilarity() {
+    public double getAverageSimilarity() {
         return averageSimilarity;
         return averageSimilarity;
     }
     }
 
 
@@ -45,7 +45,7 @@ public class Cluster<T> {
      * See {@link ClusteringResult#getCommunityStrength}
      * See {@link ClusteringResult#getCommunityStrength}
      * @return community strength of the cluster
      * @return community strength of the cluster
      */
      */
-    public float getCommunityStrength() {
+    public double getCommunityStrength() {
         return communityStrength;
         return communityStrength;
     }
     }
 
 
@@ -61,7 +61,7 @@ public class Cluster<T> {
     /**
     /**
      * @return How much each member of this cluster contributes to the {@link ClusteringResult#getCommunityStrength}.
      * @return How much each member of this cluster contributes to the {@link ClusteringResult#getCommunityStrength}.
      */
      */
-    public float getCommunityStrengthPerConnection() {
+    public double getCommunityStrengthPerConnection() {
         int size = members.size();
         int size = members.size();
         if (size < 2)
         if (size < 2)
             return 0;
             return 0;
@@ -74,9 +74,9 @@ public class Cluster<T> {
      * non-clusters. This method may only be called on clusters that are part of a ClusteringResult.
      * non-clusters. This method may only be called on clusters that are part of a ClusteringResult.
      * @return normalized community strength per connection
      * @return normalized community strength per connection
      */
      */
-    public float getNormalizedCommunityStrengthPerConnection() {
+    public double getNormalizedCommunityStrengthPerConnection() {
         List<Cluster<T>> goodClusters = clusteringResult.getClusters().stream().filter(cluster -> cluster.getCommunityStrength() > 0).toList();
         List<Cluster<T>> goodClusters = clusteringResult.getClusters().stream().filter(cluster -> cluster.getCommunityStrength() > 0).toList();
-        float posCommunityStrengthSum = (float) goodClusters.stream().mapToDouble(Cluster::getCommunityStrengthPerConnection).sum();
+        double posCommunityStrengthSum = goodClusters.stream().mapToDouble(Cluster::getCommunityStrengthPerConnection).sum();
 
 
         int size = clusteringResult.getClusters().size();
         int size = clusteringResult.getClusters().size();
         if (size < 2)
         if (size < 2)
@@ -87,7 +87,7 @@ public class Cluster<T> {
     /**
     /**
      * How much this cluster is worth during optimization.
      * How much this cluster is worth during optimization.
      */
      */
-    public double getWorth(BiFunction<T, T, Float> similarity) {
+    public double getWorth(BiFunction<T, T, Double> similarity) {
         double communityStrength = getCommunityStrength();
         double communityStrength = getCommunityStrength();
         if (members.size() > 1) {
         if (members.size() > 1) {
             communityStrength /= connections();
             communityStrength /= connections();
@@ -101,12 +101,12 @@ public class Cluster<T> {
      * @param similarity function that supplies the similarity of two cluster members.
      * @param similarity function that supplies the similarity of two cluster members.
      * @return average similarity
      * @return average similarity
      */
      */
-    private float averageSimilarity(BiFunction<T, T, Float> similarity) {
+    private double averageSimilarity(BiFunction<T, T, Double> similarity) {
         List<T> members = new ArrayList<>(this.members);
         List<T> members = new ArrayList<>(this.members);
         if (members.size() < 2) {
         if (members.size() < 2) {
             return 1;
             return 1;
         }
         }
-        float similaritySum = 0;
+        double similaritySum = 0;
         for (int i = 0; i < members.size(); i++) {
         for (int i = 0; i < members.size(); i++) {
             for (int j = i + 1; j < members.size(); j++) {
             for (int j = i + 1; j < members.size(); j++) {
                 similaritySum += similarity.apply(members.get(i), members.get(j));
                 similaritySum += similarity.apply(members.get(i), members.get(j));

+ 3 - 3
jplag/src/main/java/de/jplag/clustering/ClusteringAdapter.java

@@ -3,7 +3,7 @@ package de.jplag.clustering;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.List;
 import java.util.List;
-import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
 
 
 import org.apache.commons.math3.linear.Array2DRowRealMatrix;
 import org.apache.commons.math3.linear.Array2DRowRealMatrix;
 import org.apache.commons.math3.linear.RealMatrix;
 import org.apache.commons.math3.linear.RealMatrix;
@@ -30,7 +30,7 @@ public class ClusteringAdapter {
      * @param comparisons that should be included in the process of clustering
      * @param comparisons that should be included in the process of clustering
      * @param metric function that assigns a similarity to each comparison
      * @param metric function that assigns a similarity to each comparison
      */
      */
-    public ClusteringAdapter(Collection<JPlagComparison> comparisons, Function<JPlagComparison, Float> metric) {
+    public ClusteringAdapter(Collection<JPlagComparison> comparisons, ToDoubleFunction<JPlagComparison> metric) {
         mapping = new IntegerMapping<>(comparisons.size());
         mapping = new IntegerMapping<>(comparisons.size());
         for (JPlagComparison comparison : comparisons) {
         for (JPlagComparison comparison : comparisons) {
             mapping.map(comparison.getFirstSubmission());
             mapping.map(comparison.getFirstSubmission());
@@ -42,7 +42,7 @@ public class ClusteringAdapter {
         for (JPlagComparison comparison : comparisons) {
         for (JPlagComparison comparison : comparisons) {
             int firstIndex = mapping.map(comparison.getFirstSubmission());
             int firstIndex = mapping.map(comparison.getFirstSubmission());
             int secondIndex = mapping.map(comparison.getSecondSubmission());
             int secondIndex = mapping.map(comparison.getSecondSubmission());
-            float similarity = metric.apply(comparison);
+            double similarity = metric.applyAsDouble(comparison);
             similarityMatrix.setEntry(firstIndex, secondIndex, similarity);
             similarityMatrix.setEntry(firstIndex, secondIndex, similarity);
             similarityMatrix.setEntry(secondIndex, firstIndex, similarity);
             similarityMatrix.setEntry(secondIndex, firstIndex, similarity);
         }
         }

+ 1 - 1
jplag/src/main/java/de/jplag/clustering/ClusteringFactory.java

@@ -62,7 +62,7 @@ public class ClusteringFactory {
 
 
     private static void logClusters(ClusteringResult<Submission> result) {
     private static void logClusters(ClusteringResult<Submission> result) {
         var clusters = new ArrayList<>(result.getClusters());
         var clusters = new ArrayList<>(result.getClusters());
-        Collections.sort(clusters, (first, second) -> Float.compare(second.getCommunityStrength(), first.getCommunityStrength()));
+        clusters.sort((first, second) -> Double.compare(second.getCommunityStrength(), first.getCommunityStrength()));
         logger.info(CLUSTERING_RESULT, clusters.size());
         logger.info(CLUSTERING_RESULT, clusters.size());
         clusters.forEach(it -> logger.info(CLUSTER_PATTERN, it.getCommunityStrength(), it.getAverageSimilarity(), it.getMembers()));
         clusters.forEach(it -> logger.info(CLUSTER_PATTERN, it.getCommunityStrength(), it.getAverageSimilarity(), it.getMembers()));
     }
     }

+ 16 - 16
jplag/src/main/java/de/jplag/clustering/ClusteringOptions.java

@@ -34,15 +34,15 @@ import de.jplag.options.SimilarityMetric;
  * @param preprocessorPercentile up to which percentile of similarities the percentile-preprocessor zeroes out the
  * @param preprocessorPercentile up to which percentile of similarities the percentile-preprocessor zeroes out the
  * similarities
  * similarities
  */
  */
-public record ClusteringOptions(SimilarityMetric similarityMetric, float spectralKernelBandwidth, float spectralGaussianProcessVariance,
-        int spectralMinRuns, int spectralMaxRuns, int spectralMaxKMeansIterationPerRun, float agglomerativeThreshold, Preprocessing preprocessor,
-        boolean enabled, ClusteringAlgorithm algorithm, InterClusterSimilarity agglomerativeInterClusterSimilarity, float preprocessorThreshold,
-        float preprocessorPercentile) {
-
-    public ClusteringOptions(SimilarityMetric similarityMetric, float spectralKernelBandwidth, float spectralGaussianProcessVariance,
-            int spectralMinRuns, int spectralMaxRuns, int spectralMaxKMeansIterationPerRun, float agglomerativeThreshold, Preprocessing preprocessor,
-            boolean enabled, ClusteringAlgorithm algorithm, InterClusterSimilarity agglomerativeInterClusterSimilarity, float preprocessorThreshold,
-            float preprocessorPercentile) {
+public record ClusteringOptions(SimilarityMetric similarityMetric, double spectralKernelBandwidth, double spectralGaussianProcessVariance,
+        int spectralMinRuns, int spectralMaxRuns, int spectralMaxKMeansIterationPerRun, double agglomerativeThreshold, Preprocessing preprocessor,
+        boolean enabled, ClusteringAlgorithm algorithm, InterClusterSimilarity agglomerativeInterClusterSimilarity, double preprocessorThreshold,
+        double preprocessorPercentile) {
+
+    public ClusteringOptions(SimilarityMetric similarityMetric, double spectralKernelBandwidth, double spectralGaussianProcessVariance,
+            int spectralMinRuns, int spectralMaxRuns, int spectralMaxKMeansIterationPerRun, double agglomerativeThreshold, Preprocessing preprocessor,
+            boolean enabled, ClusteringAlgorithm algorithm, InterClusterSimilarity agglomerativeInterClusterSimilarity, double preprocessorThreshold,
+            double preprocessorPercentile) {
         this.similarityMetric = Objects.requireNonNull(similarityMetric);
         this.similarityMetric = Objects.requireNonNull(similarityMetric);
         this.spectralKernelBandwidth = spectralKernelBandwidth;
         this.spectralKernelBandwidth = spectralKernelBandwidth;
         this.spectralGaussianProcessVariance = spectralGaussianProcessVariance;
         this.spectralGaussianProcessVariance = spectralGaussianProcessVariance;
@@ -59,8 +59,8 @@ public record ClusteringOptions(SimilarityMetric similarityMetric, float spectra
     }
     }
 
 
     public ClusteringOptions() {
     public ClusteringOptions() {
-        this(SimilarityMetric.MAX, 20.f, 0.05f * 0.05f, 5, 50, 200, 0.2f, Preprocessing.CUMULATIVE_DISTRIBUTION_FUNCTION, true,
-                ClusteringAlgorithm.SPECTRAL, InterClusterSimilarity.AVERAGE, 0.2f, 0.5f);
+        this(SimilarityMetric.MAX, 20.f, 0.05 * 0.05, 5, 50, 200, 0.2, Preprocessing.CUMULATIVE_DISTRIBUTION_FUNCTION, true,
+                ClusteringAlgorithm.SPECTRAL, InterClusterSimilarity.AVERAGE, 0.2, 0.5);
     }
     }
 
 
     public ClusteringOptions withSimilarityMetric(SimilarityMetric similarityMetric) {
     public ClusteringOptions withSimilarityMetric(SimilarityMetric similarityMetric) {
@@ -69,13 +69,13 @@ public record ClusteringOptions(SimilarityMetric similarityMetric, float spectra
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);
     }
     }
 
 
-    public ClusteringOptions withSpectralKernelBandwidth(float spectralKernelBandwidth) {
+    public ClusteringOptions withSpectralKernelBandwidth(double spectralKernelBandwidth) {
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);
     }
     }
 
 
-    public ClusteringOptions withSpectralGaussianProcessVariance(float spectralGaussianProcessVariance) {
+    public ClusteringOptions withSpectralGaussianProcessVariance(double spectralGaussianProcessVariance) {
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);
@@ -99,7 +99,7 @@ public record ClusteringOptions(SimilarityMetric similarityMetric, float spectra
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);
     }
     }
 
 
-    public ClusteringOptions withAgglomerativeThreshold(float agglomerativeThreshold) {
+    public ClusteringOptions withAgglomerativeThreshold(double agglomerativeThreshold) {
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);
@@ -129,13 +129,13 @@ public record ClusteringOptions(SimilarityMetric similarityMetric, float spectra
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);
     }
     }
 
 
-    public ClusteringOptions withPreprocessorThreshold(float preprocessorThreshold) {
+    public ClusteringOptions withPreprocessorThreshold(double preprocessorThreshold) {
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);
     }
     }
 
 
-    public ClusteringOptions withPreprocessorPercentile(float preprocessorPercentile) {
+    public ClusteringOptions withPreprocessorPercentile(double preprocessorPercentile) {
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
         return new ClusteringOptions(similarityMetric, spectralKernelBandwidth, spectralGaussianProcessVariance, spectralMinRuns, spectralMaxRuns,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 spectralMaxKMeansIterationPerRun, agglomerativeThreshold, preprocessor, enabled, algorithm, agglomerativeInterClusterSimilarity,
                 preprocessorThreshold, preprocessorPercentile);
                 preprocessorThreshold, preprocessorPercentile);

+ 27 - 21
jplag/src/main/java/de/jplag/clustering/ClusteringResult.java

@@ -1,6 +1,12 @@
 package de.jplag.clustering;
 package de.jplag.clustering;
 
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.function.BiFunction;
 import java.util.function.BiFunction;
 import java.util.stream.DoubleStream;
 import java.util.stream.DoubleStream;
 
 
@@ -14,9 +20,9 @@ import org.apache.commons.math3.linear.RealMatrix;
 public class ClusteringResult<T> {
 public class ClusteringResult<T> {
 
 
     private final List<Cluster<T>> clusters;
     private final List<Cluster<T>> clusters;
-    private final float communityStrength;
+    private final double communityStrength;
 
 
-    public ClusteringResult(Collection<Cluster<T>> clusters, float communityStrength) {
+    public ClusteringResult(Collection<Cluster<T>> clusters, double communityStrength) {
         this.clusters = List.copyOf(clusters);
         this.clusters = List.copyOf(clusters);
         this.communityStrength = communityStrength;
         this.communityStrength = communityStrength;
         for (Cluster<T> cluster : clusters) {
         for (Cluster<T> cluster : clusters) {
@@ -36,7 +42,7 @@ public class ClusteringResult<T> {
      * 10.1103/PhysRevE.69.026113 It's called modularity in that paper.
      * 10.1103/PhysRevE.69.026113 It's called modularity in that paper.
      * @return community strength
      * @return community strength
      */
      */
-    public float getCommunityStrength() {
+    public double getCommunityStrength() {
         return communityStrength;
         return communityStrength;
     }
     }
 
 
@@ -45,8 +51,8 @@ public class ClusteringResult<T> {
      * @param similarity TODO DF: JAVADOC
      * @param similarity TODO DF: JAVADOC
      * @return worth
      * @return worth
      */
      */
-    public float getWorth(BiFunction<T, T, Float> similarity) {
-        return (float) getClusters().stream().mapToDouble(c -> c.getWorth(similarity)).map(worth -> Double.isFinite(worth) ? worth : 0).average()
+    public double getWorth(BiFunction<T, T, Double> similarity) {
+        return getClusters().stream().mapToDouble(c -> c.getWorth(similarity)).map(worth -> Double.isFinite(worth) ? worth : 0).average()
                 .getAsDouble();
                 .getAsDouble();
     }
     }
 
 
@@ -65,7 +71,7 @@ public class ClusteringResult<T> {
             clusterIdx++;
             clusterIdx++;
         }
         }
         List<Cluster<Integer>> clusters = new ArrayList<>(clustering.size());
         List<Cluster<Integer>> clusters = new ArrayList<>(clustering.size());
-        float communityStrength = 0;
+        double communityStrength = 0;
         if (!clustering.isEmpty()) {
         if (!clustering.isEmpty()) {
             RealMatrix percentagesOfSimilaritySums = new Array2DRowRealMatrix(clustering.size(), clustering.size());
             RealMatrix percentagesOfSimilaritySums = new Array2DRowRealMatrix(clustering.size(), clustering.size());
             percentagesOfSimilaritySums = percentagesOfSimilaritySums.scalarMultiply(0);
             percentagesOfSimilaritySums = percentagesOfSimilaritySums.scalarMultiply(0);
@@ -86,16 +92,16 @@ public class ClusteringResult<T> {
             for (int i = 0; i < clustering.size(); i++) {
             for (int i = 0; i < clustering.size(); i++) {
                 double outWeightSum = percentagesOfSimilaritySums.getRowVector(i).getL1Norm();
                 double outWeightSum = percentagesOfSimilaritySums.getRowVector(i).getL1Norm();
                 double clusterCommunityStrength = percentagesOfSimilaritySums.getEntry(i, i) - outWeightSum * outWeightSum;
                 double clusterCommunityStrength = percentagesOfSimilaritySums.getEntry(i, i) - outWeightSum * outWeightSum;
-                float averageSimilarity = calculateAverageSimilarityFor(clustering.get(i), similarity);
-                clusters.add(new Cluster<>(clustering.get(i), (float) clusterCommunityStrength, averageSimilarity));
+                double averageSimilarity = calculateAverageSimilarityFor(clustering.get(i), similarity);
+                clusters.add(new Cluster<>(clustering.get(i), clusterCommunityStrength, averageSimilarity));
                 communityStrength += clusterCommunityStrength;
                 communityStrength += clusterCommunityStrength;
             }
             }
         }
         }
         return new ClusteringResult<>(clusters, communityStrength);
         return new ClusteringResult<>(clusters, communityStrength);
     }
     }
 
 
-    private static float calculateAverageSimilarityFor(Collection<Integer> cluster, RealMatrix similarityMatrix) {
-        var sumOfSimilarities = 0f;
+    private static double calculateAverageSimilarityFor(Collection<Integer> cluster, RealMatrix similarityMatrix) {
+        double sumOfSimilarities = 0;
         List<Integer> indices = List.copyOf(cluster);
         List<Integer> indices = List.copyOf(cluster);
         for (int i = 1; i < cluster.size(); i++) {
         for (int i = 1; i < cluster.size(); i++) {
             int indexOfSubmission1 = indices.get(i);
             int indexOfSubmission1 = indices.get(i);
@@ -105,16 +111,16 @@ public class ClusteringResult<T> {
             }
             }
         }
         }
         int nMinusOne = cluster.size() - 1;
         int nMinusOne = cluster.size() - 1;
-        float numberOfComparisons = (nMinusOne * (nMinusOne + 1))
-                / 2f; /*
-                       * Use Gauss sum to calculate number of comparisons in cluster: Given cluster of size n we need Gauss sum of n-1
-                       * comparisons: compare first element of cluster to all other except itself: n-1 comparisons. compare second element to
-                       * all other except itself and first element (as these two were already compared when we processed the first element),
-                       * n-2 comparisons. compare third element to all other but itself and all previously compared: n-3 comparisons and so
-                       * on. when we reach the second to last element we have n-(n-1)=1 comparisons left. when we reach the last element it
-                       * has already been compared to all other. adding up all comparisons we get: (n-1) + (n-2) + (n-3) + ... + (n-(n-1)) =
-                       * Gauss sum of (n-1)
-                       */
+        double numberOfComparisons = (nMinusOne * (nMinusOne + 1)) / 2.0;
+        /*
+         * Use Gauss sum to calculate number of comparisons in cluster: Given cluster of size n we need Gauss sum of n-1
+         * comparisons: compare first element of cluster to all other except itself: n-1 comparisons. compare second element to
+         * all other except itself and first element (as these two were already compared when we processed the first element),
+         * n-2 comparisons. compare third element to all other but itself and all previously compared: n-3 comparisons and so
+         * on. when we reach the second to last element we have n-(n-1)=1 comparisons left. when we reach the last element it
+         * has already been compared to all other. adding up all comparisons we get: (n-1) + (n-2) + (n-3) + ... + (n-(n-1)) =
+         * Gauss sum of (n-1)
+         */
         return sumOfSimilarities / numberOfComparisons;
         return sumOfSimilarities / numberOfComparisons;
     }
     }
 
 

+ 3 - 3
jplag/src/main/java/de/jplag/clustering/algorithm/AgglomerativeClustering.java

@@ -49,7 +49,7 @@ public class AgglomerativeClustering implements GenericClusteringAlgorithm {
             Cluster leftCluster = initialClusters.get(leftIndex);
             Cluster leftCluster = initialClusters.get(leftIndex);
             for (int rightIndex = leftIndex + 1; rightIndex < initialClusters.size(); rightIndex++) {
             for (int rightIndex = leftIndex + 1; rightIndex < initialClusters.size(); rightIndex++) {
                 Cluster rightCluster = initialClusters.get(rightIndex);
                 Cluster rightCluster = initialClusters.get(rightIndex);
-                initialSimilarities.add(new ClusterConnection(leftCluster, rightCluster, (float) similarityMatrix.getEntry(leftIndex, rightIndex)));
+                initialSimilarities.add(new ClusterConnection(leftCluster, rightCluster, similarityMatrix.getEntry(leftIndex, rightIndex)));
             }
             }
         }
         }
 
 
@@ -70,7 +70,7 @@ public class AgglomerativeClustering implements GenericClusteringAlgorithm {
             nearest.left.submissions().addAll(nearest.right.submissions());
             nearest.left.submissions().addAll(nearest.right.submissions());
             Cluster combined = new Cluster(nearest.left.submissions());
             Cluster combined = new Cluster(nearest.left.submissions());
             for (Cluster otherCluster : clusters) {
             for (Cluster otherCluster : clusters) {
-                float similarity = options.agglomerativeInterClusterSimilarity().clusterSimilarity(combined.submissions, otherCluster.submissions,
+                double similarity = options.agglomerativeInterClusterSimilarity().clusterSimilarity(combined.submissions, otherCluster.submissions,
                         similarityMatrix);
                         similarityMatrix);
                 similarities.add(new ClusterConnection(combined, otherCluster, similarity));
                 similarities.add(new ClusterConnection(combined, otherCluster, similarity));
             }
             }
@@ -80,7 +80,7 @@ public class AgglomerativeClustering implements GenericClusteringAlgorithm {
         return clusters.stream().map(Cluster::submissions).collect(Collectors.toList());
         return clusters.stream().map(Cluster::submissions).collect(Collectors.toList());
     }
     }
 
 
-    private record ClusterConnection(Cluster left, Cluster right, float similarity) implements Comparable<ClusterConnection> {
+    private record ClusterConnection(Cluster left, Cluster right, double similarity) implements Comparable<ClusterConnection> {
         @Override
         @Override
         public int compareTo(ClusterConnection other) {
         public int compareTo(ClusterConnection other) {
             return (int) Math.signum(other.similarity - similarity);
             return (int) Math.signum(other.similarity - similarity);

+ 9 - 9
jplag/src/main/java/de/jplag/clustering/algorithm/InterClusterSimilarity.java

@@ -6,14 +6,14 @@ import java.util.function.BinaryOperator;
 import org.apache.commons.math3.linear.RealMatrix;
 import org.apache.commons.math3.linear.RealMatrix;
 
 
 public enum InterClusterSimilarity {
 public enum InterClusterSimilarity {
-    MIN(Float.MAX_VALUE, Math::min),
-    MAX(Float.MIN_VALUE, Math::max),
-    AVERAGE(0, Float::sum);
+    MIN(Double.MAX_VALUE, Math::min),
+    MAX(Double.MIN_VALUE, Math::max),
+    AVERAGE(0, Double::sum);
 
 
-    private final float neutralElement;
-    private final BinaryOperator<Float> accumulator;
+    private final double neutralElement;
+    private final BinaryOperator<Double> accumulator;
 
 
-    InterClusterSimilarity(float neutralElement, BinaryOperator<Float> accumulator) {
+    InterClusterSimilarity(double neutralElement, BinaryOperator<Double> accumulator) {
         this.neutralElement = neutralElement;
         this.neutralElement = neutralElement;
         this.accumulator = accumulator;
         this.accumulator = accumulator;
     }
     }
@@ -25,12 +25,12 @@ public enum InterClusterSimilarity {
      * @param similarityMatrix matrix containing similarities
      * @param similarityMatrix matrix containing similarities
      * @return similarity between the two clusters
      * @return similarity between the two clusters
      */
      */
-    public float clusterSimilarity(List<Integer> leftCluster, List<Integer> rightCluster, RealMatrix similarityMatrix) {
-        float similarity = this.neutralElement;
+    public double clusterSimilarity(List<Integer> leftCluster, List<Integer> rightCluster, RealMatrix similarityMatrix) {
+        double similarity = this.neutralElement;
 
 
         for (int leftSubmission : leftCluster) {
         for (int leftSubmission : leftCluster) {
             for (int rightSubmission : rightCluster) {
             for (int rightSubmission : rightCluster) {
-                float submissionSimilarity = (float) similarityMatrix.getEntry(leftSubmission, rightSubmission);
+                double submissionSimilarity = similarityMatrix.getEntry(leftSubmission, rightSubmission);
                 similarity = this.accumulator.apply(similarity, submissionSimilarity);
                 similarity = this.accumulator.apply(similarity, submissionSimilarity);
             }
             }
         }
         }

+ 1 - 2
jplag/src/main/java/de/jplag/clustering/algorithm/SpectralClustering.java

@@ -95,8 +95,7 @@ public class SpectralClustering implements GenericClusteringAlgorithm {
             clusters = Math.min(maxClusters, clusters);
             clusters = Math.min(maxClusters, clusters);
             Collection<Collection<Integer>> clustering = cluster(clusters, dimension, eigenValueIds, eigenDecomposition);
             Collection<Collection<Integer>> clustering = cluster(clusters, dimension, eigenValueIds, eigenDecomposition);
             ClusteringResult<Integer> modularityRes = ClusteringResult.fromIntegerCollections(new ArrayList<>(clustering), similarityMatrix);
             ClusteringResult<Integer> modularityRes = ClusteringResult.fromIntegerCollections(new ArrayList<>(clustering), similarityMatrix);
-            return new BayesianOptimization.OptimizationResult<>(modularityRes.getWorth((a, b) -> (float) similarityMatrix.getEntry(a, b)),
-                    clustering);
+            return new BayesianOptimization.OptimizationResult<>(modularityRes.getWorth(similarityMatrix::getEntry), clustering);
         });
         });
 
 
         return bayesianOptimizationResult.getValue();
         return bayesianOptimizationResult.getValue();

+ 2 - 2
jplag/src/main/java/de/jplag/clustering/preprocessors/PercentileThresholdProcessor.java

@@ -12,10 +12,10 @@ import de.jplag.clustering.ClusteringPreprocessor;
  */
  */
 public class PercentileThresholdProcessor implements ClusteringPreprocessor {
 public class PercentileThresholdProcessor implements ClusteringPreprocessor {
 
 
-    private final float percentile;
+    private final double percentile;
     private ThresholdPreprocessor thresholdPreprocessor;
     private ThresholdPreprocessor thresholdPreprocessor;
 
 
-    public PercentileThresholdProcessor(float percentile) {
+    public PercentileThresholdProcessor(double percentile) {
         this.percentile = percentile;
         this.percentile = percentile;
     }
     }
 
 

+ 6 - 6
jplag/src/main/java/de/jplag/options/JPlagOptions.java

@@ -50,11 +50,11 @@ import de.jplag.strategy.ComparisonMode;
  */
  */
 public record JPlagOptions(Language language, Integer minimumTokenMatch, List<String> submissionDirectories, List<String> oldSubmissionDirectories,
 public record JPlagOptions(Language language, Integer minimumTokenMatch, List<String> submissionDirectories, List<String> oldSubmissionDirectories,
         String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
         String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
-        SimilarityMetric similarityMetric, float similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
+        SimilarityMetric similarityMetric, double similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
         ComparisonMode comparisonMode, Verbosity verbosity, boolean debugParser) {
         ComparisonMode comparisonMode, Verbosity verbosity, boolean debugParser) {
 
 
     public static final ComparisonMode DEFAULT_COMPARISON_MODE = NORMAL;
     public static final ComparisonMode DEFAULT_COMPARISON_MODE = NORMAL;
-    public static final float DEFAULT_SIMILARITY_THRESHOLD = 0;
+    public static final double DEFAULT_SIMILARITY_THRESHOLD = 0;
     public static final int DEFAULT_SHOWN_COMPARISONS = 30;
     public static final int DEFAULT_SHOWN_COMPARISONS = 30;
     public static final int SHOW_ALL_COMPARISONS = 0;
     public static final int SHOW_ALL_COMPARISONS = 0;
     public static final SimilarityMetric DEFAULT_SIMILARITY_METRIC = SimilarityMetric.AVG;
     public static final SimilarityMetric DEFAULT_SIMILARITY_METRIC = SimilarityMetric.AVG;
@@ -69,7 +69,7 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, List<St
 
 
     public JPlagOptions(Language language, Integer minimumTokenMatch, List<String> submissionDirectories, List<String> oldSubmissionDirectories,
     public JPlagOptions(Language language, Integer minimumTokenMatch, List<String> submissionDirectories, List<String> oldSubmissionDirectories,
             String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
             String baseCodeSubmissionName, String subdirectoryName, List<String> fileSuffixes, String exclusionFileName,
-            SimilarityMetric similarityMetric, float similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
+            SimilarityMetric similarityMetric, double similarityThreshold, int maximumNumberOfComparisons, ClusteringOptions clusteringOptions,
             ComparisonMode comparisonMode, Verbosity verbosity, boolean debugParser) {
             ComparisonMode comparisonMode, Verbosity verbosity, boolean debugParser) {
         this.language = language;
         this.language = language;
         this.comparisonMode = comparisonMode;
         this.comparisonMode = comparisonMode;
@@ -112,7 +112,7 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, List<St
                 clusteringOptions, comparisonMode, verbosity, debugParser);
                 clusteringOptions, comparisonMode, verbosity, debugParser);
     }
     }
 
 
-    public JPlagOptions withSimilarityThreshold(float similarityThreshold) {
+    public JPlagOptions withSimilarityThreshold(double similarityThreshold) {
         return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionName,
         return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionName,
                 subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
                 subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
                 clusteringOptions, comparisonMode, verbosity, debugParser);
                 clusteringOptions, comparisonMode, verbosity, debugParser);
@@ -189,7 +189,7 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, List<St
     @Override
     @Override
     public List<String> fileSuffixes() {
     public List<String> fileSuffixes() {
         var language = language();
         var language = language();
-        if (fileSuffixes == null && language != null)
+        if ((fileSuffixes == null || fileSuffixes.isEmpty()) && language != null)
             return Arrays.stream(language.suffixes()).toList();
             return Arrays.stream(language.suffixes()).toList();
         return fileSuffixes == null ? null : Collections.unmodifiableList(fileSuffixes);
         return fileSuffixes == null ? null : Collections.unmodifiableList(fileSuffixes);
     }
     }
@@ -232,7 +232,7 @@ public record JPlagOptions(Language language, Integer minimumTokenMatch, List<St
         }
         }
     }
     }
 
 
-    private static float normalizeSimilarityThreshold(float similarityThreshold) {
+    private static double normalizeSimilarityThreshold(double similarityThreshold) {
         if (similarityThreshold > 100) {
         if (similarityThreshold > 100) {
             logger.warn("Maximum threshold of 100 used instead of {}", similarityThreshold);
             logger.warn("Maximum threshold of 100 used instead of {}", similarityThreshold);
             return 100;
             return 100;

+ 9 - 9
jplag/src/main/java/de/jplag/options/SimilarityMetric.java

@@ -1,27 +1,27 @@
 package de.jplag.options;
 package de.jplag.options;
 
 
-import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
 
 
 import de.jplag.JPlagComparison;
 import de.jplag.JPlagComparison;
 
 
-public enum SimilarityMetric implements Function<JPlagComparison, Float> {
+public enum SimilarityMetric implements ToDoubleFunction<JPlagComparison> {
     AVG(JPlagComparison::similarity),
     AVG(JPlagComparison::similarity),
     MIN(JPlagComparison::minimalSimilarity),
     MIN(JPlagComparison::minimalSimilarity),
     MAX(JPlagComparison::maximalSimilarity),
     MAX(JPlagComparison::maximalSimilarity),
-    INTERSECTION(it -> (float) it.getNumberOfMatchedTokens());
+    INTERSECTION(it -> (double) it.getNumberOfMatchedTokens());
 
 
-    private final Function<JPlagComparison, Float> similarityFunction;
+    private final ToDoubleFunction<JPlagComparison> similarityFunction;
 
 
-    SimilarityMetric(Function<JPlagComparison, Float> determinePercentage) {
+    SimilarityMetric(ToDoubleFunction<JPlagComparison> determinePercentage) {
         this.similarityFunction = determinePercentage;
         this.similarityFunction = determinePercentage;
     }
     }
 
 
-    public boolean isAboveThreshold(JPlagComparison comparison, float similarityThreshold) {
-        return similarityFunction.apply(comparison) >= similarityThreshold;
+    public boolean isAboveThreshold(JPlagComparison comparison, double similarityThreshold) {
+        return similarityFunction.applyAsDouble(comparison) >= similarityThreshold;
     }
     }
 
 
     @Override
     @Override
-    public Float apply(JPlagComparison comparison) {
-        return similarityFunction.apply(comparison);
+    public double applyAsDouble(JPlagComparison comparison) {
+        return similarityFunction.applyAsDouble(comparison);
     }
     }
 }
 }

+ 1 - 1
jplag/src/main/java/de/jplag/reporting/reportobject/mapper/MetricMapper.java

@@ -43,7 +43,7 @@ public class MetricMapper {
         return Arrays.stream(array).boxed().collect(Collectors.toList());
         return Arrays.stream(array).boxed().collect(Collectors.toList());
     }
     }
 
 
-    private List<TopComparison> getTopComparisons(List<JPlagComparison> comparisons, Function<JPlagComparison, Float> similarityExtractor) {
+    private List<TopComparison> getTopComparisons(List<JPlagComparison> comparisons, Function<JPlagComparison, Double> similarityExtractor) {
         return comparisons.stream().sorted(Comparator.comparing(similarityExtractor).reversed())
         return comparisons.stream().sorted(Comparator.comparing(similarityExtractor).reversed())
                 .map(comparison -> new TopComparison(submissionToIdFunction.apply(comparison.getFirstSubmission()),
                 .map(comparison -> new TopComparison(submissionToIdFunction.apply(comparison.getFirstSubmission()),
                         submissionToIdFunction.apply(comparison.getSecondSubmission()), similarityExtractor.apply(comparison)))
                         submissionToIdFunction.apply(comparison.getSecondSubmission()), similarityExtractor.apply(comparison)))

+ 1 - 1
jplag/src/main/java/de/jplag/reporting/reportobject/model/Cluster.java

@@ -4,6 +4,6 @@ import java.util.List;
 
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 
-public record Cluster(@JsonProperty("average_similarity") float averageSimilarity, @JsonProperty("strength") float strength,
+public record Cluster(@JsonProperty("average_similarity") double averageSimilarity, @JsonProperty("strength") double strength,
         @JsonProperty("members") List<String> members) {
         @JsonProperty("members") List<String> members) {
 }
 }

+ 1 - 1
jplag/src/main/java/de/jplag/reporting/reportobject/model/ComparisonReport.java

@@ -12,6 +12,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
  * @param matches the list of matches found in the comparison of the two submissions
  * @param matches the list of matches found in the comparison of the two submissions
  */
  */
 public record ComparisonReport(@JsonProperty("id1") String firstSubmissionId, @JsonProperty("id2") String secondSubmissionId,
 public record ComparisonReport(@JsonProperty("id1") String firstSubmissionId, @JsonProperty("id2") String secondSubmissionId,
-        @JsonProperty("similarity") float matchPercentage, @JsonProperty("matches") List<Match> matches) {
+        @JsonProperty("similarity") double matchPercentage, @JsonProperty("matches") List<Match> matches) {
 
 
 }
 }

+ 1 - 1
jplag/src/main/java/de/jplag/reporting/reportobject/model/TopComparison.java

@@ -3,5 +3,5 @@ package de.jplag.reporting.reportobject.model;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 
 public record TopComparison(@JsonProperty("first_submission") String firstSubmission, @JsonProperty("second_submission") String secondSubmission,
 public record TopComparison(@JsonProperty("first_submission") String firstSubmission, @JsonProperty("second_submission") String secondSubmission,
-        @JsonProperty("match_percentage") float matchPercentage) {
+        @JsonProperty("match_percentage") double matchPercentage) {
 }
 }

+ 1 - 1
jplag/src/test/java/de/jplag/BaseCodeTest.java

@@ -42,7 +42,7 @@ public class BaseCodeTest extends TestBase {
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().get(0).getMatches().size());
         assertEquals(1, result.getAllComparisons().get(0).getMatches().size());
         assertEquals(1, result.getSimilarityDistribution()[1]);
         assertEquals(1, result.getSimilarityDistribution()[1]);
-        assertEquals(85f, result.getAllComparisons().get(0).similarity(), DELTA);
+        assertEquals(85, result.getAllComparisons().get(0).similarity(), DELTA);
     }
     }
 
 
     @Test
     @Test

+ 14 - 14
jplag/src/test/java/de/jplag/NormalComparisonTest.java

@@ -25,7 +25,7 @@ class NormalComparisonTest extends TestBase {
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().get(0).getMatches().size());
         assertEquals(1, result.getAllComparisons().get(0).getMatches().size());
         assertEquals(1, result.getSimilarityDistribution()[3]);
         assertEquals(1, result.getSimilarityDistribution()[3]);
-        assertEquals(62.07f, result.getAllComparisons().get(0).similarity(), 0.1f);
+        assertEquals(62.07, result.getAllComparisons().get(0).similarity(), 0.1);
     }
     }
 
 
     /**
     /**
@@ -40,7 +40,7 @@ class NormalComparisonTest extends TestBase {
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(2, result.getAllComparisons().get(0).getMatches().size());
         assertEquals(2, result.getAllComparisons().get(0).getMatches().size());
         assertArrayEquals(expectedDistribution, result.getSimilarityDistribution());
         assertArrayEquals(expectedDistribution, result.getSimilarityDistribution());
-        assertEquals(96.55f, result.getAllComparisons().get(0).similarity(), 0.1f);
+        assertEquals(96.55, result.getAllComparisons().get(0).similarity(), 0.1);
     }
     }
 
 
     /**
     /**
@@ -53,7 +53,7 @@ class NormalComparisonTest extends TestBase {
         assertEquals(3, result.getNumberOfSubmissions());
         assertEquals(3, result.getNumberOfSubmissions());
         assertEquals(3, result.getAllComparisons().size());
         assertEquals(3, result.getAllComparisons().size());
 
 
-        result.getAllComparisons().forEach(comparison -> assertEquals(0f, comparison.similarity(), 0.1f));
+        result.getAllComparisons().forEach(comparison -> assertEquals(0, comparison.similarity(), 0.1));
     }
     }
 
 
     /**
     /**
@@ -71,27 +71,27 @@ class NormalComparisonTest extends TestBase {
         // All comparisons with E shall have no matches
         // All comparisons with E shall have no matches
         result.getAllComparisons().stream()
         result.getAllComparisons().stream()
                 .filter(comparison -> comparison.getSecondSubmission().getName().equals("E") || comparison.getFirstSubmission().getName().equals("E"))
                 .filter(comparison -> comparison.getSecondSubmission().getName().equals("E") || comparison.getFirstSubmission().getName().equals("E"))
-                .forEach(comparison -> assertEquals(0f, comparison.similarity(), DELTA));
+                .forEach(comparison -> assertEquals(0, comparison.similarity(), DELTA));
 
 
         // Hard coded assertions on selected comparisons
         // Hard coded assertions on selected comparisons
-        assertEquals(24.6f, getSelectedPercent(result, "A", "B"), 0.1f);
-        assertEquals(99.7f, getSelectedPercent(result, "A", "C"), 0.1f);
-        assertEquals(77.9f, getSelectedPercent(result, "A", "D"), 0.1f);
-        assertEquals(24.6f, getSelectedPercent(result, "B", "C"), 0.1f);
-        assertEquals(28.3f, getSelectedPercent(result, "B", "D"), 0.1f);
-        assertEquals(77.9f, getSelectedPercent(result, "C", "D"), 0.1f);
+        assertEquals(24.6, getSelectedPercent(result, "A", "B"), 0.1);
+        assertEquals(99.7, getSelectedPercent(result, "A", "C"), 0.1);
+        assertEquals(77.9, getSelectedPercent(result, "A", "D"), 0.1);
+        assertEquals(24.6, getSelectedPercent(result, "B", "C"), 0.1);
+        assertEquals(28.3, getSelectedPercent(result, "B", "D"), 0.1);
+        assertEquals(77.9, getSelectedPercent(result, "C", "D"), 0.1);
 
 
         // More detailed assertions for the plagiarism in A-D
         // More detailed assertions for the plagiarism in A-D
         var biggestMatch = getSelectedComparison(result, "A", "D");
         var biggestMatch = getSelectedComparison(result, "A", "D");
-        assertEquals(96.4f, biggestMatch.get().maximalSimilarity(), 0.1f);
-        assertEquals(65.3f, biggestMatch.get().minimalSimilarity(), 0.1f);
+        assertEquals(96.4, biggestMatch.get().maximalSimilarity(), 0.1);
+        assertEquals(65.3, biggestMatch.get().minimalSimilarity(), 0.1);
         assertEquals(12, biggestMatch.get().getMatches().size());
         assertEquals(12, biggestMatch.get().getMatches().size());
 
 
     }
     }
 
 
     // TODO SH: Methods like this should be moved to the API and also should accept wildcards
     // TODO SH: Methods like this should be moved to the API and also should accept wildcards
-    private float getSelectedPercent(JPlagResult result, String nameA, String nameB) {
-        return getSelectedComparison(result, nameA, nameB).map(JPlagComparison::similarity).orElse(-1f);
+    private double getSelectedPercent(JPlagResult result, String nameA, String nameB) {
+        return getSelectedComparison(result, nameA, nameB).map(JPlagComparison::similarity).orElse(-1.0);
     }
     }
 
 
     private Optional<JPlagComparison> getSelectedComparison(JPlagResult result, String nameA, String nameB) {
     private Optional<JPlagComparison> getSelectedComparison(JPlagResult result, String nameA, String nameB) {

+ 13 - 13
jplag/src/test/java/de/jplag/ParallelComparisonTest.java

@@ -28,7 +28,7 @@ public class ParallelComparisonTest extends TestBase {
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().size());
         assertEquals(1, result.getAllComparisons().get(0).getMatches().size());
         assertEquals(1, result.getAllComparisons().get(0).getMatches().size());
         assertEquals(1, result.getSimilarityDistribution()[3]);
         assertEquals(1, result.getSimilarityDistribution()[3]);
-        assertEquals(62.07f, result.getAllComparisons().get(0).similarity(), DELTA);
+        assertEquals(62.07, result.getAllComparisons().get(0).similarity(), DELTA);
     }
     }
 
 
     /**
     /**
@@ -41,7 +41,7 @@ public class ParallelComparisonTest extends TestBase {
         assertEquals(3, result.getNumberOfSubmissions());
         assertEquals(3, result.getNumberOfSubmissions());
         assertEquals(3, result.getAllComparisons().size());
         assertEquals(3, result.getAllComparisons().size());
 
 
-        result.getAllComparisons().forEach(comparison -> assertEquals(0f, comparison.similarity(), DELTA));
+        result.getAllComparisons().forEach(comparison -> assertEquals(0, comparison.similarity(), DELTA));
     }
     }
 
 
     /**
     /**
@@ -59,27 +59,27 @@ public class ParallelComparisonTest extends TestBase {
         // All comparisons with E shall have no matches
         // All comparisons with E shall have no matches
         result.getAllComparisons().stream()
         result.getAllComparisons().stream()
                 .filter(comparison -> comparison.getSecondSubmission().getName().equals("E") || comparison.getFirstSubmission().getName().equals("E"))
                 .filter(comparison -> comparison.getSecondSubmission().getName().equals("E") || comparison.getFirstSubmission().getName().equals("E"))
-                .forEach(comparison -> assertEquals(0f, comparison.similarity(), DELTA));
+                .forEach(comparison -> assertEquals(0, comparison.similarity(), DELTA));
 
 
         // Hard coded assertions on selected comparisons
         // Hard coded assertions on selected comparisons
-        assertEquals(24.6f, getSelectedPercent(result, "A", "B"), DELTA);
-        assertEquals(99.7f, getSelectedPercent(result, "A", "C"), DELTA);
-        assertEquals(77.9f, getSelectedPercent(result, "A", "D"), DELTA);
-        assertEquals(24.6f, getSelectedPercent(result, "B", "C"), DELTA);
-        assertEquals(28.3f, getSelectedPercent(result, "B", "D"), DELTA);
-        assertEquals(77.9f, getSelectedPercent(result, "C", "D"), DELTA);
+        assertEquals(24.6, getSelectedPercent(result, "A", "B"), DELTA);
+        assertEquals(99.7, getSelectedPercent(result, "A", "C"), DELTA);
+        assertEquals(77.9, getSelectedPercent(result, "A", "D"), DELTA);
+        assertEquals(24.6, getSelectedPercent(result, "B", "C"), DELTA);
+        assertEquals(28.3, getSelectedPercent(result, "B", "D"), DELTA);
+        assertEquals(77.9, getSelectedPercent(result, "C", "D"), DELTA);
 
 
         // More detailed assertions for the plagiarism in A-D
         // More detailed assertions for the plagiarism in A-D
         var biggestMatch = getSelectedComparison(result, "A", "D");
         var biggestMatch = getSelectedComparison(result, "A", "D");
-        assertEquals(96.4f, biggestMatch.get().maximalSimilarity(), DELTA);
-        assertEquals(65.3f, biggestMatch.get().minimalSimilarity(), DELTA);
+        assertEquals(96.4, biggestMatch.get().maximalSimilarity(), DELTA);
+        assertEquals(65.3, biggestMatch.get().minimalSimilarity(), DELTA);
         assertEquals(12, biggestMatch.get().getMatches().size());
         assertEquals(12, biggestMatch.get().getMatches().size());
 
 
     }
     }
 
 
     // TODO SH: Methods like this should be moved to the API and also should accept wildcards
     // TODO SH: Methods like this should be moved to the API and also should accept wildcards
-    private float getSelectedPercent(JPlagResult result, String nameA, String nameB) {
-        return getSelectedComparison(result, nameA, nameB).map(JPlagComparison::similarity).orElse(-1f);
+    private double getSelectedPercent(JPlagResult result, String nameA, String nameB) {
+        return getSelectedComparison(result, nameA, nameB).map(JPlagComparison::similarity).orElse(-1.0);
     }
     }
 
 
     private Optional<JPlagComparison> getSelectedComparison(JPlagResult result, String nameA, String nameB) {
     private Optional<JPlagComparison> getSelectedComparison(JPlagResult result, String nameA, String nameB) {

+ 1 - 1
jplag/src/test/java/de/jplag/TestBase.java

@@ -14,7 +14,7 @@ import de.jplag.options.Verbosity;
 public abstract class TestBase {
 public abstract class TestBase {
 
 
     protected static final String BASE_PATH = Path.of("src", "test", "resources", "de", "jplag", "samples").toString();
     protected static final String BASE_PATH = Path.of("src", "test", "resources", "de", "jplag", "samples").toString();
-    protected static final float DELTA = 0.1f;
+    protected static final double DELTA = 0.1;
 
 
     protected String getBasePath() {
     protected String getBasePath() {
         return BASE_PATH;
         return BASE_PATH;

+ 1 - 1
jplag/src/test/java/de/jplag/clustering/ClusteringAdapterTest.java

@@ -41,7 +41,7 @@ public class ClusteringAdapterTest {
             return List.of(IntStream.range(0, arg.getRowDimension()).boxed().collect(Collectors.toList()));
             return List.of(IntStream.range(0, arg.getRowDimension()).boxed().collect(Collectors.toList()));
         });
         });
 
 
-        ClusteringAdapter clustering = new ClusteringAdapter(comparisons, x -> 0.f);
+        ClusteringAdapter clustering = new ClusteringAdapter(comparisons, x -> 0.0);
         ClusteringResult<Submission> clusteringResult = clustering.doClustering(algorithm);
         ClusteringResult<Submission> clusteringResult = clustering.doClustering(algorithm);
 
 
         Collection<Collection<Submission>> expectedResult = List.of(submissions);
         Collection<Collection<Submission>> expectedResult = List.of(submissions);

+ 11 - 11
jplag/src/test/java/de/jplag/clustering/ClusteringResultTest.java

@@ -16,8 +16,8 @@ class ClusteringResultTest {
         RealMatrix similarity = new Array2DRowRealMatrix(4, 4);
         RealMatrix similarity = new Array2DRowRealMatrix(4, 4);
 
 
         // These are similar
         // These are similar
-        setEntries(similarity, 0, 1, 1f);
-        setEntries(similarity, 2, 3, 1f);
+        setEntries(similarity, 0, 1, 1.0);
+        setEntries(similarity, 2, 3, 1.0);
 
 
         // Others are dissimilar
         // Others are dissimilar
 
 
@@ -36,14 +36,14 @@ class ClusteringResultTest {
         // cluster
         // cluster
 
 
         // These are similar
         // These are similar
-        setEntries(similarity, 0, 1, 0.1f);
-        setEntries(similarity, 2, 3, 0.1f);
+        setEntries(similarity, 0, 1, 0.1);
+        setEntries(similarity, 2, 3, 0.1);
 
 
         // Others are dissimilar
         // Others are dissimilar
-        setEntries(similarity, 0, 2, 0.05f);
-        setEntries(similarity, 0, 3, 0.05f);
-        setEntries(similarity, 1, 2, 0.05f);
-        setEntries(similarity, 1, 3, 0.05f);
+        setEntries(similarity, 0, 2, 0.05);
+        setEntries(similarity, 0, 3, 0.05);
+        setEntries(similarity, 1, 2, 0.05);
+        setEntries(similarity, 1, 3, 0.05);
 
 
         ClusteringResult<Integer> result = ClusteringResult.fromIntegerCollections(List.of(List.of(0, 1), List.of(2, 3)), similarity);
         ClusteringResult<Integer> result = ClusteringResult.fromIntegerCollections(List.of(List.of(0, 1), List.of(2, 3)), similarity);
 
 
@@ -95,14 +95,14 @@ class ClusteringResultTest {
         RealMatrix similarity = new Array2DRowRealMatrix(4, 4);
         RealMatrix similarity = new Array2DRowRealMatrix(4, 4);
 
 
         // These are similar
         // These are similar
-        setEntries(similarity, 0, 1, 1f);
-        setEntries(similarity, 2, 3, 1f);
+        setEntries(similarity, 0, 1, 1.0);
+        setEntries(similarity, 2, 3, 1.0);
 
 
         // Others are dissimilar
         // Others are dissimilar
 
 
         ClusteringResult<Integer> result = ClusteringResult.fromIntegerCollections(List.of(List.of(0, 1), List.of(2, 3)), similarity);
         ClusteringResult<Integer> result = ClusteringResult.fromIntegerCollections(List.of(List.of(0, 1), List.of(2, 3)), similarity);
         var cluster = result.getClusters().stream().findFirst().orElseThrow();
         var cluster = result.getClusters().stream().findFirst().orElseThrow();
-        assertEquals(1f, cluster.getAverageSimilarity(), 0.00001);
+        assertEquals(1.0, cluster.getAverageSimilarity(), 0.00001);
     }
     }
 
 
     private static void setEntries(RealMatrix matrix, int i, int j, double similarity) {
     private static void setEntries(RealMatrix matrix, int i, int j, double similarity) {

+ 6 - 6
jplag/src/test/java/de/jplag/clustering/algorithm/ClusteringData.java

@@ -23,16 +23,16 @@ public enum ClusteringData {
         }
         }
         // These are similar
         // These are similar
         setEntries(similarity, 0, 1, 0.5);
         setEntries(similarity, 0, 1, 0.5);
-        setEntries(similarity, 2, 3, 0.5f);
+        setEntries(similarity, 2, 3, 0.5);
 
 
         // Others are dissimilar
         // Others are dissimilar
-        setEntries(similarity, 0, 2, 0.1f);
-        setEntries(similarity, 0, 3, 0.1f);
-        setEntries(similarity, 1, 2, 0.1f);
-        setEntries(similarity, 1, 3, 0.1f);
+        setEntries(similarity, 0, 2, 0.1);
+        setEntries(similarity, 0, 3, 0.1);
+        setEntries(similarity, 1, 2, 0.1);
+        setEntries(similarity, 1, 3, 0.1);
 
 
         return similarity;
         return similarity;
-    }, new int[][] {{0, 1}, {2, 3}}, new ClusteringOptions().withAgglomerativeThreshold(0.4f));
+    }, new int[][] {{0, 1}, {2, 3}}, new ClusteringOptions().withAgglomerativeThreshold(0.4));
 
 
     private final RealMatrix similarity;
     private final RealMatrix similarity;
     private final Set<Set<Integer>> expected;
     private final Set<Set<Integer>> expected;

+ 5 - 7
jplag/src/test/java/de/jplag/clustering/preprocessors/PercentilePreprocessorTest.java

@@ -1,6 +1,7 @@
 package de.jplag.clustering.preprocessors;
 package de.jplag.clustering.preprocessors;
 
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 
 import java.util.Optional;
 import java.util.Optional;
 
 
@@ -9,13 +10,11 @@ import org.junit.jupiter.api.Test;
 
 
 public class PercentilePreprocessorTest extends PreprocessingTestBase {
 public class PercentilePreprocessorTest extends PreprocessingTestBase {
 
 
-    private static final double EPSILON = 0.0000001;
-
     PercentileThresholdProcessor preprocessor;
     PercentileThresholdProcessor preprocessor;
 
 
     @BeforeEach
     @BeforeEach
     public void init() {
     public void init() {
-        preprocessor = new PercentileThresholdProcessor(0.5f);
+        preprocessor = new PercentileThresholdProcessor(0.5);
     }
     }
 
 
     @Test
     @Test
@@ -30,12 +29,11 @@ public class PercentilePreprocessorTest extends PreprocessingTestBase {
         double[][] original = createTestData();
         double[][] original = createTestData();
         double[][] result = preprocessor.preprocessSimilarities(original);
         double[][] result = preprocessor.preprocessSimilarities(original);
         withAllValues(preprocessor, original, result, (originalValue, preprocessed) -> {
         withAllValues(preprocessor, original, result, (originalValue, preprocessed) -> {
-            // Values are only 0.1 and 0.5; percentile 0.5 should only preserve values of
-            // 0.5.
-            if (originalValue > 0.1) {
+            // Median is 0.1 => Values >= 0.1 should preserved.
+            if (originalValue >= 0.1) {
                 assertEquals(Optional.of(originalValue), preprocessed);
                 assertEquals(Optional.of(originalValue), preprocessed);
             } else {
             } else {
-                assertEquals(0.0, preprocessed.orElse(0.0), EPSILON);
+                assertTrue(preprocessed.isEmpty());
             }
             }
         });
         });
     }
     }

+ 10 - 6
jplag/src/test/java/de/jplag/clustering/preprocessors/PreprocessingTestBase.java

@@ -3,7 +3,11 @@ package de.jplag.clustering.preprocessors;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.function.BiConsumer;
 import java.util.function.BiConsumer;
 import java.util.function.IntUnaryOperator;
 import java.util.function.IntUnaryOperator;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
@@ -26,13 +30,13 @@ public class PreprocessingTestBase {
         }
         }
         // These are similar
         // These are similar
         setEntries(similarity, 0, 1, 0.5);
         setEntries(similarity, 0, 1, 0.5);
-        setEntries(similarity, 2, 3, 0.5f);
+        setEntries(similarity, 2, 3, 0.5);
 
 
         // Others are dissimilar
         // Others are dissimilar
-        setEntries(similarity, 0, 2, 0.1f);
-        setEntries(similarity, 0, 3, 0.1f);
-        setEntries(similarity, 1, 2, 0.1f);
-        setEntries(similarity, 1, 3, 0.1f);
+        setEntries(similarity, 0, 2, 0.1);
+        setEntries(similarity, 0, 3, 0.1);
+        setEntries(similarity, 1, 2, 0.1);
+        setEntries(similarity, 1, 3, 0.1);
 
 
         // last row is empty
         // last row is empty
 
 

+ 6 - 6
jplag/src/test/java/de/jplag/reporting/reportobject/mapper/ClusteringResultMapperTest.java

@@ -21,21 +21,21 @@ public class ClusteringResultMapperTest {
     public void test() {
     public void test() {
         // given
         // given
         JPlagResult resultMock = mock(JPlagResult.class);
         JPlagResult resultMock = mock(JPlagResult.class);
-        Cluster<Submission> cluster1 = createClusterWith(0.2f, 0.4f, "1", "2");
-        Cluster<Submission> cluster2 = createClusterWith(0.3f, 0.6f, "3", "4", "5");
-        when(resultMock.getClusteringResult()).thenReturn(List.of(new ClusteringResult<>(List.of(cluster1, cluster2), 0.3f)));
+        Cluster<Submission> cluster1 = createClusterWith(0.2, 0.4, "1", "2");
+        Cluster<Submission> cluster2 = createClusterWith(0.3, 0.6, "3", "4", "5");
+        when(resultMock.getClusteringResult()).thenReturn(List.of(new ClusteringResult<>(List.of(cluster1, cluster2), 0.3)));
 
 
         // when
         // when
         var result = clusteringResultMapper.map(resultMock);
         var result = clusteringResultMapper.map(resultMock);
 
 
         // then
         // then
-        assertEquals(List.of(new de.jplag.reporting.reportobject.model.Cluster(0.4f, 0.2f, List.of("1", "2")),
-                new de.jplag.reporting.reportobject.model.Cluster(0.6f, 0.3f, List.of("3", "4", "5"))
+        assertEquals(List.of(new de.jplag.reporting.reportobject.model.Cluster(0.4, 0.2, List.of("1", "2")),
+                new de.jplag.reporting.reportobject.model.Cluster(0.6, 0.3, List.of("3", "4", "5"))
 
 
         ), result);
         ), result);
     }
     }
 
 
-    private Cluster<Submission> createClusterWith(Float communityStrength, Float averageSimilarity, String... ids) {
+    private Cluster<Submission> createClusterWith(Double communityStrength, Double averageSimilarity, String... ids) {
         var submissions = Arrays.stream(ids).map(this::submissionWithId).toList();
         var submissions = Arrays.stream(ids).map(this::submissionWithId).toList();
         return new Cluster<>(submissions, communityStrength, averageSimilarity);
         return new Cluster<>(submissions, communityStrength, averageSimilarity);
     }
     }

+ 9 - 7
jplag/src/test/java/de/jplag/reporting/reportobject/mapper/MetricMapperTest.java

@@ -1,6 +1,8 @@
 package de.jplag.reporting.reportobject.mapper;
 package de.jplag.reporting.reportobject.mapper;
 
 
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
@@ -21,14 +23,14 @@ public class MetricMapperTest {
     public void test_getAverageMetric() {
     public void test_getAverageMetric() {
         // given
         // given
         JPlagResult jPlagResult = createJPlagResult(MockMetric.AVG, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
         JPlagResult jPlagResult = createJPlagResult(MockMetric.AVG, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
-                comparison(submission("1"), submission("2"), .7f), comparison(submission("3"), submission("4"), .3f));
+                comparison(submission("1"), submission("2"), .7), comparison(submission("3"), submission("4"), .3));
         // when
         // when
         var result = metricMapper.getAverageMetric(jPlagResult);
         var result = metricMapper.getAverageMetric(jPlagResult);
 
 
         // then
         // then
         Assertions.assertEquals("AVG", result.name());
         Assertions.assertEquals("AVG", result.name());
         Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
         Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
-        Assertions.assertEquals(List.of(new TopComparison("1", "2", .7f), new TopComparison("3", "4", .3f)), result.topComparisons());
+        Assertions.assertEquals(List.of(new TopComparison("1", "2", .7), new TopComparison("3", "4", .3)), result.topComparisons());
         Assertions.assertEquals(
         Assertions.assertEquals(
                 "Average of both program coverages. This is the default similarity which"
                 "Average of both program coverages. This is the default similarity which"
                         + " works in most cases: Matches with a high average similarity indicate that the programs work " + "in a very similar way.",
                         + " works in most cases: Matches with a high average similarity indicate that the programs work " + "in a very similar way.",
@@ -39,14 +41,14 @@ public class MetricMapperTest {
     public void test_getMaxMetric() {
     public void test_getMaxMetric() {
         // given
         // given
         JPlagResult jPlagResult = createJPlagResult(MockMetric.MAX, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
         JPlagResult jPlagResult = createJPlagResult(MockMetric.MAX, distribution(2, 3, 5, 7, 11, 13, 17, 19, 23, 29),
-                comparison(submission("00"), submission("01"), .7f), comparison(submission("10"), submission("11"), .3f));
+                comparison(submission("00"), submission("01"), .7), comparison(submission("10"), submission("11"), .3));
         // when
         // when
         var result = metricMapper.getMaxMetric(jPlagResult);
         var result = metricMapper.getMaxMetric(jPlagResult);
 
 
         // then
         // then
         Assertions.assertEquals("MAX", result.name());
         Assertions.assertEquals("MAX", result.name());
         Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
         Assertions.assertIterableEquals(List.of(2, 3, 5, 7, 11, 13, 17, 19, 23, 29), result.distribution());
-        Assertions.assertEquals(List.of(new TopComparison("00", "01", .7f), new TopComparison("10", "11", .3f)), result.topComparisons());
+        Assertions.assertEquals(List.of(new TopComparison("00", "01", .7), new TopComparison("10", "11", .3)), result.topComparisons());
         Assertions.assertEquals(
         Assertions.assertEquals(
                 "Maximum of both program coverages. This ranking is especially useful if the programs are very "
                 "Maximum of both program coverages. This ranking is especially useful if the programs are very "
                         + "different in size. This can happen when dead code was inserted to disguise the origin of the plagiarized program.",
                         + "different in size. This can happen when dead code was inserted to disguise the origin of the plagiarized program.",
@@ -61,7 +63,7 @@ public class MetricMapperTest {
         return new CreateSubmission(name);
         return new CreateSubmission(name);
     }
     }
 
 
-    private Comparison comparison(CreateSubmission submission1, CreateSubmission submission2, float similarity) {
+    private Comparison comparison(CreateSubmission submission1, CreateSubmission submission2, double similarity) {
         return new Comparison(submission1, submission2, similarity);
         return new Comparison(submission1, submission2, similarity);
     }
     }
 
 
@@ -106,7 +108,7 @@ public class MetricMapperTest {
         AVG
         AVG
     }
     }
 
 
-    private record Comparison(CreateSubmission submission1, CreateSubmission submission2, float similarity) {
+    private record Comparison(CreateSubmission submission1, CreateSubmission submission2, double similarity) {
     }
     }
 
 
     private record CreateSubmission(String name) {
     private record CreateSubmission(String name) {

+ 4 - 4
jplag/src/test/java/de/jplag/special/VolumeTest.java

@@ -58,14 +58,14 @@ public class VolumeTest extends TestBase {
             var key = result.getFirstSubmission().getName() + result.getSecondSubmission().getName();
             var key = result.getFirstSubmission().getName() + result.getSecondSubmission().getName();
 
 
             assertTrue(csv.containsKey(key));
             assertTrue(csv.containsKey(key));
-            assertEquals(csv.getOrDefault(key, -1f), result.similarity(), DELTA);
+            assertEquals(csv.getOrDefault(key, -1.0), result.similarity(), DELTA);
         });
         });
 
 
     }
     }
 
 
-    private Map<String, Float> readCSVResults(String filePathAndName) throws IOException {
+    private Map<String, Double> readCSVResults(String filePathAndName) throws IOException {
         List<String> lines = Files.readAllLines(Path.of(filePathAndName), JPlagOptions.CHARSET);
         List<String> lines = Files.readAllLines(Path.of(filePathAndName), JPlagOptions.CHARSET);
-        var results = new HashMap<String, Float>();
+        var results = new HashMap<String, Double>();
 
 
         lines.forEach(line -> {
         lines.forEach(line -> {
             var entries = line.split(";");
             var entries = line.split(";");
@@ -74,7 +74,7 @@ public class VolumeTest extends TestBase {
                 throw new IllegalArgumentException(String.format("Illegal line: '%s'", line));
                 throw new IllegalArgumentException(String.format("Illegal line: '%s'", line));
             }
             }
 
 
-            results.put(entries[1] + entries[2], Float.parseFloat((entries[3])));
+            results.put(entries[1] + entries[2], Double.parseDouble((entries[3])));
         });
         });
 
 
         return results;
         return results;

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů