Wednesday, September 07, 2011

C++ vs Fortran

I've been wanting to put together a blog post about Fortran for a while now, but it never made it to the top of my list of priorities. I'm happy to see that someone named eric_t went ahead and put together a really nice page:

https://bitbucket.org/eric_t/modern-fortran/wiki/Home

So, predictably, the C++ mob showed up with their pitchforks to argue against the use of Fortran. (Actually, a lot of them were arguing against FORTRAN, demonstrating their ignorance.)

As someone who has used both C++ and Fortran for numerical programming, it's hard for me to think of a good reason to use C++ for this stuff.

Let me start out by explaining my perspective, which is what rarely happens in programming language debates. I write numerical programs that do statistical analysis, simulations, and various types of numerical analysis. Most of my programs are less than 5000 lines.

I don't know or care about comparisons of C++ against Fortran for 50 developers working with a codebase of a million lines. I work together with only a few others. I have no interest at all in software development. I write programs as necessary to feed myself.

C++ comes with the mother of all learning curves. I'm not talking about the fact that there's no complexity too large to fit into a C++ program (the language is more than happy to accommodate any desired level of complexity). Though of course that is a problem.

I'm talking about the ability to do basic things like linear algebra or writing functions. A Matlab user can convert to Fortran in about 10 minutes. Obviously you won't know very much, but in the time it takes to get used to the idea of compiling a program and specifying types for your variables, you can define two matrices and do a matrix multiplication in Fortran. The language was written for scientific computations. You can take a look at the gfortran manual to see all the built-in goodies that come with a Fortran compiler.

The bare minimum for doing the same exercise in C++ is that you have to get your hands on a library that does what you want. So you have to know about the existence of Eigen or another libary. Then you have to figure out how to call it. Then you have to figure out how to link to an external library. And the documentation is probably not that helpful. There are friendly C++ users for sure. It's just that you won't have a clue what they're telling you to do. They'll be telling you to set up a makefile. They'll be recommending that you look at Boost and talking about how great it is and you'll be all WTF.

All this mess because you wanted to try out C++ to do a simple matrix multiplication. In Matlab it was just a few lines. In C++ it's a month-long project.

And before you use that C++ library, are you really sure you won't end up with a memory leak? Do you even know what a memory leak is? It probably won't matter for your simple matrix multiplication, but it's real comforting to know that you should worry about such things in order to write such a simple program, isn't it?

Now that the numerical version of "Hello, World!" is out of the way, you can get on to real work. You need to start with a tutorial. Not a complete introduction to the language, of course, just a tutorial that will give you a basic understanding of the language.

An excellent tutorial (that has taught me a great deal) is C++ Primer Plus. I just pulled the Fifth Edition off my shelf. It's okay to just read through Chapter 17. You don't even have to read the appendices. The first 1039 pages of the book is enough for now.

You will have worked through Chapter 4, including the section on "Pointers and the Free Store" and "Pointers, Arrays, and Pointer Arithmetic". You'll have learned about "Dereferencing Pointers". You'll get to work through well-designed syntax like (page 308)

int sum(int (*ar2)[4], int size);

or (page 309)

*(*(ar2 + r) + c)

You'll learn about "Memory Models and Namespaces" in chapter 9. The topics include material useful to newbies like "Automatic Variables and the Stack".

Further along (page 677) you'll learn about "Inheritance and Dynamic Memory Allocation".

Maybe you can just learn the language a little bit at a time. Here's the thing. You really can't. You have to know a lot to read code written by others and to use libraries written by others. Complexity is never hidden behind the scenes with C++. You have to understand memory management before you write your first line of code.

You might think you'll just call libraries so you'll be okay. That's not programming in C++, but let's pretend it is. An easy library (written in C) to call is the GSL. You want to solve a system of equations. Here's the function call:

int (* f) (const gsl_vector * x, void * params, gsl_vector * f)
This is an example of "easy" in C++.

Then when you're done with your tutorial, at a minimum, you need to learn about templates and the STL. And, although not strictly necessary, you should pick up some books by Scott Meyers so you can learn about pitfalls of the language.

If you think I'm just some idiot blogger who doesn't know anything about programming, and don't want to take my word that C++ is too complex to be a reasonable language choice, take a look at this blog post:

http://gigamonkeys.wordpress.com/2009/10/16/coders-c-plus-plus/

It was not a group of mediocre developers too lazy to learn a programming language that he interviewed. From my perspective, Ken Thompson's comment is the most relevant:

"It certainly has its good points. But by and large I think it’s a bad language. It does a lot of things half well and it’s just a garbage heap of ideas that are mutually exclusive. Everybody I know, whether it’s personal or corporate, selects a subset and these subsets are different. So it’s not a good language to transport an algorithm—to say, “I wrote it; here, take it.” It’s way too big, way too complex."

If you can program in Matlab, you can program in Fortran. The same is not true for C++. The complexity is not optional: you just can't interact with the outside world without bumping into it.

The advice to use C++ goes something like this:
1. Spend ten years learning to write C++ programs.
2. Start writing all the programs that you could have been writing ten years ago using Fortran.

