/// <summary>
        /// Deviations squared sum. Сумма ошибок отклонений аппроксимирующей функции от известных значений
        /// </summary>
        /// <param name="dvDataValues">The data values. Значения аппроксимируемой функции</param>
        /// <param name="dvSpace">The space. Значения независимой переменной</param>
        /// <param name="approxFunc">The approximation function. Аппроксимирующая функция с фиксированными параметрами, заданными вектором параметров.
        /// Значения вычисляются над пространством независимой переменной</param>
        /// <param name="currentParametersSpacePoint">The current parameters space point.
        /// Тот самый фиксированный вектор параметров, используемый для вычисления значений аппроксимирующей функции над пространсовм независимой переменной</param>
        /// <returns>System.Double. Значение абсолютного </returns>
        private static double DeviationsSquaredSumRelative(
            DenseVector dvDataValues,
            DenseVector dvSpace,
            Func <DenseVector, double, double> approxFunc,
            DenseVector currentParametersSpacePoint,
            DenseVector dvWeights)
        {
            double distanceRelative = 0.0d;

            if (dvWeights == null)
            {
                DenseVector dvApproxFuncValues = DenseVector.Create(dvSpace.Count, ix =>
                {
                    return(approxFunc(currentParametersSpacePoint, dvSpace[ix]));
                });
                DenseVector dvDistanceAbs = dvApproxFuncValues - dvDataValues;
                distanceRelative = dvDistanceAbs.Abs() / dvDataValues.Abs();
            }
            else
            {
                DenseVector dvApproxFuncValues = DenseVector.Create(dvSpace.Count, ix =>
                {
                    return(approxFunc(currentParametersSpacePoint, dvSpace[ix]));
                });
                DenseVector dvDistanceAbs = dvApproxFuncValues - dvDataValues;
                dvDistanceAbs.MapInplace(d => Math.Abs(d));
                DenseVector dvDistanceRelative = (DenseVector)(dvDistanceAbs / dvDataValues.Map(Math.Abs));
                dvDistanceRelative = (DenseVector)dvDistanceRelative.PointwiseMultiply(dvWeights);
                distanceRelative   = dvDistanceRelative.Abs();
            }
            return(distanceRelative);
        }
Ejemplo n.º 2
0
    /*************************************************************************************************
    * Private used functions                                                                        *
    *************************************************************************************************/
    /* Square root of a matrix using eigenvectors and eigenvalues (assuming it can be applied, undefined if not) */
    /// <summary>
    /// Square root of a matrix using eigenvectors and eigenvalues (assuming it can be applied, undefined if not)
    /// </summary>
    /// <param name="M">A Matrix</param>
    /// <returns>The square root of M if applicable</returns>
    private static Matrix sqrtm(Matrix M)
    {
        MathNet.Numerics.LinearAlgebra.Matrix <double> sqrtM;
        // Calculating M^(1/2);
        Evd <double> eigenVs = M.Evd();

        DenseVector values = new DenseVector(M.RowCount);

        double[] tempValues = new double[M.RowCount];
        int      i          = 0;

        foreach (MathNet.Numerics.Complex c in eigenVs.EigenValues.ToArray())
        {
            tempValues[i] = c.Real;
            i++;
        }
        values.SetValues(tempValues);
        values.MapInplace(System.Math.Sqrt);

        DiagonalMatrix newValues = new DiagonalMatrix(M.RowCount, M.RowCount, values.ToArray());

        sqrtM = (eigenVs.EigenVectors * newValues) * eigenVs.EigenVectors.Inverse();

        return((Matrix)sqrtM);
    }
