They're extremely useful for 3D graphics and signal processing and can speed those up quite a bit. I'd still rather see some dedicated signal processors on add-on cards, but that would cause a whole lot of new bus traffic.
Anyway all those software synthesizers and cool multimedia stuff can really benefit from floating point SIMD, since it can basically speed up common floating point operations by 200-300%. e.g. digital filters usually mostly use multiply and add and that's what SIMD speeds up. SSE2 seems to do to double floats the same that SSE did to single floats.
Both mipmaps and ripmaps are used to counter aliasing artifacts in texture mapping. The mipmap contains all the filtered images that are 1/4 size of the original (decimate by 2 in x and y recursively) and the ripmap contains all the combinations obtained by halving the height or width of the bitmap (decimate by 2 in x or y recursively). Needless to say the ripmap produces a better result visually at the expense of some extra memory.
A functional language or something like parlog (parallel prolog) might do the trick. Parallelism should happend automagically, but with today's most used languages (C/C++/Java) it ain't happenin'. It's all manual and quite error-prone
(at least if you want it fine-grained).
Furthermore existing software won't benefit from multiple processors... and the existing compiler technology doesn't know how to optimize for multiple CPUs. Making applications multi-threaded can help, but a far better solution imo would be to have the compiler optimize for multiple processors and have fine-grained parallelism.
Also note that today's processors already have some built-in parallelism in the guise of MMX/SSE/3DNow!-instructions...
I have an Intense3d Wildcat 4000 card installed in my workstation (I'm doing Virtual Reality research). It came shipped with a sheet detailing export restrictions; the reason was most likely the 3 GFLOPS geometry accelerator (full lenght AGP card, full of heatsinks...). BTW, Intense3D is also working on Xfree86 4.0 drivers and their cards' OpenGL support is quite nice... Say OpenGL 1.2 with ARB imaging extensions totally hardware accelerated + 3.2 GFLOPS geometry acceleration + FSAA etc. Damn expensive though....
The export controls are hilarious. I was totally ROTFLMAO, when upgraded my Intergraph workstation at work with an Intense3D WildCat 4000 graphics card. The card came with a sheet detailing export restrictions. The card was probably restricted because it has a 3 GFLOPS geometry accelerator;) How long until you can't export the newest nVidia offering to China & co. ? M$ might lose some lucrative markets because of export restrictions...
Intentional programming: Building your own abstractions that will get translated into efficient code.
Generative programming: Write code that will write code.
Hmm. Isn't this lisp ?
Seriously... it will be packaged differently, but they have a lot in common... It is quite common practice in lisp to build abstractions with macros that will make it easier to program and usually the macros translate (codewalking, rewriting, reordering, generating extra code) the code into a more efficient form (the syntax tree is minimal, it's all lists and they're easy to manipulate). For instance, look up the loop-macro or the series-package.
No Required type-declarations: most errors will be caught when calling functions with type declarations (the built-in ones) anyway when not using unsafely optimized code.
ANSI standard issues: IMO most notably no standard
multiprocessing (threading) support, no standard GUI (there's CLIM, not on free CL's), no standard support for hard real-time programming (needs realtime GC), no standard networking... but should all of these really be a part of the language standard ? Maybe not, since it is quite big already.
Pointers: Without pointers the compiler can optimize certain things, because the program can't poke around memory. For instance, caching a variable's value in a register in C is dangerous, since it maybe modified through a pointer. Also you get pointers with the FFI (at least in CMUCL).
Personally I like Common Lisp. It is completely different from the other languages I've used. One of the most interesting things is that it encourages practices that the profs usually tell people to avoid like self-modifying code and bottom-up programming.
Having the compiler available at run-time makes for some very nice opportunities for optimization and the macro system allows for overhead-free abstractions. Using a suitable library can seem like moving from C to C++ in terms of added functionality to the language. For instance CLOS, the Common Lisp Object System was written in Common Lisp on top of Common Lisp.
This ability to extend the language is probably something we'll also see in new languages, because building abstractions to suit the problem might just be better than trying to fit the problem to a certain set of preselected abstractions.
BTW, CMUCL is just fine. I use it myself and I don't know of better free lisps (clisp - no native compiler, gcl - poor standards support, sbcl - fork of CMUCL, should be as good). It includes a good optimizing native code compiler. Note that CMUCL is freeware (as in totally free for any purpose, with no obligations), not GPL. You can get it at www.cons.org.
I think this is where design patterns really shine, and I hope pattern libraries become more standard across languages.
I don't think this will happen. Well, maybe it will in the context of mainstream OO (static language, virtual methods message passing style, inheritance, i.e. C++-type languages), but not generally anyway... Most of the patterns in the GoF book are about getting over the limitations of an inherently static language like C++. The problems the patterns solve might simply not exist in other languages.
You're absolutely right. I'd been programming for about 5 years (just hobbies, like demos) before I went to study CS. The studies make so much more sense if you're fluent in programming before you start CS. Most people seem to struggle with basic programming skills throughout the CS program, which is why the program may seem hard. If you don't know programming before you take CS, you're going to have to put a lot of time on learning it and learning it fast... BTW, people who think they know it all and haven't done CS usually have a narrower vision than those that have done CS (e.g. try doing 3D graphics, AI, or signal processing). Naturally you can learn what there is to a CS program by reading books and training, but don't think you can learn it all by just programming. No one is that smart.
DISCLAIMER: I got my Master's in CS a year ago. Naturally I would side with someone who thinks that CS is useful.
The amount of entropy depends on the statistical model used. Given a statistical model you can calculate the entropy wrt that specific model. That entropy is the best a lossless compression method can do with that model. As entropy can be coded almost optimally using arithmetic coding, the real problem IMO is finding practical statistical models that work well with pictures. For lossy compression you're trying to optimize bitrate vs. distortion and good distortion measures are hard to come up with; for instance mp3 works because of a good psychoacoustic model.
I have Watcom C++ v11.0b and the scope of for loop variables is implemented as described in the C++ ARM (i.e. for loop variables are visible outside the loop). I've also had a number of problems with namespaces causing faulty code generation and internal compiler errors. It also doesn't ship with the STL, although it works (a special version is needed though). Besides Watcom C/C++ is not developed anymore and may be opensourced (this is what I got from a developer when they said they were discontinuing WC++). It's a solid compiler though, very quick compilation compared to GCC. (Can't really say about VC++).
IMO, you can get pretty far with opaque pointers (also called handles) and modularized object based designs (usually no inheritance, although you can use pointer tricks). This way you can also implement your own kind of object systems (e.g. prototype-based OOP). For dynamism you'll still use function pointers, but then again a vtable is a table of function pointers and in C++ each object (that has virtuals) contains a pointer to its vtable where the actual functions-pointers for the virtual functions are. Note that using C it is easier to mix libraries from different vendors since C has a binary standard whereas C++ classes don't mix between compilers. If you must do that then you have to use plain C to call the object's methods (basically trampolines) and opaque pointers and then wrap that in a class in the other compiler.
As one of those dreaded TAs (actually research and little teaching on the side, I've only written a few small ~20 KLOC programs by myself using C++ and I also have my master's), I have to agree that LISP would be a better choice than C++, but then again which LISP ?
The Scheme standard library is way too small for the average student to do anyhing useful other than play around (they need to be able to do real useful programs IMO) and Common LISP is about as hard as C++, although it's a lot safer with the GC and strong typing (I'm not going to argue on this: CL is strongly (and dynamically) typed, because there is no possiblity of an undetected typing error at the maximum safety level). CL and Scheme both have free implementations with good native compilers (e.g. MIT-Scheme and CMUCL).
Java is probably a good option, because of the extensive libraries, typing and GC. However, I consider the language inelegant. Java is also quite detached from the iron (running on a VM) so traditional optimization tricks from C/C++ don't necessarily work well. Everyone should learn assembler and write a few asm/C-hybrid programs just so they can see what is going on. Assembler gives a lot of insight to programming.
NP complete problems are solvable in non-polynomial time hence the NP designation.
This is a common misconception. NP stands for non-deterministic polynomial. It it is possible to solve a NP problem with a non-deterministic algorithm in polynomial time, but there is no known polynomial time deterministic algorithm to solve them. Proving whether deterministic polynomial (P) is equal to non-deterministic polynomial (NP) or not is probably worth a Nobel prize.
What patent ? I haven't heard about that. Bump mapping as a technique is old (way older than Bitboys). Foley et al. from 1991 (IIRC) has it, haven't checked the older book. When OpenGL is a question of getting a standardized bump-mapping extension. DirectX just adds new functions and changes the version number, whereas OpenGL evolves with cleanly bundled extensions that are separate from it.
2) the (unnamed) adaptive list search algorith where you move up an item you've found in a list by one slot if it's the one you've searched for.
This is the transpose heuristic for linked lists. Some others are move-to-front and frequency-count, which are pretty self-explanatory. Another nice adaptive data structure is a splay tree by Sleator and Tarjan. It's a binary tree that changes shape on operations, so it's basically self-balancing. There are also some nice adaptive heaps, but really there are too many different data structures to keep up with;)
It would be interesting to know where almost sorted lists occur in real life.
Well, if you've once sorted a list of objects according to a certain criterion and they all change a bit maybe then ? For instance, depth sorting polygons in a game might qualify for this.
You're right, performing fast convolution is faster when the filter is long enough, but your n is a bit off. Longer filters are required for steeper frequency responses. The fast convolution approach gets faster than FIRs around 40 taps (n = 40, for audio). This would also depend on the FFT algorithm used; there are many, like radix-2, radix-4, different split-radix algorithms.
Shannon outlined RLE and Shannon-Fano-coding (a kind of top-down Huffman, less efficient, though) in his "Mathematical Theory of Communication", which predates Huffman coding. Also there are a lot of methods that aren't at all like Huffman coding (aside from the fact that they compress data). If there would be data compression then it would be arithmetic coding (quite new), which is about as near optimal as you can get (optimal, if your numerical precision is infinite).
Re:Common Problem in Technical Fields
on
Too Old To Code?
·
· Score: 1
What you were taught starts going obsolete as soon as you graduate, so many employers look for young blood with the latest knowledge.
Unless you study theoretical CS and applied and pure math, maybe some statistics and physics as well, in which case it doesn't. This just goes to show that it doesn't pay off to learn the hype, but students should focus on the bits that last. Personally I couldn't care less about the "IT jobs", I'd be bored to death within 6 months. So if you choose to study CS, you should focus on the hard science part of CS.
Something like that, I guess. One of the key factors IMO is the way information is presented to the user. For instance when the user works with a database, the data can be input using regular dialogs or the user can interact with the conceptual schema of the database.
Better and more innovative information presentation could make a lot of programs more effective to use. I'm talking about for instance information presented in interactive diagrams (like graphs, trees) that can be manipulated.
Much as I hate to admit this, Microsoft revolutionised GUI with the "Start" button and taskbar.
One the basic things about the usability of menus is that multilevel cascading menus have poor usability. They may work for beginners since they are possibly intuitive, but that's about it. The taskbar works, but there are probably better solutions.
I'd like to see more apps that let the user work with the document and not fill the screen with all kinds of toolbars, wizards, dancing paperclips and whatnot. More visible tools does not mean better usability. Simple direct manipulation interfaces are often better. There's a distinction between usability for novices and usability for experienced users. Designing for the latter usually means that the former is not as good and viceversa, so making the most stupid and simple UI is not the best solution.
Let's face it, the human ear is only 2 channels 20 KHz resolution, maybe 80 db usable dynamic range (for the purposes of computer gems, etc. Don't want or need 100 db sound effects!). Even with multichannel sound though, it isn't a lot of data.
Okay let's face it. Realistic environmental audio needs a lot more processing power than a modern PC has. Reverberation and localization is computationally expensive. I'd rather see a standard DSP-card emerge for these problems.
More audio bandwidth is also needed for realtime software synthesizers (prediction: non-programmable synths will be history and most synths will run on general purpose computers) where you need to have very low latency (a few ms to respond to a key press to be playable) and very predictable scheduling. I fear that the new audio libs will be directed towards games and not professional audio, which is what I'd rather see on Linux. BTW, I hear Linux audio currently has very low and predictable latency (beats windows hands down) with low-latency kernel mods; only the apps are missing. I'm working on one, when not working at work...
It is also your attitude towards the degree that matters. You can think for yourself and look around. Find that which is cutting edge and focus on that. Getting a CS degree should also mean that you have to think for yourself and do research on your own (at least that is why you write a thesis in the end).
No-one is asking anyone to confine themselves to the courses offered. We can for instance get cu:s for different subjects by reading books and taking exams, because there isn't enough interest in certain fields to warrant a lectured course. I'm sure many professors would gladly help people with their interests as long as the interests are scientifically oriented.
BTW, relevance is highly subjective. I for one consider theory of computation, analysis of algorithms, compilers, formal methods, and generally anything else in the hard core of CS highly relevant and most of the new hyped "innovations" (Java, etc.) less relevant. Also I'd really like to see a lot more of dsp, soft computing, and numerical methods in the CS curriculum as well as high level programming languages and pure math. OTOH, I work as a researcher, which is not everyone's cup of tea. But I know for a fact that you can get very interesting jobs in the industry with a skill set in theoretical CS, but most people won't go far enough, since it is hard and requires a lot of work. It is far easier to learn a programming language and take a job in programming.
They're extremely useful for 3D graphics and signal processing and can speed those up quite a bit. I'd still rather see some dedicated signal processors on add-on cards, but that would cause a whole lot of new bus traffic.
Anyway all those software synthesizers and cool multimedia stuff can really benefit from floating point SIMD, since it can basically speed up common floating point operations by 200-300%. e.g. digital filters usually mostly use multiply and add and that's what SIMD speeds up. SSE2 seems to do to double floats the same that SSE did to single floats.
Both mipmaps and ripmaps are used to counter aliasing artifacts in texture mapping. The mipmap contains all the filtered images that are 1/4 size of the original (decimate by 2 in x and y recursively) and the ripmap contains all the combinations obtained by halving the height or width of the bitmap (decimate by 2 in x or y recursively). Needless to say the ripmap produces a better result visually at the expense of some extra memory.
A functional language or something like parlog (parallel prolog) might do the trick. Parallelism should happend automagically, but with today's most used languages (C/C++/Java) it ain't happenin'. It's all manual and quite error-prone (at least if you want it fine-grained).
Furthermore existing software won't benefit from multiple processors... and the existing compiler technology doesn't know how to optimize for multiple CPUs. Making applications multi-threaded can help, but a far better solution imo would be to have the compiler optimize for multiple processors and have fine-grained parallelism.
Also note that today's processors already have some built-in parallelism in the guise of MMX/SSE/3DNow!-instructions...
I have an Intense3d Wildcat 4000 card installed in my workstation (I'm doing Virtual Reality research). It came shipped with a sheet detailing export restrictions; the reason was most likely the 3 GFLOPS geometry accelerator (full lenght AGP card, full of heatsinks...). BTW, Intense3D is also working on Xfree86 4.0 drivers and their cards' OpenGL support is quite nice... Say OpenGL 1.2 with ARB imaging extensions totally hardware accelerated + 3.2 GFLOPS geometry acceleration + FSAA etc. Damn expensive though....
The export controls are hilarious. I was totally ROTFLMAO, when upgraded my Intergraph workstation at work with an Intense3D WildCat 4000 graphics card. The card came with a sheet detailing export restrictions. The card was probably restricted because it has a 3 GFLOPS geometry accelerator ;) How long until you can't export the newest nVidia offering to China & co. ? M$ might lose some lucrative markets because of export restrictions...
Cheers,Let's see:
Intentional programming: Building your own abstractions that will get translated into efficient code.
Generative programming: Write code that will write code.
Hmm. Isn't this lisp ?
Seriously... it will be packaged differently, but they have a lot in common... It is quite common practice in lisp to build abstractions with macros that will make it easier to program and usually the macros translate (codewalking, rewriting, reordering, generating extra code) the code into a more efficient form (the syntax tree is minimal, it's all lists and they're easy to manipulate). For instance, look up the loop-macro or the series-package.
Cheers,
Quick answer:
No Required type-declarations: most errors will be caught when calling functions with type declarations (the built-in ones) anyway when not using unsafely optimized code.
ANSI standard issues: IMO most notably no standard multiprocessing (threading) support, no standard GUI (there's CLIM, not on free CL's), no standard support for hard real-time programming (needs realtime GC), no standard networking... but should all of these really be a part of the language standard ? Maybe not, since it is quite big already.
Pointers: Without pointers the compiler can optimize certain things, because the program can't poke around memory. For instance, caching a variable's value in a register in C is dangerous, since it maybe modified through a pointer. Also you get pointers with the FFI (at least in CMUCL).
Personally I like Common Lisp. It is completely different from the other languages I've used. One of the most interesting things is that it encourages practices that the profs usually tell people to avoid like self-modifying code and bottom-up programming.
Having the compiler available at run-time makes for some very nice opportunities for optimization and the macro system allows for overhead-free abstractions. Using a suitable library can seem like moving from C to C++ in terms of added functionality to the language. For instance CLOS, the Common Lisp Object System was written in Common Lisp on top of Common Lisp.
This ability to extend the language is probably something we'll also see in new languages, because building abstractions to suit the problem might just be better than trying to fit the problem to a certain set of preselected abstractions.
BTW, CMUCL is just fine. I use it myself and I don't know of better free lisps (clisp - no native compiler, gcl - poor standards support, sbcl - fork of CMUCL, should be as good). It includes a good optimizing native code compiler. Note that CMUCL is freeware (as in totally free for any purpose, with no obligations), not GPL. You can get it at www.cons.org.
I think this is where design patterns really shine, and I hope pattern libraries become more standard across languages.
I don't think this will happen. Well, maybe it will in the context of mainstream OO (static language, virtual methods message passing style, inheritance, i.e. C++-type languages), but not generally anyway... Most of the patterns in the GoF book are about getting over the limitations of an inherently static language like C++. The problems the patterns solve might simply not exist in other languages.
You're absolutely right. I'd been programming for about 5 years (just hobbies, like demos) before I went to study CS. The studies make so much more sense if you're fluent in programming before you start CS. Most people seem to struggle with basic programming skills throughout the CS program, which is why the program may seem hard. If you don't know programming before you take CS, you're going to have to put a lot of time on learning it and learning it fast... BTW, people who think they know it all and haven't done CS usually have a narrower vision than those that have done CS (e.g. try doing 3D graphics, AI, or signal processing). Naturally you can learn what there is to a CS program by reading books and training, but don't think you can learn it all by just programming. No one is that smart.
DISCLAIMER: I got my Master's in CS a year ago. Naturally I would side with someone who thinks that CS is useful.
The amount of entropy depends on the statistical model used. Given a statistical model you can calculate the entropy wrt that specific model. That entropy is the best a lossless compression method can do with that model. As entropy can be coded almost optimally using arithmetic coding, the real problem IMO is finding practical statistical models that work well with pictures. For lossy compression you're trying to optimize bitrate vs. distortion and good distortion measures are hard to come up with; for instance mp3 works because of a good psychoacoustic model.
I have Watcom C++ v11.0b and the scope of for loop variables is implemented as described in the C++ ARM (i.e. for loop variables are visible outside the loop). I've also had a number of problems with namespaces causing faulty code generation and internal compiler errors. It also doesn't ship with the STL, although it works (a special version is needed though). Besides Watcom C/C++ is not developed anymore and may be opensourced (this is what I got from a developer when they said they were discontinuing WC++). It's a solid compiler though, very quick compilation compared to GCC. (Can't really say about VC++).
IMO, you can get pretty far with opaque pointers (also called handles) and modularized object based designs (usually no inheritance, although you can use pointer tricks). This way you can also implement your own kind of object systems (e.g. prototype-based OOP). For dynamism you'll still use function pointers, but then again a vtable is a table of function pointers and in C++ each object (that has virtuals) contains a pointer to its vtable where the actual functions-pointers for the virtual functions are. Note that using C it is easier to mix libraries from different vendors since C has a binary standard whereas C++ classes don't mix between compilers. If you must do that then you have to use plain C to call the object's methods (basically trampolines) and opaque pointers and then wrap that in a class in the other compiler.
As one of those dreaded TAs (actually research and little teaching on the side, I've only written a few small ~20 KLOC programs by myself using C++ and I also have my master's), I have to agree that LISP would be a better choice than C++, but then again which LISP ?
The Scheme standard library is way too small for the average student to do anyhing useful other than play around (they need to be able to do real useful programs IMO) and Common LISP is about as hard as C++, although it's a lot safer with the GC and strong typing (I'm not going to argue on this: CL is strongly (and dynamically) typed, because there is no possiblity of an undetected typing error at the maximum safety level). CL and Scheme both have free implementations with good native compilers (e.g. MIT-Scheme and CMUCL).
Java is probably a good option, because of the extensive libraries, typing and GC. However, I consider the language inelegant. Java is also quite detached from the iron (running on a VM) so traditional optimization tricks from C/C++ don't necessarily work well. Everyone should learn assembler and write a few asm/C-hybrid programs just so they can see what is going on. Assembler gives a lot of insight to programming.
This is a common misconception. NP stands for non-deterministic polynomial. It it is possible to solve a NP problem with a non-deterministic algorithm in polynomial time, but there is no known polynomial time deterministic algorithm to solve them. Proving whether deterministic polynomial (P) is equal to non-deterministic polynomial (NP) or not is probably worth a Nobel prize.
What patent ? I haven't heard about that. Bump mapping as a technique is old (way older than Bitboys). Foley et al. from 1991 (IIRC) has it, haven't checked the older book. When OpenGL is a question of getting a standardized bump-mapping extension. DirectX just adds new functions and changes the version number, whereas OpenGL evolves with cleanly bundled extensions that are separate from it.
This is the transpose heuristic for linked lists. Some others are move-to-front and frequency-count, which are pretty self-explanatory. Another nice adaptive data structure is a splay tree by Sleator and Tarjan. It's a binary tree that changes shape on operations, so it's basically self-balancing. There are also some nice adaptive heaps, but really there are too many different data structures to keep up with ;)
Well, if you've once sorted a list of objects according to a certain criterion and they all change a bit maybe then ? For instance, depth sorting polygons in a game might qualify for this.
You're right, performing fast convolution is faster when the filter is long enough, but your n is a bit off. Longer filters are required for steeper frequency responses. The fast convolution approach gets faster than FIRs around 40 taps (n = 40, for audio). This would also depend on the FFT algorithm used; there are many, like radix-2, radix-4, different split-radix algorithms.
Shannon outlined RLE and Shannon-Fano-coding (a kind of top-down Huffman, less efficient, though) in his "Mathematical Theory of Communication", which predates Huffman coding. Also there are a lot of methods that aren't at all like Huffman coding (aside from the fact that they compress data). If there would be data compression then it would be arithmetic coding (quite new), which is about as near optimal as you can get (optimal, if your numerical precision is infinite).
Unless you study theoretical CS and applied and pure math, maybe some statistics and physics as well, in which case it doesn't. This just goes to show that it doesn't pay off to learn the hype, but students should focus on the bits that last. Personally I couldn't care less about the "IT jobs", I'd be bored to death within 6 months. So if you choose to study CS, you should focus on the hard science part of CS.
Something like that, I guess. One of the key factors IMO is the way information is presented to the user. For instance when the user works with a database, the data can be input using regular dialogs or the user can interact with the conceptual schema of the database.
Better and more innovative information presentation could make a lot of programs more effective to use. I'm talking about for instance information presented in interactive diagrams (like graphs, trees) that can be manipulated.
One the basic things about the usability of menus is that multilevel cascading menus have poor usability. They may work for beginners since they are possibly intuitive, but that's about it. The taskbar works, but there are probably better solutions.
I'd like to see more apps that let the user work with the document and not fill the screen with all kinds of toolbars, wizards, dancing paperclips and whatnot. More visible tools does not mean better usability. Simple direct manipulation interfaces are often better. There's a distinction between usability for novices and usability for experienced users. Designing for the latter usually means that the former is not as good and viceversa, so making the most stupid and simple UI is not the best solution.
Okay let's face it. Realistic environmental audio needs a lot more processing power than a modern PC has. Reverberation and localization is computationally expensive. I'd rather see a standard DSP-card emerge for these problems.
More audio bandwidth is also needed for realtime software synthesizers (prediction: non-programmable synths will be history and most synths will run on general purpose computers) where you need to have very low latency (a few ms to respond to a key press to be playable) and very predictable scheduling. I fear that the new audio libs will be directed towards games and not professional audio, which is what I'd rather see on Linux. BTW, I hear Linux audio currently has very low and predictable latency (beats windows hands down) with low-latency kernel mods; only the apps are missing. I'm working on one, when not working at work...
It is also your attitude towards the degree that matters. You can think for yourself and look around. Find that which is cutting edge and focus on that. Getting a CS degree should also mean that you have to think for yourself and do research on your own (at least that is why you write a thesis in the end).
No-one is asking anyone to confine themselves to the courses offered. We can for instance get cu:s for different subjects by reading books and taking exams, because there isn't enough interest in certain fields to warrant a lectured course. I'm sure many professors would gladly help people with their interests as long as the interests are scientifically oriented.
BTW, relevance is highly subjective. I for one consider theory of computation, analysis of algorithms, compilers, formal methods, and generally anything else in the hard core of CS highly relevant and most of the new hyped "innovations" (Java, etc.) less relevant. Also I'd really like to see a lot more of dsp, soft computing, and numerical methods in the CS curriculum as well as high level programming languages and pure math. OTOH, I work as a researcher, which is not everyone's cup of tea. But I know for a fact that you can get very interesting jobs in the industry with a skill set in theoretical CS, but most people won't go far enough, since it is hard and requires a lot of work. It is far easier to learn a programming language and take a job in programming.