package de.gaalop.visualizer.zerofinding; import de.gaalop.cfg.AssignmentNode; import de.gaalop.dfg.MultivectorComponent; import de.gaalop.dfg.Variable; import de.gaalop.visitors.ReplaceVisitor; import de.gaalop.visualizer.Point3d; import java.util.HashMap; import java.util.LinkedList; import java.util.logging.Level; import java.util.logging.Logger; /** * Implements a zero finder method, which samples a cube and searches at * every sample point in a neighborhood along the gradient a zero point * * @author christian */ public class GradientMethod extends PrepareZerofinder { /** * Replaces x by ox+t, y by oy and z by oz in a list of assignment nodes * @param nodes The list of assignment nodes */ public static void replace(LinkedList<AssignmentNode> nodes) { //replace x=ox+t,y=oy,z=oz ReplaceVisitor visitor = new ReplaceVisitor() { private void visitVar(Variable node) { if (node.getName().equals("_V_X")) result = new MultivectorComponent("_V_ox", 0); if (node.getName().equals("_V_Y")) result = new MultivectorComponent("_V_oy", 0); if (node.getName().equals("_V_Z")) result = new MultivectorComponent("_V_oz", 0); } @Override public void visit(MultivectorComponent node) { visitVar(node); } @Override public void visit(Variable node) { visitVar(node); } }; for (AssignmentNode node: nodes) { node.setVariable((Variable) visitor.replace(node.getVariable())); node.setValue(visitor.replace(node.getValue())); } } /** * Differentiate the codepieces with respect to ox,oy,z * @param codePieces */ private void diffentiateCodePieces(LinkedList<CodePiece> codePieces) { //differentiate each item of codePieces with respect to ox,oy,oz with the help of maxima to _V_PRODUCT_SDx/y/z for (CodePiece cp: codePieces) { //Differntiate with respect to ox LinkedList<AssignmentNode> derived; derived = differentiater.differentiate(cp, new MultivectorComponent("_V_ox",0)); if (derived != null) for (AssignmentNode d: derived) { d.setVariable(new MultivectorComponent(d.getVariable().getName()+"Dx", 0)); cp.add(d); } //Differntiate with respect to oy derived = differentiater.differentiate(cp, new MultivectorComponent("_V_oy",0)); if (derived != null) for (AssignmentNode d: derived) { d.setVariable(new MultivectorComponent(d.getVariable().getName()+"Dy", 0)); cp.add(d); } //Differntiate with respect to oz derived = differentiater.differentiate(cp, new MultivectorComponent("_V_oz",0)); if (derived != null) for (AssignmentNode d: derived) { d.setVariable(new MultivectorComponent(d.getVariable().getName()+"Dz", 0)); cp.add(d); } } } /** * Prepares the graph, given by a list of assignment nodes, i.e. create code pieces, ... * @param nodes The list of nodes * @return The generated code pieces */ private LinkedList<CodePiece> prepareGraph(LinkedList<AssignmentNode> nodes) { //replace x=ox+t,y=oy,z=oz replace(nodes); //Insert expressions, like Maxima, !!! InsertingExpression.insertExpressions(nodes); //search _V_PRODUCT and apply the sum of the squares = _V_PRODUCT_S //and store the result in myNodes LinkedList<AssignmentNode> myNodes = createSumOfSquares(nodes); //Optimize pieces of code for each multivector to be rendered LinkedList<CodePiece> codePieces = optimizeCodePieces(myNodes); //differentiate each item of codePieces with respect to ox,oy,oz with the help of maxima to _V_PRODUCT_SDx/y/z diffentiateCodePieces(codePieces); return codePieces; } @Override public HashMap<String, LinkedList<Point3d>> findZeroLocations(HashMap<MultivectorComponent, Double> globalValues, LinkedList<AssignmentNode> assignmentNodes, HashMap<String, String> mapSettings, boolean renderIn2d) { int a = Integer.parseInt(mapSettings.get("cubeEdgeLength")); float dist = Float.parseFloat(mapSettings.get("density")); double epsilon = Double.parseDouble(mapSettings.get("epsilon")); int max_n = Integer.parseInt(mapSettings.get("max_n")); LinkedList<CodePiece> codePieces = prepareGraph(assignmentNodes); HashMap<String, LinkedList<Point3d>> result = new HashMap<String, LinkedList<Point3d>>(); for (CodePiece cp: codePieces) { //search zero locations of mv cp.name in every CodePiece cp LinkedList<Point3d> points = searchZeroLocations(cp, globalValues, a, dist, epsilon, max_n, renderIn2d); result.put(cp.nameOfMultivector, points); } return result; } @Override public String getName() { return "Gradient Method"; } /** * Searches zero locations in a neigboorhood in a code piece, * starts a number of search threads * @param cp The code piece * @param globalValues The global initialised values * @return The zero locations points */ private LinkedList<Point3d> searchZeroLocations(CodePiece cp, HashMap<MultivectorComponent, Double> globalValues, int a, float dist, double epsilon, int max_n, boolean renderIn2d) { LinkedList<Point3d> points = new LinkedList<Point3d>(); int processorCount = Runtime.getRuntime().availableProcessors(); GradientMethodThread[] threads = new GradientMethodThread[processorCount]; for (int i=0;i<processorCount;i++) { float from = (i*2*a)/((float) processorCount) - a; float to = ((i != processorCount-1) ? ((i+1)*2*a)/((float) processorCount) : 2*a) - a; threads[i] = new GradientMethodThread(from, to, a, dist, globalValues, cp, epsilon, max_n, renderIn2d); threads[i].start(); } for (int i=0;i<threads.length;i++) { try { threads[i].join(); points.addAll(threads[i].points); } catch (InterruptedException ex) { Logger.getLogger(DiscreteCubeMethod.class.getName()).log(Level.SEVERE, null, ex); } } return points; } @Override public HashMap<String, String> getSettings() { HashMap<String, String> result = new HashMap<String, String>(); result.put("cubeEdgeLength", "5"); result.put("density", "1"); result.put("epsilon", "1E-4"); result.put("max_n", "50"); return result; } }