MOOS 0.2375
|
00001 //$$ solution.h // solve routines 00002 00003 #include "boolean.h" 00004 #include "myexcept.h" 00005 00006 #ifdef use_namespace 00007 namespace RBD_COMMON { 00008 #endif 00009 00010 00011 // Solve the equation f(x)=y for x where f is a monotone continuous 00012 // function of x 00013 // Essentially Brent s method 00014 00015 // You need to derive a class from R1_R1 and override "operator()" 00016 // with the function you want to solve. 00017 // Use an object from this class in OneDimSolve 00018 00019 class R1_R1 00020 { 00021 // the prototype for a Real function of a Real variable 00022 // you need to derive your function from this one and put in your 00023 // function for operator() at least. You probably also want to set up a 00024 // constructor to put in additional parameter values (e.g. that will not 00025 // vary during a solve) 00026 00027 protected: 00028 Real x; // Current x value 00029 bool xSet; // true if a value assigned to x 00030 00031 public: 00032 Real minX, maxX; // range of value x 00033 bool minXinf, maxXinf; // true if these are infinite 00034 R1_R1() : xSet(false), minXinf(true), maxXinf(true) {} 00035 virtual Real operator()() = 0; // function value at current x 00036 // set current x 00037 virtual void Set(Real X); // set x, check OK 00038 Real operator()(Real X) { Set(X); return operator()(); } 00039 // set x, return value 00040 virtual bool IsValid(Real X); 00041 operator Real(); // implicit conversion 00042 }; 00043 00044 class SolutionException : public Exception 00045 { 00046 public: 00047 static unsigned long Select; 00048 SolutionException(const char* a_what = 0); 00049 }; 00050 00051 class OneDimSolve 00052 { 00053 R1_R1& function; // reference to the function 00054 Real accX; // accuracy in X direction 00055 Real accY; // accuracy in Y direction 00056 int lim; // maximum number of iterations 00057 00058 public: 00059 OneDimSolve(R1_R1& f, Real AccY = 0.0001, Real AccX = 0.0) 00060 : function(f), accX(AccX), accY(AccY) {} 00061 // f is an R1_R1 function 00062 Real Solve(Real Y, Real X, Real Dev, int Lim=100); 00063 // Solve for x in Y=f(x) 00064 // X is the initial trial value of x 00065 // X+Dev is the second trial value 00066 // program returns a value of x such that 00067 // |Y-f(x)| <= accY or |f.inv(Y)-x| <= accX 00068 00069 private: 00070 Real x[3], y[3]; // Trial values of X and Y 00071 int L,C,U,Last; // Locations of trial values 00072 int vpol, hpol; // polarities 00073 Real YY; // target value 00074 int i; 00075 void LookAt(int); // get new value of function 00076 bool Finish; // true if LookAt finds conv. 00077 bool Captured; // true when target surrounded 00078 void VFlip(); 00079 void HFlip(); 00080 void Flip(); 00081 void State(int I, int J, int K); 00082 void Linear(int, int, int); 00083 void Quadratic(int, int, int); 00084 }; 00085 00086 00087 #ifdef use_namespace 00088 } 00089 #endif 00090 00091 // body file: solution.cpp 00092 00093 00094