00001 /* $NoKeywords: $ */ 00002 /* 00003 // 00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. 00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert 00006 // McNeel & Associates. 00007 // 00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED. 00011 // 00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>. 00013 // 00015 */ 00016 00017 #if !defined(OPENNURBS_OPTIMIZE_INC_) 00018 #define OPENNURBS_OPTIMIZE_INC_ 00019 00020 // find a local minimum of a 1 parameter function 00021 ON_BOOL32 ON_FindLocalMinimum( // returns 0 - failed to converge, 1 - success, 2 - failed to converge to requested tolerances 00022 int (*)(void*,double,double*,double*), // f(void*, double t, double* value, double* derivative ); 00023 void*, // passed as the void* argument to the above function 00024 double, double, double, // ax,bx,cx, 3 abcissa ax<bx<cx or ax>bx>cx, and 00025 // f(bx) < f(ax), and f(bx) < f(cx) 00026 double, // tol > 0 (minimum relative step size (use ON_EPSILON when in doubt) 00027 double, // zeps > 0 (minimum absolute step size (use 1/2*(desired absolute precision)) 00028 int, // maximum number of iterations ( use 100 when in doubt) 00029 double* // abcissa of local minimum returned here 00030 ); 00031 00032 // find a local zero of a 1 parameter function 00033 class ON_LocalZero1 00034 { 00035 public: 00036 ON_LocalZero1(); 00037 virtual ~ON_LocalZero1(); 00038 00039 virtual 00040 ON_BOOL32 Evaluate( // returns true if successful 00041 double, // evaluation parameter 00042 double*, // f(t) returned here - NULL never passed 00043 double*, // If not NULL, then f'(t) returned here 00044 int // < 0: evaluate from below 00045 // >= 0: evaluate from above 00046 ) = 0; 00047 00048 00049 ON_BOOL32 FindZero( double* ); // Searches domain between m_to and m_t1 00050 // domain for a root. Returns true if 00051 // a root is found. 00052 00053 // m_t0 and m_t1 specify the domain to search and must satisfy 00054 // 00055 // 1) m_t0 != m_t1 00056 // 2) f(m_t0) and f(m_t1) must have different signs 00057 // or one must have absolute value <= m_f_tolerance 00058 double m_t0, m_t1; 00059 00060 double m_f_tolerance; // (>= 0.0) If this value is > 0.0, then 00061 // the search is terminated when a parameter 00062 // "t" is found where |f(t)| <= m_f_tolerance. 00063 00064 double m_t_tolerance; // (>= 0.0) If this value is > 0.0, then 00065 // the search is terminated when a parameter 00066 // the root is bracketed in a domain with width 00067 // <= m_t_tolerance. 00068 00069 // m_k[] is either NULL or monotone increasing array of length m_k_count. 00070 // 00071 // This zero finder works on continuous piecewise c2 functions. 00072 // If the function is c2 on the interior of the domain 00073 // 00074 // [min(t0,t1), max(m_t0,m_t1)] 00075 // 00076 // then there is no need to initialize m_k[]. If the function 00077 // is not c2 on the domain in question, then the m_k[m_count] array 00078 // is a list of parameters that define the c2 domains. When m_k[] 00079 // is not NULL, m_count must be >= 2 and m_k[] must be monotone 00080 // increasing and satisfy 00081 // 00082 // m_k[0] <= min(m_t0,m_t1) 00083 // and 00084 // m_k[m_count-1] >= max(m_t0,m_t1). 00085 // 00086 // Duplicate values in m_k[] are permitted so that NURBS knot 00087 // vector arrays may be used directly. 00088 const double* m_k; 00089 00090 // length of m_k[] array ( 0 or >= 2 ). 00091 int m_k_count; 00092 00093 private: 00094 double m_s0, m_f0, m_s1, m_f1; 00095 ON_BOOL32 BracketZero(double,double,double,double,int=0); 00096 ON_BOOL32 BracketSpan(double,double,double,double); 00097 ON_BOOL32 NewtonRaphson( double, double, double, double, int, double* ); 00098 }; 00099 00100 #endif 00101