00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #define TINY 1.0e-10
00027 #define MAX_IT 1000
00028
00029 #include <limits.h>
00030 #include <float.h>
00031 #include "LineSearch.hh"
00032
00033 LineSearch::LineSearch(ObjectiveFunction* p)
00034 {
00035 iterMax = MAX_IT;
00036 iterNum = 0;
00037 fp = p;
00038 step = 0;
00039 iterHistory = new List<int>;
00040 }
00041
00042 LineSearch::LineSearch(ObjectiveFunction* p, Vector<double>* interval)
00043 {
00044 iterMax = MAX_IT;
00045 iterNum = 0;
00046 fp = p;
00047 step = interval;
00048 iterHistory = new List<int>;
00049 }
00050
00051 LineSearch::~LineSearch(){
00052 delete iterHistory;
00053 }
00054
00055 void LineSearch::appendSearchNumber()
00056 {
00057 iterHistory[0] += iterNum;
00058 }
00059
00060 List<int> LineSearch::allSearchIterations() { return iterHistory[0];}
00061 int LineSearch::searchIterations() {return iterNum;}
00062
00063 double LineSearch::currentValue() {return value;}
00064 const char* LineSearch:: objName() {return (fp->className());}
00065
00066 Model<double> LineSearch::search(Model<double>& m, Vector<double>& v,
00067 double alpha, double beta)
00068 {
00069 cerr << "You need to specify the LineSearch method!";
00070 exit(1);
00071 return 0;
00072 }
00073
00074 Model<long> LineSearch::search(Model<long>& m, Vector<double>& v,
00075 double alpha, double beta)
00076 {
00077 cerr << "You need to specify the LineSearch method!";
00078 exit(1);
00079 return 0;
00080 }
00081
00082 Vector<double>* LineSearch::numericalGradient(Model<double>& m)
00083 {
00084 int n = m.modSize();
00085 if(!step) {
00086 cerr << "For numerical gradients (finite differences) a stepsize must be specified."
00087 << endl << "Creating default vector of ones." << endl;
00088 step = new Vector<double>(n);
00089 *step = 1.0f;
00090 }
00091
00092 Vector<double>* grad = new Vector<double>(n);
00093 double diffValue, newValue, off;
00094 Model<double> m1(m);
00095
00096
00097 for (int i = 0; i < n; i++) {
00098 off = step[0][i];
00099 m1[i] -= off;
00100 newValue = fp->performance(m1);
00101 m1[i] += 2*off;
00102 diffValue = fp->performance(m1);
00103 diffValue -= newValue;
00104 (*grad)[i] = diffValue/(2*off);
00105 m1[i] = m[i];
00106 }
00107
00108
00109 return grad;
00110 }
00111
00112 Vector<double>* LineSearch::numericalGradient(Model<long>& m)
00113 {
00114 int n = m.modSize();
00115 if(!step) {
00116 cerr << "For numerical gradients (finite differences) a stepsize must be specified."
00117 << endl << "Creating default vector of ones." << endl;
00118 step = new Vector<double>(n);
00119 *step = 1.0f;
00120 }
00121
00122 Vector<double>* grad = new Vector<double>(n);
00123 double diffValue, newValue, off;
00124 Model<double> dm(m);
00125 Model<double> m1(dm);
00126
00127 double currentValue = fp->performance(dm);
00128 for (int i = 0; i < n; i++) {
00129 off = step[0][i]*dm[i];
00130 m1[i] += off;
00131 newValue = fp->performance(m1);
00132 diffValue = newValue-currentValue;
00133 (*grad)[i] = diffValue/(off);
00134 m1[i] = dm[i];
00135 }
00136 return grad;
00137 }
00138
00139 Vector<double> LineSearch::gradient(Model<double>& m)
00140 {
00141 Vector<double>* g = new Vector<double>(m.modSize());
00142 if ( (g=(fp->getGradient(m))) == NULL)
00143 g = numericalGradient(m);
00144 return g[0];
00145 }
00146
00147 Vector<double> LineSearch::gradient(Model<long>& m)
00148 {
00149 Vector<double>* g = new Vector<double>(m.modSize());
00150 if ( (g=(fp->getGradient(m))) == NULL)
00151 g = numericalGradient(m);
00152 return g[0];
00153 }
00154
00155 double LineSearch::evaluate(Model<double>& m)
00156 {
00157 return fp->performance(m);
00158 }
00159
00160 double LineSearch::evaluate(Model<long>& m)
00161 {
00162 return fp->performance(m);
00163 }
00164
00165