00001
00002
00003
00004 #if defined(_MSC_VER)
00005
00006 # pragma warning(disable:4786)
00007 #endif
00008
00009 #include <numeric>
00010
00011 #include "CoinHelperFunctions.hpp"
00012 #include "CoinPackedVectorBase.hpp"
00013
00014
00015
00016 double *
00017 CoinPackedVectorBase::denseVector(int denseSize) const throw(CoinError)
00018 {
00019 if (getMaxIndex() >= denseSize)
00020 throw CoinError("Dense vector size is less than max index",
00021 "denseVector", "CoinPackedVectorBase");
00022
00023 double * dv = new double[denseSize];
00024 CoinFillN(dv, denseSize, 0.0);
00025 const int s = getNumElements();
00026 const int * inds = getIndices();
00027 const double * elems = getElements();
00028 for (int i = 0; i < s; ++i)
00029 dv[inds[i]] = elems[i];
00030 return dv;
00031 }
00032
00033
00034
00035 double
00036 CoinPackedVectorBase::operator[](int i) const throw (CoinError)
00037 {
00038 if (! testedDuplicateIndex_)
00039 duplicateIndex("operator[]", "CoinPackedVectorBase");
00040
00041
00042
00043 const std::set<int> & sv = *indexSet("operator[]", "CoinPackedVectorBase");
00044 #if 1
00045 if (sv.find(i) == sv.end())
00046 return 0.0;
00047 return getElements()[findIndex(i)];
00048 #else
00049
00050 const size_t ind = std::distance(sv.begin(), sv.find(i));
00051 return (ind == sv.size()) ? 0.0 : getElements()[ind];
00052 #endif
00053
00054 }
00055
00056
00057
00058 void
00059 CoinPackedVectorBase::setTestForDuplicateIndex(bool test) const
00060 {
00061 if (test == true) {
00062 testForDuplicateIndex_ = true;
00063 duplicateIndex("setTestForDuplicateIndex", "CoinPackedVectorBase");
00064 } else {
00065 testForDuplicateIndex_ = false;
00066 testedDuplicateIndex_ = false;
00067 }
00068 }
00069
00070
00071
00072 int
00073 CoinPackedVectorBase::getMaxIndex() const
00074 {
00075 findMaxMinIndices();
00076 return maxIndex_;
00077 }
00078
00079
00080
00081 int
00082 CoinPackedVectorBase::getMinIndex() const
00083 {
00084 findMaxMinIndices();
00085 return minIndex_;
00086 }
00087
00088
00089
00090 void
00091 CoinPackedVectorBase::duplicateIndex(const char* methodName,
00092 const char * className)
00093 const throw(CoinError)
00094 {
00095 if (testForDuplicateIndex())
00096 indexSet(methodName, className);
00097 testedDuplicateIndex_ = true;
00098 }
00099
00100
00101
00102 bool
00103 CoinPackedVectorBase::isExistingIndex(int i) const
00104 {
00105 if (! testedDuplicateIndex_)
00106 duplicateIndex("indexExists", "CoinPackedVectorBase");
00107
00108 const std::set<int> & sv = *indexSet("indexExists", "CoinPackedVectorBase");
00109 return sv.find(i) != sv.end();
00110 }
00111
00112
00113 int
00114 CoinPackedVectorBase::findIndex(int i) const
00115 {
00116 const int * inds = getIndices();
00117 int retVal = std::find(inds, inds + getNumElements(), i) - inds;
00118 if (retVal == getNumElements() ) retVal = -1;
00119 return retVal;
00120 }
00121
00122
00123
00124 bool
00125 CoinPackedVectorBase::operator==(const CoinPackedVectorBase& rhs) const
00126 {
00127 return (getNumElements()==rhs.getNumElements() &&
00128 std::equal(getIndices(), getIndices() + getNumElements(),
00129 rhs.getIndices()) &&
00130 std::equal(getElements(), getElements() + getNumElements(),
00131 rhs.getElements()));
00132 }
00133
00134
00135
00136 bool
00137 CoinPackedVectorBase::operator!=(const CoinPackedVectorBase& rhs) const
00138 {
00139 return !( (*this)==rhs );
00140 }
00141
00142
00143
00144 double
00145 CoinPackedVectorBase::dotProduct(const double* dense) const
00146 {
00147 const double * elems = getElements();
00148 const int * inds = getIndices();
00149 double dp = 0.0;
00150 for (int i = getNumElements() - 1; i >= 0; --i)
00151 dp += elems[i] * dense[inds[i]];
00152 return dp;
00153 }
00154
00155
00156
00157 double
00158 CoinPackedVectorBase::oneNorm() const
00159 {
00160 register double norm = 0.0;
00161 register const double* elements = getElements();
00162 for (int i = getNumElements() - 1; i >= 0; --i) {
00163 norm += fabs(elements[i]);
00164 }
00165 return norm;
00166 }
00167
00168
00169
00170 double
00171 CoinPackedVectorBase::normSquare() const
00172 {
00173 return std::inner_product(getElements(), getElements() + getNumElements(),
00174 getElements(), 0.0);
00175 }
00176
00177
00178
00179 double
00180 CoinPackedVectorBase::infNorm() const
00181 {
00182 register double norm = 0.0;
00183 register const double* elements = getElements();
00184 for (int i = getNumElements() - 1; i >= 0; --i) {
00185 norm = CoinMax(norm, fabs(elements[i]));
00186 }
00187 return norm;
00188 }
00189
00190
00191
00192 double
00193 CoinPackedVectorBase::sum() const
00194 {
00195 return std::accumulate(getElements(), getElements() + getNumElements(), 0.0);
00196 }
00197
00198
00199
00200 CoinPackedVectorBase::CoinPackedVectorBase() :
00201 maxIndex_(INT_MIN),
00202 minIndex_(INT_MAX),
00203 indexSetPtr_(NULL),
00204 testForDuplicateIndex_(true),
00205 testedDuplicateIndex_(false) {}
00206
00207
00208
00209 CoinPackedVectorBase::~CoinPackedVectorBase()
00210 {
00211 delete indexSetPtr_;
00212 }
00213
00214
00215
00216
00217 void
00218 CoinPackedVectorBase::findMaxMinIndices() const
00219 {
00220 if ( getNumElements()==0 )
00221 return;
00222
00223 else if ( indexSetPtr_ != NULL ) {
00224 maxIndex_ = *indexSetPtr_->rbegin();
00225 minIndex_ = *indexSetPtr_-> begin();
00226 } else {
00227
00228 maxIndex_ = *(std::max_element(getIndices(),
00229 getIndices() + getNumElements()));
00230 minIndex_ = *(std::min_element(getIndices(),
00231 getIndices() + getNumElements()));
00232 }
00233 }
00234
00235
00236
00237 std::set<int> *
00238 CoinPackedVectorBase::indexSet(const char* methodName,
00239 const char * className) const throw(CoinError)
00240 {
00241 testedDuplicateIndex_ = true;
00242 if ( indexSetPtr_ == NULL ) {
00243
00244 indexSetPtr_ = new std::set<int>;
00245 const int s = getNumElements();
00246 const int * inds = getIndices();
00247 for (int j=0; j < s; ++j) {
00248 if (!indexSetPtr_->insert(inds[j]).second) {
00249 testedDuplicateIndex_ = false;
00250 delete indexSetPtr_;
00251 indexSetPtr_ = NULL;
00252 if (methodName != NULL) {
00253 throw CoinError("Duplicate index found", methodName, className);
00254 } else {
00255 throw CoinError("Duplicate index found",
00256 "indexSet", "CoinPackedVectorBase");
00257 }
00258 }
00259 }
00260 }
00261 return indexSetPtr_;
00262 }
00263
00264
00265
00266 void
00267 CoinPackedVectorBase::clearIndexSet() const
00268 {
00269 delete indexSetPtr_;
00270 indexSetPtr_ = NULL;
00271 }
00272
00273
00274
00275 void
00276 CoinPackedVectorBase::clearBase() const
00277 {
00278 clearIndexSet();
00279 maxIndex_ = INT_MIN;
00280 minIndex_ = INT_MAX;
00281 testedDuplicateIndex_ = false;
00282 }
00283
00284