/// <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); }
/************************************************************************************************* * 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); }
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); }
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); } }
/************************************************************************************************* * 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); }
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); } }
/// <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 }); }