I’m writing an agent-based simulation in MATLAB in which agents play a game in rounds, selling stuff to each other. Pretty much everything (agents, items, locations, contracts…) is implemented as an object using MATLAB’s OOP functionalities.
Every round I want to take a snapshot of my simulation and store it on disk so I can analyze later how the simulation developed. Now my question is what would be the best way to do so?
My current idea is that the main loop calls on every agent and asks it to report its status (e.g. how many items of what property do you own, what are your contractual obligations, account balance… While if necessary the agents call on objects they own and ask for their status and include that information in their report). My idea was to make the agents’ reports a string, possibly in XML form. Then add all reports together with a time stamp and add it at the end of a text file.
But since I have never done anything like this I’m not sure if this is a good approach. My main concern apart from having the data in a format that I can easily analyze later on, is the speed of creating the snapshot and writing it to disk. As my simulation is pretty large I expect a lot of data to be stored each round.
Alternative ideas are:
- Storing everything in a data base. But I assume database access is rather slow compared to a text file. And since the number of objects owned by each agent can change, I’m not too sure about the data base structure either.
- Using .mat files. But I don’t know if they are easily extendable and how they would deal with a changing structure (i.e. agents owning different items per round)
Thanks for any comments and suggestions!
What I implemented
I choose SQLite as a database because it stores the data in one file and was easy to setup and handle. (Using sqlite3 and the sqlite-jdbc-3.7.2 driver there is not much to install and the database is all in one simple file.)
The Matlab Database Toolbox proved to be too slow to export the mass of data out of Matlab created during my simulation. Hence I wrote a “DataOutputManager” class that dumped the data snapshots in csv files.
After the simulation the DataOutputManager creates two batch files and two sql text files with SQL commands in them and executes the batch files. The first batch file creates a SQLite database by running sqlite3.exe (http://www.sqlite.org) and giving it the SQL commands in the first text file.
After the database is created sqlite3 is told to import the data from the csv files into the database using the second batch and text file. It is not a “pretty” solution but writing the data to csv and then importing these files into a database using sqlite3 was much faster than using the Database Toolbox. (I have heard of some people using xml files)
After the simulation data is uploaded to the database I use the Database Toolbox together with a jdbc driver (sqlite-jdbc-3.7.2) to send SQL queries to the database. Since only little data is returned from these queries the Database Toolbox is not a bottleneck here.
Setting all this up (in Windows 7) required allot of searching and testing. Even though not perfect, I hope that the following snippets might be of use if someone wants to do something similar.
Creating SQLite database and importing Data from csv to database:
The first .bat file to create the database using sqlite3 is structured like this:
The first text file (.sql) is called DatabaseNameStructure.sql and is structured like this:
The second .bat file that lets sqlite3 upload the csv files to the database is structured like this:
The second text file (.sql) is called uploadCsvToDatabaseName.sql and is structured like this:
.separator “,”
.import Table1Data.csv Table1Name
.import Table2Data.csv Table2Name
.exit
For this to work you need to have sqlite3.exe in the system path e.g. saved under C:\Windows\System32. You create the stings in Matlab according to your data/csv setup and then use fprintf() to write them to files in the format described above. You then execute the bat files from Matlab using winopen().
Connect Matlab to SQLite database using jdbc driver:
The following video by Bryan Downing was helpfull for me to develope this: http://www.youtube.com/watch?v=5QNyOe79l-s
I created a Matlab class (“DataAnalyser”) that connects to the database and runs all analysis on the simulation results. Here are the class constructor and the connection function to setup the communication with the database. (I cut out some parts of my implementation that are not so important)
Get Data from connected SQLite database into Matlab
I also wrote a function for the DataAnalyser that gets data from the database when it is given a sql query. I’m posting the main parts of it here for two reasons.
Importing not all data at once but in portions as in this function makes the data import faster.
Mathworks has a suggestion how to do this in their Database Toolbox (cursor.fetch) documentation. However, using jdbc and SQLite causes an error because of a bug.
Quote from Mathworks support:
This function works around that problem: