/* * This function is used to get a lower bound on the condition number. as it stands this is pretty straight forward: * * a random point (x) and vector (v) are generated, the Raleigh quotient ( v.H(x).v / v.v ) is then taken which provides both * a lower bound on the largest eigenvalue, and an upper bound on the smallest eigenvalue. This can then be used to * come up with a lower bound on the condition number of the hessian. */ public virtual double TestConditionNumber(int samples) { double maxSeen = 0.0; double minSeen = 0.0; double[] thisV = new double[thisFunc.DomainDimension()]; double[] thisX = new double[thisV.Length]; gradFD = new double[thisV.Length]; HvFD = new double[thisV.Length]; double thisVHV; bool isNeg = false; bool isPos = false; bool isSemi = false; thisFunc.method = StochasticCalculateMethods.ExternalFiniteDifference; for (int j = 0; j < samples; j++) { for (int i = 0; i < thisV.Length; i++) { thisV[i] = generator.NextDouble(); } for (int i_1 = 0; i_1 < thisX.Length; i_1++) { thisX[i_1] = generator.NextDouble(); } log.Info("Evaluating Hessian Product"); System.Array.Copy(thisFunc.DerivativeAt(thisX, thisV, testBatchSize), 0, gradFD, 0, gradFD.Length); thisFunc.recalculatePrevBatch = true; System.Array.Copy(thisFunc.HdotVAt(thisX, thisV, gradFD, testBatchSize), 0, HvFD, 0, HvFD.Length); thisVHV = ArrayMath.InnerProduct(thisV, HvFD); if (System.Math.Abs(thisVHV) > maxSeen) { maxSeen = System.Math.Abs(thisVHV); } if (System.Math.Abs(thisVHV) < minSeen) { minSeen = System.Math.Abs(thisVHV); } if (thisVHV < 0) { isNeg = true; } if (thisVHV > 0) { isPos = true; } if (thisVHV == 0) { isSemi = true; } log.Info("It:" + j + " C:" + maxSeen / minSeen + "N:" + isNeg + "P:" + isPos + "S:" + isSemi); } System.Console.Out.WriteLine("Condition Number of: " + maxSeen / minSeen); System.Console.Out.WriteLine("Is negative: " + isNeg); System.Console.Out.WriteLine("Is positive: " + isPos); System.Console.Out.WriteLine("Is semi: " + isSemi); return(maxSeen / minSeen); }
protected internal override void Init(AbstractStochasticCachingDiffFunction func) { sList = new List <double[]>(); yList = new List <double[]>(); dir = new double[func.DomainDimension()]; }