Exemple #1
0
        public Bitmap AutoContourPlot(IFunctionWithDerivative funcition, List <Tuple <Color, List <Vector <double> > > > pointGroups,
                                      float marginPerc, int xDimIndex, int yDimIndex, int imgWidth, int imgHeight, int contoursCount, double scalePower)
        {
            double minX = double.PositiveInfinity,
                   minY = double.PositiveInfinity,
                   maxX = double.NegativeInfinity,
                   maxY = double.NegativeInfinity;

            foreach (var group in pointGroups)
            {
                foreach (var pt in group.Item2)
                {
                    minX = Math.Min(minX, pt[xDimIndex]);
                    minY = Math.Min(minY, pt[yDimIndex]);
                    maxX = Math.Max(maxX, pt[xDimIndex]);
                    maxY = Math.Max(maxY, pt[yDimIndex]);
                }
            }

            double w      = maxX - minX;
            double h      = maxY - minY;
            var    origin = new DenseVector(funcition.DimensionsCount);

            origin[xDimIndex] = minX + w / 2;
            origin[yDimIndex] = minY + h / 2;

            double stepPerPixel = Math.Max(w / imgWidth, h / imgHeight) * (1 + marginPerc);

            return(ContourPlot(funcition, origin, xDimIndex, yDimIndex, imgWidth, imgHeight,
                               stepPerPixel, contoursCount, scalePower, pointGroups));
        }
Exemple #2
0
        public bool Optimize(Vector <double> resultAndInitPos, IFunctionWithDerivative function, double minDerivCompMaxMagn,
                             Action <int, Func <Vector <double> > > iterationCallback, CancellationToken ct)
        {
            Contract.Requires(resultAndInitPos.Count == function.DimensionsCount);
            Contract.Requires(minDerivCompMaxMagn > 0);

            double minStep = minDerivCompMaxMagn / 100;

            int[] prevStepSigns = new int[function.DimensionsCount];
            var   stepSize      = new DenseVector(function.DimensionsCount);
            var   derivative    = new DenseVector(function.DimensionsCount);

            for (int i = 0; i < stepSize.Count; ++i)
            {
                stepSize[i] = initialStep;
            }

            for (int iter = 0; iter < maxIters; ++iter)
            {
                if (ct.IsCancellationRequested)
                {
                    break;
                }

                // Compute current derivative.
                function.Derivate(derivative, resultAndInitPos);
                if (derivative.AbsoluteMaximum() < minDerivCompMaxMagn)
                {
                    return(true);
                }


                // Update step sizes and step weights.
                for (int i = 0; i < prevStepSigns.Length; ++i)
                {
                    int currSign = Math.Sign(derivative[i]);
                    int sign     = currSign * prevStepSigns[i];

                    if (sign > 0)
                    {
                        stepSize[i] = Math.Min(maxStep, stepSize[i] * stepUpMult);
                    }
                    else if (sign < 0)
                    {
                        stepSize[i] = Math.Max(minStep, stepSize[i] * stepDownMult);
                        currSign    = 0;
                    }

                    resultAndInitPos[i] -= currSign * stepSize[i];
                    prevStepSigns[i]     = currSign;
                }

                if (iterationCallback != null)
                {
                    iterationCallback(iter, resultAndInitPos.Clone);
                }
            }

            return(false);
        }
