| 1 | //$$ solution.h // solve routines |
|---|
| 2 | |
|---|
| 3 | #include "boolean.h" |
|---|
| 4 | #include "myexcept.h" |
|---|
| 5 | |
|---|
| 6 | #ifdef use_namespace |
|---|
| 7 | namespace RBD_COMMON { |
|---|
| 8 | #endif |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | // Solve the equation f(x)=y for x where f is a monotone continuous |
|---|
| 12 | // function of x |
|---|
| 13 | // Essentially Brent s method |
|---|
| 14 | |
|---|
| 15 | // You need to derive a class from R1_R1 and override "operator()" |
|---|
| 16 | // with the function you want to solve. |
|---|
| 17 | // Use an object from this class in OneDimSolve |
|---|
| 18 | |
|---|
| 19 | class R1_R1 |
|---|
| 20 | { |
|---|
| 21 | // the prototype for a Real function of a Real variable |
|---|
| 22 | // you need to derive your function from this one and put in your |
|---|
| 23 | // function for operator() at least. You probably also want to set up a |
|---|
| 24 | // constructor to put in additional parameter values (e.g. that will not |
|---|
| 25 | // vary during a solve) |
|---|
| 26 | |
|---|
| 27 | protected: |
|---|
| 28 | Real x; // Current x value |
|---|
| 29 | bool xSet; // true if a value assigned to x |
|---|
| 30 | |
|---|
| 31 | public: |
|---|
| 32 | Real minX, maxX; // range of value x |
|---|
| 33 | bool minXinf, maxXinf; // true if these are infinite |
|---|
| 34 | R1_R1() : xSet(false), minXinf(true), maxXinf(true) {} |
|---|
| 35 | virtual Real operator()() = 0; // function value at current x |
|---|
| 36 | // set current x |
|---|
| 37 | virtual void Set(Real X); // set x, check OK |
|---|
| 38 | Real operator()(Real X) { Set(X); return operator()(); } |
|---|
| 39 | // set x, return value |
|---|
| 40 | virtual bool IsValid(Real X); |
|---|
| 41 | operator Real(); // implicit conversion |
|---|
| 42 | }; |
|---|
| 43 | |
|---|
| 44 | class SolutionException : public Exception |
|---|
| 45 | { |
|---|
| 46 | public: |
|---|
| 47 | static unsigned long Select; |
|---|
| 48 | SolutionException(const char* a_what = 0); |
|---|
| 49 | }; |
|---|
| 50 | |
|---|
| 51 | class OneDimSolve |
|---|
| 52 | { |
|---|
| 53 | R1_R1& function; // reference to the function |
|---|
| 54 | Real accX; // accuracy in X direction |
|---|
| 55 | Real accY; // accuracy in Y direction |
|---|
| 56 | int lim; // maximum number of iterations |
|---|
| 57 | |
|---|
| 58 | public: |
|---|
| 59 | OneDimSolve(R1_R1& f, Real AccY = 0.0001, Real AccX = 0.0) |
|---|
| 60 | : function(f), accX(AccX), accY(AccY) {} |
|---|
| 61 | // f is an R1_R1 function |
|---|
| 62 | Real Solve(Real Y, Real X, Real Dev, int Lim=100); |
|---|
| 63 | // Solve for x in Y=f(x) |
|---|
| 64 | // X is the initial trial value of x |
|---|
| 65 | // X+Dev is the second trial value |
|---|
| 66 | // program returns a value of x such that |
|---|
| 67 | // |Y-f(x)| <= accY or |f.inv(Y)-x| <= accX |
|---|
| 68 | |
|---|
| 69 | private: |
|---|
| 70 | Real x[3], y[3]; // Trial values of X and Y |
|---|
| 71 | int L,C,U,Last; // Locations of trial values |
|---|
| 72 | int vpol, hpol; // polarities |
|---|
| 73 | Real YY; // target value |
|---|
| 74 | int i; |
|---|
| 75 | void LookAt(int); // get new value of function |
|---|
| 76 | bool Finish; // true if LookAt finds conv. |
|---|
| 77 | bool Captured; // true when target surrounded |
|---|
| 78 | void VFlip(); |
|---|
| 79 | void HFlip(); |
|---|
| 80 | void Flip(); |
|---|
| 81 | void State(int I, int J, int K); |
|---|
| 82 | void Linear(int, int, int); |
|---|
| 83 | void Quadratic(int, int, int); |
|---|
| 84 | }; |
|---|
| 85 | |
|---|
| 86 | |
|---|
| 87 | #ifdef use_namespace |
|---|
| 88 | } |
|---|
| 89 | #endif |
|---|
| 90 | |
|---|
| 91 | // body file: solution.cpp |
|---|
| 92 | |
|---|
| 93 | |
|---|
| 94 | |
|---|