Answered step by step
Verified Expert Solution
Link Copied!
Question
1 Approved Answer

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

blur-text-image
Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Time Series Databases New Ways To Store And Access Data

Authors: Ted Dunning, Ellen Friedman

1st Edition

1491914726, 978-1491914724

More Books

Students explore these related Databases questions