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); }
public void TestRandomizeEpsilonIsApplied() { int count = 1000; double epsFactor = 0.2; double maxAbs = 1.0; Vector <double> vec = new DenseVector(count); for (int i = 0; i < count; i++) { vec[i] = MathHelper.RandomExceptZero(maxAbs, epsFactor); } double min = vec.AbsoluteMinimum(); double max = vec.AbsoluteMaximum(); Assert.IsTrue(min >= epsFactor * maxAbs); Assert.IsTrue(max <= maxAbs); }
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); }
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); }
public static Tuple <int, int, double> DenseMatrixAbsoluteMaximumPosition(DenseMatrix dm) { if (dm == null) { return(new Tuple <int, int, double>(0, 0, 0.0d)); } List <Tuple <int, double> > rowMaxValues = new List <Tuple <int, double> >(); var rowEnum = dm.EnumerateRowsIndexed(); foreach (Tuple <int, Vector <double> > curRow in rowEnum) { DenseVector curDV = (DenseVector)curRow.Item2; rowMaxValues.Add(new Tuple <int, double>(curDV.AbsoluteMaximumIndex(), curDV.AbsoluteMaximum())); } double maxValue = rowMaxValues.Max(tpl => tpl.Item2); int maxValueRow = rowMaxValues.FindIndex(tpl => tpl.Item2 == maxValue); DenseVector maxRow = (DenseVector)dm.Row(maxValueRow); return(new Tuple <int, int, double>(maxValueRow, maxRow.AbsoluteMaximumIndex(), maxValue)); }