Ejemplo n.º 3
0
        public static MnistModel ReadImage(string path, bool normalize, bool trainAsEncoder)
        {
            var bitmap = new Bitmap(path);

            var fileName = path.Substring(path.LastIndexOfAny(FileSeparators) + 1);
            var label    = int.Parse(fileName[0].ToString());

            var values = new DenseVector(bitmap.Height * bitmap.Width);

            for (var i = 0; i < bitmap.Height; i++)
            {
                for (var j = 0; j < bitmap.Width; j++)
                {
                    {
                        var color = bitmap.GetPixel(j, i);

                        var gray = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);

                        values[j + i * bitmap.Width] = 1 - gray / 255.0;
                    }
                }
            }

            if (normalize)
            {
                var max = values.Maximum();
                max /= 2;
                values.MapInplace(v => v - max);
            }

            //values.CoerceZero(0.005);
            //values.MapInplace(v => v > 0.995 ? 1 : v);

            Vector solution;

            if (trainAsEncoder)
            {
                solution = values;
            }
            else
            {
                solution = new DenseVector(10)
                {
                    [label] = 1.0
                };
            }

            var image = new MnistModel
            {
                Width            = bitmap.Width,
                Height           = bitmap.Height,
                Values           = values,
                FileName         = fileName,
                Label            = label,
                ExpectedSolution = solution
            };

            return(image);
        }
Ejemplo n.º 4
0
        public static DenseVector ConvKernel(StandardConvolutionKernels kernelType, int kernelHalfWidth = 10)
        {
            double      maxL     = ((double)kernelHalfWidth) * 2.0d;
            DenseVector dvKernel = DenseVector.Create(2 * kernelHalfWidth + 1, 1.0d);

            if (kernelType == StandardConvolutionKernels.cos)
            {
                dvKernel = DenseVector.Create(2 * kernelHalfWidth + 1, (idx) =>
                {
                    double curDist =
                        (new PointD(idx - (double)kernelHalfWidth, 0.0d)).Distance(
                            new PointD(0.0d, 0.0d));
                    return(Math.Cos(curDist * Math.PI / (2.0d * maxL)));
                });
            }
            else if (kernelType == StandardConvolutionKernels.gauss)
            {
                dvKernel = DenseVector.Create(2 * kernelHalfWidth + 1, (idx) =>
                {
                    double curDist =
                        (new PointD(idx - (double)kernelHalfWidth, 0.0d)).Distance(
                            new PointD(0.0d, 0.0d));
                    return(Math.Exp(-curDist * curDist / (2.0d * (maxL * maxL / 9.0d))));
                });
            }
            else if (kernelType == StandardConvolutionKernels.flat)
            {
                dvKernel = DenseVector.Create(2 * kernelHalfWidth + 1, 1.0d);
            }
            else if (kernelType == StandardConvolutionKernels.linear)
            {
                dvKernel = DenseVector.Create(2 * kernelHalfWidth + 1, (idx) =>
                {
                    double curDist =
                        (new PointD(idx - (double)kernelHalfWidth, 0.0d)).Distance(
                            new PointD(0.0d, 0.0d));

                    return(Math.Max(1.0d - curDist * (1.0d / (double)kernelHalfWidth), 0.0d));
                });
            }
            else if (kernelType == StandardConvolutionKernels.bilinear)
            {
                dvKernel = DenseVector.Create(2 * kernelHalfWidth + 1, (idx) =>
                {
                    double curDist =
                        (new PointD(idx - (double)kernelHalfWidth, 0.0d)).Distance(
                            new PointD(0.0d, 0.0d));

                    return(Math.Max(1.0d - curDist * curDist * (1.0d / (double)(kernelHalfWidth * kernelHalfWidth)), 0.0d));
                });
            }

            double kernelSum = dvKernel.Values.Sum();

            dvKernel.MapInplace(dval => dval / kernelSum);
            return(dvKernel);
        }
        //private int AttachPointToOneOfConcurrentContours(List<Contour<Point>> contours, List<PointD> lPtdMassCenters,
        //    Contour<Point> themassCentersPolygon, Point thePoint, List<DenseMatrix> dmGradField)
        private int AttachPointToOneOfConcurrentContours(List <Contour <Point> > contours, List <PointD> lPtdMassCenters,
                                                         Contour <Point> themassCentersPolygon, Point thePoint, List <DenseMatrix> dmGradField)
        {
            // density field should be defined
            if (dmDensityMesh == null)
            {
                return(-1);
            }

            PointD thePointD = new PointD(thePoint);
            // если точка внутри многоугольника, составленного центрами масс уже имеющихся кластеров - посмотрим, куда смотрит градиент.

            DenseVector dvGradVect = DenseVector.Create(2, i => dmGradField[i][thePoint.Y, thePoint.X]);

            if (contours.Count == 2)
            {
                return(AttachPointToOneOf_TWO_ConcurrentContours(contours, lPtdMassCenters, thePoint, dmGradField));
            }
            // 3.0 : else if (themassCentersPolygon.InContour(thePointD.PointF()))
            else if (themassCentersPolygon.InContour(thePointD.PointF()) >= 0.0d)
            {
                List <DenseVector> lDvDirectionVectorsToMassCenters = lPtdMassCenters.ConvertAll(ptdMassCenter =>
                {
                    DenseVector dvDirection = DenseVector.Create(2, i =>
                    {
                        if (i == 0)
                        {
                            return(ptdMassCenter.X - thePointD.X);
                        }
                        if (i == 1)
                        {
                            return(ptdMassCenter.Y - thePointD.Y);
                        }
                        return(0.0d);
                    });
                    double dValue = Math.Sqrt(dvDirection[0] * dvDirection[0] + dvDirection[1] * dvDirection[1]);
                    dvDirection.MapInplace(d => d / dValue);
                    return(dvDirection);
                });

                List <double> lDirectionsMostCloseCosValue =
                    lDvDirectionVectorsToMassCenters.ConvertAll(dvDirection => dvDirection * dvGradVect);
                // максимальное значение соответствует минимальному углу - то, что надо
                // только надо еще обработать ситуацию, когда два кластера примерно в одном направлении, - один за другим на линии градиента
                int maxIdx = lDirectionsMostCloseCosValue.IndexOf(lDirectionsMostCloseCosValue.Max());

                return(maxIdx);
            }
            else
            {
                // посчитаем расстояние до границ каждого из контуров. Для минимального - к нему и отнесем.
                List <double> lDistances =
                    contours.ConvertAll(cntr => - cntr.Distance(thePointD.PointF())); // 3.0 : -CvInvoke.PointPolygonTest(cntr, thePointD.PointF(), true)
                int minIdx = lDistances.IndexOf(lDistances.Min());
                return(minIdx);
            }
        }
