Skip to content

Commit c944acd

Browse files
committed
Replaced polarisation exceptions by log events
1 parent f096e87 commit c944acd

File tree

2 files changed

+71
-34
lines changed

2 files changed

+71
-34
lines changed

dna/src/main/java/dna/export/Polarization.java

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -466,20 +466,19 @@ private class ClusterSolution implements Cloneable {
466466
* @param n The number of nodes (must be positive).
467467
* @param k The number of clusters (must be positive).
468468
* @param memberships The membership vector (length must equal n, values must be in the range [0, k - 1]).
469-
* @throws IllegalArgumentException If any parameter is invalid.
470469
*/
471470
ClusterSolution(int n, int k, int[] memberships) {
472471
if (n <= 0) {
473-
throw new IllegalArgumentException("N must be positive.");
474-
}
475-
if (k <= 1) {
476-
throw new IllegalArgumentException("K must be larger than 1.");
477-
}
478-
if (n <= k) {
479-
throw new IllegalArgumentException("N must be larger than K.");
472+
n = memberships.length;
473+
LogEvent log = new LogEvent(Logger.WARNING, "Invalid number of nodes.",
474+
"Number of nodes (N) must be positive. Using the length of the membership vector (" + n + ") instead.");
475+
Dna.logger.log(log);
480476
}
477+
validateArguments(n, k);
481478
if (memberships == null || memberships.length != n) {
482-
throw new IllegalArgumentException("Memberships must have length equal to N.");
479+
LogEvent log = new LogEvent(Logger.ERROR, "Invalid membership vector.",
480+
"Memberships must have length equal to N.");
481+
Dna.logger.log(log);
483482
}
484483
validateMemberships(memberships, k);
485484
this.N = n;
@@ -493,18 +492,9 @@ private class ClusterSolution implements Cloneable {
493492
* @param n The number of nodes (must be positive).
494493
* @param k The number of clusters (must be positive).
495494
* @param rng The random number generator.
496-
* @throws IllegalArgumentException If any parameter is invalid.
497495
*/
498496
ClusterSolution(int n, int k, Random rng) {
499-
if (n <= 0) {
500-
throw new IllegalArgumentException("N must be positive.");
501-
}
502-
if (k <= 1) {
503-
throw new IllegalArgumentException("K must be larger than 1.");
504-
}
505-
if (n <= k) {
506-
throw new IllegalArgumentException("N must be larger than K.");
507-
}
497+
validateArguments(n, k);
508498
this.N = n;
509499
this.K = k;
510500
this.memberships = createRandomMemberships(n, k, rng);
@@ -529,13 +519,37 @@ protected ClusterSolution clone() throws CloneNotSupportedException {
529519
return new ClusterSolution(this.N, this.K, this.memberships.clone());
530520
}
531521

522+
/**
523+
* Validates the input arguments for the ClusterSolution constructor.
524+
*
525+
* @param n The number of nodes.
526+
* @param k The number of clusters.
527+
*/
528+
private void validateArguments(int n, int k) {
529+
if (k <= 1) {
530+
k = 2;
531+
LogEvent log = new LogEvent(Logger.WARNING, "Invalid number of clusters.",
532+
"Number of clusters (K) must be greater than 1. Using 2 clusters instead.");
533+
Dna.logger.log(log);
534+
}
535+
if (n <= k) {
536+
LogEvent log = new LogEvent(Logger.ERROR, "Invalid number of nodes and clusters.",
537+
"Number of nodes (N) must be greater than the number of clusters (K).");
538+
Dna.logger.log(log);
539+
}
540+
}
532541
/**
533542
* Validates that all memberships are within the range [0, K - 1].
543+
*
544+
* @param memberships The membership vector to validate.
545+
* @param k The number of clusters.
534546
*/
535547
private void validateMemberships(int[] memberships, int k) {
536548
for (int membership : memberships) {
537549
if (membership < 0 || membership >= k) {
538-
throw new IllegalArgumentException("Membership values must be in the range [0, K - 1].");
550+
LogEvent log = new LogEvent(Logger.ERROR, "Invalid membership value.",
551+
"Membership values must be in the range [0, K - 1].");
552+
Dna.logger.log(log);
539553
}
540554
}
541555
}
@@ -581,12 +595,12 @@ private int[] createRandomMemberships(int N, int K, Random rng) {
581595
*
582596
* @param foreignMemberships A membership vector of a foreign cluster solution.
583597
* @param rng The random number generator to use.
584-
* @throws IllegalArgumentException If the input vector is invalid or incompatible.
585598
*/
586-
int[] crossover(int[] foreignMemberships, Random rng) throws IllegalArgumentException{
587-
// Validate input
599+
int[] crossover(int[] foreignMemberships, Random rng) {
588600
if (foreignMemberships == null || foreignMemberships.length != this.memberships.length) {
589-
throw new IllegalArgumentException("Incompatible membership vector lengths.");
601+
LogEvent log = new LogEvent(Logger.ERROR, "Invalid membership vector.",
602+
"Membership vector must have the same length as the current solution.");
603+
Dna.logger.log(log);
590604
}
591605
validateMemberships(foreignMemberships, K);
592606

@@ -804,7 +818,6 @@ private double[] evaluateQuality(double[][] congruenceNetwork, double[][] confli
804818
* @param q The array of quality values for the parent generation (their modularity or EI scores transformed to [0, 1] where 1 is high fitness).
805819
* @param numElites The number of elite solutions to retain for the children generation.
806820
* @return A list of children containing the cloned elite solutions from the parent generation.
807-
* @throws IllegalArgumentException If the elite percentage is outside the valid range [0, 1].
808821
*/
809822
private ArrayList<ClusterSolution> eliteRetentionStep (ArrayList<ClusterSolution> clusterSolutions, double[] q, int numElites) {
810823
int[] qRanks = calculateRanks(q); // Rank the quality values in descending order
@@ -815,7 +828,6 @@ private ArrayList<ClusterSolution> eliteRetentionStep (ArrayList<ClusterSolution
815828
try {
816829
children.add((ClusterSolution) clusterSolutions.get(i).clone());
817830
} catch (CloneNotSupportedException e) {
818-
819831
LogEvent log = new LogEvent(Logger.ERROR, "Elite solution at index " + i + " could not be cloned.", "Elite solutions are not copied to the children generation.");
820832
Dna.logger.log(log);
821833
}
@@ -925,7 +937,9 @@ private ArrayList<ClusterSolution> mutationStep(ArrayList<ClusterSolution> child
925937
return children; // No mutations to perform
926938
}
927939
if (numMutations < 0) {
928-
throw new IllegalArgumentException("Number of mutations must be non-negative.");
940+
LogEvent log = new LogEvent(Logger.ERROR, "Invalid number of mutations.",
941+
"Number of mutations must be non-negative.");
942+
Dna.logger.log(log);
929943
}
930944

931945
for (int i = numElites; i < numParents; i++) {
@@ -1125,8 +1139,9 @@ private PolarizationResult geneticTimeStep(int t, long seed) {
11251139
*
11261140
* @param matrix The matrix for which to calculate the norm.
11271141
* @return The entrywise 1-norm (= sum of all absolute cell values) of the matrix.
1142+
* @throws IllegalArgumentException if the matrix is null.
11281143
*/
1129-
private double calculateMatrixNorm(double[][] matrix) {
1144+
private double calculateMatrixNorm(double[][] matrix) throws IllegalArgumentException {
11301145
if (matrix == null) {
11311146
LogEvent log = new LogEvent(Logger.ERROR, "Matrix is null.", "Error when trying to calculate the matrix norm in the genetic algorithm. Matrix cannot be null.");
11321147
Dna.logger.log(log);
@@ -1487,7 +1502,15 @@ private PolarizationResult greedyTimeStep(Matrix congruence, Matrix conflict, bo
14871502
double[][] congruenceMatrix = congruence.getMatrix();
14881503
double[][] conflictMatrix = conflict.getMatrix();
14891504
ArrayList<Double> maxQArray = new ArrayList<Double>();
1490-
double combinedNorm = calculateMatrixNorm(congruenceMatrix) + calculateMatrixNorm(congruenceMatrix);
1505+
double combinedNorm = 0.0;
1506+
try {
1507+
combinedNorm = calculateMatrixNorm(congruenceMatrix) + calculateMatrixNorm(congruenceMatrix);
1508+
} catch (Exception e) {
1509+
LogEvent log = new LogEvent(Logger.ERROR,
1510+
"Error when calculating the matrix norm.",
1511+
"Error when calculating the matrix norm in the greedy algorithm.");
1512+
Dna.logger.log(log);
1513+
}
14911514

14921515
if (congruenceMatrix.length > 0 || combinedNorm == 0.0) { // if the network has no nodes or edges, skip this step and return 0 directly
14931516

dna/src/main/java/dna/export/PolarizationResult.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import java.util.Arrays;
55
import java.util.Objects;
66

7+
import dna.Dna;
8+
import logger.*;
9+
710
/**
811
* Stores the results of a single run of the genetic algorithm, i.e., for a
912
* single time step of the time window algorithm or the whole network if no
@@ -35,24 +38,35 @@ public final class PolarizationResult {
3538
* @param start The start date and time of the time window network. Cannot be null. If no time window was set, this is the date of the network.
3639
* @param stop The end date and time of the time window network. Cannot be null. If no time window was set, this is the date of the network.
3740
* @param middle The mid-point date of the time window network. Cannot be null. If no time window was set, this is the date of the network.
38-
* @throws IllegalArgumentException if any array is null, has invalid sizes, or if start, stop, or middle is null.
3941
*/
4042
public PolarizationResult(double[] maxQ, double[] avgQ, double[] sdQ, double finalMaxQ,
4143
int[] memberships, String[] names, boolean earlyConvergence,
4244
LocalDateTime start, LocalDateTime stop, LocalDateTime middle) {
4345

4446
// Validate input
4547
if (maxQ == null || avgQ == null || sdQ == null || memberships == null || names == null) {
46-
throw new IllegalArgumentException("Input arrays cannot be null.");
48+
LogEvent l = new LogEvent(Logger.ERROR,
49+
"Input arrays cannot be null.",
50+
"While creating a PolarizationResult object, null objects were encountered.");
51+
Dna.logger.log(l);
4752
}
4853
if (start == null || stop == null || middle == null) {
49-
throw new IllegalArgumentException("Start, stop, and middle dates cannot be null.");
54+
LogEvent l = new LogEvent(Logger.ERROR,
55+
"Dates cannot be null.",
56+
"While creating a PolarizationResult object, the start, stop, or middle date was null.");
57+
Dna.logger.log(l);
5058
}
5159
if (maxQ.length != avgQ.length || maxQ.length != sdQ.length) {
52-
throw new IllegalArgumentException("maxQ, avgQ, and sdQ must have the same length.");
60+
LogEvent l = new LogEvent(Logger.ERROR,
61+
"maxQ, avgQ, and sdQ must have the same length.",
62+
"While creating a PolarizationResult object, the maxQ, avgQ, and sdQ arrays had different lengths.");
63+
Dna.logger.log(l);
5364
}
5465
if (memberships.length != names.length) {
55-
throw new IllegalArgumentException("Memberships and names must have the same length.");
66+
LogEvent l = new LogEvent(Logger.ERROR,
67+
"Memberships and names must have the same length.",
68+
"While creating a PolarizationResult object, the memberships and names arrays had different lengths.");
69+
Dna.logger.log(l);
5670
}
5771

5872
// Assign fields

0 commit comments

Comments
 (0)