units and dimensions with C++ templates

I personally consider templates to be the most powerful and distinguishing feature of C++ across all languages (note that I surely don't know all programming languages).

In this post, I shall show you the control they provide in handling units and dimensions in programming in a very elegant way. I got the motivation to read and think about it from Scott Meyers Most Important Aha moments - Scott Meyers Most Important Aha Moments (Understanding the use of non-type template parameters in Barton’s and Nackman’s approach to dimensional analysis).

I wrote a piece of sample code to illustrate it on codeguru discussion forum. The approach gives compile time validation in various computations so that they are dimensionally correct and various units are handled in a less error prone manner.

I shall not blabber much about it as you may find a lot to read about it and understand it from the web and will drop off the sample code for you to take a look at. It is a very initial attempt and I seriously hope that you can better it with adding multiple dimensions apart from just 3 that I used (mass, length and time).

Here is a working piece of code illustrating the approach.

[CODE]
#include<iostream>

//internally for everything use SI units.
//mass in kilograms,
//time in seconds
//length in meters

template <int M, int L, int T>
class Unit;

template <int M, int L, int T>
const Unit<M,L,T> operator+(const Unit<M,L,T>&, const Unit<M,L,T>&);

template <int M, int L, int T>
const Unit<M,L,T> operator-(const Unit<M,L,T>&, const Unit<M,L,T>&);

template<int M, int L, int T>
class Unit{
               public:
                               Unit(double val=0.0) : value(val){}
                               Unit& operator+=(const Unit& rhs){
                                               value+=rhs.value;
                                               return *this;
                               }
                               Unit& operator-=(const Unit& rhs){
                                               value-=rhs.value;
                                               return *this;
                               }
                               double getValue() const{
                                               return value;
                               }
                               private:
                                               double value;
                               friend const Unit<M,L,T> operator+<M, L, T>(const Unit<M,L,T>&, const Unit<M,L,T>&);
                               friend const Unit<M,L,T> operator-<M, L, T>(const Unit<M,L,T>&, const Unit<M,L,T>&);

};

template <int M, int L, int T>
const Unit<M,L,T> operator+(const Unit<M,L,T>& lhs, const Unit<M,L,T>& rhs)
{
               return Unit<M,L,T>(lhs)+=rhs;
}
template <int M, int L, int T>
const Unit<M,L,T> operator-(const Unit<M,L,T>& lhs, const Unit<M,L,T>& rhs)
{
               return Unit<M,L,T>(lhs)-=rhs;
}
template <int M1, int L1, int T1, int M2, int L2, int T2>
const Unit<M1+M2,L1+L2,T1+T2> operator*(const Unit<M1,L1,T1>& lhs, const Unit<M2,L2,T2>& rhs)
{
               return Unit<M1+M2,L1+L2,T1+T2>(lhs.getValue()*rhs.getValue());
}
template <int M, int L, int T>
const Unit<M,L,T> operator*(const double& lhs, const Unit<M,L,T>& rhs)
{
               return Unit<M,L,T>(lhs*rhs.getValue());
}

template <int M1, int L1, int T1, int M2, int L2, int T2>
const Unit<M1-M2,L1-L2,T1-T2> operator/(const Unit<M1,L1,T1>& lhs, const Unit<M2,L2,T2>& rhs)
{
               return Unit<M1-M2,L1-L2,T1-T2>(lhs.getValue()/rhs.getValue());
}

template <int M, int L, int T>
bool operator==(const Unit<M,L,T>& lhs, const Unit<M,L,T>& rhs)
{
               return (lhs.getValue()==rhs.getValue());
}
template <int M, int L, int T>
bool operator<=(const Unit<M,L,T>& lhs, const Unit<M,L,T>& rhs)
{
               return lhs.getValue()<=rhs.getValue();
}
template <int M, int L, int T>
bool operator>=(const Unit<M,L,T>& lhs, const Unit<M,L,T>& rhs)
{
               return lhs.getValue()>=rhs.getValue();
}
template <int M, int L, int T>
bool operator< (const Unit<M,L,T>& lhs, const Unit<M,L,T>& rhs)
{
               return lhs.getValue()<rhs.getValue();
}
template <int M, int L, int T>
bool operator> (const Unit<M,L,T>& lhs, const Unit<M,L,T>& rhs)
{
               return lhs.getValue()>rhs.getValue();
}

typedef Unit<1,0,0> Mass;
typedef Unit<0,1,0> Length;
typedef Unit<0,0,1> Time;

//length units - verify the constants
const Length meter = 1.0;
const Length centimeter = 0.01;
const Length feet = 0.3048*meter;
const Length mile = 5280*feet;

//time units
const Time second = 1.0;

//mass units
const Mass kilogram = 1.0;

//Can have more constants for all other units in terms of meter, second and kilogram
//feet,yard,inches,micrometer,hour,minute,grams,pounds, etc etc etc....

int main()
{
               Length distanceinCMs = 100000;
               Length distanceinFeets = distanceinCMs*centimeter/feet;
               std::cout << "distanceinCMs = " << distanceinCMs.getValue() << std::endl;
               std::cout << "distanceinFeets = " << distanceinFeets.getValue() << std::endl;
               //get in terms of miles and feets
               double total_in_miles = (distanceinCMs*centimeter/mile).getValue();
               double total_in_feets = (distanceinCMs*centimeter/feet).getValue();

               std::cout << "above distance = " << static_cast<int>(total_in_miles)
               << " miles and " << static_cast<int>(((total_in_miles -
                                               static_cast<int>(total_in_miles))*mile/feet).getValue())
                                               << " feet (approx.)" << std::endl;
               return 0;
}


If you run this code, with the sample main that I provided, you will see an output as follows:

[OUTPUT]
distanceinCMs = 100000
distanceinFeets = 3280.84
above distance = 0 miles and 3280 feet (approx.)


Isn't that very elegant and easy to use? The best part is, it takes care of everything in SI units for the calculations but you can provide constants for any unit (as defined above, for example 'feet') and you would just need to specify it with the values/variables (as shown in the sample above).

New web BASIC launched!

The new Run BASIC site is now up! This site is a starting point for new web technologies that use Liberty BASIC is the core language. The site is a modest (but very cool) demo of what's to come. If you have always enjoyed programming in BASIC we think you'll like Run BASIC. Check it out! http://www.runbasic.com

-Carl Gundel and Scott McLaughlin

vector iterator invalidation

There are quite a few member functions of the vector class that can potentially invalidate iterators and element references. The following shows a list of those methods and actions:
  • assign
  • clear
  • erase (invalidates those after the erased element)
  • insert
  • pop_back (may or may not, I am not sure)
  • push_back (if causes reallocation - may not when extra space for more elements reserved)
  • resize
  • reserve
  • swap
  • assignment operator=
  • when the vector object is destroyed

All these are capable of causing reallocations of the vector and hence are capable of invalidating iterators. I will try to make it more simpler : anything that can change size() or capacity()! If there can be exceptions to this statement, please let me know!

Cheers!!!

Shrink to fit

I have found quite a number of people wondering if the vector object releases memory once it goes out of scope or is cleared. Some even start assuming it to be a flaw with their STL vector implementation.

Well... it's not that and it certainly isn't a flaw. It just indicates that the runtime does not immediately release all the memory not being used by a cleared vector to the operating system heap manager.

Not only that, sometimes after a call to clear, you may note that the size becomes 0 but the capacity remains the same. That means the vector object is still keeping a huge array internally. This sometimes proves efficient in that the runtime does not always need to go and ask the heap manager to provide blocks from the free store (which is considered to be an expensive operation).

There is a technique though, with which you can do the best about it. It is famed by the name shrink-to-fit. To know more about this technique, please take a look at the following FAQ - http://www.codeguru.com/forum/showthread.php?t=405839

Nice one... isn't it? Have fun! Cheers.

Vector's size and capacity

Are you confused with vector's two member functions namely size() and capacity? Don't be.

size() is related to the number of elements currently in a vector object. It has no relation to memory management internally taken care of by the vector (well there is but that's not a direct relation and you will understand that better as you proceed ahead with this post).

On the contrary, capacity() is directly affected and is directly related to vector's memory management.

Consider vector to have an internal array that it maintains to hold elements. Not all locations of the array can be occupied by elements or refer to valid constructed objects. The total size of that array is called and referred to as vector's capacity. And the total number of elements constructed and being currently held in that array is called and referred to as size().

When all the void places of the array get utilized to keep multiple objects and you add one more element to that collection, you will see that the capacity increases (probably twice the last value, I say "probably" because it is an implementation detail, the standard does not mandate it and hence the factor can vary from one STL implementation to another) but size will only increase by 1.

Its like size() <= capacity(). This will never be untrue for any correct standard vector implementation. Implementations may have a default capacity (8 or 16 elements holding power minimum) and you can't go below that even with the shrink-to-fit technique to empty the vector container object. There may be STL implementations where there might not be any minimum capacity limit and you might see a non-zero positive capacity for an empty vector object (even though it does not have any elements i.e. size() would return 0). There is nothing wrong with that though, since it is something that is implementation defined by the C++ standards. To test what I said, you may write a small test program where you can verify the size() and capacity relationship : size() being always <= capacity. You can keep inserting about 100 elements in the vector and see how each push back affects the size() and capacity() both. A small note on vector member function reserve(): when you do reserve() for any "N" (positive integral value) elements - the capacity is guaranteed to be >= N, not less than that. And if "N" is lower than the current capacity of the vector object it is invoked on then the capacity remains unchanged.

That is all there is to it as far as the distinction between size() and capacity() is concerned.

More, later! Have a great time!

Tiny BASIC Revisited

Scott and I decided to port Tiny BASIC over to Liberty BASIC last week. What we have is mostly working now and I'll make it available after I've polished it a little more.

In the Wikipedia article I mentioned before there are two versions of Tiny BASIC implemented in BASIC. The one we decided to use is here: http://www.aldweb.com/articles.php?lng=en&pg=7407 We decided to use this one because it is simpler. It is also open source.

So what we have is a cute little line numbered BASIC interpreter. In fact the version of BASIC used in the original TRS-80 Model I computer was Tiny BASIC. So if you've ever used this machine or anything like it (VIC-20, C64, Atari 400/800, Sinclair ZX81, etc.) you remember entering code a line at a time each with a line number, typing LIST and RUN. You also have immediate evaluation, which is a nice feature that most languages (even BASIC) don't have today.

The limitations? Single letter variable names. No string variables at all. Only about 100 lines of code per program (a completely artifical limit left to the reader to remove). No GOSUB/RETURN.

Okay, so why do this at all? Clearly this is not a useful programming language, right? I'm not so sure.

First, as an example of how to create a simple programming language it is great. The code is pretty well written (even though it looks like it is also written in a version of Tiny BASIC) and I had no trouble following it.

Then, when I consider just how small this program is I am impressed. In very little code the author has created an interactive programming environment.

If someone wants to use this as a platform to experiment it is wide open. One could try extending the language with string variables, add graphics support, or build a programmable robot battle game on top of it. Perhaps it could even be used to support scripting for Liberty BASIC applications.

Very cool. :-)

BASIC and iPhone

Well, my post the other day about the iPhone wasn't about BASIC programming, but now that I've had a chance to think about it this new device does have some implications. One interesting thing about iPhone's introduction is that nothing was mentioned about development tools. This is a little bit of a contradiction since the iPhone runs Apple's OS X, a full blown Unix operating system. Since this new device is more computer than phone you would expect there to be some way to at least customize it by installing software, or perhaps by scripting. This would also make it easier to justify spending $500. On the other hand you must be a Cingular customer. Hmmm. :-/

It would be great if Apple decides to support this. Imagine Liberty BASIC on the iPhone! If software installation isn't a feature of the iPhone at least you will be able to run our web BASIC on it using the Safari web browser since you'll have an always-on internet connection. :-)