Ejemplo n.º 6
0
    /*************************************************************************************************
    * Private used functions                                                                        *
    *************************************************************************************************/
    /* Square root of a matrix using eigenvectors and eigenvalues (assuming it can be applied, undefined if not) */
    /// <summary>
    /// Square root of a matrix using eigenvectors and eigenvalues (assuming it can be applied, undefined if not)
    /// </summary>
    /// <param name="M">A Matrix</param>
    /// <returns>The square root of M if applicable</returns>
    private Matrix sqrtm(Matrix M)
    {
        MathNet.Numerics.LinearAlgebra.Matrix <double> sqrtM;
        // Calculating M^(1/2);
        Evd <double> eigenVs = M.Evd();

        DenseVector values = new DenseVector(M.RowCount);

        double[] tempValues = new double[M.RowCount];
        int      i          = 0;

        foreach (MathNet.Numerics.Complex c in eigenVs.EigenValues.ToArray())
        {
            tempValues[i] = c.Real;
            i++;
        }
        values.SetValues(tempValues);
        values.MapInplace(System.Math.Sqrt);

        DiagonalMatrix newValues = new DiagonalMatrix(M.RowCount, M.RowCount, values.ToArray());

        sqrtM = (eigenVs.EigenVectors * newValues) * eigenVs.EigenVectors.Inverse();

        /* This is debug to see what's actually inside M & M^1/2 */

        /*
         * Debug.Log("Old matrix");
         * for (int j = 0; j < M.RowCount; j++)
         * {
         *  string message = "";
         *  for (int k = 0; k < M.ColumnCount; k++)
         *  {
         *      message += M.Row(j).At(k).ToString(null, null) + "   ";
         *  }
         *  Debug.Log(message);
         * }
         * Debug.Log("New matrix");
         * for (int j = 0; j < sqrtM.RowCount; j++)
         * {
         *  string message = "";
         *  for (int k = 0; k < sqrtM.ColumnCount; k++)
         *  {
         *      message += sqrtM.Row(j).At(k).ToString(null, null) + "   ";
         *  }
         *  Debug.Log(message);
         * }
         */

        return((Matrix)sqrtM);
    }
