Archive for November, 2013

8:30 is the perfect time for anything

Tuesday, November 26th, 2013

8:30 is the perfect time for anything

http://alecjacobson.com/art/digital

http://alecjacobson.com/art/

Correlation does not imply causation

Tuesday, November 26th, 2013

Correlation does not imply causation

http://alecjacobson.com/art/digital

http://alecjacobson.com/art/

Bug fix in AntTweakBar TwDefineEnumFromString

Wednesday, November 20th, 2013

After experiencing some odd behavior, I tracked down a bug in AntTweakBar’s TwDefineEnumFromString function. The problem seems to be that the labels in the label-value pairs stored for custom enum types are stored as const char *. The original code sets these pointers to dynamically allocated std::strings via the c_str function. This is trouble because the strings are in a local scope and then the memory can be arbitrarily written over.

Without changing too much I fixed this by first copying the strings into dynamic memory. This causes a leak, but I think to fix the leak I’d have to change the implementation of the struct that stores the label-value pair and refactor.

So just change the code in TwMgr.cpp to look like:

TwType TW_CALL TwDefineEnumFromString(const char *_Name, const char *_EnumString)
{
    if (_EnumString == NULL) 
        return TwDefineEnum(_Name, NULL, 0);

    // split enumString
    stringstream EnumStream(_EnumString);
    string Label;
    vector<string> Labels;
    while( getline(EnumStream, Label, ',') ) {
        // trim Label
        size_t Start = Label.find_first_not_of(" \n\r\t");
        size_t End = Label.find_last_not_of(" \n\r\t");
        if( Start==string::npos || End==string::npos )
            Label = "";
        else
            Label = Label.substr(Start, (End-Start)+1);
        // store Label
        Labels.push_back(Label);
    }
    // create TwEnumVal array
    vector<TwEnumVal> Vals(Labels.size());
    for( int i=0; i<(int)Labels.size(); i++ )
    {
        Vals[i].Value = i;
        // CHANGE HERE:
        //Vals[i].Label = Labels[i].c_str();
        char * c_label = new char[Labels[i].length()+1];
        std::strcpy(c_label, Labels[i].c_str());
        Vals[i].Label = c_label;
    }

    return TwDefineEnum(_Name, Vals.empty() ? NULL : &(Vals[0]), (unsigned int)Vals.size());
}

MATLAB gotcha: operator precedence with backslash

Tuesday, November 19th, 2013

Matlab’s backslash operator \ seemingly acts as a matrix inverse then multiply operator. So I often read:

x = A\b

as x = A-1 b. Indeed,

help \

reveals in matlab’s documentation:

A\B is the matrix division of A into B, which is roughly the same as INV(A)*B, except it is computed in a different way.

This is very misleading when you consider:

x = 2*A\b;

If A=1;b=1; then this sets x to 0.5! This is because \ as a division operator does not take precedence over *, and because it comes later in the expression this is equivalent to:

x = (2*A)\b;

which—so long as A is invertible— is equivalent to:

x = 0.5*(A\b);

but decidedly not equivalent to:

x = 2*inv(A)*b;

or

x = 2*A^-1*b;

which both set x to 2.

Uninstalling Maple toolbox breaks matlab app

Tuesday, November 12th, 2013

I tried to uninstall the maple matlab toolbox via Uninstall Maple 17.app. This seem to execute OK, but then when I tried to launch Matlab the app immediately exited. Investigating the console I saw that it was producing an error:

2013-11-12 19:23:22.290 StartMATLAB[494:707] execl("/Applications/MATLAB_R2012a.app/Contents/MacOS/../../bin/matlab", "/Applications/MATLAB_R2012a.app/Contents/MacOS/../../bin/matlab", "-desktop", "-arch=maci64", nil) failed!  errno: 13

Upon closer inspection it seems that the matlab file existed but it’s permissions were not setup for executing. I fixed this by issuing:

sudo chmod a+x /Applications/MATLAB_R2012a.app/Contents/MacOS/../../bin/matlab

My guess is that maple’s script tried to replace matlab with a backup but forgot to recent the permissions.

Well, it’s probably not February.

Thursday, November 7th, 2013

Well, it's probably not february

http://alecjacobson.com/art/digital

http://alecjacobson.com/art/

What color are tennis balls?

Friday, November 1st, 2013

Some colleagues and I were debating this today. Of my enormous dataset so far of 6 people, 3 vote for yellow and 3 for green. Interesting the yellow votes all came from Europeans and the greens from non-Europeans. Here’s a very rushed experiment to determine the average color of a tennis ball. From top to bottom: I took a screen capture of a google search for tennis ball, created a mask that mostly contains just the tennis balls, then took an average of the masked colors resulting in the solid bottom color.

tennis ball

If you ask me—and I think you should—I’ll tell you that’s green.

Here’s the matlab script I used to create this:

im = imresize(im2double(imread('tennis-ball-google-search.png')),1.0);
ntsc = rgb2ntsc(im);
M = [ntsc(:,:,1)>0.5 & ntsc(:,:,2)>0];
avg = sum(sum(bsxfun(@times,M,im),1),2)./sum(M(:));
comp = [...
  im; ...
  repmat(M,[1 1 3]); ...
  bsxfun(@times,M,im); ...
  repmat(avg,[size(im,1) size(im,2) 1])];
imshow(comp);

Convert mkv into high quality mp4 for iPad

Friday, November 1st, 2013

Here’s what I’m using to convert 1080p BluRay rips from .mkv to .mp4s for playing back on the iPad.

ffmpeg -i input.mkv -acodec aac -ac 2 -strict experimental -ab 160k -s 1920x1080 -vcodec copy -f mp4 -threads 0 output.mp4

Update: This only works if the input .mkv file is already using h264 as the video codec (see, it’s copying the video rather than transcoding it). Otherwise, you’ll need this (takes much longer):

ffmpeg -i input.mkv -acodec aac -ac 2 -strict experimental -ab 160k -vcodec libx264 -preset slow -profile:v baseline -level 30 -maxrate 10000000 -bufsize 10000000 -b 1200k -f mp4 -threads 0 output.mp4