A (one dimensional) cellular automaton is a function1 F : Σ → Σ with the property that there is a K > 0 such that F (x)i depends only on the 2K + 1 coordinates xi−K , xi−K+1, . . . , xi−1, xi, xi+1, . . . , xi+K . A periodic point of σ is any x such that σ^p (x) = x for some p ∈ N, and a periodic point of F is any x such that F^q (x) = x for some q ∈ N. Given a cellular automaton F, a point x ∈ Σ is jointly periodic if there are p, q ∈ N such that σ^p (x) = F^q (x) = x, that is, it is a periodic point under both functions.
This project aims to explore the nature of one-dimensional Cellular Automata, in the hope of finding the structure of cellular automata through its periodic points.
License: MIT
ubuntu2004
/* * Copyright (C) 2004 Bryant Lee * * This file is part of FDense. * * FDense is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * FDense is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FDense; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Main function * FDense program takes as input N (shift size), k (shift period), the c.a. * rule f, and m. It determines whether f is m-dense where m-dense means * that every word of length m appears in a jointly periodic point. If it * is not m-dense, it lists the words that do not appear in jointly periodic * points. * * Written by: Bryant Lee * Date: 9/01/05 */ #define USEARRAY 0 #define DEBUG 0 //Standard C++ #include <string.h> #include <iostream> #include <iomanip> #include <fstream> //for file ops //C #include <stdlib.h> //for atoi #include <math.h> //for pow //STL #include <vector> #include <list> #include <map> //local #include "StringOps.h" #include "Comp.h" #include "StorageKey.h" #include "StorageVal.h" #include "RecNode.h" #include "GroupData.h" #include "MList.h" /* * Function definitions */ void convertPeriodList(const string &strInput, vector<int> &periodList); void exhaustiveExp(unsigned int shiftSize, const vector<int> &periodList, unsigned int density, Comp *comp, list<MList> &recList, MList &unionList, string &prefix, vector<string> &commandbuffer); void exhaustiveExpTwoShift(unsigned int shiftSize, const vector<int> &periodList, unsigned int density, Comp *comp, list<MList> &recList, MList &unionList, string &prefix, vector<string> &commandbuffer); void clearStorageNodes(vector<StorageVal*> &table); void clearRecList(list<RecNode*> &recList); void output(unsigned int shiftSize, int density, string &prefix, const vector<int> &periodList, Comp * comp, list<MList> &recList, MList &unionList, vector<string> &commandbuffer); void groupoutput(int density, string &prefix, vector<string> &commandbuffer, vector<GroupData> &groupdata); void findDivisors(unsigned int x, vector<int> &divisorsList); bool leastPeriod(byte *word, unsigned int currPeriod, const vector<int> &divisorsList); bool leastPeriod(unsigned int word, unsigned int currPeriod, const vector<int> &divisorsList); void makeMPrefixList(vector<bool> &m_table, MList &record, unsigned int shiftSize); /* * GLOBAL variables */ int UINTSIZE = 32; int VERBOSE = 0; //display non-appearing m-words for each individual K //boolean that determines whether output is given after each completed experiment (after each K) //or only at end bool OUTPUT_AFTER_EACH = false; //determine whether the output is in the "group" format or the normal format bool GROUP = false; //main int main() { //book-keeping variables unsigned int shiftSize; //# symbols in shift string prefix; //prefix for output files string strInput, strInput2, strInput3; //temp variables string outoption; //output after each or at end vector<int> periodList; //list of periods unsigned int i = 0, temp; //counter //results variables list<MList> recList; //list of prefixes not seen, this is per K value MList unionList = MList(0); //list of prefixes not seen, over all K values //computation variables Comp *comp = NULL; //composition to apply unsigned int density; //hold the command strings vector<string> commandbuffer; int commandbufferit; //storage for the "group" option vector<GroupData> groupdata; unsigned int groupdatait; //grab all input from cin and put in an array of strings while(!cin.eof()) { std::getline(cin, strInput); commandbuffer.push_back(strInput); } commandbufferit = 0; //get "output after each" or "output at end" outoption = commandbuffer[commandbufferit++]; trim(outoption); transform(outoption.begin(), outoption.end(), outoption.begin(), tolower); if(outoption == "output after each") { OUTPUT_AFTER_EACH = true; } else if(outoption == "output at end") { OUTPUT_AFTER_EACH = false; } else { cout << "Error on line 1: invalid value for output mode\n"; goto cleanup; } //get "group" or "no group" strInput = commandbuffer[commandbufferit++]; trim(strInput); transform(strInput.begin(), strInput.end(), strInput.begin(), tolower); if(strInput == "group") { GROUP = true; } else if(strInput == "no group") { GROUP = false; } else { cout << "Error on line 2: invalid value for group mode\n"; goto cleanup; } //get filename prefix prefix = commandbuffer[commandbufferit++]; trim(prefix); //get N, the number of symbols in the full shift strInput = commandbuffer[commandbufferit++]; trim(strInput); shiftSize = atoi(strInput.c_str()); //get set of K, the periodicities to be tested strInput = commandbuffer[commandbufferit++]; convertPeriodList(strInput, periodList); //get m, to check for m-dense strInput = commandbuffer[commandbufferit++]; trim(strInput); density = atoi(strInput.c_str()); //Allocate composition object comp = new Comp(shiftSize); //get "Begin Definitions" strInput = commandbuffer[commandbufferit++]; //make it lowercase trim(strInput); transform(strInput.begin(), strInput.end(), strInput.begin(), tolower); if(strInput.compare("begin definitions") != 0) { cout << "ERROR: Expecting \"BEGIN DEFINITIONS\"\n"; goto cleanup; } //read definitions while(1) { strInput = commandbuffer[commandbufferit++]; //strInput2 is lowercased and trimmed strInput2.resize(strInput.length()); transform(strInput.begin(), strInput.end(), strInput2.begin(), tolower); trim(strInput2); //strInput3 is lowercased and NOT TRIMMED strInput3.resize(strInput.length()); transform(strInput.begin(), strInput.end(), strInput3.begin(), tolower); if(strInput2 == "" || (strInput2[0] == '/' && strInput2[1] == '/')) { //ignore blank lines and allow comment out } else if(strInput2 == "begin commands") { break; //BREAK } else { i = 0; while(i < strInput.length()) { if(strInput[i] == '=') { break; } i++; } if(strInput2[0] == 'o' && strInput2[1] == 'p' && strInput2[2] == 't') { temp = strInput3.find("opt"); temp += 3; comp->addFunc(strInput.substr(i+1, strInput.length() - (i+1)), strInput.substr(temp, i-temp), true); } else { comp->addFunc(strInput.substr(i+1, strInput.length() - (i+1)), strInput.substr(0,i), false); } } } //read all the valid commands and store in groupdata array while(commandbufferit < (int)commandbuffer.size()) { strInput = commandbuffer[commandbufferit++]; trim(strInput); //ignore blank lines and allow comment out with "//" if(strInput != "" && !(strInput[0] == '/' && strInput[1] == '/')) { GroupData gd; gd.name = strInput; groupdata.push_back(gd); } } //iterate and execute commands for(groupdatait = 0; groupdatait < groupdata.size(); groupdatait++) { strInput = groupdata[groupdatait].name; //set composition if(!comp->setComposition(strInput)) { cout << "ERROR: Command \"" << strInput << "\" references undefined function\n"; goto cleanup; } int maxshiftperiod = 0; for(i = 0; i < periodList.size(); i++) maxshiftperiod = (maxshiftperiod < periodList[i] ? periodList[i] : maxshiftperiod); //do experiment if(shiftSize == 2 && sizeof(unsigned int) == 4 && !USEARRAY && maxshiftperiod <= 32) //if shift period goes > 32 then must use array representation exhaustiveExpTwoShift(shiftSize, periodList, density, comp, recList, unionList, prefix, commandbuffer); else exhaustiveExp(shiftSize, periodList, density, comp, recList, unionList, prefix, commandbuffer); if(!OUTPUT_AFTER_EACH) output(shiftSize, density, prefix, periodList, comp, recList, unionList, commandbuffer); groupdata[groupdatait].recList = recList; groupdata[groupdatait].unionList = unionList; groupdata[groupdatait].pending = false; //clear list of prefixes recList.clear(); if(OUTPUT_AFTER_EACH) { groupoutput(density, prefix, commandbuffer, groupdata); } } //Do the group output (assuming output at end) if(!OUTPUT_AFTER_EACH) { groupoutput(density, prefix, commandbuffer, groupdata); } //cleanup and exit cleanup: //delete composition (and the functions in the Comp object's storage) delete comp; return 0; } /* * Group output */ void groupoutput(int density, string &prefix, vector<string> &commandbuffer, vector<GroupData> &groupdata) { int commandbufferit; int groupdatait; if(GROUP) { ofstream fout; string fname = prefix + "group.txt"; fout.open(fname.c_str(), ios::trunc | ios::out); if(!fout.is_open()) { cout << "ERROR: could not create file " << fname << "\n"; } fout << "FDense 3.67\n\n"; //copy of the input fout << "INPUT\n"; fout << "--------------------\n"; for(commandbufferit = 0; commandbufferit < (int)commandbuffer.size(); commandbufferit++) { string test; test = commandbuffer[commandbufferit]; trim(test); if(test != "") { fout << commandbuffer[commandbufferit] << "\n"; } } fout << "--------------------\n"; fout << "\n"; fout << "For m = " << density << " the following maps were found to have m-dense jointly periodic points of (not least) shift period k, " << "for the following k:" << "\n"; fout << "\n"; for(groupdatait = 0; groupdatait < (int)groupdata.size(); groupdatait++) { bool none = true; fout << "Map: " << groupdata[groupdatait].name << "\n"; fout << "----" << "\n"; if(groupdata[groupdatait].pending) { fout << "PENDING" << "\n"; } else { list<MList>::const_iterator it; for(it = groupdata[groupdatait].recList.begin(); it != groupdata[groupdatait].recList.end(); it++) { if((*(it->List.begin())).compare("m-dense") == 0) { fout << it->currPeriod << "\n"; none = false; } } if(none) { fout << "none" << "\n"; } } fout << "\n"; } fout.close(); } } /* * Full output */ void output(unsigned int shiftSize, int density, string &prefix, const vector<int> &periodList, Comp * comp, list<MList> &recList, MList &unionList, vector<string> &commandbuffer) { list<MList>::const_iterator it; //unsigned int i; unsigned int commandbufferit; if(!GROUP) { //output ofstream fout; string fname = prefix + comp->returnName() + ".txt"; fout.open(fname.c_str(), ios::trunc | ios::out); if(!fout.is_open()) { cout << "ERROR: could not create file " << fname << "\n"; return; } //HEADER fout << "FDense 3.67\n"; /* fout << "N = " << shiftSize << "\n"; fout << "K = "; for(i = 0; i < periodList.size(); i++) { fout << periodList[i]; if(i != periodList.size() - 1) fout << ","; } fout << "\n"; fout << "m = " << density; fout << "\n"; */ fout << "\n"; //copy of the input fout << "INPUT\n"; fout << "--------------------\n"; for(commandbufferit = 0; commandbufferit < commandbuffer.size(); commandbufferit++) { string test; test = commandbuffer[commandbufferit]; trim(test); if(test != "") { fout << commandbuffer[commandbufferit] << "\n"; } } fout << "--------------------\n"; fout << "\n"; //fill on right side, show in fixed notation fout << setiosflags(ios::left | ios::fixed); fout << "COMMAND:\n"; fout << comp->returnName() << "\n"; fout << "WITH DEFINITIONS:\n"; comp->printDefinitions(fout); fout << "\n"; fout << "Outcomes Summary\n"; for(it = recList.begin(); it != recList.end(); it++) { fout << "K=" << it->currPeriod << " "; if(it->pending) { fout << "PENDING"; } else { if((*(it->List.begin())).compare("m-dense") == 0) { fout << "m-dense"; } else { fout << "not m-dense"; } } fout << "\n"; } fout << "\n"; fout << "List of m-words not appearing in jointly periodic points\n\n"; fout << "For union of all K (excluding those that are PENDING)\n\n"; list<string>::const_iterator subit; for(subit = unionList.List.begin(); subit != unionList.List.end(); subit++) { fout << *subit << "\n"; } fout << "\n"; if(VERBOSE) { fout << "For each particular value of K\n\n"; for(it = recList.begin(); it != recList.end(); it++) { fout << "K = " << it->currPeriod << "\n"; if(it->pending) { fout << "PENDING" << "\n"; fout << "\n"; } else { for(subit = it->List.begin(); subit != it->List.end(); subit++) { fout << *subit << "\n"; } fout << "\n"; } } } //DONE fout.close(); } } void exhaustiveExp(unsigned int shiftSize, const vector<int> &periodList, unsigned int density, Comp *comp, list<MList> &recList, MList &unionList, string &prefix, vector<string> &commandbuffer) { unsigned int i = 0, j = 0; //k = 0; //counters unsigned int currPeriod; list<StorageKey> orbitList; list<StorageKey> periodicPoints; vector<int> table; //table for storing points, checking for intersections vector<bool> global_m_table(pow(shiftSize,density), false); //table for storing m-words not found in union over all K list<MList>::iterator recIterator; if(DEBUG) cout << "Arrays\n"; //make a list of MList nodes, one per K value for(i = 0; i < periodList.size(); i++) { recList.push_back(MList(periodList[i])); } //initialize recIterator recIterator = recList.begin(); for(i = 0; i < periodList.size(); i++) { currPeriod = periodList[i]; byte itWord[currPeriod]; //iterating word MList *record = &(*recIterator); if(DEBUG) cout << "currPeriod = " << currPeriod << "\n"; //set table size table.resize(pow(shiftSize,currPeriod), -2); //initialize to -2 if(DEBUG) cout << "Allocated table\n"; //zero the itWord for(j = 0; j < currPeriod; j++) { itWord[j] = 0; } while(true) { byte cWord[currPeriod]; //curr word byte output[currPeriod]; //helper word unsigned int period = 0, preperiod = 0; int rt; bool halt = false; while(halt != true && table[StorageKey(itWord,currPeriod).hash(shiftSize)] != -2) { halt = iterateWord(itWord, currPeriod, shiftSize); } if(halt == true) break; //exit loop //Set current word copyWord(cWord, itWord, currPeriod); StorageKey sk1 = StorageKey(cWord, currPeriod); table[sk1.hash(shiftSize)] = 0; orbitList.push_back(sk1); //DEBUG //cout << "\n-- Start orbit --\n"; //printArray(cWord, currPeriod); //Perform experiment j = 1; while(true) { comp->image(cWord, currPeriod, output); copyWord(cWord, output, currPeriod); //DEBUG //printArray(cWord, currPeriod); StorageKey sk2 = StorageKey(cWord, currPeriod); rt = table[sk2.hash(shiftSize)]; if(rt != -2) { break; } else { table[sk2.hash(shiftSize)] = j; orbitList.push_back(sk2); } j++; } if(rt == -1) { //returned to a point we've seen //none of these points can be periodic list<StorageKey>::iterator it; for(it = orbitList.begin(); it != orbitList.end(); it++) { table[it->hash(shiftSize)] = -1; } } else { //we circled back to an active point period = j - rt; preperiod = rt; list<StorageKey>::iterator it; for(it = orbitList.begin(); it != orbitList.end(); it++) { table[it->hash(shiftSize)] = -1; //mark as seen if(preperiod > 0) { preperiod--; } else { periodicPoints.push_back(*it); } } } //cout << "Clearing list\n"; orbitList.clear(); } //cout << "Clearing table\n"; table.clear(); //DEBUG /* { cout << "\n\nPeriodic points\n"; list<StorageKey>::iterator it; for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) { printArray(it->word, currPeriod); } } */ //DEBUG //DEBUG: make a fake point for testing /* periodicPoints.clear(); byte t_arr[7]; t_arr[0] = 1; t_arr[1] = 2; t_arr[2] = 0; t_arr[3] = 1; t_arr[4] = 1; t_arr[5] = 1; t_arr[6] = 1; periodicPoints.push_back(StorageKey(t_arr, 7)); */ //DEBUG //now cross off all m_words that do not exist in periodic point vector<bool> m_table(pow(shiftSize,density), false); //table of all m_words (for this particular K) byte m_word[density]; StorageKey hasher(m_word, density); unsigned int location; list<StorageKey>::iterator it; for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) { for(location = 0; location < currPeriod; location++) { //read the word for(j = 0; j < density; j++) { hasher.word[j] = it->word[(j + location) % currPeriod]; } //MAKE SURE TO USE hash_baseB SO THEY HASH TO THE RIGHT PLACE m_table[hasher.hash_baseB(shiftSize)] = true; //for this particular K global_m_table[hasher.hash_baseB(shiftSize)] = true; //for all K } } makeMPrefixList(m_table, (*record), shiftSize); unionList.List.clear(); //clear the list, it will be reset from the complete global table that has all the info makeMPrefixList(global_m_table, unionList, shiftSize); //clear periodicpoints list periodicPoints.clear(); record->pending = false; //advance recIterator to next in list recIterator++; if(OUTPUT_AFTER_EACH) { output(shiftSize, density, prefix, periodList, comp, recList, unionList, commandbuffer); } } } void makeMPrefixList(vector<bool> &m_table, MList &record, unsigned int shiftSize) { unsigned int j; //counter //DEBUG: make a fake table for testing /* for(j = 0; j < m_table.size(); j++) m_table[j] = false; for(j = 0; j <= 1; j++) { m_table[j] = true; } for(j = 12; j <= 27; j++) { m_table[j] = true; } for(j = 52; j < m_table.size(); j++) { m_table[j] = true; } */ //DEBUG //DEBUG: print the m_table /* cout <<"\n\nm_table\n"; for(j = 0; j < m_table.size(); j++) { if(m_table[j]) { unsigned int t; for(t = m_table.size() / shiftSize; t >= 1; t /= shiftSize) { cout << (j / t) % shiftSize; if(t > 1) cout << ","; } cout << "\n"; } } */ //DEBUG //now list the m words lexicographically with truncate unsigned int count_true = 0; //count true's, lets us know if table full for(j = 0; j < m_table.size(); j++) { if(!m_table[j]) { string m_prefix = ""; if(j % shiftSize == 0) { //has a zero at lsb so this might be cut to a prefix //t = shiftSize ^ (numzeros on right in j in base shiftsize) unsigned int t; for(t = shiftSize; (j / t) % shiftSize == 0 && t < m_table.size(); t *= shiftSize) { } //count is how many adjacent elements are false (counting this one) unsigned int count; for(count = 1; count < t && !m_table[j + count]; count++) { } //s is the largest power of shiftsize that is <= count unsigned int s; for(s = shiftSize; s <= count; s *= shiftSize) { } s /= shiftSize; //adjust since the for loop goes 1 further int spacing = 0; //count up to four, then add a space //create the correct prefix for(t = m_table.size() / shiftSize; t >= 1; t /= shiftSize) { char temp_c[80]; if(t >= s) { sprintf(temp_c, "%d", (j / t) % shiftSize); m_prefix += string(temp_c); } else m_prefix += "-"; if(spacing % 4 == 3) //on every fourth char, add a space m_prefix += " "; spacing++; } // j JUMPS s SPACES AHEAD because these s elements constitute // one prefix, but at the end of the loop j increments 1 more, // so we need to increment by s - 1 j += (s - 1); } else { //not a prefix unsigned int t; int spacing = 0; for(t = m_table.size() / shiftSize; t >= 1; t /= shiftSize) { char temp_c[80]; sprintf(temp_c, "%d", (j / t) % shiftSize); m_prefix += string(temp_c); if(spacing % 4 == 3) m_prefix += " "; spacing++; } } //push back a prefix of non-appearing word record.List.push_back(m_prefix); } else { count_true++; //push back m-dense if(count_true == m_table.size()) { record.List.push_back("m-dense"); } } } } void exhaustiveExpTwoShift(unsigned int shiftSize, const vector<int> &periodList, unsigned int density, Comp *comp, list<MList> &recList, MList &unionList, string &prefix, vector<string> &commandbuffer) { unsigned int i = 0, j = 0; //k = 0; //counters unsigned int currPeriod, numTrials; list<unsigned int> orbitList; list<unsigned int> periodicPoints; vector<int> table; //table for storing points, checking for intersections vector<bool> global_m_table(pow(shiftSize,density), false); //table for storing m-words not found in union over all K list<MList>::iterator recIterator; if(DEBUG) cout << "Special case 2-shift\n"; //make a list of MList nodes, one per K value for(i = 0; i < periodList.size(); i++) { recList.push_back(MList(periodList[i])); } //initialize recIterator recIterator = recList.begin(); for(i = 0; i < periodList.size(); i++) { currPeriod = periodList[i]; unsigned int itWord = 0; //iterating word MList *record = &(*recIterator); numTrials = (int) pow(2, currPeriod); table.resize(numTrials, -2); while(true) { unsigned int cWord = 0; //curr word unsigned int output = 0; //helper word unsigned int period = 0, preperiod = 0; int rt; while(itWord != numTrials && table[itWord] != -2) { itWord++; } if(itWord == numTrials) break; //exit loop //Set current word cWord = itWord; table[cWord] = 0; orbitList.push_back(cWord); //DEBUG //cout << "-- start orbit --\n"; //printUInt(cWord, currPeriod); //Perform experiment j = 1; while(true) { comp->image(&cWord, currPeriod, &output, 1); cWord = output; //DEBUG //printUInt(cWord, currPeriod); rt = table[cWord]; if(rt != -2) { break; } else { table[cWord] = j; orbitList.push_back(cWord); } j++; } //DEBUG //cout << "-- end orbit --\n"; if(rt == -1) { //returned to a point we've seen //none of these points can be periodic list<unsigned int>::iterator it; for(it = orbitList.begin(); it != orbitList.end(); it++) { table[*it] = -1; } } else { //we circled back to an active point period = j - rt; preperiod = rt; list<unsigned int>::iterator it; for(it = orbitList.begin(); it != orbitList.end(); it++) { table[*it] = -1; if(preperiod > 0) { preperiod--; } else { periodicPoints.push_back(*it); } } } //cout << "Clearing list\n"; orbitList.clear(); } //cout << "Clearing table\n"; table.clear(); //DEBUG /* { cout << "\n\nPeriodic points\n"; list<unsigned int>::iterator it; for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) { printUInt(*it, currPeriod); } } */ //DEBUG //DEBUG: make up the periodicpoint /* periodicPoints.clear(); periodicPoints.push_back(23); */ //DEBUG //now cross off all m_words that exist in periodic point vector<bool> m_table(pow(2,density), false); //table of all m_words byte m_word[density]; StorageKey hasher(m_word, density); unsigned int location; list<unsigned int>::iterator it; for(it = periodicPoints.begin(); it != periodicPoints.end(); it++) { for(location = 0; location < currPeriod; location++) { //read the word for(j = 0; j < density; j++) { int index = (j + location) % currPeriod; hasher.word[j] = (*it & (1 << index)) >> index; } //MAKE SURE TO USE hash_baseB SO THEY HASH TO THE RIGHT PLACE m_table[hasher.hash_baseB(2)] = true; //for this K global_m_table[hasher.hash_baseB(2)] = true; //for union of K } } makeMPrefixList(m_table, (*record), shiftSize); unionList.List.clear(); //clear the list, it will be reset from the complete global table that has all the info makeMPrefixList(global_m_table, unionList, shiftSize); //clear periodicPoints periodicPoints.clear(); record->pending = false; //advance recIterator to next in list recIterator++; if(OUTPUT_AFTER_EACH) { output(shiftSize, density, prefix, periodList, comp, recList, unionList, commandbuffer); } } } void convertPeriodList(const string &strInput, vector<int> &periodList) { vector<string> strList; //all terms vector<string> subList; //vector representation of an "[a,b]" term unsigned int strListLength = 0, i = 0; split(strInput,';', strList); strListLength = strList.size(); for(i = 0; i < strListLength; i++) { string *temp = &(strList[i]); trim(*temp); if((*temp)[0] == '[') { int j, low, high; temp->erase(0,1); //remove '[' temp->erase(temp->length() - 1, 1); //remove ']' split(*temp, ',', subList); trim(subList[0]); trim(subList[1]); low = atoi(subList[0].c_str()); high = atoi(subList[1].c_str()); for(j = low; j <= high; j++) { periodList.push_back(j); } subList.clear(); } else { periodList.push_back(atoi(temp->c_str())); } } } /* * Delete the nodes pointed to by ptrs in recList */ void clearRecList(list<RecNode*> &recList) { list<RecNode*>::iterator it; for(it = recList.begin(); it != recList.end(); it++) { delete (*it); } } /* * Delete the nodes pointed to by the values in the table */ void clearStorageNodes(vector<StorageVal*> &table) { vector<StorageVal*>::iterator it; for(it = table.begin(); it != table.end(); it++) { delete (*it); } } /* * Find divisors of X, excluding X itself */ void findDivisors(unsigned int x, vector<int> &divisorsList) { unsigned int i = 2; unsigned int halfX = x/2; divisorsList.clear(); if(x > 1) { divisorsList.push_back(1); } for(i = 2; i <= halfX; i++) { if(x % i == 0) { divisorsList.push_back(i); } } } /* * returns true if this word has least period p */ bool leastPeriod(byte *word, unsigned int currPeriod, const vector<int> &divisorsList) { bool result = false; unsigned int i, j, k; if(currPeriod == 1) return true; //for every divisor d for(i = 0; i < divisorsList.size(); i++) { unsigned int d = divisorsList[i]; result = false; //check in chunks of length d for(j = 0; j < currPeriod; j+= d) { //check that this chunk is same as other chunks for(k = 0; k < d; k++) { if(word[k + j] != word[k]) { result = true; break; } } if(result == true) break; } if(result == false) break; } return result; } /* * returns true if this word has least period p */ bool leastPeriod(unsigned int word, unsigned int currPeriod, const vector<int> &divisorsList) { bool result = false; unsigned int i, j, k; if(currPeriod == 1) return true; //for every divisor d for(i = 0; i < divisorsList.size(); i++) { unsigned int d = divisorsList[i]; result = false; //check in chunks of length d for(j = 0; j < currPeriod; j+= d) { //check that this chunk is same as other chunks for(k = 0; k < d; k++) { if(((word >> (k + j)) & 1) != ((word >> k) & 1)) { result = true; break; } } if(result == true) break; } if(result == false) break; } return result; }