Ejemplo n.º 7
0
        public static DenseVector ConvKernelAsymmetric(StandardConvolutionKernels kernelType, int kernelWidth = 10, bool centerToTheRight = true)
        {
            DenseVector dvKernel = ConvKernel(kernelType, kernelWidth - 1);

            if (centerToTheRight)
            {
                dvKernel = (DenseVector)dvKernel.SubVector(0, kernelWidth);
            }
            else
            {
                dvKernel = (DenseVector)dvKernel.SubVector(kernelWidth - 1, kernelWidth);
            }

            double kernelSum = dvKernel.Values.Sum();

            dvKernel.MapInplace(dval => dval / kernelSum);
            return(dvKernel);
        }
        public static DenseVector ExponentialMovingAverage(DenseVector dvValues, int gap = 10, double smoothingParameter = 0.4d)
        {
            DenseVector dvOutValues = (DenseVector)dvValues.Clone();

            dvOutValues.MapIndexedInplace(new Func <int, double, double>((i, x) =>
            {
                DenseVector dvWeights = DenseVector.Create(1 + gap * 2, new Func <int, double>(j =>
                {
                    int k = j - gap;
                    if (i + k < 0)
                    {
                        return(0.0d);
                    }
                    if (i + k >= dvOutValues.Count)
                    {
                        return(0.0d);
                    }
                    return(Math.Exp(-Math.Abs(k) * smoothingParameter));
                }));
                //dvWeights.MapIndexedInplace(new Func<int,double,double>((j, dVal) =>
                //{
                //    if (double.IsNaN(dvValues[])) return 0.0d;
                //}))
                double sum = dvWeights.Sum();
                dvWeights.MapInplace(new Func <double, double>(d => d / sum));

                double retVal = 0.0d;
                for (int n = 0; n < 1 + gap * 2; n++)
                {
                    int m = n - gap + i;
                    if ((m < 0) || (m >= dvOutValues.Count))
                    {
                        continue;
                    }
                    double weight = dvWeights[n];
                    retVal       += weight * dvValues[m];
                }
                return(retVal);
            }));
            return(dvOutValues);
        }
        private int AttachPointToOneOf_TWO_ConcurrentContours(List <Contour <Point> > contours, List <PointD> lPtdMassCenters, Point thePoint, List <DenseMatrix> dmGradField)
        {
            // density field should be defined
            if (dmDensityMesh == null)
            {
                return(-1);
            }
            if (contours.Count != 2)
            {
                // этот метод не для таких ситуаций
                throw new NotImplementedException();
            }


            PointD      thePointD  = new PointD(thePoint);
            DenseVector dvGradVect = DenseVector.Create(2, i => dmGradField[i][thePoint.Y, thePoint.X]);
            // три варианта:
            // 1,2. точка с одной из внешних сторон пары центров масс уже имеющихся кластеров
            // 3. Точка между ними
            DenseVector dvMassCentersConnectingLineVector = DenseVector.Create(2, i =>
            {
                if (i == 0)
                {
                    return(lPtdMassCenters[1].X - lPtdMassCenters[0].X);
                }
                if (i == 1)
                {
                    return(lPtdMassCenters[1].Y - lPtdMassCenters[0].Y);
                }
                else
                {
                    return(0.0d);
                }
            });
            //DenseVector dvMassCentersConnectingOrthogonal = DenseVector.Create(2,
            //    i => (i == 0) ? (dvMassCentersConnectingLineVector[1]) : (-dvMassCentersConnectingLineVector[0]));
            List <DenseVector> listDVdirectionsPtTomassCenters = lPtdMassCenters.ConvertAll <DenseVector>(
                ptdMassCenter =>
            {
                DenseVector dvDir = DenseVector.Create(2, i =>
                {
                    if (i == 0)
                    {
                        return(ptdMassCenter.X - thePointD.X);
                    }
                    if (i == 1)
                    {
                        return(ptdMassCenter.Y - thePointD.Y);
                    }
                    return(0.0d);
                });
                double dValue = Math.Sqrt(dvDir[0] * dvDir[0] + dvDir[1] * dvDir[1]);
                dvDir.MapInplace(d => d / dValue);
                return(dvDir);
            });
            double dOverallProductOfScalarProducts = 1.0d;

            foreach (DenseVector dvPtTomassCenter in listDVdirectionsPtTomassCenters)
            {
                dOverallProductOfScalarProducts *= dvPtTomassCenter * dvMassCentersConnectingLineVector;
            }

            // случай 1,2 - когда dOverallProductOfScalarProducts >= 0.0d - то есть, углы между dvMassCentersConnectingLineVector и векторами направления
            // от точки на центры масс - либо оба острые (cos > 0 для обоих), либо оба тупые (cos < 0 для обоих)
            // случай 3 - когда dOverallProductOfScalarProducts < 0.0d

            if (dOverallProductOfScalarProducts < 0.0d)
            {
                // точка между центрами масс - смотрим, куда скатывается градиент
                List <double> lDirectionsMostCloseCosValue =
                    listDVdirectionsPtTomassCenters.ConvertAll(dvDirection => dvDirection * dvGradVect);
                // максимальное значение cos соответствует минимальному углу - то, что надо
                int maxIdx = lDirectionsMostCloseCosValue.IndexOf(lDirectionsMostCloseCosValue.Max());
                return(maxIdx);
            }
            else
            {
                // точка снаружи пары - берем ближайшую
                List <double> lDistances =
                    contours.ConvertAll(cntr => - cntr.Distance(thePointD.PointF())); // 3.0 : CvInvoke.PointPolygonTest(cntr, thePointD.PointF(), true)
                int minIdx = lDistances.IndexOf(lDistances.Min());
                return(minIdx);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Centers data to have mean zero along axis 0. This is here because
        /// nearly all linear models will want their data to be centered.
        /// If sample_weight is not None, then the weighted mean of X and y
        /// is zero, and not the mean itself
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="fitIntercept"></param>
        /// <param name="normalize"></param>
        /// <param name="sampleWeight"></param>
        internal static CenterDataResult CenterData(
            Matrix <double> x,
            Matrix <double> y,
            bool fitIntercept,
            bool normalize = false,
            Vector <double> sampleWeight = null)
        {
            Vector <double> xMean;
            Vector <double> yMean = new DenseVector(y.ColumnCount);
            Vector <double> xStd;

            if (fitIntercept)
            {
                if (x is SparseMatrix)
                {
                    xMean = DenseVector.Create(x.ColumnCount, i => 0.0);
                    xStd  = DenseVector.Create(x.ColumnCount, i => 1.0);
                }
                else
                {
                    if (sampleWeight == null)
                    {
                        xMean = x.MeanOfEveryColumn();
                    }
                    else
                    {
                        xMean = x.MulColumnVector(sampleWeight).SumOfEveryColumn().Divide(sampleWeight.Sum());
                    }

                    x = x.SubtractRowVector(xMean);

                    if (normalize)
                    {
                        xStd = new DenseVector(x.ColumnCount);

                        foreach (var row in x.RowEnumerator())
                        {
                            xStd.Add(row.Item2.PointwiseMultiply(row.Item2), xStd);
                        }

                        xStd.MapInplace(Math.Sqrt);

                        for (int i = 0; i < xStd.Count; i++)
                        {
                            if (xStd[i] == 0)
                            {
                                xStd[i] = 1;
                            }
                        }

                        x.DivRowVector(xStd, x);
                    }
                    else
                    {
                        xStd = DenseVector.Create(x.ColumnCount, i => 1.0);
                    }
                }

                if (sampleWeight == null)
                {
                    yMean = y.MeanOfEveryColumn();
                }
                else
                {
                    yMean = y.MulColumnVector(sampleWeight).SumOfEveryColumn() / sampleWeight.Sum();
                }

                y = y.Clone();
                y = y.SubtractRowVector(yMean);
            }
            else
            {
                xMean = DenseVector.Create(x.ColumnCount, i => 0);
                xStd  = DenseVector.Create(x.ColumnCount, i => 1);
            }

            return(new CenterDataResult {
                X = x, Y = y, xMean = xMean, yMean = yMean, xStd = xStd
            });
        }