Abelian Sandpile(C++) The goal of this project will be to generate an animation of the Abelian sandpile model approaching it's stable state. https://en.wikipedia.org/wiki/Abelian_sandpile_model Requirements The
Abelian Sandpile(C++) The goal of this project will be to generate an animation of the Abelian sandpile model approaching it's stable state. https://en.wikipedia.org/wiki/Abelian_sandpile_model
Requirements The program shall compile The program shall execute without error. The program shall include a test configuration (test_cases.yaml) for testing purposes.
-----------------------------------------------------------------------------------------------------------------------------
// main.cpp // contains samplue usage of PythonVisualizer.h
#include "PythonVisualizer.h" #include #include
int main() { PythonVisualizer pvis; pvis.setupVisualization();
for (int i = 0; i < 5; i++) { std::vector> data(3); for (auto &row : data) { row.resize(3); for (auto &el : row) { el = i; } row[0] = 0; row[1] = i/2; row[2] = i/3; } pvis.visualize(data); } }
-----------------------------------------------------------------------------------------------------------------------------
// PythonVisualizer.h // // This header contains a class implementation for interfacing with Python // through the C API. In order to use the class, you must first instantiate a // PythonVisualizer object. Once you create the object, before it can be used, // you must call the setupVisualization function on that instance. That function // will do some initial image setup. After the setup, you can then call the // visualize function, passing in a vector of vectors of ints (your matrix // representing the Abelian Sandpile). This will in realtime update the plot. // // Do note that when running this code, there may be a delay in startup time as // your program loads the Python virtual machine and runtime environment. //
#include
#include #include #include
class PythonVisualizer { public: PythonVisualizer(const PythonVisualizer&) = delete; void operator=(const PythonVisualizer&) = delete;
PythonVisualizer() : pyModule(nullptr), setupHandle(nullptr), plotHandle(nullptr) { setenv("PYTHONHOME", "/usr/lib/x86_64-linux-gnu", 1); setenv("PYTHONPATH", "/usr/lib/python2.7/:/usr/lib/python2.7/plat-x86_64-linux-gnu:/usr/lib/python2.7/site-packages/:/usr/lib/python2.7/dist-packages:/usr/lib/python2.7/lib-dynload/:/usr/lib/python2.7/lib-tk/:.", 1);
Py_Initialize();
pyModule = PyImport_ImportModule("ABSVisualizer"); if (pyModule == nullptr) { throw std::runtime_error("There were problems loading the ABSVisualizer module."); }
setupHandle = PyObject_GetAttrString(pyModule, "setup"); if (setupHandle == nullptr) { throw std::runtime_error("There were problems loading the ABSVisualizer.setup method."); }
plotHandle = PyObject_GetAttrString(pyModule, "plot"); if (pyModule == nullptr) { throw std::runtime_error("There were problems loading the ABSVisualizer.plot method."); } }
~PythonVisualizer() { Py_Finalize(); }
void setupVisualization() { PyObject *pyRetval = PyObject_CallObject(setupHandle, nullptr); if (pyRetval == nullptr) { throw std::runtime_error("Failed to invoke the setupHandle!"); }
Py_DECREF(pyRetval); }
void visualize(const std::vector> &data) { PyObject *plotArgs = PyTuple_New(1); if (plotArgs == nullptr) { throw std::runtime_error("Could not create a Python tuple!"); }
PyObject *pyData = PyList_New(data.size()); if (pyData == nullptr) { throw std::runtime_error("Could not create a Python list!"); }
if (PyTuple_SetItem(plotArgs, 0, pyData) != 0) { throw std::runtime_error("Could not populate the argument tuple with the list!"); }
size_t rowSize = data.size(); size_t colSize = data[0].size(); for (size_t rowIdx = 0; rowIdx < rowSize; ++rowIdx) { PyObject *pyRow = PyList_New(data[rowIdx].size()); if (pyRow == nullptr) { throw std::runtime_error("Could not create a new list for row " + std::to_string(rowIdx) + "!"); }
if (PyList_SetItem(pyData, rowIdx, pyRow) != 0) { throw std::runtime_error("Could not set the list for row " + std::to_string(rowIdx) + "!"); }
for (size_t colIdx = 0; colIdx < colSize; ++colIdx) { PyObject *pyDatum = PyInt_FromLong(data[rowIdx][colIdx]); if (pyDatum == nullptr) { throw std::runtime_error("Could not convert " + std::to_string(data[rowIdx][colIdx]) + " to a Python int!"); }
if (PyList_SetItem(pyRow, colIdx, pyDatum) != 0) { throw std::runtime_error("Could not set the value for row " + std::to_string(rowIdx) + ", column" + std::to_string(colIdx) + "!"); } } }
PyObject *pyRetval = PyObject_CallObject(plotHandle, plotArgs); if (pyRetval == nullptr) { throw std::runtime_error("Failed to invoke the plotHandle!"); }
Py_DECREF(pyRetval); Py_DECREF(pyData); Py_DECREF(plotArgs); }
private: PyObject *pyModule; PyObject *setupHandle; PyObject *plotHandle; };
-----------------------------------------------------------------------------------------------------------------------------
# Basic make file #
CXX:=g++ STD:=-std=c++11 CFLAGS:=-Wall -Werror -Weffc++ -pedantic DEBUG_FLAGS:=-g -O2
SRC:=$(wildcard *.cpp) OBJ:=$(SRC:.cpp=.o) TRGT:=main.exe
INCLUDES:=-isystem /usr/include/python2.7/ PYTHON_LIBDIR:=/usr/lib/x86_64-linux-gnu PYTHON_LIB:=python2.7
TEST:=test/test.py
NAM:=$(shell echo "$(wordlist 4,5,$(shell finger $(USER)))" | sed -e 's/ /_/g') DIR := $(lastword $(subst /, ,$(PWD))) ZIP_FILE = $(shell echo $(DIR)_$(NAM).zip | tr A-Z a-z)
ZIP:=$(wildcard *.zip)
$(TRGT): $(OBJ) $(CXX) -L$(PYTHON_LIBDIR) -l$(PYTHON_LIB) $^ -o $@
clean: rm -f $(OBJ) $(TRGT) *.txt *.pyc
test: $(TEST) $(TRGT) @python $(TEST)
zip: clean zip -r $(ZIP_FILE) *
unzip: $(TAR) tar -xzvf $(TAR)
%.o: %.cpp PythonVisualizer.h $(CXX) $(STD) $(DEBUG_FLAGS) $(CFLAGS) $(INCLUDES) -c $< -o $@
.PHONY:all clean test zip
-----------------------------------------------------------------------------------------------------------------------------
# Special visualizer for the Abelian Sandpile Model #
import matplotlib.pyplot as plt import numpy as np
plt.ion() im = None;
def setup(): ''' Sets up the initial image ''' global im data = np.zeros([1,1]) im = plt.imshow(data, vmin=0, vmax=5, interpolation='none') plt.clim()
def plot(data): ''' Updates the image data and refreshes the plot window ''' im.set_data(data) im.autoscale() plt.draw()
Step by Step Solution
There are 3 Steps involved in it
Step: 1
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started