00001 00002 00008 /* 00009 */ 00011 00012 #include "History.h" 00013 #include "LinearInterpolator.h" 00014 namespace O_SESSAME { 00015 00016 History::History() : m_OriginalInterpolator(new LinearInterpolator) 00017 { 00018 ResetHistory(); 00019 m_TimeHistory.reserve(HISTORY_RESERVE_SIZE); 00020 m_TimeInterpolations.reserve(HISTORY_RESERVE_SIZE); 00021 m_TimeInterpolations.front() = NULL; 00022 } 00023 00024 History::~History() 00025 { 00026 // delete the old interpolator 00027 if(m_OriginalInterpolator) 00028 delete m_OriginalInterpolator; 00029 } 00030 00031 void History::AppendHistory(const double &_appendTime) 00032 { 00033 AppendHistory(ssfTime(_appendTime)); 00034 } 00035 void History::AppendHistory(const ssfTime &_appendTime) 00036 { 00037 m_TimeHistory.push_back(_appendTime); 00038 } 00039 00040 vector<ssfTime>::difference_type History::AppendHistory(const vector<ssfTime> &_appendTime) 00041 { 00042 vector<ssfTime>::const_iterator iter; 00043 00044 // Determine if there is already a time history that overlaps with the appending time 00045 vector<ssfTime>::iterator replacementTime = std::find_if(m_TimeHistory.begin(), m_TimeHistory.end(), bind2nd(greater_equal<ssfTime>(), *(_appendTime.begin()))); 00046 vector<ssfTime>::difference_type retDistance = 0; 00047 00048 // If there is an overlap, delete the times following the overlap point. 00049 if(replacementTime != m_TimeHistory.end()) 00050 { 00051 // Store the distance from the overlapping point to the end & then delete the overlap. 00052 retDistance = distance(replacementTime, m_TimeHistory.end()); 00053 m_TimeHistory.erase(replacementTime, m_TimeHistory.end()); 00054 } 00055 // Append the new times to the time history. 00056 for(iter = _appendTime.begin(); iter != _appendTime.end(); ++iter) 00057 m_TimeHistory.push_back(*iter); 00058 00059 return retDistance; 00060 } 00061 00062 void History::ResetHistory() 00063 { 00064 vector<ssfTime> newTime(0); 00065 m_TimeHistory.swap(newTime); 00066 return; 00067 } 00068 00069 Matrix History::GetHistory() 00070 { 00071 Matrix returnMatrix(m_TimeHistory.size(), 1); 00072 int ii = 0; 00073 vector<ssfTime>::const_iterator iter; 00074 for(iter = m_TimeHistory.begin(); iter != m_TimeHistory.end(); ++iter) 00075 { 00076 returnMatrix(MatrixIndexBase + ii, MatrixIndexBase) = iter->GetSeconds(); 00077 ++ii; 00078 } 00079 00080 return returnMatrix; 00081 00082 } 00083 00084 vector<ssfTime>::difference_type History::GetState(const ssfTime& _requestedTime) 00085 { 00086 // Find the nearest (lower) corresponding time point 00087 vector<ssfTime>::iterator nearestTimeIterator = find_if(m_TimeHistory.begin(), m_TimeHistory.end(), bind2nd(greater_equal<ssfTime>(), _requestedTime)); 00088 // Store the distance from the first matching data point to the end 00089 vector<ssfTime>::difference_type nearestTimeIndex = distance(m_TimeHistory.begin(), nearestTimeIterator); 00090 00091 /* The code commented out below was a model for interpolation in the derived classes. It is not needed, but 00092 was left to verify against for the time being. nilspace:(13.5.03) 00093 int numDataPoints = 0; 00094 if(m_OriginalInterpolator) 00095 numDataPoints = m_OriginalInterpolator->GetNumberDataPoints(); 00096 else 00097 return nearestTimeIndex; 00098 Vector timeVector(numDataPoints); 00099 Matrix dataMatrix(numDataPoints, 1); 00100 00101 // See if there is data at the requested time. 00102 if((*nearestTimeIterator != _requestedTime) && (nearestTimeIterator != m_TimeHistory.end())) 00103 { 00104 // Determine if there is currently an interpolation through the requested point. 00105 // if there isn't, create one, then evaluate the interpolation at the requested data point. 00106 while(m_TimeInterpolations.capacity() < nearestTimeIndex) 00107 { 00108 m_TimeInterpolations.reserve(m_TimeInterpolations.capacity() + HISTORY_RESERVE_SIZE); 00109 } 00110 if(!m_TimeInterpolations[nearestTimeIndex]) 00111 { 00112 00113 // fill in the 'missing' interpolations 00114 for(int kk = m_TimeInterpolations.size(); kk < nearestTimeIndex; ++kk) 00115 m_TimeInterpolations.push_back(m_OriginalInterpolator->NewPointer()); 00116 00117 m_TimeInterpolations.push_back(m_OriginalInterpolator->NewPointer()); 00118 } 00119 // Calculate the interpolation parameters if necessary 00120 if(!m_TimeInterpolations[nearestTimeIndex]->GetValid()) 00121 { 00122 for(int ii = 1; ii <= numDataPoints; ++ii) 00123 { 00124 timeVector(ii) = m_TimeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetSeconds(); 00125 for(int jj = 1; jj <= dataMatrix[MatrixColsIndex].getIndexBound(); ++jj) 00126 { 00127 dataMatrix(ii,jj) = m_TimeHistory[nearestTimeIndex - (numDataPoints/2-1) + ii].GetSeconds(); 00128 } 00129 } 00130 00131 m_TimeInterpolations[nearestTimeIndex]->Interpolate(timeVector, dataMatrix); 00132 } 00133 00134 _requestedTime.Set(m_TimeInterpolations[nearestTimeIndex]->Evaluate(_requestedTime.GetSeconds())(1)); 00135 00136 } 00137 else if((nearestTimeIterator == m_TimeHistory.begin()) || (nearestTimeIterator == m_TimeHistory.end())) 00138 { // the requested time isn't in the stored interval 00139 return (nearestTimeIndex = -1); 00140 } 00141 else 00142 { // there happens to be meshpoint data at the requested time, return it. 00143 _requestedTime = *nearestTimeIterator; 00144 } 00145 */ 00146 return nearestTimeIndex; 00147 } 00148 00149 void History::SetInterpolator(Interpolator* _newInterpolator) 00150 { 00151 // delete the old interpolator 00152 if(m_OriginalInterpolator) 00153 delete m_OriginalInterpolator; 00154 00155 // make a copy of the new base interpolator 00156 m_OriginalInterpolator = _newInterpolator->Clone(); 00157 } 00158 00159 } // close namespace O_SESSAME 00160 00161 // Do not change the comments below - they will be added automatically by CVS 00162 /***************************************************************************** 00163 * $Log: History.cpp,v $ 00164 * Revision 1.10 2003/05/22 21:01:44 nilspace 00165 * Updated comments. 00166 * 00167 * Revision 1.9 2003/05/20 17:50:01 nilspace 00168 * Updated comments. 00169 * 00170 * Revision 1.8 2003/05/15 18:10:50 nilspace 00171 * Fixed the constructor initialize error of an extra , 00172 * 00173 * Revision 1.7 2003/05/13 18:45:35 nilspace 00174 * Added interpolation functionality. 00175 * 00176 * Revision 1.6 2003/05/01 18:24:36 nilspace 00177 * Prevented overlapping Appends by removing the old states and times. 00178 * 00179 * Revision 1.5 2003/04/27 22:04:33 nilspace 00180 * Created the namespace O_SESSAME. 00181 * 00182 * Revision 1.4 2003/04/25 17:14:59 nilspace 00183 * Added OrbitHistory & made sure it builds. 00184 * Moved Appending time to History.cpp. 00185 * 00186 * Revision 1.3 2003/04/23 17:01:02 nilspace 00187 * Time is now stored as an ssfTime object. 00188 * 00189 * Revision 1.2 2003/04/23 16:30:58 nilspace 00190 * Various bugfixes & uploading of all changed code for new programmers. 00191 * 00192 * Revision 1.1 2003/03/27 20:29:02 nilspace 00193 * Initial Submission. 00194 * 00195 ******************************************************************************/