diff --git a/misc/perp b/misc/perp index d687b927..9d4b48f4 100644 --- a/misc/perp +++ b/misc/perp @@ -2,21 +2,22 @@ pkg load optim; function y = f (x) - y(1) = ( + y = [ + ( (x(3) - x(1)) * (x(7) - x(5)) + (x(4) - x(2)) * (x(8) - x(6)) - ) ^ 2; - y(2) = ( + ) ^ 2, + ( (x(11) - x(9)) * (x(7) - x(5)) + (x(12) - x(10)) * (x(8) - x(6)) - ) ^ 2; + ) ^ 2]; y(3) = 0;y(4) = 0;y(5) = 0;y(6) = 0;y(7) = 0;y(8) = 0; y(9) = 0;y(10) = 0;y(11) = 0;y(12) = 0; endfunction x0 = [100, 100, 600, 600, 700, 600, 900, 100, 1100, 100, 1600, 600]; #x = fminunc(@f, reshape(x0, 12,1)); -x = bfgsmin('f', {reshape(x0, 12,1)}); #WORKS! +x = fsolve(@f, x0); #WORKS! #x = x0; l1 = [x(1), x(2); x(3), x(4)]; diff --git a/src/cad/fx/App2DCtrl.java b/src/cad/fx/App2DCtrl.java index 234af8c9..876f8346 100644 --- a/src/cad/fx/App2DCtrl.java +++ b/src/cad/fx/App2DCtrl.java @@ -1,46 +1,42 @@ package cad.fx; import cad.gcs.Constraint; -import cad.gcs.GradientDescent; -import cad.gcs.GradientDescent2; -import cad.gcs.GradientDescent3; +import cad.gcs.Figures; import cad.gcs.Param; import cad.gcs.Solver; -import cad.gcs.constr.Constraint2; +import cad.gcs.constr.P2LDistance; import cad.gcs.constr.Parallel; import cad.gcs.constr.Perpendicular; -import cad.gcs.constr.Perpendicular2; -import cad.gcs.constr.X; -import cad.gcs.constr.XY; import cad.math.Vector; import gnu.trove.list.TDoubleList; +import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.fxml.Initializable; import javafx.scene.Group; import javafx.scene.control.Button; import javafx.scene.layout.Pane; import javafx.scene.shape.Line; -import org.apache.commons.math3.analysis.MultivariateMatrixFunction; import org.apache.commons.math3.analysis.MultivariateVectorFunction; -import org.apache.commons.math3.analysis.function.Max; -import org.apache.commons.math3.linear.Array2DRowRealMatrix; -import org.apache.commons.math3.linear.MatrixUtils; -import org.apache.commons.math3.linear.RealMatrix; -import org.apache.commons.math3.optim.ConvergenceChecker; import org.apache.commons.math3.optim.InitialGuess; import org.apache.commons.math3.optim.MaxEval; import org.apache.commons.math3.optim.MaxIter; -import org.apache.commons.math3.optim.PointVectorValuePair; import org.apache.commons.math3.optim.nonlinear.vector.ModelFunction; import org.apache.commons.math3.optim.nonlinear.vector.ModelFunctionJacobian; import org.apache.commons.math3.optim.nonlinear.vector.Target; import org.apache.commons.math3.optim.nonlinear.vector.Weight; -import org.apache.commons.math3.optim.nonlinear.vector.jacobian.GaussNewtonOptimizer; +import org.apache.commons.math3.optim.nonlinear.vector.jacobian.LevenbergMarquardtOptimizer; +import org.jacop.constraints.Sum; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.ResourceBundle; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; + +import static java.util.Arrays.asList; public class App2DCtrl implements Initializable { @@ -48,6 +44,7 @@ public class App2DCtrl implements Initializable { public Pane viewer; public Button solve; + public Button square; @Override public void initialize(URL location, ResourceBundle resources) { @@ -62,13 +59,17 @@ public class App2DCtrl implements Initializable { content.getChildren().addAll(l1, l2, l3); + square.setOnAction(event -> { + solveFigure(Figures.square(100)); + }); + solve.setOnAction(event -> { Vector as = new Vector(l1.getStartX(), l1.getStartY()); - Vector ae = new Vector(l1.getEndX(), l1.getEndY()); + Vector ae = new Vector(l1.getEndX(), l1.getEndY()); Vector bs = new Vector(l2.getStartX(), l2.getStartY()); - Vector be = new Vector(l2.getEndX(), l2.getEndY()); + Vector be = new Vector(l2.getEndX(), l2.getEndY()); Param l1p1x = new Param(l1.getStartX()); @@ -86,57 +87,53 @@ public class App2DCtrl implements Initializable { Param l3p2x = new Param(l3.getEndX()); Param l3p2y = new Param(l3.getEndY()); - +// l2p2x.setLocked(true); +// l2p2y.setLocked(true); +// l2p1x.setLocked(true); +// l2p1y.setLocked(true); + + Perpendicular perpendicular = new Perpendicular( - l1p1x, - l1p1y, - l1p2x, - l1p2y, - l2p1x, - l2p1y, - l2p2x, - l2p2y + l1p1x, + l1p1y, + l1p2x, + l1p2y, + l2p1x, + l2p1y, + l2p2x, + l2p2y ); Parallel parallel = new Parallel( - l3p1x, - l3p1y, - l3p2x, - l3p2y, - l2p1x, - l2p1y, - l2p2x, - l2p2y + l3p1x, + l3p1y, + l3p2x, + l3p2y, + l2p1x, + l2p1y, + l2p2x, + l2p2y + ); + + P2LDistance p2l1 = new P2LDistance( + 10, + l3p1x, l3p1y, + l2p1x, l2p1y, + l2p2x, l2p2y + ); + + P2LDistance p2l2 = new P2LDistance( + 10, + l1p2x, l1p2y, + l2p1x, l2p1y, + l2p2x, l2p2y ); - XY xy = new XY(as, new Vector(100, 100)); - - X x = new X( - l1p1x, - l1p1y, - l1p2x, - l1p2y, - l2p1x, - l2p1y, - l2p2x, - l2p2y - ); - - List constrs = Arrays.asList(perpendicular); - Solver.SubSystem subSystem = new Solver.SubSystem(constrs); -// Solver.optimize(subSystem); -// - - -// while (subSystem.error() > 0.0001 ) { - Solver.solve_LM(subSystem); -// } - -// solveGC(subSystem); - - java.lang.System.out.println("ANGLE |- :" + perpendicular.angle()); - java.lang.System.out.println("ANGLE || :" + parallel.angle()); + Runnable update = () -> { + System.out.println("ANGLE |- : " + perpendicular.angle()); + System.out.println("ANGLE || : " + parallel.angle()); + System.out.println("DISTANCE : " + p2l1.error()); // Constraint2 constr = xy; @@ -157,27 +154,97 @@ public class App2DCtrl implements Initializable { // l2.setEndX(be.x); // l2.setEndY(be.y); - l1.setStartX(l1p1x.get()); - l1.setStartY(l1p1y.get()); - l1.setEndX(l1p2x.get()); - l1.setEndY(l1p2y.get()); + l1.setStartX(l1p1x.get()); + l1.setStartY(l1p1y.get()); + l1.setEndX(l1p2x.get()); + l1.setEndY(l1p2y.get()); - l2.setStartX(l2p1x.get()); - l2.setStartY(l2p1y.get()); - l2.setEndX(l2p2x.get()); - l2.setEndY(l2p2y.get()); + l2.setStartX(l2p1x.get()); + l2.setStartY(l2p1y.get()); + l2.setEndX(l2p2x.get()); + l2.setEndY(l2p2y.get()); - l3.setStartX(l3p1x.get()); - l3.setStartY(l3p1y.get()); - l3.setEndX(l3p2x.get()); - l3.setEndY(l3p2y.get()); + l3.setStartX(l3p1x.get()); + l3.setStartY(l3p1y.get()); + l3.setEndX(l3p2x.get()); + l3.setEndY(l3p2y.get()); // scale(l1); // scale(l2); // scale(l3); + }; + + + List constrs = Arrays.asList(parallel); +// List constrs = Arrays.asList(p2l1); + Solver.SubSystem subSystem = new Solver.SubSystem(constrs); +// Solver.optimize(subSystem); +// + + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + globalSolve(subSystem, () -> Platform.runLater(update)); + if (true) return; + while (subSystem.error() > 0.0001) { + Solver.solve_LM(subSystem); +// solveLM_COMMONS(subSystem); +// Solver.solve_DL(subSystem); +// Solver.solve_BFGS(subSystem, true); + Platform.runLater(update); + } + }); }); } + private void solveFigure(Figures.Figure square) { + + Solver.SubSystem subSystem = new Solver.SubSystem(square.constraints); + + List lines = new ArrayList<>(); + + for (Param[] line : square.lines) { + Line fxLine = new Line(); + fxLine.setStartX(line[0].get()); + fxLine.setStartY(line[1].get()); + fxLine.setEndX(line[2].get()); + fxLine.setEndY(line[3].get()); + lines.add(fxLine); + } + + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + globalSolve(subSystem, () -> Platform.runLater(() -> { + for (int i = 0; i < square.lines.length; i++) { + Param[] line = square.lines[i]; + Line fxLine = lines.get(i); + fxLine.setStartX(line[0].get()); + fxLine.setStartY(line[1].get()); + fxLine.setEndX(line[2].get()); + fxLine.setEndY(line[3].get()); + } + })); + }); + } + + private void globalSolve(Solver.SubSystem subSystem, Runnable linearSolvedCallback) { + + double eps = 0.0001; + while (subSystem.error() > eps) { + solveLM_COMMONS(subSystem); +// Solver.solve_LM(subSystem); + TDoubleList residuals = subSystem.calcResidual(); + double worseValue = residuals.max(); + if (Math.abs(worseValue) > eps) { + int worseId = residuals.indexOf(worseValue); + Solver.SubSystem worse = new Solver.SubSystem(asList(subSystem.constraints.get(worseId))); + solveLM_COMMONS(worse); +// Solver.solve_LM(worse); + System.out.println("WORSE FIXED ERROR:" + worse.error()); + } + linearSolvedCallback.run(); + } + } + double xxx = 100; private void scale(Line l) { @@ -191,18 +258,12 @@ public class App2DCtrl implements Initializable { l.setEndY(l.getStartY() + v.y); } - private void solveGC(final Solver.SubSystem subSystem) { - GaussNewtonOptimizer optimizer = new GaussNewtonOptimizer((iteration, previous, current) -> { - return subSystem.value() < 0.00001; - }) { + private void solveLM_COMMONS(final Solver.SubSystem subSystem) { + double eps = 1e-10, eps1 = 1e-80; + double tau = 1e-3; - @Override - protected double[] computeResiduals(double[] objectiveValue) { - TDoubleList residual = subSystem.calcResidual(); - return residual.toArray(); - } + LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(eps, eps, eps1); - }; double[] wieght = new double[subSystem.cSize()]; Arrays.fill(wieght, 1); optimizer.optimize( diff --git a/src/cad/fx/app2d.fxml b/src/cad/fx/app2d.fxml index dea147e3..60e2ae62 100644 --- a/src/cad/fx/app2d.fxml +++ b/src/cad/fx/app2d.fxml @@ -15,6 +15,7 @@