I understand what these C++ developers are going through. If I invested ten years of my life learning nearly 1% of the C++ language, I would be upset to find out that those ten years were wasted. I'd be looking for some way to make it feel as though I didn't flush ten years of my working life down the toilet.

There are better choices. For many things, Fortran is an excellent choice. It even has recursive functions and lets you specify that a function is pure. It's not Lisp but that does offer a bit of comfort to someone like me.

If you like the object oriented side of things, Java has closed the speed gap a lot (not that I like Java, but being a better choice than C++ is a low standard). There's also D and Objective-C. The more I use D the more I like it. You really should have your head examined if you have the choice between D and C++ and you choose C++ because you think it's a better language. There might be a different reason to use C++ (like, you're too stubborn to admit that your favorite language sucks) but it's definitely not the case that C++ is a better language.

There are languages like Scala (I've played with it a little but not done any real work, so I can't say much about it) and Clojure that have access to the JVM. You can do the performance critical parts in Java if necessary.

LuaJIT2 is really fast, and the upcoming GSL Shell will be based on LuaJIT2 (at least that's my understanding). Even the current version of GSL Shell does well for speed. PyPy is constantly improving as well. Both are excellent, if somewhat incomplete, choices.

C++? No way. There might be a few cases in which C++ is the best choice, but given the time investment required to learn C++, that is a very small set. If you factor in the time to learn the language, write/debug your program, revisit the program later to fix bugs/add features, and then compile and run programs, even pure interpreted Ruby is likely to be a better choice.

Update: I just watched an excellent presentation by Herb Sutter:

http://channel9.msdn.com/posts/C-and-Beyond-2011-Herb-Sutter-Why-C

He definitely makes a strong case for C++. I don't disagree with much of what he said, except that I think he overstates the speed gap for many tasks between C++ and languages like Java, though for the applications he's talking about the difference still matters. Interestingly, for those applications, developer time is almost irrelevant.

He never says C++ has replaced Fortran. In fact, at the beginning of the talk, he specifies that the three languages that can deliver the needed performance are C, C++, and Fortran. Later at that same conference, they talked about D:

http://channel9.msdn.com/posts/Scott-Meyers-Andrei-Alexandrescu-and-Herb-Sutter-C-and-Beyond

Friday, September 02, 2011

Gretl on Scientific Linux

I don't even use Gretl, but sometimes it needs to be available to others. That's why I created Gretl SlackBuilds, and now I have tried to build it for SL.

I pulled the following required packages from the Fedora build at
http://pkgs.fedoraproject.org/gitweb/?p=gretl.git;a=blob_plain;f=gretl.spec;hb=fe69e968cb87ca23907ba147a8071420f702a960

BuildRequires: desktop-file-utils
BuildRequires:    gtk2-devel
BuildRequires:    glib2-devel
BuildRequires:    blas-devel
BuildRequires:    fftw-devel
BuildRequires:    gettext
BuildRequires:    libxml2-devel
BuildRequires:    gtksourceview-devel
BuildRequires:    libgnomeui-devel
BuildRequires:    lapack-devel
BuildRequires:    readline-devel
BuildRequires:    ncurses-devel
BuildRequires:    gmp-devel
BuildRequires:    mpfr-devel
BuildRequires:    gnuplot
BuildRequires: gnu-free-sans-fonts
BuildRequires: bitstream-vera-sans-mono-fonts
BuildRequires: bitstream-vera-sans-fonts





I made sure all of that stuff was installed. Then I did
./configure --with-lapack-prefix=/usr
make -j 4
make check
make install (as root)

Be sure you have everything in the list above. I thought I did, but missed libgnomeui-devel. It compiled and installed, but I ended up with only gretlcli. It won't necessarily fail if you're missing something.

There are packages available on the Gretl homepage, but not 64-bit, which is why I did the compilation. Now if only I could figure out how to get ACML to work with Gretl...

Rmpi on Scientific Linux 6.1

Update: No need to read my frustrated rant. Here's what I did to get Rmpi working on Scientific Linux 6.1 64-bit. It should also work on Red Hat Enterprise Linux 6.1 64-bit and CentOS 6.1 64-bit, though I've not tried, and would appreciate feedback if it doesn't work:

1. yum install openmpi openmpi-devel
2. If you don't have a working R installation: yum install R-core R-devel
3. From within R: install.packages("Rmpi",configure.args=c("--with-Rmpi-include=/usr/include/openmpi-x86_64","--with-Rmpi-libpath=/usr/lib64/openmpi/lib/","--with-Rmpi-type=OPENMPI"))
4. As root (at the command line, not in R) open /etc/ld.so.conf, add /usr/lib64/openmpi/lib, then run ldconfig.


-- Actual post plus rant follows --

Continuing on with my Scientific Linux trial, when I've got a few minutes to spare, I tried to install Rmpi. Oy. I guess I've been spoiled by Slackware (likely the best strategy is just to stick with Slackware 13.1).

First, I installed openmpi and openmpi-devel.

Then I tried installing Rmpi but got stupid errors about mpi.h not found. Went to Google. Wasted time. Went to Google some more. Wasted some more time. Should not be this dang difficult.

Finally, based on this:
http://www.cybaea.net/Blogs/Data/R-tips-Installing-Rmpi-on-Fedora-Linux.html
I was able to construct the magic incantation:

install.packages("Rmpi",configure.args=c("--with-Rmpi-include=/usr/include/openmpi-x86_64","--with-Rmpi-libpath=/usr/lib64/openmpi/lib/","--with-Rmpi-type=OPENMPI"))

Now hopefully it works. I was going to record here all the stuff that needs to be done to get a working SL 6.1 installation that can be used on other machines. It's turning out to be more work than I anticipated. Can it really be the case that nobody uses Rmpi on RHEL-based distros? Or am I just missing the easy way to do this? I thought Rocks Cluster was based on CentOS. Given the popularity of R, somebody must have done this already.

Edit: I also had to add /usr/lib64/openmpi/lib to /etc/ld.so.conf, then run ldconfig, all as root.

Thursday, September 01, 2011

gvim on Scientific Linux

Almost got the software I need. gvim is not gvim or vim-gtk, on Scientific Linux it is given in package vim-X11.

RKWard on Scientific Linux

Update: It's probably a good idea to put the summary up front. I even confused myself when installing on another computer this weekend.

Summary:
1. Install any of the above listed build dependencies that are not on your system.
2. Download the latest rkward source.
3. Unpack the source, enter the directory.
4. mkdir build; cd build
5. cmake .. -DCMAKE_INSTALL_PREFIX=`kde4-config --prefix`
6. make -j 4 (or however many processors you've got)
7. make install (as root)
8. Start RKWard. Click on >> Settings >> Configure RKWard
9. Add /usr/share/kde4/apps/rkward/all.pluginmap under the section titled "Select .pluginmap file(s)"

{The last step may not be needed. You'll know if it is when you open RKWard.}


-- Actual post follows --

As with LyX 2.0, I'm going to have to bite the bullet and build RKWard myself. A Google search for "building rkward" leads me to koji.

The requirements are listed as (omitting rmplibs):
R-devel >= 2.13.1
cmake
desktop-file-utils
gettext
giflib-devel
kdelibs-devel
pcre-devel




 I'm missing giflib-devel and kdelibs-devel on my system, so I install them. I download the rkward source and unpack it.

Following the instructions on this page:
http://sourceforge.net/apps/mediawiki/rkward/index.php?title=Building_RKWard_From_Source
I do the following.

mkdir build; cd build
cmake ..        {I'm not specifying any options}
make -j 4
make install

It works (there's an entry for it under "Education") but not correctly. I get a message "Plugins are needed: you may manage these through "Settings->Configure RKWard"." Unfortunately no such option exists.

I look at the documentation again. I try
cmake .. -DCMAKE_INSTALL_PREFIX=`kde4-config --prefix`
make -j 4
make install

The plugins message still comes up, but now I've got a full menu and the ability to open files. I open >> Settings >> Configure RKWard and the menu is on Plugins. I added /usr/share/kde4/apps/rkward/all.pluginmap.

Now when I open RKWard there are no more error messages and everything works properly.








LyX 2.0 on Scientific Linux

I'm giving Scientific Linux a try. While it's a nice looking distro, I'm disappointed that rkward is not available at all, and LyX is still stuck in the 1.6.x series. I'm trying to build LyX 2.0. This is my experience - for my own reference, but if it helps someone else, even better. Google did not provide directions.

yum-builddep lyx doesn't work. Even though I've got the source repos enabled, and used yumdownloader to download the source rpm, I get the message

No source RPM found for lyx-1.6.10-1.el6.x86_64

It would be nice to have (useful) documentation. I am new to the RHEL-based distros so I have no idea what I'm doing.

My initial ./configure says

** moc 4 binary not found !

** uic 4 binary not found !

** qt 4 library not found !


I'm installing qt-devel. I don't see a collection for KDE or Qt development in the package manager GUI, so that's my best guess.

A search for moc turns up automoc, "Automatic moc for Qt 4". Hopefully that's it.

The top result in a search for uic - which I've never heard of before - is basket. I'm pretty sure that's not what I need. Scrolling through the entire list does not bring up anything helpful. A Google search for "lyx uic" turns up nothing helpful. "qt uic" gives background about the "User Interface Compiler" but not anything that solves my problem. "rhel uic" indicates PyQt4 might do the trick.That's what I try. Doesn't seem like the optimal choice, but if it works, I'll take it.

"Configuration of LyX was successful." Awesome!

make - completes with no errors
make install - completes with no errors

I've got a menu item for LyX. Open it up, it's 2.0, everything works.

Summary (can probably improve on the choice of build dependencies, but I have no time or interest in digging into it further - what I've got works)
1. Install qt-devel PyQt4 automoc
2. Download the latest LyX source.
3. Unpack the source and enter the new directory.
4. ./configure
5. make
6. make install (as root)

Friday, August 12, 2011

I am not afraid to admit that I've used Lisp for real work

[Really long post, but I don't see how to break it into smaller pieces. I wrote it a few weeks ago. I didn't want to post it at that time because I wrote some negative things about certain Lisp implementations. I took out a few of the negative comments, but most of them are still there. I stand by my opinions. You're free to have your own opinions, just like me, but I don't publish comments with swear words. I also don't publish comments that are uncivil or completely uninformative.]

As is the case with most programmers, I'd heard of Lisp, but didn't take it seriously because it was always presented as a dead language. Many of those comments came from former Lisp users. Lisp was just not up to the standards of "modern" languages, like Java, C++, Python, Ruby, (add your favorite language). Lots of nostalgia, but they'd made peace with the death of Lisp the way you make peace with the death of a pet dog when you're in middle school.

As is also the case for many programmers, I came upon the writings of Paul Graham and decided that Lisp might be worthy of further exploration. Then I read that the only app anyone admits having written in Lisp was later rewritten in Python. (That's only a slight exaggeration.)

It's hard to come upon examples of the use of Lisp the way you can find examples of Ruby, Python, or even Tcl.

Let me proudly say that I'm not afraid to write programs in Lisp. My situation is different from, say, a web developer for a Fortune 500 corporation. I do numerical programming. I get paid to do simulations, statistical analysis, and a variety of other types of numerical analysis.

I have one of the best jobs in the world. I am free to choose my programming language. It makes no difference if I'm the only programmer in the world using a particular language. Most of the programs I write are less than a few thousand lines, and most of the time, they are almost independent of all the other programs I write. In other words, what matters is that the program I write for a specific task does its job for that task and that task alone. Yep, I do scripting.

Which languages do I use? If you have read other posts on this blog (making you part of a very small group) you know R is what I use most often. Yet I love Lisp and plan to do a lot more Lisp programming going forward. I would not be surprised if five years from now Lisp was my main programming language.

Lisp is a great language and you too can trust it if you write numerical programs of 5000 lines or less. You can probably trust it for other tasks as well but I don't have such an experience with Lisp. Please tell the world that Lisp is a great language for numerical/statistical analysis. Those who dismiss it are wrong. There's absolutely no reason to not give it a trial. See what libraries are available. Look at some code written by others. It never hurts to learn another language, and if you have used only Matlab, you will learn a hell of a lot about programming even if the only thing you do is read The Scheme Programming Language without writing a single line of Lisp code. You have a lot to gain and nothing to lose. I guarantee it.*

Now that I've given a little background, I'd like to discuss the question of which Lisp to use. There are a number of alternatives in the Lisp world. The choice can be confusing to beginners, which would have included me not that long ago. I will briefly discuss four of the available options: Common Lisp, Scheme, Clojure, and newLISP.

Common Lisp: This one is often described as the "industrial strength" Lisp. In many cases, someone will just say "Lisp" when in fact they are referring to Common Lisp. My assessment of Common Lisp is that it's what you'd have if you start with Java, take out most of the good stuff, add on some Lisp features in the clumsiest possible way, and leave changes to a political process that ensures change will never happen.

Common Lisp is sort of the Oldsmobile of programming languages. It was good relative to the alternatives in the mid-80's, but then it stagnated, leading to its downfall.

There are some advantages. It's the only Lisp that's ever been popular in the enterprise. There's a lot of documentation available. There are a lot of libraries available. Some of the compilers have the potential to produce really fast code. There are, possibly surprisingly to the outsider, a lot of programmers who have used Common Lisp. That helps to the extent that you need to interact with other Lisp users, say to ask questions.

The community is a serious drawback. While most of the community is great, they haven't figured out how to control a vocal few.

My opinion: Stay away from Common Lisp as a beginner. The user community is stuck in the disco era. You can always try it later if you want. If you try only Common Lisp you will agree with those who say Lisp is not a suitable alternative to today's more popular languages. It had its chance to be popular, it failed spectacularly, and it failed spectacularly for a reason. If you have a beard and 15 years of Unix experience, you will probably feel right at home, so my advice doesn't apply to you.

Scheme: My first use of Scheme to any degree was going through SICP. Absolutely awesome experience.

I've written elsewhere about the big problem with Scheme. It's elegant, but the core language is too small to do anything useful, and the extensions are of exceptionally low quality, with some of the worst documentation of any product in the western hemisphere.

Scheme is an excellent language for teaching programming. The Scheme developers do not have an incentive to put together high-quality, properly documented language extensions. This is what you will encounter if you read the documentation on a Scheme extension:

foo [option] name code

foo transforms name into code. You can set options as desired.

Section 5 of the Scheme specification prohibits the use of informative examples when documenting functions. The 80th time I had to look at source code to figure out what an extension did was when I gave up on Scheme.

The developers of Scheme extensions are happy when they can say, "It is possible to do X" for any choice of X. To be useful, they'd need to be able to say, "It is possible to do X in a reasonable amount of time with a reasonable amount of effort." You sure as heck don't want to be relying on a piece of code and then find out that it's not doing what you thought it was, and have no idea how to fix the problem. That's when you start thinking about the reaction of your family if you get fired.

And no, Racket is not different in that regard, the extensions are a complete mess and the examples, if they exist at all, are unlikely to help much. This is not a criticism of Scheme or Racket. They are intended to be used as tools for teaching and research. I'm fine with that. There are other choices available. If you are learning Lisp do not get frustrated that Scheme/Racket can't do what you need. That does not mean Lisp is a bad choice of language.

Clojure: This is one awesome language. It's a modern Lisp. Not only is the language awesome, but the creator, Rich Hickey, has a lot of interesting things to say. You can tell that he has been in the trenches for a long time doing real programming, yet he is excited to incorporate ideas from the academic community.

Oh, Clojure also runs on the JVM, meaning you have access to everything provided by the king of enterprise programming languages. There are several good Clojure books out already, and more are on the way. There is serious upside both in terms of the language and the prospects for a career writing Lisp programs.

There are at least two downsides. The first is that using Clojure almost guarantees you will be bringing in some Java. That means many of the bad things about Java apply to Clojure as well. With time, Clojure is likely to develop its own libraries, which will minimize the Java drawbacks. The second downside is that the development tools are not mature, as you should expect with such a young language.

newLISP: Ultimately, I have come to like newLISP the best. newLISP is unmatched in the Lisp world in terms of documentation. After dealing with Common Lisp and Scheme documentation, I was shocked at the quality and quantity of examples that come with newLISP. You can learn to do everything the language does with little difficulty.

Another attractive feature of newLISP is that Common Lisp programmers criticize it for failing to meet their definition of being a "real" Lisp. That's a good sign, because Common Lisp has failed, so if you want to put together a language programmers actually want to use you better do some things differently from Common Lisp. newLISP lets you get work done quickly and correctly, and that's the only reason I've ever used a programing language.

As a scripting language, newLISP is not a competitor to either Common Lisp or Clojure. It is not a speed demon, but if you're using a scripting language, you obviously should not expect the speed of C or Java. It does quite well in terms of speed relative to other scripting languages I've used including Tcl and Python.

For most Linux distributions you will have to compile it yourself. However, that is easy (almost trivial - just follow the directions) and extremely fast (measured in seconds rather than minutes).

The bottom line: If you want to get started with Lisp for real world projects and have programming experience, install newLISP and try it out. The documentation on the website will definitely help you to get going quickly.

If you want to learn to program, install Racket, and use drracket with SICP. Any Scheme will also do.

If you want something suitable for the enterprise, get one of the Clojure books and give that a try.

Although I don't have any recommend uses for Common Lisp, there are many resources available if you want to go that route. CLISP is a good choice, but keep in mind that it does not come with a compiler. I will add that Land of Lisp is a very, very good book (and recent to boot) that will be one of the best purchases you ever make.

The decision of which Lisp is not as big as it might seem. You can carry a lot of your knowledge from one to the other. The best strategy may well be to study all of them. Whichever you choose you will be happy with your choice - even if that choice turns out to be Common Lisp.

*I'm an anonymous blogger, so don't expect my guarantee to mean much.

Monday, July 11, 2011

Why not use Scheme more?

Another observation post, probably not worth your time, but I want to express my thoughts. You've been warned.

I really first started using Scheme when I went through SICP. Well, I didn't make it all the way through, but I learned a lot in any event. When you've got masters like that to show you what can be done with Scheme/Lisp you wonder why everyone isn't using it.

As you can guess, I think I know why not everyone is using it. I primarily do numerical computing, so that is the set of features I consider when evaluating a new programming language. A couple of things stand out when I think about using Scheme rather than R and Fortran.

1. There is a lack of libraries. This is well known, sometimes called "the island problem".

2. There is a lack of data structures. If I want to do matrix algebra, I want to use a language that offers a matrix class as part of the language. I want to use a language that does matrix multiplication as part of the language. There are good reasons for that: less hassle, less chance of breakage when the core of the language changes, less chance that you're relying on an extension written by one individual that will stop working when he gets bored and moves on.

Item 1 is not as true as it used to be. The major Schemes have a lot of libraries available. There are also tools for wrapping C code, so honestly, any lack of libraries more or less reflects the small user base, rather than the other way around. If there were more interest, the libraries would appear quickly. There's just no interest.

Item 2 is still a problem and likely to remain so forever. I'm just not sure that a minor inconvenience is a major hurdle to adoption. Something like a standard set of libraries being available with each implementation would be a solution.

I've reconsidered the situation since discovering Clojure, and IMO the real problem with Scheme (any of them) is the sucky documentation. It stinks. It really, really stinks. {Clarification: Upon reading the post, I was not clear that I'm talking about the developers of Scheme extensions, not the developers of the core language itself. There exists very good documentation for the core language if you're doing the usual things.}

Have the Scheme documentation writers never heard of examples?

I've never seen a community that was so collectively clueless about how to write documentation. And I'm a Slackware user. I don't think anyone has ever complained about the excessive documentation that comes with Slackware.

I might even consider writing some documentation myself, if not for the fact that I can never get anything in Scheme to work, because the documentation sucks so bad. My philosophy is to just move on if I have to work too hard to figure something out. I've come to realize that developers that don't document their work very well are usually not good developers.

Let me elaborate on that point a bit. The software might work as intended, but the underlying code is only part of the project, and by itself has no value. A good design means I don't have to think too much to use it. And when I return to the code in a year, I'll be able to easily figure out what I did and how to extend it.

If I have to work for six hours to figure out how to call a simple function, that's a sign that at some point I'm going to find that my program isn't doing what I thought it was doing. At some point I'm going to say, "WTF? Why was that matrix transposed? It makes no sense." Of course there was no way I could have known that, and there's no way I will ever understand the philosophy driving the development of the library. Then a few seconds later I'll be terrified, "Hold on, if the developer would do something like that, how can I trust the other lines of code that I've been writing for the last two weeks? There's no freaking documentation!" Then I'll move on to a real language, redo everything, and be sure to avoid the mistake of trusting Scheme in the future.

Go to one of the popular Scheme implementations. Just pick one. They're all equally useless. Pick out an extension that does something you need for numerical computing. If there's documentation at all - and there may very well not be - try to use that documentation to write a program. Use all of the important "things" that the extension does. Use those important things in different ways, like you would actually use them in an actual programming exercise where you are actually trying to feed yourself. Can you even figure out how to call all of the functions properly in less than two weeks?

Most of the documentation is just a slopped-together list of functions and a short, content-free description that might (though in most cases probably won't) be sufficient to jog the memory of the developer himself as to what the function should do. There's no chance in hell that a programmer writing a program related to his career is going to spend enough time to figure out how to use the extension. Sure, there are hobbyists who will figure it out, but I'm talking about real work in an environment where money is on the line.

I cannot treat the developers of Scheme as real developers. They're not professionals. Some are, of course, but I'm talking averages here, and the average Scheme developer is of pretty low quality relative to the average Java developer. The average Scheme developer thinks he's much better than the average Java developer because he can use recursion properly and was smart enough to recognize the brilliance of Lisp. Great, but if you measure developer quality in terms of the value of the output in a given amount of programmer time, Scheme developers probably have a negative value, because most of what they do gets in the way of developers interested in making a product that does something of value.

Do I like Java? Not a chance in hell. If I had to choose between Scheme and Java to do something with money on the line, even assuming all the same libraries are available in Scheme and Java, which would I choose? I'd take Java in a second. Scheme could learn a lot from Java about working with beginners.

It's a shame that Scheme has been plagued by crappy documentation. There's no reason that Scheme, on technical merit, cannot be Java. The difference is that Java was written for business applications, and that required documentation, and they got it. The Scheme community has decided that working with beginners is not fun and it has caused Scheme to be viewed as a goofy artifact of the past, rather than the language of the future.

Saturday, July 09, 2011

What's wrong with Clojure syntax?

Short post, not a lot of value.

I keep reading things about Clojure's syntax being ugly. I don't think that's the case at all. It's extremely consistent and easy to follow. Maybe I'm just weird, but I've always preferred Tcl for short scripts because I like the syntax. Sometimes the critics of Clojure/Lisp syntax are even Java programmers!

Saturday, June 18, 2011

Calling R from Clojure

From what I've read and based on the time I've played around with it, Clojure looks like a very good language. There's no reason to praise it here. Just ask Google if you want to read some praise for Clojure.

For me, it is promising because it runs on the JVM and has complete access to existing Java code. That means it's both fast and will do most of what you want to do. (Scala fits into the same category. I will be checking out Scala in the future.)

In addition, it is a dialect of Lisp, which means I'm a huge fan of the syntax as wells as the approach to problem solving. I've enjoyed using Scheme in the past, but given the lack of libraries, Scheme is not suitable for the numerical programming I do. I'm aware of projects like Chicken Scheme and Gambit-C, and I know about Swig and their foreign function interfaces and all that, but I'm too busy to do everything my employer wants me to do. There's no way I'm going to spend months of my time extending the language, usually with crappy documentation if it even exists at all.

I said above that Java will do "most" of what you want to do because one of the few limitations of Java is that it is just not complete in terms of numerics. The situation is better than it was ten years ago, but I've still not worked much with Java, simply because I know it won't do everything I need it to do. Oh, and I hate the syntax with a passion. 8000 lines of GOTO-infested FORTRAN 77 is much more pleasant to me than 200 lines of Java.

The Clojure community offers a project called incanter that provides access to many of the available Java math libraries. There's also a project called rincanter that is supposed to bring R functionality to Clojure, building on the Java Rserve client. If it worked I would be happy to use it. Unfortunately rincanter does not work right now.

An Example

It's easy enough to get it working in Clojure. Here's what I did, along with a short example code.

First, I installed Eclipse. I then installed counterclockwise (no idea why they chose that name). I went through the tutorial instructions to set up a working project. All of my previous Clojure programs were REPL, so I just went through the experience of setting up the Eclipse environment, and can happily say that it is easy to do. I then downloaded Rserve.jar and Rengine.jar from rforge.

After starting my new project, I told Eclipse about Rserve.jar and Rengine.jar by right-clicking on "Referenced Libraries" --> "Build Path" --> "Configure Build Path..." --> "Add External JARs...".

Here's a sample program to demonstrate the calling syntax. You can convert the other parts of the Rserve Java examples into Clojure using the same ideas.

(import '(org.rosuda.REngine))
(import '(org.rosuda.REngine.Rserve RConnection))

(def c (new RConnection))
(def d (. c eval "rnorm(10)"))
(def e (. d asDoubles))
(println (first e))
(println (rest e))

This was done using Clojure 1.2 and Eclipse 3.5.2 on Linux Mint 11.

Tuesday, December 21, 2010

Starting R to run Rmpi jobs

I always forget the proper command to start R to run Rmpi jobs. Here it is:

mpirun -np 1 --hostfile [name of hosts file] R --no-save

The thing that always throws me is that I use -np 2 or whatever number of processors. I forget that you need to start one instance of R and then from within that one instance you can access however many processors you have in your hosts file.

Note: You get the same thing by using "orterun" rather than "mpirun" in the above command, but I like mpirun because it is obvious what it is doing.

Monday, October 04, 2010

Slow PDF printing in Linux

I've struggled with slow printing of PDF files in Linux recently. It's only been in recent months though. I do not recall having this problem before.

I finally realized that it was only a problem to print PDF files that are scanned images. The solution was buried in this thread:

http://ubuntuforums.org/archive/index.php/t-1073942.html

I set up a second printer. It is parallel, so (in Gnome) I went to System > Administration > Add

I selected "Other". I needed a Device URI. A google search suggested for parallel printers that parallel:/dev/lp0 might work. I tried it, used "Generic" for the manufacturer, and chose PCL 5e as the driver.

Works great. All PDF images print fast if I remember to choose the Generic printer rather than the HP.

Tuesday, August 03, 2010

Cuda on Slackware 13.1

This was much easier than I expected. Note that I'm running Slackware 13.1 32-bit.

Step 1: Install the latest NVidia driver (256.44 in my case). You can't use the SlackBuild from slackbuilds.org. The latest NVidia packages are quite different from 195.*. I uninstalled the existing driver (that I had earlier installed from slackbuilds.org), downloaded the latest NVidia driver, and installed it according to the instructions.

Step 2: Install the CUDA toolkit for Fedora 12. This amounted to downloading the file and running it. I accepted all the defaults.

Step 3: Install the CUDA SDK. Again, I downloaded the file, ran it, and accepted the defaults.

Step 4: Change the paths according to the CUDA instructions.

Done! This was so much easier than Ubuntu, Mint, Debian, and others. I didn't expect it to work by just downloading a few files and running them. I'm certainly not complaining. I ran make for the examples, they all compiled and ran perfectly.

Wednesday, July 28, 2010

Gretl on Slackware 13.1

I recently built gretl 1.9.1 for Slackware 13.1. I needed to install two packages first, fftw and gdk-pixbuf. Both are available from slackbuilds.org.

LAPACK and BLAS are also necessary. I prefer to use the ACML because it is a lot faster than an unoptimized BLAS. I created symbolic links to make libacml.a appear to be both libblas.a and liblapack.a in /usr/lib:

ln -s /opt/acml4.4.0/gfortran32/lib/libacml.a /usr/local/lib/libblas.a
ln -s /opt/acml4.4.0/gfortran32/lib/libacml.a /usr/local/lib/liblapack.a

Here's the SlackBuild. It built a package and upon installation it runs correctly.
#!/bin/sh
# Heavily based on the Slackware 12.2 SlackBuild
# http://gretl.sourceforge.net/gretl_italiano.html

NAME=gretl
VERSION=1.9.1
ARCH=${ARCH:-i486}
BUILD=1mf
CWD=`pwd`

if ["$TMP" = ""]; then
 TMP=/tmp
fi

PKG=$TMP/package-$NAME

if [ "$ARCH" = "i486" ]; then
  SLKCFLAGS="-O2 -march=i486 -mtune=i686"
elif [ "$ARCH" = "i686" ]; then
  SLKCFLAGS="-O2"
elif [ "$ARCH" = "x86_64" ]; then
  SLKCFLAGS="-O2"
fi

if [ ! -d $TMP ]; then
 mkdir -p $TMP
fi
if [ ! -d $PKG ]; then
 mkdir -p $PKG
fi

mkdir -p $PKG/usr

cd $TMP

tar xvjf $CWD/$NAME-$VERSION.tar.bz2

cd $NAME-$VERSION

CFLAGS="$SLKCFLAGS" \
./configure --prefix=/usr --build=i486-slackware-linux --with-lapack-prefix=/usr

make
make prefix=$PKG/usr install

mkdir -p $PKG/usr/doc/$NAME-$VERSION
cp -a ChangeLog COPYING EXTENDING INSTALL README README.audio README.win32 TODO $PKG/usr/doc/$NAME-$VERSION
mkdir -p $PKG/install
mkdir -p $PKG/usr/share/pixmaps
mkdir -p $PKG/usr/share/applications
cat $CWD/slack-desc > $PKG/install/slack-desc
cp $CWD/gretl.png $PKG/usr/share/pixmaps/gretl.png
cat $CWD/Gretl.desktop > $PKG/usr/share/applications/gretl.desktop
cp $CWD/$NAME.SlackBuild $PKG/usr/doc/$NAME-$VERSION/

( cd $PKG
  find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
  find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
)

mv $PKG/usr/share/man $PKG/usr
gzip -9 $PKG/usr/man/*/*
chmod 755 $PKG/usr/bin/*

cd $PKG

chown -R root:root .

requiredbuilder -v -y -s $CWD $PKG

cat $CWD/slack-required > $PKG/install/slack-required
cat $CWD/slack-required > $PKG/usr/doc/$NAME-$VERSION/slack-required

makepkg -l y -c n $CWD/$NAME-$VERSION-$ARCH-$BUILD.tgz

if [ "$1" = "--cleanup" ]; then
 rm -rf $TMP/$NAME-$VERSION
 rm -rf $PKG
fi
License note: This is a modified version of a SlackBuild downloaded from slacky.eu a long time ago. It is in the public domain, as I understand it, and my modifications are public domain as well.

Monday, January 18, 2010

Simple clamav tutorial

To install clamav on Slackware 13, I used the SlackBuilds.org SlackBuild.

To update the database:

freshclam

To scan all files in directory dir:

cd /dir
clamscan -r -i

This will scan all files in that directory and all subdirectories, and will only print out the names of infected files.

Restart networking in Slackware 13

Couldn't easily find it, so here it is. As root, run

/etc/rc.d/rc.inet1 eth0_restart

You may have to change the "eth0" if your interface goes by a different name.

Monday, September 28, 2009

gretl on Slackware 13.0

I had some difficulties getting gretl 1.8.4 installed on Slackware 13. Here is what I did.

The problem was with the LAPACK libraries. After a lot of digging, I found that the problem was twofold: (a) I had built my own LAPACK library using the SlackBuild from slackbuilds.org, and gretl wasn't looking for the library in the right directory. (b) It wasn't finding libblas.a. (You can open config.log for gretl in the /tmp/gretl-1.8.4 directory to find the configuration problems.)

To handle the first problem, I had to edit the SlackBuild script to add the configure option --with-lapack-prefix=/usr to tell it to look for liblapack.a in /usr/lib. It will look in the /lib subdirectory of the directory you give, so if you pass the option --with-lapack-prefix=/usr/lib, it will look in /usr/lib/lib and quit with an error.

The second problem was caused by the fact that I had built my LAPACK library against ACML, AMD's optimized math libraries. I created a symbolic link of that library into /usr/local/lib. (There are probably alternatives, but I know it will be found if I put it there.) I had installed ACML in the default directory, so the symbolic link I created was

ln -s /opt/acml4.3.0/gfortran32/lib/libacml.a /usr/local/lib/libblas.a

The gretl SlackBuild built a package that installed properly and ran, but gave an error when I attempted to plot a graph. I don't know what the error was but it was fixed when I ran gretl from a Slackware 12.1 installation. After that, gretl plotting worked.

Tuesday, September 01, 2009

Slackware 13 Automount USB Drive

Scratch this: It worked once and now it doesn't work upon reboot!!!
This is so frustrating I may just give up on Slackware altogether.

With Slackware 12.1 and 12.2, USB drives automounted out of the box. Not so for my Slackware 13 installation. The obvious thing was to check which groups I was already a member of, using the command

groups

in Konsole. It said I was a member of cdrom, but not plugdev, so I used the command

gpasswd -a [user] plugdev

and logged out. I logged in again, double checked that I was in plugdev, and tested. Nothing. I didn't know what to do and Google didn't help. I added myself to a bunch of other groups, but none worked.

Some more extensive searching took me here:

http://www.linuxquestions.org/questions/slackware-14/12.0-and-hal-read-this-566862/

Long story short, I had to open the file /etc/login.defs as root and add plugdev to the line referenced in that post. I logged out and back in, and then I could automount USB drives.

Tuesday, July 14, 2009

Multivariate normal distribution in Python

I could not find a Python function to evaluate the multivariate normal distribution in Python. Here's one that gives equivalent results to the dmvnorm function in the mvtnorm package for R. It's something that works. I've not had time or need yet to fix it up.

b: A vector
mean: The mean of the elements in b (same dimensions as b)
cov: The covariance matrix of the multivariate normal distribution

License: GPL version 2
http://www.gnu.org/licenses/gpl-2.0.html
k = b.shape[0]
part1 = numpy.exp(-0.5*k*numpy.log(2*numpy.pi))
part2 = numpy.power(numpy.linalg.det(cov),-0.5)
dev = b-mean
part3 = numpy.exp(-0.5*numpy.dot(numpy.dot(dev.transpose(),numpy.linalg.inv(cov)),dev))
dmvnorm = part1*part2*part3

Wednesday, July 01, 2009

Static IP address information in Slackware 12

To find information about a static IP address in Slackware 12:

1. Open /etc/rc.d/rc.inet1.conf
Find the IP address, gateway, and netmask.

2. Open /etc/resolv.conf
There will be information about the nameserver(s).

You can restart the network using the command
/etc/rc.d/rc.inet1 restart

This came in helpful, because I wanted to set up my static IP in Vector 6.0, needed to pull the information from my Slackware installation, but was unable to reboot my computer. I was able to enter the information using Netconf in the Control Center but did not have a way to restart the network.