cisst-saw
Loading...
Searching...
No Matches
nmrPolynomialTermPowerIndex.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: 2001-10-21
8
9 (C) Copyright 2001-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
26
27#ifndef _nmrPolynomialTermPowerIndex_h
28#define _nmrPolynomialTermPowerIndex_h
29
30#include <vector>
31#include <stdexcept>
34
36
41#ifndef DEFINE_FORMATTED_OUTPUT
42#define DEFINE_FORMATTED_OUTPUT 0
43#endif
44
90{
91public:
95 typedef int VariableIndexType;
98 typedef int PowerType;
101 typedef unsigned long MultinomialCoefficientType;
102
103
110 nmrPolynomialTermPowerIndex(VariableIndexType numVariables = 1, PowerType minDegree = 0, PowerType maxDegree = 4);
111
116
121 int GetDegree() const
122 {
123 return Degree;
124 }
125
127 {
128 return MaxDegree;
129 }
130
132 {
133 return MinDegree;
134 }
135
136 void SetMaxDegree(PowerType newMax) CISST_THROW(std::runtime_error)
137 {
138 if (newMax < this->Degree) {
139 throw std::runtime_error("nmrPolynomialTermPowerIndex: Attempt to set max degree below current degree");
140 }
141 if (newMax < this->MinDegree) {
142 throw std::runtime_error("nmrPolynomialTermPowerIndex: Attempt to set max degree below set minimum");
143 }
144 MaxDegree = newMax;
145 }
146
147 void SetMinDegree(PowerType newMin) CISST_THROW(std::runtime_error)
148 {
149 if (newMin > this->Degree) {
150 throw std::runtime_error("nmrPolynomialTermPowerIndex: Attempt to set min degree above current degree");
151 }
152 if (newMin > this->MaxDegree) {
153 throw std::runtime_error("nmrPolynomialTermPowerIndex: Attempt to set max degree above set maximum");
154 }
155 MinDegree = newMin;
156 }
157
161 bool IsValid() const
162 {
163 return (MinDegree <= Degree) && (Degree <= MaxDegree);
164 }
165
167 {
168 return Powers.size();
169 }
170
176 {
177 return Powers[variable];
178 }
179
181 const PowerType * GetPowers() const
182 {
183 return &(Powers[0]);
184 }
185
187 const int * GetPowersAsSigned() const
188 {
189 return reinterpret_cast<const int *>(GetPowers());
190 }
191
197 {
198 Degree += power - Powers[variable];
199 Powers[variable] = power;
200 }
201
203 void SetPowers(const PowerType powers[])
204 {
206 Degree = 0;
207 for (i = 0; i < GetNumVariables(); i++) {
208 Powers[i] = powers[i];
209 Degree += powers[i];
210 }
211 }
212
218
221 void SetDegree(PowerType degree);
222
224 void GoBegin();
226 void GoEnd();
227
245 void Increment();
246
256 void Decrement();
257
259 bool IsBegin() const
260 {
261 return (GetDegree() == GetMinDegree()) && (GetPower(0) == GetMinDegree());
262 }
263
265 bool IsEnd() const
266 {
267 return (GetDegree() == GetMaxDegree()) && (GetPower(GetNumVariables() - 1) == GetMaxDegree());
268 }
269
284 int Compare(const nmrPolynomialTermPowerIndex & other) const;
285
290 bool operator< (const nmrPolynomialTermPowerIndex& other) const
291 {
292 return (this->Compare(other) < 0);
293 }
294
299 bool operator > (const nmrPolynomialTermPowerIndex& other) const
300 {
301 return (other < *this);
302 }
303
304 bool operator<= (const nmrPolynomialTermPowerIndex & other) const
305 {
306 return (this->Compare(other) <= 0);
307 }
308
309 bool operator>= (const nmrPolynomialTermPowerIndex & other) const
310 {
311 return (other <= *this);
312 }
313
319 bool operator== (const nmrPolynomialTermPowerIndex& other) const;
320 // This is an incorrect definition of operator==
321 //{ return (this->Compare(other) == 0); }
322
323
324 // For a set of powers 'p1',...,'pn' whose sum is 'd', return
325 // d! / (p1! p2! ... pn!).
326 // In this function, d is given as an argument, so there is assumed to
327 // be an implicit (non-independent) variable in the polynomial.
330 PowerType chooseFrom, const PowerType indices[]);
331
332 // For a set of powers 'p1',...,'pn' whose sum is 'd', return
333 // d! / (p1! p2! ... pn!).
334 // In this function, d is the sum of all the powers stored in 'indices'
337 const PowerType indices[]);
338
339
340 // For a set of powers 'p1',...,'pn' whose sum is 'd', return
341 // d! / (p1! p2! ... pn!).
342 // In this function, d is the sum of all the powers stored in this term.
347
348 // For a set of powers 'p1',...,'pn' whose sum is 'd', return
349 // d! / (p1! p2! ... pn!).
350 // In this function, d is given as an argument, so there is assumed to
351 // be an implicit (non-independent) variable in the polynomial.
356
357 // Return the combinatorial number of possible power sets for the term.
358 //
359 // For a fixed degree d, and n variables, the number of combinations
360 // is the number of multisets of size d over n elements.
361 // First we choose k = number of variables in the term. if d<n we can choose
362 // k=1..d, otherwise we can choose k=1..n . But for simplicity and arithmetic
363 // reasons we will assume k=1..d. We will see that it does not affect the
364 // final result. Next, we have to choose the variables in the term. We have
365 // \choose{n}{k} combinations. Finally we choose the power for each variable.
366 // We have \choose{d-1}{k-1} combinations. The entire expression is
367 //
368 // \sum_{k=1}^{d} \choose{n}{k} \choose{d-1}{k-1}
369 //
370 // Note that for any k>n, \choose{n}{k} = 0, so we don't need to worry about
371 // d>n.
372 // The entire sum can be simplified into \choose{n+d-1}{d}. However, for a term
373 // index of n variables, we have to sum over all possible degrees:
374 //
375 // \sum_{d=MinDegree}^{MaxDegree} \choose{n+d-1}{d}.
376 //
377 // \choose{n+d}{d+1} = (n+d)! / ( (d+1)! (n-1)! ) = ((n+d)(n+d-1)) / ((d+1) d! (n-1)!)
378 // = ((n+d)/(d+1)) * ( (n+d-1)! d! (n-1)! ) = ((n+d)/(d+1)) * \choose{n+d-1}{d}
379 //
380 // Therefore, we only need to make a long computation for the first element of the
381 // sum, and the rest are received incrementally.
383
388
389#if DEFINE_FORMATTED_OUTPUT
390 // Print the powers of the term index in sprintf format into a character
391 // buffer. No assertion is made to ensure that the buffer has enough capacity
392 // to store the formatted message. All powers are printed, included zeroes.
393 // Parameters:
394 // buffer [i/o] -- destination buffer for the output
395 // widthFormat [i] -- a format specification to enable equal column width.
396 //
397 // Return: a pointer to the character immediately following the formatted output
398 char * FormatPowers(char * buffer, const char * widthFormat = "%d") const;
399#endif
400
401
402#if DEFINE_FORMATTED_OUTPUT
403 // Print the entire term index in formatted output. The format is:
404 // [numVariables minDegree maxDegree] powers...
405 // See FormatPowers for parameter and return value specification.
406 char * FormatTermIndex(char * buffer, const char * widthFormat = "%d") const;
407#endif
408
409#if DEFINE_FORMATTED_OUTPUT
410 // Return the estimated number of characters required to store the formatted
411 // powers (from FormatPowers())
412 int CalculateFormatPowerLength(const char * widthFormat = "%d") const
413 {
414 char buff[10];
415 sprintf( buff, widthFormat, GetMaxDegree() );
416 int varLength = strlen(buff) + 1;
417 return varLength * GetNumVariables();
418 }
419#endif
420
426 void SerializeRaw(std::ostream & output) const;
427
431 void DeserializeRaw(std::istream & input);
432
438 void SerializeIndexRaw(std::ostream & output) const;
439
442 void DeserializeIndexRaw(std::istream & input);
443
444protected:
445 std::vector<PowerType> Powers; // the powers of all the variables in the term
446 PowerType MinDegree; // the minimal possible degree of the term
447 PowerType MaxDegree; // the maximal possible degree of the term
448
449 // the degree of the term. Note that it may be negative, in which case the term is
450 // invalid. This member should always be equal to the sum of all powers. It
451 // is therefore redundant information is only serves as a cache for sorting
452 // purposes. It is not serialized.
454
455};
456
457#endif // _nmrPolynomialTermPowerIndex_h
Definition nmrPolynomialBase.h:52
std::vector< PowerType > Powers
Definition nmrPolynomialTermPowerIndex.h:445
int GetDegree() const
Definition nmrPolynomialTermPowerIndex.h:121
PowerType GetPower(VariableIndexType variable) const
Definition nmrPolynomialTermPowerIndex.h:175
unsigned long MultinomialCoefficientType
Definition nmrPolynomialTermPowerIndex.h:101
PowerType MinDegree
Definition nmrPolynomialTermPowerIndex.h:446
bool IsEnd() const
Definition nmrPolynomialTermPowerIndex.h:265
PowerType GetMaxDegree() const
Definition nmrPolynomialTermPowerIndex.h:126
nmrPolynomialTermPowerIndex(VariableIndexType numVariables=1, PowerType minDegree=0, PowerType maxDegree=4)
void SetMaxDegree(PowerType newMax) CISST_THROW(std
Definition nmrPolynomialTermPowerIndex.h:136
int Degree
Definition nmrPolynomialTermPowerIndex.h:453
int PowerType
Definition nmrPolynomialTermPowerIndex.h:98
int Compare(const nmrPolynomialTermPowerIndex &other) const
bool IsBegin() const
Definition nmrPolynomialTermPowerIndex.h:259
VariableIndexType GetNumVariables() const
Definition nmrPolynomialTermPowerIndex.h:166
MultinomialCoefficientType GetMultinomialCoefficient() const
Definition nmrPolynomialTermPowerIndex.h:343
void DeserializeRaw(std::istream &input)
static MultinomialCoefficientType EvaluateMultinomialCoefficient(VariableIndexType numIndices, PowerType chooseFrom, const PowerType indices[])
PowerType MaxDegree
Definition nmrPolynomialTermPowerIndex.h:447
nmrPolynomialTermPowerIndex(const nmrPolynomialBase &p)
void SetPower(VariableIndexType variable, PowerType power)
Definition nmrPolynomialTermPowerIndex.h:196
const int * GetPowersAsSigned() const
Definition nmrPolynomialTermPowerIndex.h:187
void SetPowers(const PowerType powers[])
Definition nmrPolynomialTermPowerIndex.h:203
void SetMinDegree(PowerType newMin) CISST_THROW(std
Definition nmrPolynomialTermPowerIndex.h:147
void SerializeRaw(std::ostream &output) const
MultinomialCoefficientType CountLowerOrderTerms() const
bool IsValid() const
Definition nmrPolynomialTermPowerIndex.h:161
void CopyPowers(const nmrPolynomialTermPowerIndex &other)
PowerType GetMinDegree() const
Definition nmrPolynomialTermPowerIndex.h:131
int VariableIndexType
Definition nmrPolynomialTermPowerIndex.h:95
MultinomialCoefficientType CountPowerCombinations() const
void SerializeIndexRaw(std::ostream &output) const
void SetDegree(PowerType degree)
MultinomialCoefficientType GetMultinomialCoefficient(PowerType d) const
Definition nmrPolynomialTermPowerIndex.h:352
void DeserializeIndexRaw(std::istream &input)
const PowerType * GetPowers() const
Definition nmrPolynomialTermPowerIndex.h:181
static MultinomialCoefficientType EvaluateMultinomialCoefficient(VariableIndexType numIndices, const PowerType indices[])
#define CISST_EXPORT
Definition cmnExportMacros.h:50
Portability across compilers and operating systems tools.
#define CISST_THROW(exceptionParameter)
Somewhat portable compilation warning message. This works with very recent versions of gcc (4....
Definition cmnPortability.h:559
Rules of exporting.
bool operator==(const vctDynamicConstMatrixBase< __matrixOwnerType, _elementType > &otherMatrix) const
Definition vctDynamicConstMatrixBase.h:715