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 FPeriod. * * FPeriod 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. * * FPeriod 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 FPeriod; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * Represents a composition of poly functions * * Written by: Bryant Lee * Date: 11/22/04 **/ #include <vector> #include <string> #include <map> //uses a map in printDefinitions() #include <fstream> //used in printDefinitions() #include <math.h> //for ceil #include "Comp.h" #include "StringOps.h" extern int UINTSIZE; Comp::Comp(int iShiftSize) { shiftSize = iShiftSize; } Comp::~Comp() { clearFuncStore(); } string Comp::returnName() { string compStr; int i; for(i = compNames.size() - 1; i >= 0; i--) { //elements are already trimmed (see setComposition()) compStr.append(compNames[i]); if(i != 0) compStr.append("#"); } return compStr; } //printDefinitions void Comp::printDefinitions(ofstream & fout) { int i; map <string, bool> seen; //track functions used twice (so we define only once) map<string, Func *>::iterator frt; for(i = compNames.size() - 1; i >= 0; i--) { if(seen.find(compNames[i]) == seen.end()) { seen.insert(pair<string,bool>(compNames[i], true)); frt = funcStore.find(compNames[i]); if(frt->second->isOpt()) fout << "OPT "; fout << compNames[i] << " = "; frt->second->print(fout); } } } void Comp::print() { //dead function /* unsigned int size = composition.size(), i; for(i = 0; i < size; i++) { cout << "Comp func " << i << ": "; composition[i]->print(); } cout << "\n"; */ } bool Comp::setComposition(const string & inStr) { int i; vector <string> cArr; split(inStr, '#', cArr); //run through string backwards to create composition composition.clear(); compNames.clear(); for(i = cArr.size() - 1; i >= 0; i--) { trim(cArr[i]); //permanently trims map<string, Func *>::iterator cfunc = funcStore.find(cArr[i]); if(cfunc == funcStore.end()) return false; else { composition.push_back(cfunc->second); compNames.push_back(cArr[i]); } } return true; } void Comp::addFunc(const string & inStr, string name, bool opt) { trim(name); funcStore.insert(pair<string, Func *>(name, new Func(inStr, shiftSize, opt))); } void Comp::image(byte *word, int wordLength, byte *output) { int size = composition.size(), i; byte temp[wordLength]; copyWord(temp, word, wordLength); for(i = 0; i < size; i++) { if(i % 2 == 0) { composition[i]->image(temp, wordLength, output); } else { // i is odd composition[i]->image(output, wordLength, temp); } } if(size % 2 == 0) copyWord(output, temp, wordLength); } /* * NOTE: the 4th parameter, blocks, could be derived from wordLength, but * it requires a division. It is cheaper to pass it. */ void Comp::image(unsigned int *word, int wordLength, unsigned int *output, unsigned int blocks) { int size = composition.size(), i; unsigned int temp[blocks]; copyUIntArray(temp, word, blocks); for(i = 0; i < size; i++) { if(i % 2 == 0) { composition[i]->image(temp, wordLength, output, blocks); } else { // i is odd composition[i]->image(output, wordLength, temp, blocks); } } if(size % 2 == 0) copyUIntArray(output, temp, blocks); } void Comp::clearFuncStore() { map<string, Func *>::iterator it; for(it = funcStore.begin(); it != funcStore.end(); it++) { delete(it->second); } }