New Apple Phone

I admit this has nothing to do with BASIC, but go to http://www.apple.com and see what their new iPhone looks like. I'd be tempted to think this whole thing is an April fool's joke, but it's only January.

Eclipse - cvc-elt.1: Cannot find the declaration of element error

When working with XML files in Eclipse, a common error developers encounter is;
cvc-elt.1: Cannot find the declaration of element "some-element-name".


The error message gives a clue on which file the error exists by pointing to the element name, but does not give any information on why this error is shown or how it could be fixed. Given error is generated if parser could not find any specification on the given elements when Eclipse tries to parse the XML file using Xerces XML parser. To over come the error, XML file must be provided with a specification (a schema file or a DTD file).

Examples of such files may look like below.
<!DOCTYPE mule-configuration PUBLIC "-//Comp //DTD configuration XML V1.0//EN" 
"http://www.comp.com/dtds/proj/project-configuration.dtd">

or

<element 
xmlns="http://www.comp.com/schema/element"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.comp.com/schema/element
http://www.comp.com/schema/element/elements-1.0.xsd">

Hope this tip would help you.

A sneak peek at our web BASIC

Alyce Watson asked if she could post about the sneak peek we gave to her of our server in action. Have a look at what she had to say.

http://libertybasic.conforums.com/index.cgi?board=lb5&action=display&num=1168003459