Exemple #3
0
        private ActionResult plot(IFunctionWithDerivative f, PlotViewModel model)
        {
            List <Tuple <Color, List <Vector <double> > > > points = new List <Tuple <Color, List <Vector <double> > > >();
            double minDeriv = model.MinDerivCompMaxMagn;
            var    result   = new DenseVector(f.DimensionsCount);
            {
                result[0] = model.InitialX;
                result[1] = model.InitialY;
                var ps = new List <Vector <double> >();
                points.Add(new Tuple <Color, List <Vector <double> > >(Color.Lime, ps));
                var sdImpl = new SteepestDescentBasicOptmizer(model.BasicStep, model.MaxIters);
                sdImpl.Optimize(result, f, model.MinDerivCompMaxMagn, (i, pFunc) => ps.Add(pFunc()), CancellationToken.None);
            }
            {
                result[0] = model.InitialX;
                result[1] = model.InitialY;
                var ps = new List <Vector <double> >();
                points.Add(new Tuple <Color, List <Vector <double> > >(Color.Red, ps));
                var sdImpl = new SteepestDescentBasicOptmizer(model.MomentumStep,
                                                              model.MomentumStart, model.MomentumEnd, model.MaxIters);
                sdImpl.Optimize(result, f, model.MinDerivCompMaxMagn, (i, pFunc) => ps.Add(pFunc()), CancellationToken.None);
            }
            {
                result[0] = model.InitialX;
                result[1] = model.InitialY;
                var ps = new List <Vector <double> >();
                points.Add(new Tuple <Color, List <Vector <double> > >(Color.Blue, ps));
                var sdImpl = new SteepestDescentAdvancedOptmizer(model.MomentumStep,
                                                                 model.MomentumStart, model.MomentumEnd, model.MaxIters);
                sdImpl.Optimize(result, f, model.MinDerivCompMaxMagn, (i, pFunc) => ps.Add(pFunc()), CancellationToken.None);
            }
            {
                result[0] = model.InitialX;
                result[1] = model.InitialY;
                var ps = new List <Vector <double> >();
                points.Add(new Tuple <Color, List <Vector <double> > >(Color.Magenta, ps));
                var sdImpl = new RpropPlusOptmizer(model.BasicStep, 10, 1.2, 0.5, model.MaxIters);
                sdImpl.Optimize(result, f, model.MinDerivCompMaxMagn, (i, pFunc) => ps.Add(pFunc()), CancellationToken.None);
            }
            {
                result[0] = model.InitialX;
                result[1] = model.InitialY;
                var ps = new List <Vector <double> >();
                points.Add(new Tuple <Color, List <Vector <double> > >(Color.Cyan, ps));
                var sdImpl = new ImprovedRpropMinusOptmizer(model.BasicStep, 10, 1.2, 0.5, model.MaxIters);
                sdImpl.Optimize(result, f, model.MinDerivCompMaxMagn, (i, pFunc) => ps.Add(pFunc()), CancellationToken.None);
            }

            var fp = new FunctionPlotter();

            var img = fp.AutoContourPlot(f, points, 0.1f, 0, 1, model.Width, model.Height,
                                         model.ContoursCount, model.ScalePower);
            var ms = new MemoryStream();

            img.Save(ms, ImageFormat.Png);
            ms.Seek(0, SeekOrigin.Begin);

            return(File(ms, "image/png"));
        }
Exemple #4
0
        //private void performTrainTestWithPlots(Net net, Matrix<double> inputs, int[] outputIndices,
        //		double learningRate, double regularizationLambda, int maxIters, double stepPerPixel) {
        //	var optimizer = new SteepestDescentAdvancedOptmizer(learningRate, 0.6, 0.99, 1e-4, maxIters);
        //	var trainer = new NetTrainer(net, optimizer, regularizationLambda);

        //	var cf = new NetCostFunction(net, inputs, outputIndices, regularizationLambda);
        //	trainer.InitializeCoefs(net);
        //	double costBefore = cf.Evaluate(net.Coefficients.Pack());

        //	var optimizationSteps = new List<Vector<double>>();
        //	bool result = trainer.Train(inputs, outputIndices, p => optimizationSteps.Add(p));

        //	new FunctionPlotter()
        //		.FunctionPlot(optimizationSteps.Select(pt => cf.Evaluate(pt)).ToArray(), 1024, 512, 0, 2)
        //		.Save("err.png", ImageFormat.Png);

        //	int dims = cf.DimensionsCount;
        //	var plotOrigin = net.Coefficients.Pack();
        //	for (int dx = 0; dx < dims; ++dx) {
        //		for (int dy = dx + 1; dy < dims; ++dy) {
        //			plotOptimization(cf, plotOrigin, dx, dy, stepPerPixel, optimizationSteps);
        //		}
        //	}

        //	double costAfter = cf.Evaluate(net.Coefficients.Pack());
        //	Assert.IsTrue(costAfter < costBefore);

        //	var actualOutputIndices = trainer.Predict(inputs);
        //	CollectionAssert.AreEqual(outputIndices, actualOutputIndices);

        //	Assert.IsTrue(result);
        //}

        private void plotOptimization(IFunctionWithDerivative fun, Vector <double> origin, int xDimIndex, int yDimIndex,
                                      double stepPerPixel, List <Vector <double> > points)
        {
            var plotter = new FunctionPlotter();
            var img     = plotter.ContourPlot(fun, origin, xDimIndex, yDimIndex, 512, 512, stepPerPixel, 10, 0.5,
                                              new List <Tuple <Color, List <Vector <double> > > >()
            {
                new Tuple <Color, List <Vector <double> > >(Color.DarkGreen, points)
            });

            img.Save(string.Format("x={0};y={1}.png", xDimIndex, yDimIndex), ImageFormat.Png);
        }
        public static void PerformDerivativeTest(IFunctionWithDerivative func, params double[][] points)
        {
            var nd       = new NumericDerivator(func.Evaluate, COMPUTE_EPSILON);
            var actual   = new DenseVector(points[0].Length);
            var expected = new DenseVector(points[0].Length);

            foreach (var point in points)
            {
                var pt = new DenseVector(point);
                nd.ComputeDerivative(expected, pt);
                func.Derivate(actual, pt);

                for (int i = 0; i < expected.Count; ++i)
                {
                    Assert.IsTrue(Math.Abs(expected[i] - actual[i]) < CHECK_EPSILON);
                }
            }
        }
