# uttumuttu

Member

10

122 Neutral

• Rank
Member
1. ## Frame rate independent air friction

It's also possible to combine the linear and the quadratic air friction models, so that dv/dt = -C_1*v^2 - C_2*v Where C_1 and C_2 are non-negative constants. I haven't verified the solution, but I got something like new_v = [C_2 * C_3 * exp(- C_2 * timestep)] / [1 - C_1 * C_3 * exp(- C_2 * timestep)], where C_3 = old_v / [C_2 + C_1 * old_v]
2. ## Applying Conjugate Gradient Method to Fluid Simulations

Actually, you don't need to construct a matrix of any kind. If you're using CG to enforce mass conservation, then "multiplication of A and x" simply means computing the laplacian of x. - Mikko
3. ## [.net] C# arrays: multidimensional versus lexicographic

Thank you for your kind replies, gentlemen! Changing the order indexing for multidimensional arrays from grid[x,y] to grid[y,x] boosted up the code a lot, probably due to better cache coherence. I also tried out jagged arrays, and in fact, they were even faster than the unidimensional lexicographic arrays! @_@ I was quite surprised by this, I thought that the "double indirection" required by jagged arrays was highly detrimental to efficiency. Anyways, thanks guys. - Mikko
4. ## [.net] C# arrays: multidimensional versus lexicographic

Hello, Lately I've been doing some processor intensive physical modeling in C#. Basically, my simulation code needs to store a two-dimensional array. This can be implemented in two ways: 1.) Use true multidimensional arrays, created as double[,] grid = new double[width,height], and indexed as grid[x,y]. 2.) Use unidimensional arrays with lexicographic indexing, created as double[] grid = new double[width*height] and indexed as grid[y*width+x]. Now, according to my profilings (System.Diagnostics.Stopwatch), unidimensional arrays make the code 2-4 times faster than multidimensional arrays! Is it common knowledge that multidimensional arrays are slower than unidimensional ones? How are multidimensional arrays implemented internally? I was quite shocked by the speed difference. Thanks a lot, - Mikko P.S. Yes, I've checked that both types of arrays produce the same results (i.e. my simulator isn't buggy). Also, the profiling is repeated a number of times (to avoid program startup bias etc.), and the random variation is negligible.
5. ## Programming on the job

>The code I write is for Philips Research so all of it is for demo >and research purposes. Therefore re usability is not high on the >list of priorities (code >quality is though). >Polymorphism and inheritance is only used if it makes the code simpler >of better readable. I even avoid inheritance and polymorphism if it >only adds generalism for the sake of anticipating on possible future >features because, hell, in this >research environment it is nearly >impossible to anticipate future features. Oh, I've found inheritance to be most useful in an R&D environment. R&D is all about trying out new stuff and comparing them, and what could be a better tool for doing that than a small interface-based OO framework that allows plugging new stuff in easily? - Mikko
6. ## STRIPS and concurrent actions

It's certainly possible to use STRIPS for multiagent planning. The simplest way is to replace the action space with the cross-product of the action spaces of the individual agents. For example, if a single agent has two actions (move, shoot), then two agents "acting as one" will have four actions ((move,move), (move,shoot), (shoot,move), (shoot,shoot)). Ok, granted, there are some additional complications, such as eliminating illegal actions (e.g. both agents can't move to the same block), but theoretically this kind of system would be capable of doing co-operative planning (e.g. agent one gets the red key while agent two gets the blue key, thereby halving the time to get both keys). - Mikko
7. ## Design Patterns

Some afternotes --------------- Clearly, design patterns are as relevant as ever. The motivation for design patterns can be traced back to a few simple "meta principles": * Automatic dispatch: this is the pinnacle of all object oriented languages. Instead of having huge switch clauses, frameworks based on sound patterns implement dispatch automatically. * Static over dynamic (explicit over implicit): instead of using the Command pattern, we could have simply used a function pointer (in C++, at least). But using the Command pattern makes our program more explicit. Named abstractions are a powerful, self-documenting tool. * Open/closed principle: this principle says, essentially, that you should never "modify" old classes, but only add new classes that help old classes interwork in new ways. For example, the Adapter pattern is a great example. * Loosened coupling: by interworking through abstractions, programs can eliminate cyclic dependencies (see John Lakos' "Large Scale C++" for elaboration). * Rule of demeter: essentially, objects should avoid "train code", such as engine->getObjectList()->getObjectAt(0)->setVisible(true); and replace it with code such as engine->setForegroundVisible(); This is really just a special case of loosing coupling. "Pragmatic Programmer" includes some further (non-academic) elaboration. (Ah, isn't doing other people's homework the best way to avoid one's own? ;) Take care, - Mikko [Edited by - uttumuttu on May 20, 2007 5:12:56 AM]
8. ## Design Patterns

Structural patterns ------------------- Adapter: used when you want to used legacy software to a new framework. Using an adapter is better than rewriting, since it respects the open/closed principle. Composite: useful in modular frameworks. For example, if some class supports only a single Observer, you can still write a BroadcastObserver class that broadcasts the observations to multiple Observers. Decorator: my favorite pattern! Used e.g. in Java's stream framework, where you can make any kind of InputStream buffered by creating a BufferedInputStream that uses the original InputStream as its source. Flyweight: caches can often be described as Flyweight factorys. Proxy: essential for complying with the rule of demeter. [Edited by - uttumuttu on May 20, 2007 5:04:45 AM]
9. ## Design Patterns

Creational patterns ------------------- Abstract factory / Factory method: these are often a useful and preferred way of constructing objects, since they allow making the newly constructed objects "context sensitive". For example, if you let your Company object create Employee objects, the Company can automatically set some of the the Employee's fields to comply with the Company's policies. Java's XML frameworks use these patterns. Singleton: ah, the infamous Singleton... IMHO it's used too widely ;) Basically, using global objects destroys modularity, since clients of the Singleton must agree about its state - or in other words, each client must be kind of "aware" of each client. Used quite a bit in Java: for example, class XXX { public XXX getXXX(); } or class YYY { public YYY getInstance(); } speaks of the Singleton pattern. [Edited by - uttumuttu on May 20, 2007 5:51:42 AM]
10. ## Design Patterns

Using this site as a reference: http://www.tml.tkk.fi/~pnr/GoF-models/html/ Behavioral patterns ------------------- Command: used heavily in threading/scheduling. Java's Runnable interface is a prime example. Iterator: Java's enumerator, C++ stdlib iterators, etc. It's also a good idea to build your own iterators sometimes, to traverse non-linear structures (e.g. permutations of numbers). Mediator: essential for complying with the rule of demeter ("delegating"). Observer: this is so often used it should require no further elaboration. Strategy: used in modular algorithms (an example from AI: separating the search algorithm from search strategy). Template method: an alternative to the Strategy pattern, used e.g. in Java's ResourceBundle (most of the implementation is given, you just need to plug in some of your own). Visitor: a rather complex pattern IMHO, but allows doing type-safe multiple dispatch.