I’ve been thinking lately about what makes good engineering. Actually, let’s be honest. As engineers, that’s not what we focus on. We get hung up on the failures—which always seem to outnumber the successes. Of course once you get out into the real world of programming for a livelihood, success is measured in terms of project completion and client satisfaction, but as easy as it is to put your head down and focus on the next ticket, that doesn’t absolve us of having to master our craft, to learn new things and better understand and utilize the old.
But I won’t try to say anything intelligent on good engineering. Instead, I’ll try to communicate the regrets that surfaced last weekend when I plugged in my old laptop and sifted through a decade-old folder called projects
.
The first thing I went looking for was one of my first major programming efforts, the result of the reason I started programming. A pretty long time ago, I came across a paper called Visual Simulation of Smoke by some pretty impressive people at Stanford. Research like this is what makes those Pixar movies possible. That you can simulate such complex dynamics from a set of simple principles fascinated me. This was about halfway through high school, so I decided to learn vector calculus and linear algebra just to make this happen.
It was a long, slow process. Timestamps indicate that I finally got something working five years later in about 2005 (Junior year of college). Frankly, I still feel pretty good about the result!
In hindsight, this shouldn’t really amount to more than a week or two of work, but learning is the process of making hindsight obvious. One way or another though, I had something special: knowledge. And experience. At this point, I had three options:
Given my experience at the time, it’s hard to say I chose the wrong option, but let’s be clear: I chose (3), and I didn’t just slowly wade into it. I sought out complexity. I enhanced the complexity. No, seriously. I took the basic method and made it as absolutely opaque as I could. I wanted to enter it into the International Obfuscated C Code Contest:
#include<X11/Xlib.h>
#include<math.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#define R(x)(x)/2
#define r(w)_(w,0)
#define V(w)(w)*(w)
#define _(w,Z)u[w][p+Z]
#define p a+l*b+V(l+1)*c+b
#define o(x,j,S)U(x,j,l-j,S)
#define L(w,Z,z)(1-z)*(w)+z*(Z)
#define M(Z,j)(Z>j?j:(Z<0?0:Z))
#define T(x,j)o(c,x,o(b,x,o(a,x,j)))
#define U(w,Z,j,x)for(w=Z;w<j;w++){x}
#define P(j)U(d,0,3,r(9)=_(9,j O[2-d]);h=a;a=b;b=c;c=h;)
#define I m=V(l+1);Q=M(a-F[0]-(f=(int)(a-F[0])),l);E=M(\
b-F[1]-(g=(int)(b-F[1])),l);W=u[d]+f+O[1]*g+m*(e=(int)(\
c-F[2]));r(d+4)=L(L(L(W[0],W[1],Q),L(W[l+1],W[l+2],Q),E\
),L(L(W[m],W[m+1],Q),L(W[m+l+1],W[m+l+2],Q),E),M(c-F[2]-e,l));
#define K(j)F[j]=R(R(r(j)+_(j,O[d])+_(j,O[j])+_(j,O[d]+O[j])));/*F(){..*4\
7,f-e-e.d/c/c0e.d/c0b0b("(b(#'b($&b($&b(%%b(&$b('#b(("_.d.d.d.d.d.d.HUH?*/
int a,b,c,d,e,f,g,h,i,j,k=1,l,m,Y;double Q,E,*u[012],F[3],*W;char*X,t[99];
int main(int S,char**v){Y=**++v-48;l=atoi(*(v-2+S));Display*q=XOpenDisplay
(0);Window H=RootWindow(q,0);if(S==02)l=(b=getchar())==9?80:b,S-=b==9;if(S
!=2||b==9)putchar(l);GC G=XCreateGC(q,H,0,0);int O[3]={1,l+1,V(l+1)};U(a,0
,10,u[a]=calloc(O[1]*V(l+1),8);)H=XCreateSimpleWindow(q,H,0,0,l*Y,l*Y,0,0,
0);if(S-1){T(0,if(V(b-2)+V(c-R(l))+V(a-R(l))<V(l/10)){r(3)=r(7)=0.02;r(1)=
7;})}else{U(e,0,22,gets(t);)X=t;while(k<=1948){S=!S;U(m,0,*X-33,U(e,044,44
,j=k%80+(l/2-k/80)*O[1]-(p)+e*V(l+1);_(7,j)=_(3,j)=S*0.1;)k++;)X++;}T(0,if
(a<40&&(Q=r(3))){a=80-a;r(3)=Q;a=80-a;})S=1;}XMapWindow(q,H);while(G){U(a,
0,l,U(b,0,l,if(S-2){Q=0;U(c,0,l,E=0;f=a;g=b;e=c;while(f&&g-l&&e-l){E+=_(03
,f--+g++*O[1]-(p)+(e+=S==1)*V(l+1));}Q+=r(3)*exp(-E*0.97e2);)e=(M(Q*015410
,0377));putchar(e);}else{e=getchar();}XSetForeground(q,G,e|e<<8|e<<020|e<<
24);U(f,0,Y,U(g,0,Y,XDrawPoint(q,H,G,a*Y+f,(l-b-1)*Y+g);))))if(S-2){i=1,j=
0,k=2;T(0,if(b>2)r(1)+=(r(3)+_(3,l+1))*3.5/(1+4*(S==1));if(b<3){d=b;b=l-2+
(d==1);r(d)=_(d,-l-1);b=d;})U(d,0,3,h=k;k=j;j=i;i=h;U(c,1,l-(k!=2),U(b,1,l
-(j!=2),U(a,1,l-(i!=2),F[d]=r(d);K(j)K(i)I))))T(1,U(d,0,3,F[d]=R(r(d)+_(d,
O[d]));)I)T(0,r(8)=0;U(d,0,3,r(8)+=_(4+d,O[d])-r(4+d);))f=80;while(f--){U(
a,0,l,U(b,0,l,c=0;P()c=l-1;P(-)))T(1,Q=-r(8);U(d,0,3,Q+=_(9,O[d])+_(9,-O[d
]);)r(9)+=0117*(Q/6-r(9))/0620;)}T(1,U(d,0,3,if(a)r(d)=r(d+4)-r(9)+_(011,-
O[d]);))W=u[3],u[3]=u[7],u[7]=W;}if(S-2)putchar(05);else{if(getchar()-05){
rewind(stdin);getchar();}}usleep(9<<9);}}
This has basically all the features of the video above, except it’s dramatically less useful. I even RLE-encoded the University of Michigan ‘M’ on line 22 and a small part of line 21. It has a X-Windows interface. It doesn’t run correctly unless line 1 starts with a tab.
So am I proud of this code? Yeah, a little. (It’s on github by the way.) But that’s vastly outweighed by the regret I have over not having used this period of my life more effectively. It’s likely I may never again have the combination of time, motivation, and inspiration that it takes to dive so deep into this particular confluence of math, science, and programming.
Actually, I went a bit farther. The next stop on this journey through my time capsule was into the pejoratively named field of Colorful Fluid Dynamics (CFD) (not to be confused with the more useful field of Computational Fluid Dynamics). Colorful Fluid Dynamics is what you get when you leave behind rigor and accuracy and just try to make pretty pictures.
In 2006, I got my Incomplete LU-Preconditioned Bi-Conjugate Gradient Stabilized (ILU-Preconditioned BiCG-Stab) solver working and used it to solve Laplace’s equation (think: stretched membrane) on a two-dimensional finite volume grid. I’m pretty certain it remains the most complicated thing I’ve ever programmed successfully, but by the time I finally got it working, I was so exhausted and burned out on my search for complexity that the rest of my career in Aerospace Engineering was really just a slow coming-to-terms with the fact that I no longer wanted anything to do with it.
I found the complexity I was looking for, but it didn’t have the meaning I’d hoped for.
I’m not trying to bash all my old projects. I learned a lot. I made some things I’m proud of. But for such a large amount of effort, there are so many ways I could’ve put this effort and energy to better use. So has anything changed? I’d definitely say so—at least I like to think I’m finally failing less—but for someone who codes full-time now, it’s hard to look at my github page and convince myself that I’m actually doing a better job of integrating meaningfully into a larger community of developers. Of course to be frank, that’s not the goal I’m after anyway. Tools are fun to use, learn, and create, but they’re not inherently meaningful. They are means to an end. So my real goal?
And frankly, I think I’ve been doing a pretty poor job. But I’m trying real hard.