Pans are the primary cooking device in most kitchens and mine is no different. I have three primary pans and some special use pans. And though they are called “saucepans,” they are really more like pots than pans (and aren’t good for saucemaking either), so I’ll leave those out. I’ll be skipping roasting pans as well and sticking to the general class of stove-top pans.
MATLAB is a great environment to quickly prototype scientific algorithms, especially with interactive debugging, decent data plotting facilities, dynamic typing, and all the built-in toolboxes. However, it’s definitely pretty slow when it comes to code-execution performance compared to, well, almost every other language out there. This is largely because MATLAB is an interpreted language – that handy ability to set a breakpoint and then run code and plot data comes at the cost of not being able to compile or optimize the code in advance and having to do everything on-the-fly. This can cause MATLAB code to execute up to hundreds of times slower!
Vectorize
So in particular, loops are pretty bad because MATLAB has to interpret every line of code individually and loops just mean lots of time spent interpreting. Basically, in MATLAB, the fewer lines of code you can do something in, the better. Fortunately, because MATLAB was designed to work with matrices, most of the built-in functions can process entire matrices at a time, rather than having to process them one element at a time as you would in most languages. This is called vectorization. For instance, in C, to take the square root of every element of a 2-D array and multiply them by 2, you’d need to have a nested set of FOR loops to iterate over every element – this would look something like: (using MATLAB syntax)
for i = 1:size(matrix, 1) % Loops BAD! for j = 1:size(matrix, 2) out(i,j) = sqrt(matrix(i,j)) * 2; end end
In MATLAB, this takes forever. The proper, vectorized way is simply:
out = sqrt(matrix) * 2; % Vectorized!
not only is the vectorized version much faster (0.022 vs 1.1882 seconds – 125X – on a 1M element array in MATLAB 2009b on an Intel Core i5), it’s much shorter to type. Basically, whenever you want to write a FOR loop do to something on an array, you should instead be vectorizing it.
The MathWorks guide to vectorization is here.
Pre-allocate Memory
This is important in most languages, but especially so in MATLAB. If MATLAB has to keep reallocating memory for the array as it grows, it slows down a lot. In the above FOR loop example, adding one line cuts the execution time in half:
out = zeros(size(matrix)); % Preallocate output matrix for i = 1:size(matrix, 1) for j = 1:size(matrix, 2) out(i,j) = sqrt(matrix(i,j)) * 2; end end
Suppress Output (aka Semicolons are your friend)
In MATLAB, if you don’t terminate a line with a semicolon, that’s OK! Your code will still run, but without the semicolon, MATLAB will print the output to the Command Window. Just as if you’d thrown a cout/printf after that line of code. In the previous FOR loop example, leaving off the semicolon on the line:
out(i,j) = sqrt(matrix(i,j)) * 2
means that MATLAB will print the entire million element array for EACH of the million iterations! This takes a small eternity – hit CTRL-C to kill it and put that semicolon in. In fact, it’s typically best to make it a habit of terminating every line of code with a semicolon and using the ‘disp’ command to write formatted output.
Aside from displaying text in the command window, drawing figures is also very time-consuming. If you’re trying to update a plot frequently, consider deleting the specific elements and drawing just the new ones, rather than redrawing the entire plot. Also, if you’re generating a bunch of plots that you won’t be looking at, say because you’re writing them to disk, don’t keep spawning new figures – just create one and keep erasing it. The more figures your have open, the slower MATLAB’s graphics engine becomes.
Use the Profiler!
MATLAB has a pretty nice profiler which will tell you how many times each line is called and how much processing time each takes. Makes it pretty easy to figure out what’s really bogging down your program so you can speed it up, whether by refactoring, vectorizing, or simply converting it into a MEX function.
Install Lightspeed
There are a good number of useful functions in MATLAB which are, sadly, unoptimized. One of the biggest is repmat, which is really handy when it comes to vectorizing code as it is used to create matrices by tiling a smaller matrix. This function, plus a lot of other useful functions, have been written as blazingly fast MEX-functions (see the next section for details) by Tom Minka over at Microsoft Research. I’ve seen many-fold to orders-of-magnitude speedups with this toolbox! Also, in some vectorization guides, they’ll tell you not to use repmat as it’s slow, and to use the ones indexing trick to simulate the functioning of repmat. Don’t bother – just install Lightspeed and use repmat to your heart’s content.
Download Lightspeed here.
Write MEX-functions
MEX-functions are C, C++, or FORTRAN programs that have been compiled with the MEX interface so that MATLAB can call the program. Because the MEX-functions are compiled, they typically run much faster than normal MATLAB code. Just absolutely have to do something in a FOR loop? Write a MEX function. This is also great for pulling in external functions from a library like OpenCV. Basically, all a MEX-function is is a program with an interface wrapper to define how data is passed into and out of the program from MATLAB.
MathWorks MEX Guide is here.
Install the latest version of MATLAB
So over the years, MathWorks has put some effort into improving the performance of MATLAB. Repmat, for instance, has been sped up many-fold, though the Lightspeed version is still faster. MATLAB now also has a Just-In-Time accelerator which allows MATLAB to compile certain things on-the-fly, including simple FOR loops. So you need not fear loops – as much! There are certain rules, though, for what can and cannot be accelerated. This document lists these rules. The profiler also helps to identify what is and is not being accelerated, as described here. Finally, if you’re willing to pony up for the Parallel Computing Toolbox, this is an pretty easy way to take advantage of multiple processors/core/machines.
So go out there and write some code! And if you come up with any tips of your own, drop us a line!
For a smartphone, the iPhone 4 has a pretty decent camera, with a backside-illuminated 5MP sensor and a fast fixed-aperture f/2.8 lens. Compared to it’s contemporaries, it’s held up pretty well. The image quality is good enough that I typically don’t bother lugging my point and shoot around for most casual events and only step up to my SLR for more photo-intensive days. One issue, however, is that the iPhone 4 has a fixed 30mm-equivalent lens. This is a decent, all-round focal length, especially as the close-focusing capabilities are quite good (~3 inches). But sometimes, especially indoors and in video mode where the iPhone camera crops the image, one wishes for a wider lens.
The olloclip
Well, the olloclip, developed by Patrick O’Neill and Chong Pak, is a pretty good solution. The olloclip is a 3-in-1 clip-on lens adapter for the iPhone 4, with wide-angle, fish-eye, and macro lenses. Currently they are selling for $69.95 direct from olloclip. I received one of the first batch of units recently due to my support of the Kickstarter project which raised funds for the production tooling and the first manufacturing run. The unit body is made of a pretty sturdy plastic, while the lens barrels are aluminum. The larger end is the fisheye and the other end is the wide-angle. The macro is located underneath the wide-angle and is accessed by unscrewing the wide-angle lens. The fisheye has a specified field of view of 151 degrees and the wide-angle is about 91 degrees. The macro is 10X. For reference, the stock iPhone 4 lens is about 60 degrees field of view. The fisheye image is not full-frame – the corners are unused. In video mode, the iPhone crops the image, making the effective field of views 77 degrees for the fisheye, 53 degrees for the wide angle, and 36 degrees for the standard lens. The fisheye is full-frame in video mode due to the crop.
It is 1.35 inches in length and 0.99 inches wide. Pretty small – I’ve been tucking it in the included microfiber bag and stuffing it in my soft-sided sunglasses case. Not so small that people won’t notice it – on the very first session I was wandering around with the olloclip, I was stopped by curious passers-by.
The Basics
Usage is pretty straightforward – just slide it over the camera. If you need the other lens, just pull it off, flip it over, and slide it back on. As mentioned earlier, the macro is accessed by unscrewing the wide-angle lens – this is easiest done when the olloclip is on your phone. The olloclip itself is held on by friction – I haven’t seen any scratching on either side of the phone’s glass yet and the olloclip guys say it won’t hurt the Gorilla Glass. Now the olloclip was designed to operate on bare iPhones, so if you have a case, you’ll have to remove it beforehand. It’s been tested to work with a number of screen protectors, but if the thickness is too great, even those can be a problem. The suggested workaround is to cut off the corner of the protector where the olloclip mounts. Also, the main body of the olloclip does cover the LED flash on the iPhone, so it’s not possible to use both simultaneously. A great future enhancement would be to design a transparent housing which would convert the LED flash into a ring flash for the macro. And though the olloclip is relatively small, you’ll still have to remove it before putting your phone in your pocket.
No special app required – just fire up any camera app and you’re in business.
Sample Images
The fisheye is pretty blurry away from the center and as mentioned earlier, not full-frame, except in video mode.
The wide-angle lens shows quite a bit of barrel distortion in photo mode – in video mode it’s much less noticable due to the crop. Soft in the corners.
Standard iPhone 4 image
Macro – extremely shallow depth of field – about 0.25 inch. You have to hold it very close to the subject, about 0.5-0.75 inch. This translates to about a 0.5-0.8 inch image diagonal.
Standard iPhone image
Lens Calibration
In my day job, I occasionally calibrate cameras to determine the intrinsic camera parameters – effective focal length, camera center, and distortion are the big ones. I ran a quick-and-dirty calibration on the wide-angle and fisheye lenses and got estimated errors of about 2-3 pixels, which is decent for the conditions. It’s probably not worth running more rigorous calibration since the lens is not fixed and the camera center is probably going to wander from test to test. Interestingly, for the fisheye I get an estimated diagonal field of view of about 141 degrees, about 10 degrees less than the designers mentioned on Kickstarter. The caveat here is that my calibration may not be sufficiently accurate – when undistorting my calibration images, I’m still seeing some distortion near the edges. I estimate the horizontal field-of-view at 126 degrees and the vertical field-of-view at 88 degrees. For the wide angle, the entire image is used, and I estimate 80 degrees diagonal, 68 degrees horizontal, and 54 degrees vertical.
Fisheye calibration
Wide angle calibration
Conclusions
The olloclip is a great gadget which really improves the flexibility of the iPhone 4 camera while being small enough that carrying it around isn’t too much of a problem. While the fisheye and wide-angle do suffer from significant barrel distortion as well as edge softness, this is balanced by the low cost of the system. Videographers will especially love the wider lens options, especially as the system does not suffer as much from distortion, vignetting and corner softness in video mode compared to photo mode. Realtors and landlords will appreciate the ability to quickly take wide-angle photos of interior rooms and architecture buffs will be able to pull this out to capture that skyscraper or cathedral. The macro is really nifty for those high-magnification shots, but is limited by the small range of focus distances and extremely shallow depth of field. Still, coupled with a small tripod and an adapter like the Glif, this makes for a pretty decent rig for shooting coins and other small objects. We urge the developers of the olloclip to consider making the plastics surrounding the macro lens translucent to allow the built-in LED flash to work as a ring flash. Of course, there is the criticism that this is an iPhone 4-only accessory; it is rumored that the next iPhone will retain the same form factor, but even if this was only useful for the next year, the olloclip would probably make for a nice bundle addition when you finally sell or hand down the phone.
More Images
Fisheye -> Wide Angle -> Normal
More macro samples
Last year I went to Switzerland for a conference where I learned about the wonders of Rösti and efficient public transport. But above all, I learned about the Swiss and cheese. I’m always hearing about how Americans are known for putting cheese on everything, but I’m pretty sure the Swiss take the (cheese)cake. They dunk things in cheese (fondue), broil cheese on thin crusts (tarte flambée), and pour melted cheese on bread (Chäsbrätel). What I didn’t get to try when I was there was Raclette, which seems to be the Swiss version of Chinese hot pot. Essentially you have a spread of small boiled potatoes, vegetables, gherkins, pickled onions, and charcuterie and then you pour melted cheese on it right before you eat it. The cheese used is typically a Raclette, though Emmentaler or Gruyere work as well. Traditionally, this was done by the fire. Today, for large groups and restaurants, a wedge is placed over a professional grill such as this and the cheese scraped out onto the plate as it melts with a raclette knife. For home use, you have tabletop grills such as this Swissmar, where each person has an individual tray which holds a slice of cheese under the heating element. One nice feature of these tabletop grills is that while the cheese trays go under the heating element, the top can be used as a grill for cooking things. Like hot pot, Raclette is a relaxed affair where you chat as your cheese melts.
The RoboGourmet is an apartment dweller, so having an 8-person grill seems a bit extravagant and space-consuming. A few months ago, however, Wine.Woot had the Boska Holland Mini-Raclette grill for $20 and I pounced. The Mini-Raclette is a two person grill, though if you are patient or have other dinner items, you could probably use it for four people. It’s fairly well built, being pretty much a heating element, a couple of non-stick trays, and a non-stick top. It comes with a pair of plastic spatulas, which is handy for getting the cheese out of the trays, but being non-stick, the cheese pours out pretty easily. The cord is a bit short, so an extension cord is a good thing to have. Usage is pretty simple – turn on the grill, let it warm up for a few minutes, then place cheese in the trays and pop them under the grill. The cheese melts in a few minutes, and if you wait a bit longer, it even browns nicely. With two people, you can keep a near-constant flow of melted cheese out of this thing if you immediately put more cheese in to melt while you eat. Clean up is a cinch – wipe out the trays, spatulas, and the removable top with a sponge and some soap and quickly run a damp cloth over the exterior of the grill (after you’ve unplugged it and let it cool!).
I’ve used it a few times so far, and it’s pretty tasty. I go with small boiled potatoes (I get a mix of fingerling, red creamer, new potatoes, and purple potatoes) with the skin on, sautéed mushrooms, picked onions, cornichons, and Prosciutto. I typically serve with a sautéed green vegetable and optionally a good crusty bread like my local Acme Bread Company baguettes or bâtards. I have not had this with wine, but I imagine a dry white or a beaujolais, as suggested here, would work nicely.
David Lebovitz’s article on Raclette in Switzerland. <- photos!
Got an “error closing file” today while saving a very large MAT file in MATLAB. I’ve been dumping my workspace into a MAT file at different stages of a very large computation for debugging purposes and today it broke. It seems that even though I’m running MATLAB 7.9.0 (R2009b), the default is to save MAT files in version 7 format, which has a 2GB size limit. As of version 7.3 (R2006b), the MAT format uses the HDF5 format and removes the 2GB limit. This can be fixed by specifying the switch ‘-v7.3’ in the save command or editing the settings in File > Preferences > General > MAT-Files.
At work, we are developing a indoor modeling backpack system which is carried by a person through building interiors. Using cameras, lasers, and an IMU, we can reconstruct the 3D model of the areas the person walked through. The data is currently captured with a laptop outfitted with three hard drives in a RAID 0 (stripe) array. This week, I was having problems capturing data with some new, higher resolution cameras and discovered that the RAID array was operating at significantly slower speed when on battery power. Using HDTune, I went from a max sustained read of 350MB/s and 2400MB/s peak on AC to 125MB/s sustained and 230MB/s peak on battery. This was a problem.
We’re running Windows XP Professional x64 and an onboard Intel ICH8R/ICH9R RAID.
The solution? Drivers. We were still using the original Intel Matrix Storage drivers from version 7.6. Upgrading to 8.9 didn’t help, but upgrading to the renamed Rapid Storage Technology drivers, version 10.1.0.1008, fixed it. No performance degradation when operating on battery. Battery life sucks, but at least things are fast!
I was working on installing the Carnegie Mellon Robot Navigation Toolkit (CARMEN) on Ubuntu 10.04 LTS today so I could parse some logs generated by another program. It’s a bit old, having been updated last in 2008 and so there are a few annoying things like dependencies on old libraries. I’ve updated the Ubuntu wiki with new instructions here.
One problem I’m constantly having in building medium-sized prototype robotics systems is power distribution. I’ve got enough sensors and things that I don’t want to have one massive wire junction tied into my power supply. Terminal blocks are sort of OK, but I’ve always felt they were a bit lacking and also didn’t provide any circuit protection. Recently, I’ve run across a few power distribution boards which look pretty nice and are pretty cheap, especially compared to the price of building a one-off.
The Altronix PD8 (Amazon) comes out of the security industry (alarm systems) and which takes up to 28VAC/VDC @ 10A as input on a pair of screw terminals and distributes it to 8 individually fused outputs on two strips of screw terminals. There is a handy slide switch to switch power on and off, along with an indicator LED. Dimensions are 5/25″ x 3.25″ x 1″. The board takes standard 3AG (1.25″ x 0.25″) glass fuses. For some odd reason, even though the instructions say the board is good to 10A, the main bus fuse I got was rated for 5A. The output fuses are 3.5A. A pretty good deal for around $20. Good documentation on the Altronix website, including CAD drawings. Altronix also makes 4 and 16 output versions, as well as PTC fused versions.
If you have a smaller robot, or just don’t need all the circuit protection, there’s the Miller Engineering #4805 (near the bottom of the page). Originally designed for lighted signs for model train sets, this takes in power via a pair of binding posts or a DC barrel jack and gives you 10 outputs on two rows of screw terminals. Dimensions are 4.5″ x 2.25″. In the original application, this took 4.5VDC and drove 180mA signs. This is a bit low for many robotic applications, but I’m sure the board can probably handle more current unless they really skimped on trace widths. As I mentioned, there is no circuit protection for this board. Runs about $15.
I spent some time this week trying to get public key authentication to work with SSH so that when I used TortoiseSVN, I wouldn’t have to keep typing in my password. I generated a key, installed the public key on the repository server – but nothing. SSH connections still asked for a password. These are the problems I had on a Windows 7 machine running PuTTY, Pageant and the aforementioned TortoiseSVN, connecting to both OpenSSH and commercial SSH servers running some flavor of UNIX.
1. Generate a keypair.
If you’re using PuTTY, you can use the utility PuTTYGen to generate a keypair. You want to generate either an SSH-2 RSA or an SSH-2 DSA keypair and definitely use a good passphrase! I would also recommend putting in a descriptive key comment which includes your name and the generation date and even if it’s an RSA or DSA key. Something like userName-rsa-20110512. The keypair consists of a private key and a public key. Save both files and also copy the public key in the box called “Public key for pasting into OpenSSH authorized_keys file.” The private key you should keep safe on your client machine. The public key should be installed on the server in one of three places.
2. Install the public key
Newer versions of OpenSSH want your key to be in a file ~/.ssh/authorized_keys. Older versions had two files, ~/.ssh/authorized_keys for SSH1 connections and ~/.ssh/authorized_keys2 for SSH2 connections. Basically just copy and paste your public key into these files. If you didn’t copy it from Pageant as described in step 1, you can load your private key in Pageant and it will regenerate the public key for you to copy. Only public keys you want to have access should be in the authorized_keys/authorized_keys2 files! Each key in the file looks something like:
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIBeIywsWQFXXoWsQG7aNKkt4AVyjkt4/c7yCudH5sMUrsnfpBxGJn1SjNaZorCnZm4j7k+gGw2QFJBrJFsWLAqZwceanHQlid9xmKB9wTN45yzfqFuKrYwpByT9npX2MMC7RjOUm7ccPH3gg1KYn2kPIv/EGsSHNwGYG56EKBZaxQ== userName-rsa-20110512
This breaks down to the key type (RSA/DSA), the key itself, and the comment field.
One important thing – newer versions of the OpenSSH server daemon check the permissions of the authorized_keys/authorized_keys2 files to ensure that they are not world or group writable and will quietly fail if it is! I spent a long time trying to figure this out before a sysadmin put me straight.
The commercial version of SSH has a file ~/.ssh2/authorization which lists the accepted key files, each line looking something like:
Key keyFile.pub
where keyFile.pub is a text file containing your public key. This was generated by PuTTYgen when you hit the “Save public key” button and should look like:
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "userName-rsa-20110512"
AAAAB3NzaC1yc2EAAAABJQAAAIBeIywsWQFXXoWsQG7aNKkt4AVyjkt4/c7yCudH
5sMUrsnfpBxGJn1SjNaZorCnZm4j7k+gGw2QFJBrJFsWLAqZwceanHQlid9xmKB9
wTN45yzfqFuKrYwpByT9npX2MMC7RjOUm7ccPH3gg1KYn2kPIv/EGsSHNwGYG56E
KBZaxQ==
---- END SSH2 PUBLIC KEY ----
Where I work, my home directory is on a central file server and is automatically linked to by the other servers on the network, so I have my public key in all three locations to handle the different versions of SSH servers on the network.
3. Connect with your key.
In your PuTTY connection settings under Connection > SSH > Auth, you want to specify the location of your private key. If you’re going to be using Pageant, you’ll instead want to check the box “Attempt authentication using Pageant.”
4. Setup Pageant to handle your private keys. (optional)
Pageant is a utility that manages your private keys so you don’t have to specify which key is for what connection. Also, if your private key is protected by a passphrase, you only have to enter it once and Pageant will store the decoded key. This is pretty straight forward – just run Pageant and add your private key(s).
That’s it! At this point you should be able to connect without password authentication! If you’re having problems, you may want to try setting up a connection in PuTTY where you give it the path to your private key directly and see if that works.
Edit (February 17, 2012): Recently installed TortoiseSVN 1.7 and public key authentication broke. Apparently it requires PuTTY/Pageant 0.61 or later.
I’ve been using Dial Complete foaming hand soap dispensers for a few years now, and I’ve just been refilling my original dispensers. Recently, their output has been a bit anemic and has seemed to require a bit more force to get soap out. I suspect that the soap tends to dry out and build up inside the pump over time, clogging up the works.
I’d originally planned to disassemble the pump to clean it, but as I could not immediately take it apart, I tried running some hot water through it. I took the pump off the bottle, filled a sink full of hot water, and pumped that through the dispenser – there was quite a bit of soap in there as I pumping for a few minutes and never got just water coming out. Still, at the end of it the pump was working better and I was getting much more throughput. I pulled the pump out of the water, pumped it dry, then put it back on the bottle. And voila – it was working like new.