Exemple #6
0
        public bool Optimize(Vector <double> resultAndInitPos, IFunctionWithDerivative function, double minDerivCompMaxMagn,
                             Action <int, Func <Vector <double> > > iterationCallback, CancellationToken ct)
        {
            Contract.Requires(resultAndInitPos.Count == function.DimensionsCount);
            Contract.Requires(minDerivCompMaxMagn > 0);

            var derivative = new DenseVector(function.DimensionsCount);
            var prevStep   = new DenseVector(function.DimensionsCount);
            var position   = new DenseVector(function.DimensionsCount);

            for (int iter = 0; iter < maxIters; ++iter)
            {
                if (ct.IsCancellationRequested)
                {
                    break;
                }

                resultAndInitPos.CopyTo(position);

                double momentum = momentumStart + (momentumEnd - momentumStart) * ((double)iter / maxIters);
                // Compute derivative take step to point + momentum * prevStep and compute derivative there.
                prevStep.Multiply(momentum, prevStep);
                prevStep.Add(position, resultAndInitPos);
                function.Derivate(derivative, resultAndInitPos);
                if (derivative.AbsoluteMaximum() < minDerivCompMaxMagn)
                {
                    return(true);
                }

                // Scale derivative and subtract from result to take "correction" step.
                derivative.Multiply(step, derivative);
                resultAndInitPos.Subtract(derivative, resultAndInitPos);

                // Conpute prevStep as (result - point).
                resultAndInitPos.Subtract(position, prevStep);

                if (iterationCallback != null)
                {
                    iterationCallback(iter, resultAndInitPos.Clone);
                }
            }

            return(false);
        }
Exemple #7
0
        public bool Optimize(Vector <double> resultAndInitPos, IFunctionWithDerivative function, double minDerivCompMaxMagn,
                             Action <int, Func <Vector <double> > > iterationCallback, CancellationToken ct)
        {
            Contract.Requires(resultAndInitPos.Count == function.DimensionsCount);
            Contract.Requires(minDerivCompMaxMagn > 0);

            var derivative = new DenseVector(function.DimensionsCount);
            var prevStep   = new DenseVector(function.DimensionsCount);

            for (int iter = 0; iter < maxIters; ++iter)
            {
                if (ct.IsCancellationRequested)
                {
                    break;
                }

                function.Derivate(derivative, resultAndInitPos);
                if (derivative.AbsoluteMaximum() < minDerivCompMaxMagn)
                {
                    return(true);
                }

                derivative.Multiply(step, derivative);

                double momentum = momentumStart + (momentumEnd - momentumStart) * ((double)iter / maxIters);
                prevStep.Multiply(momentum, prevStep);
                prevStep.Add(derivative, prevStep);
                resultAndInitPos.Subtract(prevStep, resultAndInitPos);

                if (iterationCallback != null)
                {
                    iterationCallback(iter, resultAndInitPos.Clone);
                }
            }

            return(false);
        }
