- Main Page
- Namespaces
- Classes
- Files

# proto/Source/utils.cpp

Go to the documentation of this file.

    00001
    00004 #include <sstream>
    00005 #include <iomanip>
    00006
    00007 #include "utils.h"
    00008
    00009 namespace ace {
    00010
    00011 /* Interface item implementation.
    00012  */
    00013 std::string unsigned2str(size_t num) {
    00014     std::stringstream ss(std::ios::in | std::ios::out);
    00015     ss << num;
    00016     return ss.str();
    00017 }
    00018
    00019 /* Interface item implementation.
    00020  */
    00021 std::string double2str(double num, unsigned precision) {
    00022     std::stringstream ss(std::ios::in | std::ios::out);
    00023     ss << std::setprecision(static_cast<std::streamsize>(precision));
    00024     ss << num;
    00025     return ss.str();
    00026 }
    00027
    00028 #ifdef _DEPENDENCY_MODE
    00029
    00036 size_t _get_decompositions(size_t sum, size_t addends_count, sum_decompositions_t& results) {
    00037     // Remember the number of already stored results,
    00038     // to let (possible) superior call of itself know the index from which to alter results.
    00039     size_t started_at = results.size();
    00040
    00041     if ( addends_count == 0 ) {
    00042         // No possibility to create new sum.
    00043         return started_at;
    00044     }
    00045     if ( (addends_count == 1) || (sum == 0) ) {
    00046         // Only one possibility to create new sum.
    00047         std::vector<size_t> new_one;
    00048         if ( addends_count == 1 ) {
    00049             // Last addend has to be equal to sum.
    00050             new_one.push_back(sum);
    00051         } else {
    00052             // All remaining addends should be equal to zero.
    00053             for ( size_t i = 1; i <= addends_count; ++i ) {
    00054                 new_one.push_back(0);
    00055             }
    00056         }
    00057         // Store result.
    00058         results.push_back(new_one);
    00059         return started_at;
    00060     }
    00061     // To store index of last accessed array.
    00062     size_t start_at = 0;
    00063     //
    00064     for ( size_t i = 0; i <= sum; ++i ) {
    00065         // The call to get_decompositions() returns index of first_item in `results`,
    00066         // which has been altered by the function execution. It's very important to recent call,
    00067         // because we have to start altering results at exactly the same index.
    00068         start_at = _get_decompositions(sum - i, addends_count - 1, results);
    00069         // Alter only the items extended by last recursive call to get_decompositions():
    00070         for ( ; start_at < results.size(); ++start_at ) {
    00071             results[start_at].push_back(i);
    00072         }
    00073     }
    00074     return started_at;
    00075 }
    00076
    00077 SumDecompositions::~SumDecompositions(void) {
    00078     // Delete all tables created for overflowed-calls.
    00079     for ( overflow_sum_decompositions_mapping_t::const_iterator iter = _overflow.begin(); iter != _overflow.end(); ++iter ) {
    00080         delete iter->second;
    00081     }
    00082     for ( size_t i = 0; i < _n*_m; ++i ) {
    00083         // Delete all tables.
    00084         delete _tables[i];
    00085     }
    00086     // Delete the index table itself.
    00087     delete[] _tables;
    00088 }
    00089
    00090
    00091 void SumDecompositions::_init(void) {
    00092     for ( size_t i = 0; i < _n; ++i ) {
    00093         for ( size_t j = 0; j < _m; ++j ) {
    00094             _tables[i*_m + j] = new sum_decompositions_t();
    00095             // Note the increased parameters! Table indexes starts at 0 for both values,
    00096             // but the tables are created for values = index + 1.
    00097             _get_decompositions(i+1, j+1, *_tables[i*_m + j]);
    00098         }
    00099     }
    00100 }
    00101
    00102
    00103 const sum_decompositions_t * SumDecompositions::get_decompositions_table(size_t sum, size_t addends) {
    00104     // Invalid argument(s)!
    00105     if ( (sum == 0) || (addends == 0) ) {
    00106         return NULL;
    00107     }
    00108     // Ok! Return pointer to desired table, if table has been already evaluated.
    00109     if ( (sum <= _n) && (addends <= _m) ) {
    00110         return _tables[(sum-1)*_m + (addends-1)];
    00111     }
    00112
    00113     // TODO: Else we have to count new table.
    00114     size_t overflow_key = sum*1000 + addends;
    00115     overflow_sum_decompositions_mapping_t::const_iterator iter = _overflow.find(overflow_key);
    00116     if ( iter != _overflow.end() ) {
    00117         return iter->second;
    00118     } else {
    00119         sum_decompositions_t *sd = new sum_decompositions_t();
    00120         _get_decompositions(sum, addends, *sd);
    00121         _overflow.insert(overflow_sum_decompositions_mapping_t::value_type(overflow_key, sd));
    00122         return sd;
    00123     }
    00124 }
    00125
    00126 #else
    00127
    00128 bools_table_t bools_table(size_t ones, size_t length) {
    00129     bools_table_t table;
    00130     size_t bound = 1 << length;
    00131     for ( size_t i = 0; i < bound; ++i ) {
    00132         if ( bits_in(i) == ones ) {
    00133             std::vector<bool> bools;
    00134             for ( size_t j = 0; j < length; ++j ) {
    00135                 bools.push_back(ith_bit(i, j));
    00136             }
    00137             table.push_back(bools);
    00138         }
    00139     }
    00140     return table;
    00141 }
    00142
    00143 #endif
    00144
    00145 } // namespace ace