cisst-saw
Loading...
Searching...
No Matches
nmrPolynomialContainer.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3
4/*
5
6 Author(s): Ofri Sadowsky
7 Created on: 2003
8
9 (C) Copyright 2003-2007 Johns Hopkins University (JHU), All Rights
10 Reserved.
11
12--- begin cisst license - do not edit ---
13
14This software is provided "as is" under an open source license, with
15no warranty. The complete license can be found in license.txt and
16http://www.cisst.org/cisst/license.txt.
17
18--- end cisst license ---
19*/
20
21
22#ifndef _nmrPolynomialContainer_h
23#define _nmrPolynomialContainer_h
24
26
27#define MAP_CONTAINER 1
28#define LIST_CONTAINER 2
29#define CONTAINER_TYPE LIST_CONTAINER
30
31#if (CONTAINER_TYPE == MAP_CONTAINER)
32#include <map>
33#elif (CONTAINER_TYPE == LIST_CONTAINER)
34#include <list>
35#include <algorithm>
36#endif
37
38#include <iostream>
39
41
42// class nmrPolynomialContainer is a templated class to contain the terms of a
43// multi-variable polynomial. The concrete polynomial may still define properties
44// such as basis functions (standard, Bernstein, etc.). The terms are indexed
45// by a nmrPolynomialTermPowerIndex object, and ordered according to the order relation
46// of class nmrPolynomialTermPowerIndex. The current implementation uses STL map to
47// contain all the terms. The key is the power index, and the value varies by the concrete
48// polynomial class. That is, nmrPolynomialContainer is templated over the additional
49// information associated with a term. For a standard polynomial, it is only the coefficient.
50// For a Bernstein polynomial, it is the coefficient and a multinomial factor.
51//
52// nmrPolynomialContainer defines iterators for quick and sequential access/manipulation
53// of data in the polynomial. The user can index a term by its powers, whether it's stored
54// in the container or not, in logarithmic time. Referencing a term which is already in
55// the polynomial by an iterator is quicker. Therefore, some operations which were defined
56// in the base class nmrPolynomialBase to use a nmrPolynomialTermPowerIndex argument are
57// redefined here with an iterator argument for faster processing.
58template<class _TermInfo>
60{
61public:
63
64 typedef _TermInfo TermInfoType;
65
66#if (CONTAINER_TYPE == MAP_CONTAINER)
67 typedef std::map<nmrPolynomialTermPowerIndex, TermInfoType> TermContainerType;
68#elif (CONTAINER_TYPE == LIST_CONTAINER)
69 typedef std::pair<nmrPolynomialTermPowerIndex, TermInfoType> ContainerElementType;
70 typedef std::list<ContainerElementType> TermContainerType;
71#endif
72
73 typedef typename TermContainerType::value_type TermType;
74 typedef typename TermContainerType::iterator TermIteratorType;
75 typedef typename TermContainerType::const_iterator TermConstIteratorType;
76
77
78#if (CONTAINER_TYPE == LIST_CONTAINER)
85 {
86 public:
88 : Target(target)
89 {}
90
91 inline bool operator() (const ContainerElementType & element)
92 {
93 return (Target.Compare(element.first) == 0);
94 }
95 private:
96 const nmrPolynomialTermPowerIndex & Target;
97 };
98
105 {
106 public:
108 : Target(target)
109 {}
110
111 inline bool operator() (const ContainerElementType & element)
112 {
113 return (Target.Compare(element.first) <= 0);
114 }
115 private:
116 const nmrPolynomialTermPowerIndex & Target;
117 };
118
119#endif
120
121 // Ctor determines the number of variables and the degree of the polynomial
123 : BaseType(numVariables, minDegree, maxDegree)
124 {}
125
127 {
128 Clear();
129 }
130
132 {
133 return Terms.size();
134 }
135
136 // Tell if there are any terms in the polynomial
137 virtual bool IsEmpty() const
138 {
139 return Terms.empty();
140 }
141
142 //: Implemented from nmrPolynomialBase
143 virtual void SetMinDegree(PowerType newMin) CISST_THROW(std::runtime_error)
144 {
145 if (newMin > this->MaxDegree) {
146 throw std::runtime_error("nmrPolynomialContainer: Attempt to set the min degree higher than max");
147 }
148 if (this->IsEmpty()) {
149 this->MinDegree = newMin;
150 return;
151 }
152 const TermType & firstTerm = *(Terms.begin());
153 const nmrPolynomialTermPowerIndex & termPowers = firstTerm.first;
154 const PowerType firstDegree = termPowers.GetDegree();
155 if (newMin > firstDegree) {
156 throw std::runtime_error("nmrPolynomialContainer: Attempt to set the min degree above existing term");
157 }
158 MinDegree = newMin;
159 }
160
161 //: Implemented from nmrPolynomialBase
162 virtual void SetMaxDegree(PowerType newMax) CISST_THROW(std::runtime_error)
163 {
164 if (newMax < this->MinDegree) {
165 throw std::runtime_error("nmrPolynomialContainer: Attempt to set the max degree lower than min");
166 }
167 if (this->IsEmpty()) {
168 this->MaxDegree = newMax;
169 return;
170 }
171 const TermType & lastTerm = *(Terms.rbegin());
172 const nmrPolynomialTermPowerIndex & termPowers = lastTerm.first;
173 const PowerType lastDegree = termPowers.GetDegree();
174 if (newMax < lastDegree) {
175 throw std::runtime_error("nmrPolynomialContainer: Attempt to set the max degree below existing term");
176 }
177 MaxDegree = newMax;
178 }
179
180 // Generate all possible terms for this polynomial, and store them for later
181 // use.
182 virtual void FillAllTerms()
183 {
184 nmrPolynomialTermPowerIndex termIndex( *this );
185 termIndex.GoBegin();
186
187 while (termIndex.IsValid()) {
188 TermIteratorType termIterator = FindTerm(termIndex);
189 if (termIterator == EndTermIterator())
190 SetCoefficient(termIndex, 0);
191 termIndex.Increment();
192 }
193 }
194
195 // Find a term by its index. Return true is the term is found.
196 // return 'false' otherwise.
197 virtual bool IncludesIndex(const nmrPolynomialTermPowerIndex& target) const
198 {
199#if (CONTAINER_TYPE == MAP_CONTAINER)
200 return Terms.find(target) != Terms.end();
201#elif (CONTAINER_TYPE == LIST_CONTAINER)
202 return std::find_if(Terms.begin(), Terms.end(), EqualityTester(target)) != Terms.end();
203#endif
204 }
205
206 // Find a term by its coefficients. If the term is found, return the sequential
207 // position (zero-based) of the term in the sequence of terms for this polynomial.
208 // If the term is not found, return a number greater than or equal to the current number
209 // of terms in the sequence.
211 {
212 if (this->IsEmpty()) {
213 return 0;
214 }
215
217 const TermConstIteratorType endTermIterator = EndTermIterator();
218 TermCounterType result = 0;
219 for (; termIterator != endTermIterator; ++termIterator) {
220 if ( (termIterator->first).Compare(term) == 0 ) {
221 break;
222 }
223 ++result;
224 }
225 return result;
226 }
227
231 {
233 TermCounterType index = 0;
234 const TermIteratorType endTermIterator = EndTermIterator();
235 for (; (index < position) && (result != endTermIterator); ++index, ++result)
236 {}
237
238 return result;
239 }
240
241 // Returns an iterator for the first actual term in the polynomial.
243 { return Terms.begin(); }
245 { return Terms.begin(); }
246
247 // Returns an iterator to the end of the polynomial container. See the end()
248 // method for STL containers.
250 { return Terms.end(); }
252 { return Terms.end(); }
253
254 // Returns an iterator that refers to the term of the given power index. If this
255 // polynomial does not contain a term with the given index, returns EndTermIterator().
257 {
258#if (CONTAINER_TYPE == MAP_CONTAINER)
259 return Terms.find(target);
260#elif (CONTAINER_TYPE == LIST_CONTAINER)
261 return std::find_if(Terms.begin(), Terms.end(), EqualityTester(target));
262#endif
263 }
265 {
266#if (CONTAINER_TYPE == MAP_CONTAINER)
267 return Terms.find(target);
268#elif (CONTAINER_TYPE == LIST_CONTAINER)
269 return std::find_if(Terms.begin(), Terms.end(), EqualityTester(target));
270#endif
271 }
272
273 // Remove a term from the polynomial. The term is given by power index.
274 // Equivalent to setting the coefficient of the term to zero, except that this
275 // function also reclaims the space allocated for the term.
276 virtual void RemoveTerm(const nmrPolynomialTermPowerIndex & where)
277 {
278 TermIteratorType foundTerm = FindTerm(where);
279 if (foundTerm != EndTermIterator()) {
280 RemoveTerm(foundTerm);
281 }
282 }
283
284 // Remove a term from the polynomial. The term is given by iterator.
285 // The function also reclaims the space allocated for the term.
286 virtual void RemoveTerm(TermIteratorType & where)
287 {
288 Terms.erase(where);
289 }
290
291 virtual void Clear()
292 {
293 Terms.clear();
294 }
295
296 // Re-implemented from nmrPolynomialBase to provide v-table access.
298
299 // Set a coefficient for a term given by iterator.
300 // Implemented for each concrete polynomial class.
302
303 // Retrieve the value of the user defined coefficient for a term given by iterator.
304 virtual CoefficientType GetCoefficient(const TermConstIteratorType & where) const = 0;
305 virtual CoefficientType GetCoefficient(const TermIteratorType & where) const = 0;
306
307 // Collect all the coefficients into an array. Re-implemented from nmrPolynomialBase
308 virtual void CollectCoefficients(CoefficientType target[]) const
309 {
311 int coefficientIndex = 0;
312 for (; termIterator != EndTermIterator(); ++termIterator, ++coefficientIndex) {
313 target[coefficientIndex] = GetCoefficient(termIterator);
314 }
315 }
316
317 // Restore all the coefficients from an array.
318 // Re-implemented from nmrPolynomialBase
319 virtual void RestoreCoefficients(const CoefficientType source[])
320 {
321 TermIteratorType termIterator = FirstTermIterator();
322 int coefficientIndex = 0;
323 for (; termIterator != EndTermIterator(); ++termIterator, ++coefficientIndex) {
324 SetCoefficient(termIterator, source[coefficientIndex]);
325 }
326 }
327
329 { return where->first; }
331 { return where->first; }
332
333#if INCLUDE_DEPRECATED_POLYNOMIAL_CODE
334 // Evaluate the basis function for a term given by iterator. The use of iterator can
335 // optimize evaluation by caching elements such as multinomial factor with the term
336 // coefficient, eliminating the need to re-evaluate it for every evaluation of
337 // the basis function.
338 ValueType EvaluateBasis(const TermConstIteratorType & where) const
339 {
340 return EvaluateBasis(where, *VariablePowers);
341 }
342 ValueType EvaluateBasis(const TermIteratorType & where) const
343 {
344 return EvaluateBasis(where, *VariablePowers);
345 }
346#endif // INCLUDE_DEPRECATED_POLYNOMIAL_CODE
348 const nmrMultiVariablePowerBasis & variables) const = 0;
350 const nmrMultiVariablePowerBasis & variables) const = 0;
351
352 // Evaluate a single term referenced by iterator.
354 {
355 return GetCoefficient(where) * EvaluateBasis(where);
356 }
358 {
359 return GetCoefficient(where) * EvaluateBasis(where);
360 }
362 const nmrMultiVariablePowerBasis & variables) const
363 {
364 return GetCoefficient(where) * EvaluateBasis(where, variables);
365 }
367 const nmrMultiVariablePowerBasis & variables) const
368 {
369 return GetCoefficient(where) * EvaluateBasis(where, variables);
370 }
371
372 // Evaluate the polynomial at the currently point (specified by the values of the variables).
373 virtual ValueType Evaluate(const nmrMultiVariablePowerBasis & variables) const
374 {
375 ValueType polyVal = 0;
376
379 while (termIt != endIt) {
380 polyVal += EvaluateTerm(termIt, variables);
381 ++termIt;
382 }
383
384 return polyVal;
385 }
386
388 virtual void EvaluateBasisVector(const nmrMultiVariablePowerBasis & variables,
389 ValueType termBaseValues[]) const
390 {
393 ValueType * valuePtr = termBaseValues;
394
395 for (; termIt != endIt; ++termIt, ++valuePtr) {
396 *valuePtr = EvaluateBasis(termIt, variables);
397 }
398 }
399
400 // Evaluate the polynomial using externally defined coefficients.
402 const CoefficientType coefficients[]) const
403 {
404 ValueType polyVal = 0;
405
406 CoefficientType const * coefficientIndex = coefficients;
407
410 for (; termIt != endIt; ++termIt, ++coefficientIndex) {
411 polyVal += BaseType::EvaluateTerm(termIt->first,
412 variables, *coefficientIndex);
413 }
414
415 return polyVal;
416 }
417
419 virtual void Scale(CoefficientType scaleFactor)
420 {
423 for (; termIt != endIt; ++termIt) {
424 CoefficientType currentCoefficient = GetCoefficient(termIt);
425 SetCoefficient(termIt, scaleFactor * currentCoefficient);
426 }
427 }
428
431 virtual void AddConstant(CoefficientType shiftAmount) = 0;
432
434 virtual void AddConstantToCoefficients(CoefficientType coefficients[],
435 CoefficientType shiftAmount) const = 0;
436
437
438#if DEFINE_FORMATTED_OUTPUT
439 virtual char * Format(char * buffer) const
440 {
443 while (termIterator != endIterator) {
444 sprintf(buffer, "%.4f ", GetCoefficient(termIterator));
445 buffer += strlen(buffer);
446 sprintf(buffer, "{");
447 buffer+=strlen(buffer);
448 buffer = GetTermPowerIndex(termIterator).FormatPowers(buffer);
449 sprintf(buffer, "}\n");
450 buffer += strlen(buffer);
451
452 termIterator++;
453 }
454
455 return buffer;
456 }
457#endif
458
468 virtual void SerializeTermInfo(std::ostream & output, const TermConstIteratorType & termIterator) const = 0;
469
478 virtual void DeserializeTermInfo(std::istream & input, TermIteratorType & termIterator) = 0;
479
485 virtual void SerializeRaw(std::ostream & output) const
486 {
489 output.write( (const char *)&numTerms, sizeof(numTerms));
491 for (; termIterator != EndTermIterator(); ++termIterator) {
492 GetTermPowerIndex(termIterator).SerializeIndexRaw(output);
493 SerializeTermInfo(output, termIterator);
494 }
495 }
496
502 virtual void DeserializeRaw(std::istream & input)
503 {
504 // Restore NumVariables, MinDegree, MaxDegree
506 TermCounterType numTermsLeft;
507 input.read( (char *)&numTermsLeft, sizeof(numTermsLeft));
508 for (; numTermsLeft > 0; --numTermsLeft) {
510 termIndex.DeserializeIndexRaw(input);
511 TermInfoType termInfo;
512#if (CONTAINER_TYPE == MAP_CONTAINER)
513 Container[termIndex] = termInfo;
514#elif (CONTAINER_TYPE == LIST_CONTAINER)
515 Terms.push_back( ContainerElementType(termIndex, termInfo) );
516#endif
517 TermIteratorType termIterator = FindTerm(termIndex);
518 DeserializeTermInfo(input, termIterator);
519 }
520 }
521
522protected:
524
525 const TermInfoType & GetTermInfo(const TermConstIteratorType & termIterator) const
526 {
527 // good for both map and list!
528 return termIterator->second;
529 }
530
532 {
533 // good for both map and list!
534 return termIterator->second;
535 }
536
537};
538
539
540#endif // _nmrPolynomialContainer_h
Definition nmrMultiVariablePowerBasis.h:38
PowerType MinDegree
Definition nmrPolynomialBase.h:432
PowerType MaxDegree
Definition nmrPolynomialBase.h:433
virtual void SerializeRaw(std::ostream &output) const
nmrPolynomialTermPowerIndex::MultinomialCoefficientType TermCounterType
Definition nmrPolynomialBase.h:59
VariableIndexType GetNumVariables() const
Definition nmrPolynomialBase.h:69
nmrPolynomialTermPowerIndex::PowerType PowerType
Definition nmrPolynomialBase.h:58
virtual void DeserializeRaw(std::istream &input)
double ValueType
Definition nmrPolynomialBase.h:54
double CoefficientType
Definition nmrPolynomialBase.h:56
PowerType GetMinDegree() const
Definition nmrPolynomialBase.h:74
nmrPolynomialTermPowerIndex::VariableIndexType VariableIndexType
Definition nmrPolynomialBase.h:57
InsertStatus
Definition nmrPolynomialBase.h:61
PowerType GetMaxDegree() const
Definition nmrPolynomialBase.h:79
nmrPolynomialBase(VariableIndexType numVariables, PowerType minDegree, PowerType maxDegree)
EqualityTester(const nmrPolynomialTermPowerIndex &target)
Definition nmrPolynomialContainer.h:87
LessOrEqualityTester(const nmrPolynomialTermPowerIndex &target)
Definition nmrPolynomialContainer.h:107
virtual void RestoreCoefficients(const CoefficientType source[])
Definition nmrPolynomialContainer.h:319
ValueType EvaluateTerm(const TermConstIteratorType &where, const nmrMultiVariablePowerBasis &variables) const
Definition nmrPolynomialContainer.h:361
virtual ValueType Evaluate(const nmrMultiVariablePowerBasis &variables) const
Definition nmrPolynomialContainer.h:373
virtual void Clear()
Definition nmrPolynomialContainer.h:291
TermIteratorType FindTerm(const nmrPolynomialTermPowerIndex &target)
Definition nmrPolynomialContainer.h:256
virtual void FillAllTerms()
Definition nmrPolynomialContainer.h:182
virtual TermCounterType GetIndexPosition(const nmrPolynomialTermPowerIndex &term) const
Definition nmrPolynomialContainer.h:210
virtual void SetMinDegree(PowerType newMin) CISST_THROW(std
Definition nmrPolynomialContainer.h:143
const TermInfoType & GetTermInfo(const TermConstIteratorType &termIterator) const
Definition nmrPolynomialContainer.h:525
TermContainerType::iterator TermIteratorType
Definition nmrPolynomialContainer.h:74
virtual void DeserializeRaw(std::istream &input)
Definition nmrPolynomialContainer.h:502
virtual bool IncludesIndex(const nmrPolynomialTermPowerIndex &target) const
Definition nmrPolynomialContainer.h:197
virtual void CollectCoefficients(CoefficientType target[]) const
Definition nmrPolynomialContainer.h:308
ValueType EvaluateTerm(const TermConstIteratorType &where) const
Definition nmrPolynomialContainer.h:353
TermIteratorType EndTermIterator()
Definition nmrPolynomialContainer.h:249
virtual ValueType EvaluateBasis(const TermIteratorType &where, const nmrMultiVariablePowerBasis &variables) const =0
TermInfoType & GetTermInfo(const TermConstIteratorType &termIterator)
Definition nmrPolynomialContainer.h:531
virtual InsertStatus SetCoefficient(const nmrPolynomialTermPowerIndex &where, CoefficientType coefficient)=0
TermConstIteratorType FirstTermIterator() const
Definition nmrPolynomialContainer.h:244
virtual void RemoveTerm(const nmrPolynomialTermPowerIndex &where)
Definition nmrPolynomialContainer.h:276
virtual InsertStatus SetCoefficient(TermIteratorType &where, CoefficientType coefficient)=0
TermContainerType::value_type TermType
Definition nmrPolynomialContainer.h:73
nmrPolynomialContainer(VariableIndexType numVariables, PowerType minDegree, PowerType maxDegree)
Definition nmrPolynomialContainer.h:122
virtual void SetMaxDegree(PowerType newMax) CISST_THROW(std
Definition nmrPolynomialContainer.h:162
TermContainerType Terms
Definition nmrPolynomialContainer.h:523
ValueType EvaluateTerm(const TermIteratorType &where, const nmrMultiVariablePowerBasis &variables) const
Definition nmrPolynomialContainer.h:366
virtual void AddConstantToCoefficients(CoefficientType coefficients[], CoefficientType shiftAmount) const =0
virtual void AddConstant(CoefficientType shiftAmount)=0
virtual ~nmrPolynomialContainer()
Definition nmrPolynomialContainer.h:126
TermConstIteratorType EndTermIterator() const
Definition nmrPolynomialContainer.h:251
virtual ValueType EvaluateForCoefficients(const nmrMultiVariablePowerBasis &variables, const CoefficientType coefficients[]) const
Definition nmrPolynomialContainer.h:401
virtual bool IsEmpty() const
Definition nmrPolynomialContainer.h:137
virtual void RemoveTerm(TermIteratorType &where)
Definition nmrPolynomialContainer.h:286
virtual void DeserializeTermInfo(std::istream &input, TermIteratorType &termIterator)=0
virtual void Scale(CoefficientType scaleFactor)
Definition nmrPolynomialContainer.h:419
TermIteratorType GetTermIteratorForPosition(TermCounterType position)
Definition nmrPolynomialContainer.h:230
virtual void SerializeTermInfo(std::ostream &output, const TermConstIteratorType &termIterator) const =0
virtual void SerializeRaw(std::ostream &output) const
Definition nmrPolynomialContainer.h:485
ValueType EvaluateTerm(const TermIteratorType &where) const
Definition nmrPolynomialContainer.h:357
TermContainerType::const_iterator TermConstIteratorType
Definition nmrPolynomialContainer.h:75
const nmrPolynomialTermPowerIndex & GetTermPowerIndex(const TermIteratorType &where) const
Definition nmrPolynomialContainer.h:330
void * TermInfoType
Definition nmrPolynomialContainer.h:64
virtual ValueType EvaluateBasis(const TermConstIteratorType &where, const nmrMultiVariablePowerBasis &variables) const =0
TermConstIteratorType FindTerm(const nmrPolynomialTermPowerIndex &target) const
Definition nmrPolynomialContainer.h:264
const nmrPolynomialTermPowerIndex & GetTermPowerIndex(const TermConstIteratorType &where) const
Definition nmrPolynomialContainer.h:328
virtual CoefficientType GetCoefficient(const TermConstIteratorType &where) const =0
TermIteratorType FirstTermIterator()
Definition nmrPolynomialContainer.h:242
virtual CoefficientType GetCoefficient(const TermIteratorType &where) const =0
std::list< ContainerElementType > TermContainerType
Definition nmrPolynomialContainer.h:70
std::pair< nmrPolynomialTermPowerIndex, TermInfoType > ContainerElementType
Definition nmrPolynomialContainer.h:69
virtual TermCounterType GetNumberOfTerms() const
Definition nmrPolynomialContainer.h:131
virtual void EvaluateBasisVector(const nmrMultiVariablePowerBasis &variables, ValueType termBaseValues[]) const
Definition nmrPolynomialContainer.h:388
nmrPolynomialBase BaseType
Definition nmrPolynomialContainer.h:62
Represents the power index of a single term in a multi-variable polynomial.
Definition nmrPolynomialTermPowerIndex.h:90
int GetDegree() const
Definition nmrPolynomialTermPowerIndex.h:121
bool IsValid() const
Definition nmrPolynomialTermPowerIndex.h:161
void DeserializeIndexRaw(std::istream &input)
#define CISST_EXPORT
Definition cmnExportMacros.h:50
#define CISST_THROW(exceptionParameter)
Somewhat portable compilation warning message. This works with very recent versions of gcc (4....
Definition cmnPortability.h:559
virtual ValueType EvaluateBasis(const nmrPolynomialTermPowerIndex &where, const nmrMultiVariablePowerBasis &variables) const
Rules of exporting.
const_reference operator()(size_type rowIndex, size_type colIndex) const CISST_THROW(std
Definition vctDynamicConstMatrixBase.h:352