de.bund.bfr.knime.pmm.common/src/de/bund/bfr/knime/pmm/common/math/MathUtilities.java
File `MathUtilities.java` has 284 lines of code (exceeds 250 allowed). Consider refactoring./******************************************************************************* * Copyright (c) 2015 Federal Institute for Risk Assessment (BfR), Germany * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Department Biological Safety - BfR *******************************************************************************/package de.bund.bfr.knime.pmm.common.math; import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.regex.Matcher;import java.util.regex.Pattern; import org.apache.commons.math3.distribution.TDistribution;import org.lsmp.djep.djep.DJep;import org.lsmp.djep.djep.DiffRulesI;import org.lsmp.djep.djep.diffRules.MacroDiffRules;import org.lsmp.djep.xjep.MacroFunction;import org.nfunk.jep.ASTConstant;import org.nfunk.jep.ASTFunNode;import org.nfunk.jep.ASTVarNode;import org.nfunk.jep.Node;import org.nfunk.jep.ParseException; `MathUtilities` has 22 methods (exceeds 20 allowed). Consider refactoring.public class MathUtilities { public static double EPSILON = 0.00001; private static Random random = null; private MathUtilities() { } Method `nodeToString` has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring. public static String nodeToString(Node n) throws Exception { if (n instanceof ASTFunNode) { String s = n.toString() + "("; for (int i = 0; i < n.jjtGetNumChildren(); i++) { if (i != 0) { s += ","; } s += nodeToString(n.jjtGetChild(i)); } return s + ")"; } else if (n instanceof ASTConstant) { return n.toString(); } else if (n instanceof ASTVarNode) { return n.toString(); } else { throw new Exception("Unknown Node"); } } Method `removeNullValues` has a Cognitive Complexity of 17 (exceeds 5 allowed). Consider refactoring.
Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed. public static void removeNullValues(List<Double> targetValues, List<List<Double>> argumentValues) { for (int i = 0; i < targetValues.size(); i++) { boolean remove = false; if (targetValues.get(i) == null) { remove = true; continue; } if (!remove) { for (int j = 0; j < argumentValues.size(); j++) { if (argumentValues.get(j).get(i) == null) { remove = true; break; } } } if (remove) { targetValues.remove(i); for (int j = 0; j < argumentValues.size(); j++) { argumentValues.get(j).remove(i); } i--; } } } public static Random getRandomGenerator() { if (random == null) { random = new Random(); } return random; } public static int getRandomNegativeInt() { if (random == null) random = new Random(); int value = random.nextInt(); if (value > 0) value = -value; return value; } public static double computeSum(List<Double> values) { double sum = 0.0; for (double v : values) { sum += v; } return sum; } public static DJep createParser() { DJep parser = new DJep(); parser.setAllowAssignment(true); parser.setAllowUndeclared(true); parser.setImplicitMul(true); parser.addStandardFunctions(); parser.addStandardDiffRules(); parser.removeVariable("x"); try {Define a constant instead of duplicating this literal "log10" 3 times. parser.addFunction("log10", new MacroFunction("log10", 1, "ln(x)/ln(10)", parser)); parser.addDiffRule(new MacroDiffRules(parser, "log10", "1/(x*ln(10))")); parser.addDiffRule(new ZeroDiffRule("<")); parser.addDiffRule(new ZeroDiffRule(">")); parser.addDiffRule(new ZeroDiffRule("<=")); parser.addDiffRule(new ZeroDiffRule(">=")); parser.addDiffRule(new ZeroDiffRule("&&")); parser.addDiffRule(new ZeroDiffRule("||")); parser.addDiffRule(new ZeroDiffRule("==")); parser.addDiffRule(new ZeroDiffRule("!=")); } catch (ParseException e) { e.printStackTrace(); } return parser; } public static String replaceVariable(String formula, String var, String newVar) { if (var.equals(newVar)) { return formula; } String newFormular = " " + formula + " "; for (int i = 1; i < newFormular.length() - var.length(); i++) { boolean matches = newFormular.substring(i, i + var.length()).equals(var); boolean start = !isVariableCharacter(newFormular.charAt(i - 1)); boolean end = !isVariableCharacter(newFormular.charAt(i + var.length())); if (matches && start && end) { String prefix = newFormular.substring(0, i); String postfix = newFormular.substring(i + var.length()); newFormular = prefix + newVar + postfix; i = prefix.length() + newVar.length(); } } return newFormular.replace(" ", ""); } Method `isFunctionDefinedFor` has 7 arguments (exceeds 4 allowed). Consider refactoring. public static boolean isFunctionDefinedFor(String formula, List<String> parameters, List<Double> parameterValues, String variable, double minValue, double maxValue, int steps) { DJep parser = createParser(); Node function = null; parser.addVariable(variable, 0.0); Similar blocks of code found in 3 locations. Consider refactoring. for (int i = 0; i < parameters.size(); i++) { parser.addConstant(parameters.get(i), parameterValues.get(i)); } try { function = parser.parse(formula.substring(formula.indexOf("=") + 1)); for (int i = 0; i < steps; i++) { double value = minValue + (double) i / (double) (steps - 1) * (maxValue - minValue); parser.setVarValue(variable, value); if (!(parser.evaluate(function) instanceof Double)) { return false; } } } catch (ParseException e) { e.printStackTrace(); } return true; } Method `evaluateFunction` has 5 arguments (exceeds 4 allowed). Consider refactoring.
Method `evaluateFunction` has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring. public static List<Double> evaluateFunction(String formula, List<String> parameters, List<Double> parameterValues, List<String> variables, List<List<Double>> variableValues) { List<Double> values = new ArrayList<>(); DJep parser = createParser(); Similar blocks of code found in 3 locations. Consider refactoring. for (int i = 0; i < parameters.size(); i++) { parser.addConstant(parameters.get(i), parameterValues.get(i)); } for (int i = 0; i < variables.size(); i++) { parser.addVariable(variables.get(i), 0.0); } try { Node function = parser.parse(formula.substring(formula.indexOf("=") + 1)); for (int i = 0; i < variableValues.get(0).size(); i++) {Identical blocks of code found in 2 locations. Consider refactoring. for (int j = 0; j < variables.size(); j++) { parser.setVarValue(variables.get(j), variableValues.get(j).get(i)); } values.add((Double) parser.evaluate(function)); } } catch (ParseException e) { e.printStackTrace(); } return values; } private static class ZeroDiffRule implements DiffRulesI { private String name; public ZeroDiffRule(String name) { this.name = name; } @OverrideMethod `differentiate` has 5 arguments (exceeds 4 allowed). Consider refactoring. public Node differentiate(ASTFunNode node, String var, Node[] children, Node[] dchildren, DJep djep) throws ParseException { return djep.getNodeFactory().buildConstantNode(0.0); } @Override public String getName() { return name; } } public static Double getMSE(Double rmse) { if (rmse == null) { return null; } return rmse * rmse; } public static Double getRMSE(double sse, double numParam, double numSample) { if (numParam >= numSample) { return null; } return Math.sqrt(sse / (numSample - numParam)); } public static Double getRMSE(double sse, double numSample) { return Math.sqrt(sse / numSample); } public static Double getRSquared(double sse, List<Double> targetValues) { double targetMean = MathUtilities.computeSum(targetValues) / targetValues.size(); double targetTotalSumOfSquares = 0.0; for (int i = 0; i < targetValues.size(); i++) { targetTotalSumOfSquares += Math.pow(targetValues.get(i) - targetMean, 2.0); } Make sure "targetTotalSumOfSquares" can't be zero before doing this division. double rSquared = 1 - sse / targetTotalSumOfSquares; // rSquare < 0 möglich, siehe hier: // http://mars.wiwi.hu-berlin.de/mediawiki/sk/index.php/Bestimmtheitsmass return Math.max(rSquared, 0.0); } public static Double akaikeCriterion(final int numParam, final int numSample, final double sse) { if (numSample <= numParam + 2) { return null; } return numSample * Math.log(sse / numSample) + 2 * (numParam + 1) + 2 * (numParam + 1) * (numParam + 2) / (numSample - numParam - 2); } public static double getPValue(double tValue, int degreesOfFreedom) { TDistribution dist = new TDistribution(degreesOfFreedom); return 1.0 - dist.probability(-Math.abs(tValue), Math.abs(tValue)); } public static boolean isVariableCharacter(char ch) { return Character.isLetterOrDigit(ch) || ch == '_' || ch == '$'; } public static int generateID(int seed) { Random rand = new Random(seed); int id = rand.nextInt(); if (id > 0) { id = -id; } return id; } public static String getBoundaryCondition(String formula) { Pattern p = Pattern.compile("\\*\\(\\(\\(\\(\\(.+\\)\\)\\)\\)\\)$"); Matcher m = p.matcher(formula); while (m.find()) { String s = m.group(); s = s.substring(6, s.length() - 5); if (countOccurences(s, '(') == countOccurences(s, ')')) { return s; } } return null; } Method `getAllButBoundaryCondition` has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring. public static String getAllButBoundaryCondition(String formula) { String cond = getBoundaryCondition(formula); if (cond != null) { String f = formula.replace("*(((((" + cond + ")))))", ""); int i = f.indexOf("="); if (f.charAt(i + 1) == '(' && f.endsWith(")")) { String withoutBrackets = f.substring(i + 2, f.length() - 1); try { createParser().parse(withoutBrackets); f = f.substring(0, i + 1) + withoutBrackets; } catch (ParseException e) { // Do not remove brackets when expression without brackets // cannot be parsed } } return f; } else { return formula; } } public static String getFormula(String formula, String boundaryCondition) { if (boundaryCondition != null && !boundaryCondition.isEmpty()) { int i = formula.indexOf("="); return formula.substring(0, i + 1) + "(" + formula.substring(i + 1) + ")*(((((" + boundaryCondition + ")))))"; } else { return formula; } } public static boolean isValid(Object value) { return value instanceof Double && !((Double) value).isNaN() && !((Double) value).isInfinite(); } private static int countOccurences(String s, char c) { int n = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == c) { n++; } } return n; } }