Wednesday, April 17, 2013
Wednesday, April 10, 2013
Emacs, Flyspell/Ispell, Aspell, and Windows
I also use Emacs a lot. I used to program mostly on Linux, and my school courses were all done with Emacs, so I got used to it. Now Emacs feels more like my index finger than a programming environment, but I digress.
I generally use Emacs for Latex as well, but until recently, I never bothered spell-checking my Latex on Windows (I just did it on whatever flavor of Unix I had installed on, or let my co-writers handle those changes).
But now, I really really need to finish my thesis, so spell-checking is important now at all times. So I can't find a decent howto for this, so here goes. (For my own sanity as well)
- Install Aspell. You'll need to download the binary installer (GNU Aspell-0.50.3 (win32)) as well as the dictionary (I use English), (Aspell-en-0.50-2-3.exe).
- Add
(add-to-list 'exec-path "C:/Program Files (x86)/Aspell/bin/")
(setq ispell-program-name "aspell")
(setq ispell-dictionary "american")
to your .emacs/.emacs.el/whatever initialization you use.
- Restart or M-x load-file .your_file_name_obviously_not_this_exact_name.
- M-x flyspell-mode or M-x ispell or whatever should work now.
As always, with unsolicited free Internet advice, YMMV.
Wednesday, December 19, 2012
Monday, December 10, 2012
Track of the Day - TV on the Radio, "Caffeinated Consciousness"
I recently realized they are my Favorite Band ®. Kind of like realizing your best friend forever is your soul-mate. All that time spent listening to MGMT, I could've been rocking out to you TVOTR --what was I thinking.
Sunday, December 9, 2012
Saturday, September 29, 2012
Latex Tables from Google Spreadsheets
So I would generally use Excel for this, but I find Google spreadsheets to be easier to use because I'm using more than 2 computers more often these days. I hate having to copy things back and forth and as friendly as google-drive is, Excel is less so. My workstation in the lab, for example is the French language version, which I can barely use (the commas kill me.)
Anyways so here it is, Google docs spreadsheets have a Javascript runtime that is exposed much like VBA. You can use it to write custom functions and other things. I wrote a handy button that will take my selected range and output a latex table.
Once you have your sheet filled out, you can then hit Tools->Script Manager from the menu bar. Hit "spreadsheet."
In another browser window, the javascript editor will show up with a handy example provide by Google. Here's what I did with mine.
function latexify() {
var range = SpreadsheetApp.getActiveRange();
var numRows = range.getNumRows();
var numCols = range.getNumColumns();
var values = range.getValues();
var cs = new Array(numCols);
var strRows = "";
for(var k = 0; k < numCols; k++){
cs[k] = 'c';
}
strRows = "\\begin{table}\n";
strRows += "\\centering\n";
strRows += "\\begin{tabular}";
strRows += "{|" + cs.join("|") + "|}\n"
strRows += "\\hline\n";
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
for (var j = 0; j <= numCols - 1; j++){
var cell = row[j];
strRows = strRows + cell;
if(j < numCols-1)
strRows = strRows + " & ";
}
strRows += "\\\\ \n\\hline\n";
}
strRows += "\\hline";
strRows += "\\end{tabular}\n";
strRows += "\\label{table:table}\n";
strRows += "\\caption{\\small{}} \n";
strRows += "\\end{table}\n";
Logger.log(strRows);
};
Lovely, isn't it? Choose Run from the menu in the editor, and then View->Logs to show the output. Documentation is available from the Help menu, but I found the API Reference most useful.
Sunday, August 21, 2011
Thursday, October 14, 2010
Track of the Day
♪ The Radio Dept - "David"
Wednesday, October 13, 2010
Whoa
Thursday, May 20, 2010
Track of The Day
Janelle Monae, international superstar, channels James Brown and rips the Late Show a new one. Seriously it's that good.
Wednesday, May 5, 2010
Track of The Day
Sounds like JJ, hanging out with "some dudes." Soon to be a summer hit. Random spelling note: no more "alot," mmmkay?
Tuesday, April 20, 2010
Track of The Day
BSS new album can now be heard at NPR's website. By the way, check out the sleeve-face homage.
Stuff I like
Major Lazer "Keep it Going Louder" from Eric Wareheim on Vimeo.
Sunday, April 18, 2010
Stuff I like
HEALTH "We are Water" from Eric Wareheim on Vimeo.
Wednesday, April 14, 2010
Stuff I like
via pitchfork, via via.
Track of the Day
On infinite repeat for the foreseeable future.
Sunday, April 11, 2010
Track of The Day
Add one part MGMT to one part Passion Pit, shake well. This album (No Mas) could kickstart, well, just about anything.
Friday, April 9, 2010
Research (Nuts and Bolts)
So I was avoiding installing openmpi on the Rochester system because I figured it would be difficult at best, and impossible at worst. But eventually I gave up on getting hadoop to play nice and find that it is remarkably easy to set up OpenMPI on a given cluster. If you have a cluster with a common NFS mount, all you have to do is download and unpack and set your path to wherever you installed openmpi. Let me just blog this in case you're wondering how to go about it.
First, I downloaded the tarball from here and unpacked it into ~/openmpi. Then in that directory,
$./configure --prefix=/u/rim/opt/openmpi $ make all install
Thats pretty much it, other than setting
PATH=$PATH:/u/rim/opt/openmpi/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/u/rim/opt/openmpi/lib
in my .bashrc file. YMMV depending on your favorite shell.
Now I had to write my MPI program, which actually I already did, but here it is for completeness, or at least the main function. This generates a kernel matrix, which is relatively easy to do parallel, I just give row indices of the test matrix to each node and ask them politely to kernelize that part of the final matrix.
When they're done they send them back to the master node, which copies these columns into the big matrix. The only tricky part with ublas is to make sure that the MPI receive and send copy the respective right parts of the matrix. Here, since we're copying rows of the final kernel matrix, we want everything to be row major.
int main(int argc, char *argv[]){ matrix<double> Xtrain; matrix<double> Ytrain; matrix<double> Xtest; matrix<double> Ytest; MPI_Status status; int size = 1; int rank = 0; MPI_Init(&argc, &argv); size = MPI::COMM_WORLD.Get_size(); rank = MPI::COMM_WORLD.Get_rank(); char name[MPI_MAX_PROCESSOR_NAME]; int len; memset(name,0,MPI_MAX_PROCESSOR_NAME); MPI::Get_processor_name(name,len); memset(name+len,0,MPI_MAX_PROCESSOR_NAME-len); if(!load_data(argv[1], Xtrain, Ytrain)){ cout << "klr_test (error): Bad train filename" << endl; return 0; } if(!load_data(argv[2], Xtest, Ytest)){ cout << "klr_test (error): Bad test filename" << endl; return 0; } kernelType kernel = RBF; if(string(argv[3]) == "CHI2"){ kernel = CHI2; } if(string(argv[3]) == "POLY"){ kernel = POLY; } if(string(argv[3]) == "LINEAR"){ kernel = LINEAR; } if(string(argv[3]) == "EUCLIDEAN"){ kernel = EUCLIDEAN; } double param1 = atof(argv[4]); int N = Xtest.size1(); int D = Xtrain.size1(); //split the matrix into row matrices int offset = floor((double)N / (double)size); int start = rank*offset; int end = (rank+1)*offset; end = end > N ? N : end; int M = end - start; if(rank + 1 == size){ end = N; M = end - start; } ublas::matrix<double, ublas::row_major> K(N, D); if(rank == 0){ K.assign(ublas::zero_matrix<DBL_TYPE>(N, D)); }else{ K.resize(M, D, false); K.assign(ublas::zero_matrix<DBL_TYPE>(M, D)); } for(int k = start; k < end; k++){ matrix_row< matrix<double> > u1(Xtest, k); int j = k - start; for(int i = 0; i < D; i++){ matrix_row< matrix<double> > u2(Xtrain, i); K(j, i) = kernelize(u1, u2, kernel, param1); } if(VERBOSE && (k % 100 == 0)) std::cout << k << ": " << rank << " " << name << std::endl; } if(size > 1){ if(rank == 0){ for(int i = 1; i < size; i++){ start = i*offset; end = (i+1)*offset; end = end > N ? N : end; M = end - start; if(i+1 == size){ end = N; M = end - start; } MPI_Recv((void *)&K.data()[start*D], M*D, MPI_DOUBLE, i, TAG_MATRIX_PARTITION, MPI_COMM_WORLD, &status); } }else{ MPI_Send((void *)&K.data()[0], M*D, MPI_DOUBLE, 0, TAG_MATRIX_PARTITION, MPI_COMM_WORLD); } } if(rank == 0){ ofstream output(argv[5], ios::out); for(unsigned int i = 0; i < K.size1(); i++){ for(unsigned int j = 0; j < K.size2(); j++){ output << K(i, j); if(j < (K.size2()-1)){ output << ","; } } output << std::endl; } } MPI_Finalize(); return 0; }
Now to make and run, just edit your Makefile to do something like
MPICC=mpic++ ... $(MPICC) kernelize_mat2.cpp -o kernelize_mat2 $(LFLAGS) $(CFLAGS) $(INC) $(OLIBS)
where everything to the right of -o kernelize_mat2 are just settings and flags I otherwise needed. The only change I made was to add the mpi wrapper for the g++ compiler, mpic++. The other bits are stuff that I already had/needed.
After building, you can run. On the cluster, they use Torque for scheduling, so you can either do it via shell script or via the interactive start. I generally prefer to use the shell script since it's less wasteful, but here I use the interactive start up because I wanted to make sure it was all kosher.
$ qsub -I -lnodes=5,walltime=3600,mem=1000M
I like to use funny names for my pbs jobs, but I skip that here. That command line requests 5 nodes with an hour of cpu time and a gig of memory each, which is about what I wanted.
$ mpirun -np 5 --hostfile $PBS_NODEFILE /path/to/kernelize_mat2 train.csv test.csv RBF .7 kernel.csv
-np tells how many processors you want to use and the --hostfile $PBS_NODEFILE says which hosts you want to run your process on. You can, of course use less, but thats a little silly, no? You can also run it locally if you exclude hosts in the hostfile. That is you can also specify
-np 4 --host node33In any case at each step I was expecting the thing to say, root access required or something, but I guess that's being silly. Anyways, the whole thing worked like a charm and took roughly 20 minutes to set up and get running (almost all of that time was spent compiling).
That's pretty much it, so now you too can write cool apps for the cluster, and if you're using the one I use, then by all means, you can just set your paths to mine (although names were changed to protect the innocent). By the way, does this code really need comments? I don't even know where I would put one.
Wednesday, April 7, 2010
Montreal
Monday, April 5, 2010
Stuff I like...
TWOYOUTUBEVIDEOSANDAMOTHERFUCKINGCROSSFADER.