private double GetFourierValue(function f, derivative2 d2, double min, double max, double val, int it) { it++; if (it > maxIterations) { //Console.WriteLine("Obtener Fourier Value: Mas de 30 iteraciones"); return(GetValueInFourierInterval(f, d2, min, max, val)); } double gMin = f(min) - val; double gMax = f(max) - val; double inter = min + (max - min) / 2.0; double gInter = f(inter) - val; if (Math.Abs(gInter) < 0.02) { return(inter); } if (gMin * gInter < 0) { return(GetFourierValue(f, d2, min, inter, val, it)); } else { return(GetFourierValue(f, d2, inter, max, val, it)); } }
/** Method: * Devuelve el punto de fourier con el que el metodo de Newton Raphson converge muy rapidamente * Fourier Convergence Conditions value. Returns zero if does not fit conditions * f(a)*f(b) less than 0 2) f" greater than 0 en [a,b] val is for non roots (otherwise 0) * f - funcion mediante la cual se calcula el valor de dicha funcion * d2 - funcion mediante la cual se calcula el valor de la derivada segunda de dicha funcion * a - Valor minimo del intervalo en el cual busca la raiz o cero * b - Valor maximo del intervalo en el cual busca la raiz o cero * val - Valor para el cual se desea buscar la inversa de la función */ private double GetValueInFourierInterval(function f, derivative2 d2, double a, double b, double val) { double posValue = 0; double negValue = 0; double ga = f(a) - val; double gb = f(b) - val; if (ga * gb >= 0) { return(0); } if (ga > 0) { posValue = a; negValue = b; } else { posValue = b; negValue = a; } //Second derivative constant in the interval (warning: sign is not verified on intermediate values) if (d2(a) > 0 && d2(b) > 0) { return(posValue); } else { return(negValue); } }
/** Method: * Metodo Newton Raphson para encontrar una raiz o cero de una función * Si val es cero entonces encuantra la raiz de la funcion * si no, encuentra la inversa de la función <paramref name="f"/> en val * f - function * d - first derivative * d2 - second derivative * min - min value of the interval * max - max value of the interval * val - value to add (0 if pure root search) * eps - epsilon for solution validation * maxIt - maximum of iterations */ internal double NewtonRaphsonOneRoot(function f, derivative d, derivative2 d2, double min, double max, double val) { if ((f(min) - val) * f(max) - val > 0) { throw new ArgumentException("No zero between these values"); } double nr = 0; double x; int i = 0; while (nr == 0) { x = GetFourierValue(f, d2, min, max, val); nr = NewtonRaphson(f, d, x, val); if (i > maxIterations) { throw new Exception("Exceed the maximun iterations"); } i++; } return(nr); }
/** Method: * Metodo Steffenson, que es una forma mas rapida de encontrar una raiz o cero de una función * Si val es cero entonces encuantra la raiz de la funcion * si no, encuentra la inversa de la función * f - function * d - first derivative * d2 - second derivative * min - min value of the interval * max - max value of the interval * val - value to add (0 if pure root search) * maxIterations - maximum of iterations */ internal double SteffensenAccOneRoot(function f, derivative d, derivative2 d2, double min, double max, double val, int maxIterations) { if ((f(min) - val) * f(max) - val > 0) { throw new Exception("No zero between these values"); } double st = 0; double x; int i = 0; while (st == 0) { x = GetFourierValue(f, d2, min, max, val); st = SteffensenAcceleration(f, d, x, val); i++; if (i > maxIterations) { throw new Exception("Exceed maximun iterations"); } } //Console.WriteLine("val = " + val + " , st = " + st + " , it = " + i); return(st); }
/** Method: * Encuentra el punto de fourier con el que el metodo de Newton Raphson converge muy rapidamente * Fourier Convergence Conditions value for functions with one root on interval * f - funcion mediante la cual se calcula el valor de dicha funcion * d2 - funcion mediante la cual se calcula el valor de la derivada segunda de dicha funcion * min - Valor minimo del intervalo en el cual busca la raiz o cero * max - Valor maximo del intervalo en el cual busca la raiz o cero * val - Valor para el cual se desea buscar la inversa de la función * Si no existe una raiz, entonces genera error * the calculated fourier value */ internal double GetFourierVal(function f, derivative2 d2, double min, double max, double val) { double a = randGen.NextDouble(min, max); double b = randGen.NextDouble(min, max); int i = 0; if (i > maxIterations - 1) { a = min; b = max; } double ga = f(a) - val; double gb = f(b) - val; if (ga * gb < 0) { return(GetValueInFourierInterval(f, d2, a, b, val)); } while (true) { a = randGen.NextDouble(min, max); b = randGen.NextDouble(min, max); ga = f(a) - val; gb = f(b) - val; if (ga * gb < 0) { return(GetValueInFourierInterval(f, d2, a, b, val)); } if (i > maxIterations) { throw new Exception("Exceed the maximun iterations"); } i++; } }
/** Method: * Encuentra el punto de fourier con el que el metodo de Newton Raphson converge muy rapidamente</para> * Fourier Convergence Conditions value for functions with one root on interval</para> * f - funcion mediante la cual se calcula el valor de dicha funcion * d2 - funcion mediante la cual se calcula el valor de la derivada segunda de dicha funcion * min - Valor minimo del intervalo en el cual busca la raiz o cero * max - Valor maximo del intervalo en el cual busca la raiz o cero * val - Valor para el cual se desea buscar la inversa de la función * Si no existe una raiz, entonces genera error * the calculated fourier value */ internal double GetFourierValue(function f, derivative2 d2, double min, double max, double val) { return(GetFourierValue(f, d2, min, max, val, 0)); }