We plan to unveil this web BASIC as a free site this month. Later we will sell personal licenses perhaps an affordable subscription service. After that, who knows? ;-)

Patent damages tripled in 2006


Trend of Patent lawsuits are increasing drametically. According to sources, the total amount awarded in 2006 is $1 billion. Compared to $379 million which was awarded in 2005, this is almost a threefold increase.

The top winner of the year was Rambus who won the case over Hynix Semiconductor with $307 million. Rambus has a ton of patents on their list.

Even though there are pros/cons on having the patent concept, it seems companies are willing to goto courts to protect their technologies while few companies do it for the sake of grabbing some money from a company who misuses a technology or concept.

Gmail hacked? All contacts and messages deleted in some accounts

Recently some gmail users made complains saying all their mails and contacts were automatically deleted from their mail accounts.


And this was first reported on 19-12-2006 saying "Lost Everything in My Account..email,contacts,sent mail..". It further explained the issue as;
Found my account clean..nothing in Inbox, contacts ,sent mail..How can all these information residing in different folders disappear? ..How to write to gmail help team to restore the account..is it possible? ..Where to report this abuse?.

This message received so many replies saying others also faced the issue. But one important point came up there was that they were using Firefox 2.0.

Another user pointed out that the following message was left after deleting all the mails.
"This is not a mistake. All your emails and contacts have been deleted
on purpose. This was a malicious attack and not an error. Have a nice
day. =)"


People who got attacked had kept the Gmail opened under Firefox 2.0. I was also used to keep my Gmail opened under Firefox 1.5 (not 2.0) and fortunately I was not caught to the attack.

Blessings for a very happy new year 2007



I wish you Health...
So you may enjoy each day in comfort.

I wish you the Love of friends and family...
And Peace within your heart.

I wish you the Beauty of nature...
That you may enjoy the work of God.

I wish you Wisdom to choose priorities...
For those things that really matter in life.

I wish you Generousity so you may share...
All good things that come to you.

I wish you Happiness and Joy...
And Blessings for the New Year.

I wish you the best of everything...
That you so well deserve.

Happy New Year!


(Author unknown, if you do let me know).

Check out this stream