/// <summary>Apply a function to every element of every component of this vector, and replace with the result.</summary> /// <param name="fn">the function to apply to every element of every component.</param> public virtual void MapInPlace(IDoubleUnaryOperator fn) { for (int i = 0; i < pointers.Length; i++) { if (pointers[i] == null) { continue; } if (copyOnWrite[i]) { copyOnWrite[i] = false; pointers[i] = pointers[i].MemberwiseClone(); } if (sparse[i]) { pointers[i][1] = fn.ApplyAsDouble(pointers[i][1]); } else { for (int j = 0; j < pointers[i].Length; j++) { pointers[i][j] = fn.ApplyAsDouble(pointers[i][j]); } } } }
public virtual void Map(IDoubleUnaryOperator fn) { for (int i = 0; i < values.Length; i++) { for (int j = 0; j < values[i].Length; j++) { values[i][j] = fn.ApplyAsDouble(values[i][j]); } } }
public virtual void DiscretizeCompute(IDoubleUnaryOperator function, int numPoints, double low, double high) { double inc = (high - low) / numPoints; memory = Generics.NewHashMap(); for (int i = 0; i < numPoints; i++) { double x = low + i * inc; double y = function.ApplyAsDouble(x); memory[x] = y; log.Info("for point " + x + '\t' + y); } DumpMemory(); }
private double GetRoot(IDoubleUnaryOperator func, double lower, double upper) { double mid = 0.5 * (lower + upper); double Tol = 1e-8; double skew = 0.4; int count = 0; if (func.ApplyAsDouble(upper) > 0 || func.ApplyAsDouble(lower) < 0) { Say("LOWER AND UPPER SUPPLIED TO GET ROOT DO NOT BOUND THE ROOT."); } double fval = func.ApplyAsDouble(mid); while (System.Math.Abs(fval) > Tol) { count += 1; if (fval > 0) { lower = mid; } else { if (fval < 0) { upper = mid; } } mid = skew * lower + (1 - skew) * upper; fval = func.ApplyAsDouble(mid); if (count > 100) { break; } } Say(" " + nf.Format(mid) + " f" + nf.Format(fval)); return(mid); }
public virtual double Minimize(IDoubleUnaryOperator function) { double tol = this.tol; double low = this.low; double high = this.high; // cdm Oct 2006: The code used to do nothing to find or check // the validity of an initial // bracketing; it just blindly placed the midpoint at the golden ratio // I now try to grid search a little in case the function is very flat // (RTE contradictions). double flow = function.ApplyAsDouble(low); double fhigh = function.ApplyAsDouble(high); if (Verbose) { log.Info("Finding min between " + low + " (value: " + flow + ") and " + high + " (value: " + fhigh + ')'); } double mid; double oldY; bool searchRight; if (false) { // initialize with golden means mid = GoldenMean(low, high); oldY = function.ApplyAsDouble(mid); if (Verbose) { log.Info("Initially probed at " + mid + ", value is " + oldY); } if (oldY < flow || oldY < fhigh) { searchRight = false; } else { // Galen had this true; should be false mid = GoldenMean(high, low); oldY = function.ApplyAsDouble(mid); if (Verbose) { log.Info("Probed at " + mid + ", value is " + oldY); } searchRight = true; if (!(oldY < flow || oldY < fhigh)) { log.Info("Warning: GoldenSectionLineSearch init didn't find slope!!"); } } } else { // grid search a little; this case doesn't do geometric differently... if (Verbose) { log.Info("20 point gridsearch for good mid point...."); } double bestPoint = low; double bestVal = flow; double incr = (high - low) / 22.0; for (mid = low + incr; mid < high; mid += incr) { oldY = function.ApplyAsDouble(mid); if (Verbose) { log.Info("Probed at " + mid + ", value is " + oldY); } if (oldY < bestVal) { bestPoint = mid; bestVal = oldY; if (Verbose) { log.Info(" [best so far!]"); } } if (Verbose) { log.Info(); } } mid = bestPoint; oldY = bestVal; searchRight = mid < low + (high - low) / 2.0; if (oldY < flow && oldY < fhigh) { if (Verbose) { log.Info("Found a good mid point at (" + mid + ", " + oldY + ')'); } } else { log.Info("Warning: GoldenSectionLineSearch grid search couldn't find slope!!"); // revert to initial positioning and pray mid = GoldenMean(low, high); oldY = function.ApplyAsDouble(mid); searchRight = false; } } memory[mid] = oldY; while (geometric ? (high / low > 1 + tol) : high - low > tol) { if (Verbose) { log.Info("Current low, mid, high: " + nf.Format(low) + ' ' + nf.Format(mid) + ' ' + nf.Format(high)); } double newX = GoldenMean(searchRight ? high : low, mid); double newY = function.ApplyAsDouble(newX); memory[newX] = newY; if (Verbose) { log.Info("Probed " + (searchRight ? "right" : "left") + " at " + newX + ", value is " + newY); } if (newY < oldY) { // keep going in this direction if (searchRight) { low = mid; } else { high = mid; } mid = newX; oldY = newY; } else { // go the other way if (searchRight) { high = newX; } else { low = newX; } searchRight = !searchRight; } } return(mid); }