"Beauty in things exists in the mind which contemplates them."
- David Hume (1711-1776)
Conway's Game of Life theme continues. Here is a short video with the Game of Life, this time running on Altera DE2 FPGA board with custom soft MIPS CPU.
"Beauty in things exists in the mind which contemplates them."
- David Hume (1711-1776)
Conway's Game of Life theme continues. Here is a short video with the Game of Life, this time running on Altera DE2 FPGA board with custom soft MIPS CPU.
Last week I received a short e-mail from my former manager at Morgan Stanley:
"Hi Manfred,
Just to let you know that GlobalAxe all went live last week and so far no issues at all."
Since the people on the trading floor started using my system and it seems to be standing on its feet so far, it probably is a good time to recap on what had happened over my ten week internship at Morgan Stanley.
I was working as technology analyst in repo trading team (in institutional securities group). My task was to develop and integrate a new screen into trading software, to create an associated e-mail subsystem generating daily/weekly reports for senior executives and to code a website which would provide access to the data for executives/sales people without the trading software on their machines.
Development-wise it involved working with quite a wide range of technologies, such as C# and CAB for UI development, Java/Spring for e-mail report generation/server backend, MVC under ASP.NET for the website, Transact-SQL for Sybase DB backend; everything interconnected with SOAP/XML and distributed locally over in-house pubsub systems or through IBM's MQ for inter-continental data transactions.
Even though working and learning about all these technologies was fun on it's own right, the best thing I would say about my experience was the people.
There is no better feeling than having a quick call with traders in New York demoing them the stuff that you just wrote, then dropping an e-mail to Tokyo checking if your recent changes made it through to their database, discussing the architecture of your system with the guys in your team and then going to the global team video-meeting; all in the same day.And sometimes you feel the need to pinch yourself, because the level of responsibility that you get as an intern is staggering. You have the same rights and responsibilities as any other team member: a screw up in your code can block sixty people from submitting their code before the end of the iteration, a failure to convince the head of traders in NY that what you are doing is going to help them will affect the name of the whole team, and so on.
But then, you own your project: you make the final design decisions, you implement it and you give it to the end-users, who often appear to be bigshots. And that more than makes up for a few late nights in the office. Plus, Canary Wharf is absolutely beautiful at night.
Without expanding too much (and breaching too many non-disclosure agreements) - it was definitely the best experience so far: in terms of team, project, technology, skill, involvement and everything else. And it seems like I will have a chance to repeat it again: I have already received an unconditional offer for the internship at MS next summer!
Oh, and regarding the summer days spent in glass, steel and stone towers... well, Majorca more than made up for it!
In 1970s John Horton Conway (British mathematician and University of Cambridge graduate) opened a whole new field of mathematical research by publishing a revolutionary paper on the cellular automaton called the Game of Life. Suffice it to say that the game which he has described with four simple rules has the power of a universal Turing machine, i.e. anything that can be computed algorithmically can be computed within Conway's Game of Life (outlines of a proof for given by Berlekamp et al; implemented by Chapman as a universal register machine within the Game of Life in 2002).
The Game of Life is a zero-player game, i.e. the player interacts only by creating an initial configuration on a two-dimensional grid of square cells and then observing how it evolves. Every new generation of cells (which can be either live or dead) is a pure function of the previous generation and is described by this set of rules:
For more information, patterns and current news about the research involving Game of Life check out the brilliant LifeWiki at conwaylife.com.
The following applet visualising the Game of Life has been developed as part of the coursework for Object-Oriented Programming at the University of Cambridge, all code was written and compiled in Sun's Java SE 1.6.
Click on any of the screenshots or the button below to launch the Game of Life (and if nothing shows up, make sure that you have the Java Runtime Environment (JRE) installed).
45 minutes, 28 MIPS instructions and £25.
Computer Science FTW.
# Copyright Manfredas Zabarauskas, 2009. # MIPS routine that reads an array of ten integers # and prints the sorted array to console. .text main: sub $t7, $sp, 40 l_read: li $v0, 5 syscall sw $v0, 0($t7) add $t7, $t7, 4 bne $t7, $sp, l_read l_out: sub $t8, $sp, 36 sub $t7, 40 l_inn: add $t8, $t8, 4 lw $t2, -8($t8) lw $t3, -4($t8) ble $t2, $t3, no_swp sw $t2, -4($t8) sw $t3, -8($t8) move $t7, $sp no_swp: bne $t8, $sp, l_inn beq $t7, $sp, l_out l_prnt: li $v0, 11 li $a0, 10 syscall li $v0, 1 lw $a0, 0($t7) syscall add $t7, $t7, 4 bne $t7, $sp, l_prnt li $v0, 10 syscall
The main purpose behind writing this tutorial was to provide a more detailed set of instructions for someone who is trying to implement an eigenface based face detection or recognition systems. It is assumed that the reader is familiar (at least to some extent) with the eigenface technique as described in the original M. Turk and A. Pentland papers (see "References" for more details).
The idea behind eigenfaces is similar (to a certain extent) to the one behind the periodic signal representation as a sum of simple oscillating functions in a Fourier decomposition. The technique described in this tutorial, as well as in the original papers, also aims to represent a face as a linear composition of the base images (called the eigenfaces).
The recognition/detection process consists of initialization, during which the eigenface basis is established and face classification, during which a new image is projected onto the "face space" and the resulting image is categorized by the weight patterns as a known-face, an unknown-face or a non-face image.
To download the software shown in video for 32-bit x86 platform, click here. It was compiled using Microsoft Visual C++ 2008 and uses GSL for Windows.
First of all, we have to obtain a training set of grayscale face images . They should be:
So just capturing everything formally, we want to obtain a set , where \begin{align} I_k = \begin{bmatrix} p_{1,1}^k & p_{1,2}^k & ... & p_{1,N}^k \\ p_{2,1}^k & p_{2,2}^k & ... & p_{2,N}^k \\ \vdots \\ p_{N,1}^k & p_{N,2}^k & ... & p_{N,N}^k \end{bmatrix}_{N \times N} \end{align} and
Once we have that, we should change the representation of a face image from a matrix, to a point in -dimensional space. Now here is how we do it: we concatenate all the rows of the matrix into one big vector of dimension . Can it get any more simpler than that? Continue reading
Since last week we have spent quite some time debugging Samsung SMRP6400/SMDK64X0 IIC drivers, I thought I might share with one particular example here. It is both a good showcase of the hardware/software synchronization issues and since the bugs are in the latest version of the drivers shipped together with the development platforms, it might save someone from additional headaches.
So, while working on the drivers for IIC one of our automated tests to make sure that IIC still works was to write some data on the bus, do an immediate read-back and verify that both data written and read back matches; something similar to this:
UCHAR outData[3] = { REGISTER, DATA_BYTE_1, DATA_BYTE2 }; UCHAR inData[2] = { 0, 0 }; IIC_Write(SLAVE_ADDRESS, outData, 3); IIC_Read(SLAVE_ADDRESS, REGISTER, inData, 2); if ((inData[0] != DATA_BYTE_1) || (inData[1] != DATA_BYTE_2)) { DEBUGMSG(ERROR_MSG, (TEXT("Immediate write/read data mismatch: data sent [0x%X " \ "0x%X] differs from the data received [0x%X, 0x%X]."), DATA_BYTE_1, DATA_BYTE_2, inData[0], inData[1])); }
However, after we added some IIC read calls from another hardware driver it started spitting fire throwing the following error message:
Immediate write/read data mismatch: data sent [0xCA, 0xFE] differs from the data received [0xCA, 0xFE].
Now this clearly meant we had a serious problem: the error message was saying that the data does not match, which obviously was not the case as shown by the message text!
Since we were pretty confident about our side of things, as well as the readings from the scope, it seemed like a good time to start looking at the Samsung IIC drivers (and especially s3c64X0_iic_lib.cpp). The driver structure there is pretty straightforward: the first read/write byte on the bus triggers the hardware IRQ, which is mapped to SysIntr triggering a transfer event; then any subsequent call to a read/write function blocks waiting for a transfer-done
event, which is triggered when the last byte is read/written in the IST.
Everything looks sane up to the point where a transfer-done
event is signalled from the IST (pseudocode, not the original code below, due to the legal issues):
static HANDLE ghTransferEvent; static HANDLE ghTransferDone; static DWORD IICSysIntr; ... static DWORD IST(LPVOID lpContext) { BOOL bTransferDone = FALSE; while (TRUE) { WaitForSingleObject(ghTransferEvent, INFINITE); switch (IIC_BUS_STATUS) { case MASTER_RECEIVE: // receive bytes and store them in the buffer break; case MASTER_TRANSMIT: // transmit bytes from the buffer in memory if (LAST_BYTE) bTransferDone = TRUE; break; InterruptDone(IICSysIntr); if (bTransferDone) { SetEvent(ghTransferDone); } } } }
Two major problems with this code are:
bTransferDone
variable is never set from the IIC read, and hence the transfer-done
event for bus reads is never triggered,bTransferDone
is set from the IIC write, it is never reset, hence the transfer-done
event is triggered after reading/writing single byte on the bus in all subsequent transactions.That explains the initial test case failure: during the write/immediate read data comparison the data arrives exactly between the if
statement and the following printout, thus triggering the error message, but printing the correct data to the output due to the early signal of the event.
The way to solve this is also straightforward: make sure that the bTransferDone
variable is cleared after the transfer-done
event is triggered, and make sure that master-receive mode sets the bTransferDone
variable after reading the last byte of the transaction from the IIC bus.
In pseudocode it would look similar to:
static DWORD IST(LPVOID context) { BOOL bTransferDone = FALSE; while (TRUE) { WaitForSingleObject(ghTransferEvent, INFINITE); switch (IIC_BUS_STATUS) { case MASTER_RECEIVE: // receive bytes and store them in the buffer if (LAST_BYTE) bTransferDone = TRUE; break; case MASTER_TRANSMIT: // transmit bytes from the buffer in memory if (LAST_BYTE) bTransferDone = TRUE; break; InterruptDone(IICSysIntr); if (bTransferDone) { bTransferDone = FALSE; SetEvent(ghTransferDone); } } } }
The lesson of the day (quoting my colleague) is: "The first rule about multithreading - you're wrong".