private static ConvexBound ToConvexBound(this LineHalfPlane @this, Func <Vector, double> monitoredFunction, ConvexBound.Type type, double threshold) { return(ConvexBoundBuilder.Create(monitoredFunction, @this.Compute, type, threshold) .WithDistanceNorm(1, @this.ClosestPointL1) .WithDistanceNorm(2, @this.ClosestPointL2) .ToConvexBound()); }
public ConvexBound UpperBound(Vector initialVector, double threshold) { (var x0, var y0) = initialVector.Halve(HalfDimension); var constantPart = (x0 - y0) * (x0 - y0); double ConvexFunc(Vector vector) { (var x, var y) = vector.Halve(HalfDimension); var convexPart = (x + y) * (x + y); var linearPart = 2 * (vector - initialVector) * (x0 - y0).Concat(y0 - x0, HalfDimension); return(0.25 * (convexPart - (linearPart + constantPart))); } Either <Vector, double> DistanceFunc(Vector vector, int nodeId) { if (double.IsInfinity(threshold)) { return(double.PositiveInfinity); } var T = threshold; (var p0, var q0) = vector.Halve(HalfDimension); var m = p0 + q0; var n = p0 - q0; var r = x0 - y0; Vector GetXY(double t) { var sum = m / t; var diff = n - r + r * t; var x = (sum + diff) / 2.0; var y = (sum - diff) / 2.0; return(x.Concat(y, HalfDimension)); } var a = -2 * r * r; var b = 3 * r * r - 2 * r * n - 4 * T; var c = 0; var d = m * m; var ts = FindRoots.Cubic(d, c, b, a).ToArray(); if (a == 0.0) { ts = FindRoots.Quadratic(d, c, b).ToArray(); } return(ts.Where(t => t.IsNearReal()).Select(t => t.Real) .Select(GetXY).MinBy(vector.DistL2FromVector()).First()); } return(ConvexBoundBuilder.Create(MonitoredFunction.Function, ConvexFunc, ConvexBound.Type.UpperBound, threshold) .WithDistanceNorm(2, DistanceFunc) .ToConvexBound()); }
public ConvexBound LowerBound(Vector initialVector, double threshold) { (var x0, var y0) = initialVector.Halve(HalfDimension); var constantPart = (x0 + y0) * (x0 + y0); double ConvexFunc(Vector vector) { (var x, var y) = vector.Halve(HalfDimension); var convexPart = (x - y) * (x - y); var linearPart = 2 * (vector - initialVector) * (x0 + y0).Concat(x0 + y0, HalfDimension); return(0.25 * ((linearPart + constantPart) - convexPart)); } Either <Vector, double> ClosestPointFromVector(Vector vector, int nodeId) { if (double.IsNegativeInfinity(threshold)) { return(double.PositiveInfinity); } var T = threshold; (var p0, var q0) = vector.Halve(HalfDimension); var m = p0 + q0; var n = p0 - q0; var k = x0 + y0; Vector GetXY(double t) { var sum = m - k + k * t; var diff = n / t; var x = (sum + diff) / 2.0; var y = (sum - diff) / 2.0; return(x.Concat(y, HalfDimension)); } var a = -2 * k * k; var b = -2 * k * m + 3 * k * k + 4 * T; var c = 0; var d = n * n; var ts = FindRoots.Cubic(d, c, b, a).ToArray(); if (a == 0.0) { ts = FindRoots.Quadratic(d, c, b).ToArray(); } return(ts.Where(t => t.IsNearReal()).Select(t => t.Real) .Select(GetXY).MinBy(vector.DistL2FromVector()).First()); } return(ConvexBoundBuilder.Create(MonitoredFunction.Function, ConvexFunc, ConvexBound.Type.LoweBound, threshold) .WithDistanceNorm(2, ClosestPointFromVector).ToConvexBound()); }
private static ConvexBound LowerBound(Vector <double> referenceMatrix, double threshold) { var(eigenvector, eigenvalue) = referenceMatrix.AsMatrix().PowerIterationMethod(Epsilon, Rnd); var lastDataInside = new Dictionary <int, Vector <double> >(); double LowerBoundFunction(Vector <double> currentVector) { var currentMatrix = currentVector.AsMatrix(); var l1HalfPlane = eigenvector * currentMatrix * eigenvector; var l2ConvexBound = currentMatrix.SecondLargestEigenvalue(eigenvector, eigenvalue, Epsilon, Rnd); return(l1HalfPlane - l2ConvexBound); } Either <Vector <double>, double> CalculateDistance(Vector <double> currentVector, int node) { var lowerBound = LowerBoundFunction(currentVector); if (lowerBound > threshold) { return(DistanceFromInside(currentVector, node)); } if (lowerBound < threshold) { return(DistanceFromOutside(currentVector, node)); } return(0); } Either <Vector <double>, double> DistanceFromInside(Vector <double> currentVector, int node) { lastDataInside[node] = currentVector.Clone(); var value = LowerBoundFunction(currentVector); var delta = (value - threshold); return(delta / Math.Sqrt(2)); } Either <Vector <double>, double> DistanceFromOutside(Vector <double> currentVector, int node) { var result = ((currentVector - lastDataInside[node]) * 2).L2Norm(); return(result); } return(ConvexBoundBuilder.Create(LowerBoundFunction, value => value >= threshold) .WithDistanceNorm(2, CalculateDistance) .ToConvexBound()); }
public ConvexBound LowerBound(Vector initVector, double threshold) { Either <Vector, double> DistanceL1(Vector point, int nodeId) { var entropy = LowerBoundEntropy(point); if (entropy > threshold) { return(ClosestL1PointFromAbove(threshold, point)); } if (entropy < threshold) { return(ClosestL1PointFromBelow(threshold, point)); } return(initVector); } return(ConvexBoundBuilder.Create(MonitoredFunction.Function, LowerBoundEntropy, ConvexBound.Type.LoweBound, threshold) .WithDistanceNorm(1, DistanceL1).ToConvexBound()); }
public ConvexBound UpperBound(Vector initialVector, double threshold) { ClosestPointFromPoint closestPoint = (point, nodeId) => { var currentSum = Compute(point); if (currentSum <= 0.0000000001) { return(threshold); } var desiredSum = threshold; var mulBy = Math.Sqrt(threshold / currentSum); var result = point * mulBy; return(result); }; return(ConvexBoundBuilder.Create(MonitoredFunction.Function, Compute, ConvexBound.Type.UpperBound, threshold) .WithDistanceNorm(2, closestPoint) .ToConvexBound()); }
public ConvexBound LowerBound(Vector reducedVector, double threshold) { Either <Vector, double> DistanceL1(Vector point, int node) { var functionValue = ComputeEntropySketch(point); if (functionValue > threshold) { return(DecreaseEntropySketch.l1DecreaseEntropySketchTo(point, Dimension, threshold, Approximations.ApproximationEpsilon)); } if (functionValue < threshold) { return(IncreaseEntropySketch.l1IncreaseEntropySketchTo(point, Dimension, threshold, Approximations.ApproximationEpsilon)); } return(point); } return(ConvexBoundBuilder.Create(MonitoredFunction.Function, ComputeEntropySketch, ConvexBound.Type.LoweBound, threshold) .WithDistanceNorm(1, DistanceL1) .ToConvexBound()); }
public ConvexBound LowerBound(Vector initVector, double threshold) { /*Either<Vector, double> DistanceL1(Vector point, int nodeId) * { * var entropy = LowerBoundEntropy(point); * if (entropy > threshold) * return ClosestL1PointFromAbove(threshold, point); * if (entropy < threshold) * return ClosestL1PointFromBelow(threshold, point); * return initVector; * }*/ var pivots = new Dictionary <int, double>(Dimension); var gradients = new Dictionary <int, double>(Dimension); var generalPivot = 1.0 / (10.0 * Dimension); for (int i = 0; i < Dimension; i++) { var value = initVector[i]; var pivot = value.AlmostEqual(0) ? generalPivot : Math.Min(generalPivot, value); var gradient = ComputeEntropyToValue(pivot) / pivot; pivots[i] = pivot; gradients[i] = gradient; } double LowerBoundEntropyToValue(int index, double value) { if (value <= pivots[index]) { return(gradients[index] * value); } return(ComputeEntropyToValue(value)); } double LowerBoundEntropy(Vector vector) => vector.IndexedValues.Sum(kv => LowerBoundEntropyToValue(kv.Key, kv.Value)); return(ConvexBoundBuilder.Create(MonitoredFunction.Function, LowerBoundEntropy, ConvexBound.Type.LoweBound, threshold) // .WithDistanceNorm(1, DistanceL1) .ToConvexBound()); }
public ConvexBound LowerBound(Vector initialVector, double threshold) { if (threshold <= 0) { ClosestPointFromPoint closestPoint = (pt, nodeId) => double.MaxValue; return(ConvexBoundBuilder.Create(MonitoredFunction.Function, Compute, ConvexBound.Type.LoweBound, double.NegativeInfinity) .WithDistanceNorm(1, closestPoint) .WithDistanceNorm(2, closestPoint) .ToConvexBound()); } var currentNorm = Compute(initialVector); var newPointNorm = threshold; var mulBy = Math.Sqrt(newPointNorm / currentNorm); var point = initialVector * mulBy; var constantPart = -currentNorm; var parameters = initialVector * 2; var lineHalfPlane = LineHalfPlane.Create(parameters, constantPart, threshold, Dimension); return(lineHalfPlane.ToConvexLowerBound(MonitoredFunction.Function, threshold)); }
private ConvexBound LowerBound(Vector data, double threshold) { Debug.Assert(Height % 2 == 1); var halfHeight = 1 + Height / 2; var rowToAverage = new Dictionary <int, double>(Height); for (int row = 0; row < Height; row++) { rowToAverage[row] = RowSquarredAverage(data, row); } var releventRows = rowToAverage.OrderByDescending(pair => pair.Value).Select(pair => pair.Key).Take(halfHeight).ToArray(); var rowToColToLine = new Dictionary <int, Dictionary <int, Line> >(); foreach (var row in releventRows) { rowToColToLine.Add(row, new Dictionary <int, Line>(Width)); for (int col = 0; col < Width; col++) { var x = GetValue(data, row, col); var y = x * x; var m = 2 * x; rowToColToLine[row].Add(col, Line.OfPointAndGradient(m, x, y)); } } Func <int, double> CalcAverageValueOfRow(Vector currentData) => row => { var sum = 0.0; for (int col = 0; col < Width; col++) { sum += rowToColToLine[row][col].Compute(GetValue(currentData, row, col)); } return(sum / Width); }; double LowerBoundFunction(Vector currentData) { return(releventRows.Select(CalcAverageValueOfRow(currentData)).Min()); } var formulaDenominators = new Dictionary <int, double>(halfHeight); releventRows.ForEach(r => formulaDenominators.Add(r, Math.Sqrt(rowToColToLine[r].Values.Sum(l => l.M * l.M)))); // releventRows.ForEach(r => formulaDenominators.Add(r, rowToColToLine[r].Values.Sum(l => l.M * l.M))); Either <Vector, double> DistanceL2(Vector point, int nodeId) { // if (threshold <= 0.0) //return double.PositiveInfinity; double DistanceOfRow(int row) { var residual = threshold - CalcAverageValueOfRow(point)(row); var denominator = formulaDenominators[row]; if (denominator <= 0.0) { return(double.PositiveInfinity); } return(residual / denominator); } var distances = releventRows.Map(DistanceOfRow); if (distances.All(d => d <= 0.0)) { return(-distances.Max()); } else { return(distances.Where(d => d > 0.0).Sum()); } } Either <Vector, double> DistanceL_Inf(Vector point, int nodeId) { // if (threshold <= 0.0) //return double.PositiveInfinity; double DistanceOfRow(int row) { var residual = threshold - CalcAverageValueOfRow(point)(row); var denominator = formulaDenominators[row]; if (denominator <= 0.0) { return(double.PositiveInfinity); } return(residual / denominator); } var distances = releventRows.Map(DistanceOfRow); if (distances.All(d => d <= 0.0)) { return(-distances.Max()); } else { return(distances.Max()); } } return(ConvexBoundBuilder.Create(MonitoredFunction.Function, LowerBoundFunction, ConvexBound.Type.LoweBound, threshold) .WithDistanceNorm(2, DistanceL2) .WithDistanceNorm(0, DistanceL_Inf) .ToConvexBound()); }
private ConvexBound UpperBound(Vector data, double threshold) { var halfHeight = 1 + Height / 2; var rowToAverage = new Dictionary <int, double>(Height); for (int row = 0; row < Height; row++) { rowToAverage[row] = RowSquarredAverage(data, row); } var releventRows = rowToAverage.OrderBy(pair => pair.Value).Select(pair => pair.Key).Take(halfHeight).ToArray(); double UpperBoundFunction(Vector currentData) { return(releventRows.Select(row => RowSquarredAverage(currentData, row)).Max()); } Either <Vector, double> DistanceL2(Vector currentData, int nodeId) { double L2DistanceOfRow(int row) { var rowValue = RowSquarredAverage(currentData, row); if (rowValue <= 0.0) { return(-Math.Sqrt(threshold * Width)); } var rowData = GetRowValues(currentData, row).ToVector(); var closestData = rowData * Math.Sqrt(threshold / rowValue); var value = closestData * closestData / Width; var mul = rowValue <= threshold ? -1 : 1; return(mul * closestData.DistL2FromVector()(rowData)); } var distances = releventRows.Map(L2DistanceOfRow); if (distances.All(d => d <= 0.0)) { return(-distances.Max()); } else { return(distances.Where(d => d > 0.0).Sum()); } } Either <Vector, double> DistanceL_Inf(Vector currentData, int nodeId) { double DistanceOfRow(int row) { var rowValue = RowSquarredAverage(currentData, row); if (rowValue <= 0.0) { return(-Math.Sqrt(threshold * Width)); } var rowData = GetRowValues(currentData, row).ToVector(); var closestData = rowData * Math.Sqrt(threshold / rowValue); var value = closestData * closestData / Width; var mul = rowValue <= threshold ? -1 : 1; return(mul * closestData.DistL2FromVector()(rowData)); } var distances = releventRows.Map(DistanceOfRow); if (distances.All(d => d <= 0.0)) { return(-distances.Max()); } else { return(distances.Max()); } } return(ConvexBoundBuilder.Create(MonitoredFunction.Function, UpperBoundFunction, ConvexBound.Type.UpperBound, threshold) .WithDistanceNorm(2, DistanceL2) .WithDistanceNorm(0, DistanceL_Inf) .ToConvexBound()); }
private static ConvexBound UpperBound(Vector <double> referenceMatrix, double threshold) { return(ConvexBoundBuilder.Create(_ => 0.0, value => value <= threshold) .WithDistanceNorm(2, (point, id) => 0.0) .ToConvexBound()); }