Exemple #8
0
        public Bitmap ContourPlot(IFunctionWithDerivative funcition, Vector <double> origin, int xDimIndex, int yDimIndex,
                                  int imgWidth, int imgHeight, double stepPerPixel, int contoursCount, double scalePower,
                                  List <Tuple <Color, List <Vector <double> > > > pointGroups)
        {
            var point = new DenseVector(origin.Count);

            origin.CopyTo(point);

            double xOrigin = origin[xDimIndex] - stepPerPixel * imgWidth / 2;
            double yOrigin = origin[yDimIndex] - stepPerPixel * imgHeight / 2;

            double min, max;

            min = max = funcition.Evaluate(origin);

            double[,] values = new double[imgHeight, imgWidth];
            for (int y = 0; y < imgHeight; ++y)
            {
                point[yDimIndex] = yOrigin + (imgHeight - y - 1) * stepPerPixel;

                for (int x = 0; x < imgWidth; ++x)
                {
                    point[xDimIndex] = xOrigin + x * stepPerPixel;

                    double value = funcition.Evaluate(point);
                    values[y, x] = value;

                    if (value < min)
                    {
                        min = value;
                    }
                    else if (value > max)
                    {
                        max = value;
                    }
                }
            }

            double range = max - min;

            var img     = new Bitmap(imgWidth, imgHeight, PixelFormat.Format24bppRgb);
            var imgData = img.LockBits(new Rectangle(0, 0, imgWidth, imgHeight), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            int[,] contours = new int[imgHeight, imgWidth];

            unsafe {
                byte *imgPtr    = (byte *)imgData.Scan0;
                int   imgStride = imgData.Stride;

                // Image colors.
                for (int y = 0; y < imgHeight; ++y)
                {
                    int stride = y * imgStride;

                    for (int x = 0; x < imgWidth; ++x)
                    {
                        int contour = (int)(contoursCount * Math.Pow((values[y, x] - min) / range, scalePower));
                        if (contour >= contoursCount)
                        {
                            contour = contoursCount - 1;                              // Fox for values that are equa to max.
                        }

                        Contract.Assert(contour >= 0 && contour < contoursCount);
                        contours[y, x] = contour;
                        byte color = (byte)(55 + 200 * contour / (contoursCount - 1));

                        int baseI = stride + x * 3;
                        imgPtr[baseI]     = color;
                        imgPtr[baseI + 1] = color;
                        imgPtr[baseI + 2] = color;
                    }
                }

                // Contours in x direction.
                for (int y = 0; y < imgHeight; ++y)
                {
                    int stride = y * imgStride;

                    for (int x = 1; x < imgWidth; ++x)
                    {
                        if (contours[y, x] == contours[y, x - 1])
                        {
                            continue;
                        }

                        int baseI = stride + x * 3;
                        imgPtr[baseI]     = 0;
                        imgPtr[baseI + 1] = 0;
                        imgPtr[baseI + 2] = 0;
                    }
                }

                // Contours in y direction.
                for (int x = 0; x < imgWidth; ++x)
                {
                    int offset = x * 3;

                    for (int y = 1; y < imgHeight; ++y)
                    {
                        if (contours[y, x] == contours[y - 1, x])
                        {
                            continue;
                        }

                        int baseI = y * imgStride + offset;
                        imgPtr[baseI]     = 0;
                        imgPtr[baseI + 1] = 0;
                        imgPtr[baseI + 2] = 0;
                    }
                }
            }

            img.UnlockBits(imgData);

            // Points.
            if (pointGroups != null)
            {
                using (var g = Graphics.FromImage(img)) {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    int labelY      = 10;
                    int labelYSpace = 20;
                    g.FillRectangle(new SolidBrush(Color.FromArgb(192, Color.White)), 8, labelY - 4, 40, labelYSpace * pointGroups.Count);

                    foreach (var tuple in pointGroups)
                    {
                        var points = tuple.Item2;
                        if (points.Count < 2)
                        {
                            continue;
                        }

                        Pen arrowPen = new Pen(Color.FromArgb(128, tuple.Item1), 1);
                        arrowPen.EndCap = LineCap.ArrowAnchor;

                        PointF previousPt = new PointF(
                            (float)((points[0][xDimIndex] - xOrigin) / stepPerPixel),
                            imgHeight - (float)((points[0][yDimIndex] - yOrigin) / stepPerPixel) - 1);

                        const int margin = 1024;

                        // Arrows.
                        for (int i = 1; i < points.Count; ++i)
                        {
                            PointF pt = new PointF(
                                (float)((points[i][xDimIndex] - xOrigin) / stepPerPixel),
                                imgHeight - (float)((points[i][yDimIndex] - yOrigin) / stepPerPixel) - 1);
                            if (pt.X < -margin || pt.Y < -margin || pt.X >= imgHeight + margin || pt.Y >= imgHeight + margin)
                            {
                                continue;
                            }

                            g.DrawLine(arrowPen, previousPt, pt);
                            previousPt = pt;
                        }

                        string steps = points.Count.ToString();
                        g.DrawString(steps, SystemFonts.DefaultFont, new SolidBrush(tuple.Item1), 10, labelY);
                        labelY += labelYSpace;
                    }
                }
            }

            return(img);
        }