Eurobot2012_Primary

Dependencies:   mbed Eurobot_2012_Primary

Files at this revision

API Documentation at this revision

Comitter:
narshu
Date:
Wed Oct 17 22:22:28 2012 +0000
Parent:
24:7a3906c2f5d5
Child:
26:0995f61cb7b8
Commit message:
Commit before publishing;

Changed in this revision

Eurobot_shared/.lib Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/IR/IR.cpp Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/IR/IR.h Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/Kalman.cpp Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/Kalman.h Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/Sonar/RF12B/RF12B.cpp Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/Sonar/RF12B/RF12B.h Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/Sonar/RF12B/RF_defs.h Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/Sonar/RFSRF05.cpp Show diff for this revision Revisions of this file
Eurobot_shared/Kalman/Sonar/RFSRF05.h Show diff for this revision Revisions of this file
Eurobot_shared/Motion/motion.cpp Show diff for this revision Revisions of this file
Eurobot_shared/Motion/motion.h Show diff for this revision Revisions of this file
Eurobot_shared/TSH.h Show diff for this revision Revisions of this file
Eurobot_shared/ai/ai.cpp Show diff for this revision Revisions of this file
Eurobot_shared/ai/ai.h Show diff for this revision Revisions of this file
Eurobot_shared/geometryfuncs/geometryfuncs.h Show diff for this revision Revisions of this file
Eurobot_shared/system/system.cpp Show diff for this revision Revisions of this file
Eurobot_shared/system/system.h Show diff for this revision Revisions of this file
Eurobot_shared/ui/ui.cpp Show diff for this revision Revisions of this file
Eurobot_shared/ui/ui.h Show diff for this revision Revisions of this file
PID.lib Show diff for this revision Revisions of this file
PID/PID.cpp Show annotated file Show diff for this revision Revisions of this file
PID/PID.h Show annotated file Show diff for this revision Revisions of this file
QEI.lib Show diff for this revision Revisions of this file
QEI/QEI.cpp Show annotated file Show diff for this revision Revisions of this file
QEI/QEI.h Show annotated file Show diff for this revision Revisions of this file
Servo/.lib Show diff for this revision Revisions of this file
Servo/Servo.cpp Show diff for this revision Revisions of this file
Servo/Servo.h Show diff for this revision Revisions of this file
globals.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
mbed.lib Show diff for this revision Revisions of this file
rtos.lib Show annotated file Show diff for this revision Revisions of this file
tvmet.lib Show diff for this revision Revisions of this file
tvmet/AliasProxy.h Show annotated file Show diff for this revision Revisions of this file
tvmet/BinaryFunctionals.h Show annotated file Show diff for this revision Revisions of this file
tvmet/CommaInitializer.h Show annotated file Show diff for this revision Revisions of this file
tvmet/CompileTimeError.h Show annotated file Show diff for this revision Revisions of this file
tvmet/Extremum.h Show annotated file Show diff for this revision Revisions of this file
tvmet/Functional.h Show annotated file Show diff for this revision Revisions of this file
tvmet/Io.h Show annotated file Show diff for this revision Revisions of this file
tvmet/Matrix.h Show annotated file Show diff for this revision Revisions of this file
tvmet/MatrixBinaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/MatrixEval.h Show annotated file Show diff for this revision Revisions of this file
tvmet/MatrixFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/MatrixImpl.h Show annotated file Show diff for this revision Revisions of this file
tvmet/MatrixOperators.h Show annotated file Show diff for this revision Revisions of this file
tvmet/MatrixUnaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/NumericTraits.h Show annotated file Show diff for this revision Revisions of this file
tvmet/RunTimeError.h Show annotated file Show diff for this revision Revisions of this file
tvmet/TvmetBase.h Show annotated file Show diff for this revision Revisions of this file
tvmet/TypePromotion.h Show annotated file Show diff for this revision Revisions of this file
tvmet/UnaryFunctionals.h Show annotated file Show diff for this revision Revisions of this file
tvmet/Vector.h Show annotated file Show diff for this revision Revisions of this file
tvmet/VectorBinaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/VectorEval.h Show annotated file Show diff for this revision Revisions of this file
tvmet/VectorFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/VectorImpl.h Show annotated file Show diff for this revision Revisions of this file
tvmet/VectorOperators.h Show annotated file Show diff for this revision Revisions of this file
tvmet/VectorUnaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/config.h Show annotated file Show diff for this revision Revisions of this file
tvmet/config/config-gcc.h Show annotated file Show diff for this revision Revisions of this file
tvmet/config/config-icc.h Show annotated file Show diff for this revision Revisions of this file
tvmet/config/config-kcc.h Show annotated file Show diff for this revision Revisions of this file
tvmet/config/config-pgi.h Show annotated file Show diff for this revision Revisions of this file
tvmet/config/config-vc71.h Show annotated file Show diff for this revision Revisions of this file
tvmet/loop/Gemm.h Show annotated file Show diff for this revision Revisions of this file
tvmet/loop/Gemmt.h Show annotated file Show diff for this revision Revisions of this file
tvmet/loop/Gemtm.h Show annotated file Show diff for this revision Revisions of this file
tvmet/loop/Gemtv.h Show annotated file Show diff for this revision Revisions of this file
tvmet/loop/Gemv.h Show annotated file Show diff for this revision Revisions of this file
tvmet/loop/Matrix.h Show annotated file Show diff for this revision Revisions of this file
tvmet/loop/Vector.h Show annotated file Show diff for this revision Revisions of this file
tvmet/meta/Gemm.h Show annotated file Show diff for this revision Revisions of this file
tvmet/meta/Gemmt.h Show annotated file Show diff for this revision Revisions of this file
tvmet/meta/Gemtm.h Show annotated file Show diff for this revision Revisions of this file
tvmet/meta/Gemtv.h Show annotated file Show diff for this revision Revisions of this file
tvmet/meta/Gemv.h Show annotated file Show diff for this revision Revisions of this file
tvmet/meta/Matrix.h Show annotated file Show diff for this revision Revisions of this file
tvmet/meta/Vector.h Show annotated file Show diff for this revision Revisions of this file
tvmet/tvmet.h Show annotated file Show diff for this revision Revisions of this file
tvmet/util/General.h Show annotated file Show diff for this revision Revisions of this file
tvmet/util/Incrementor.h Show annotated file Show diff for this revision Revisions of this file
tvmet/util/Random.h Show annotated file Show diff for this revision Revisions of this file
tvmet/util/Timer.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/BinOperator.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/Eval.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/Identity.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/Literal.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MMProduct.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MMProductTransposed.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MMtProduct.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MVProduct.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/Matrix.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixBinaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixCol.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixDiag.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixOperators.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixRow.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixTranspose.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MatrixUnaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MtMProduct.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/MtVProduct.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/Null.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/UnOperator.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/Vector.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/VectorBinaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/VectorFunctions.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/VectorOperators.h Show annotated file Show diff for this revision Revisions of this file
tvmet/xpr/VectorUnaryFunctions.h Show annotated file Show diff for this revision Revisions of this file
--- a/Eurobot_shared/.lib	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/narshu/libraries/Eurobot_shared/m9hgot
\ No newline at end of file
--- a/Eurobot_shared/Kalman/IR/IR.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#include "IR.h"
-#include "Kalman.h"
-#include "system.h"
-#include "geometryfuncs.h"
-#include "globals.h"
-#include "mbed.h"
-
-IR::IR(Kalman &kalmanin):
-#ifdef ROBOT_PRIMARY
-        IRserial(p9, p10),
-#else
-        IRserial(p13, p14),
-#endif
-        kalman(kalmanin) {
-
-    //Setting up IR serial
-    IRserial.baud(115200);
-    IRserial.format(8,Serial::Odd,1);
-}
-
-void IR::detachisr() {
-    IRserial.attach(NULL,Serial::RxIrq);
-}
-
-void IR::attachisr() {
-    IRserial.attach(this, &IR::vIRValueISR, Serial::RxIrq);
-}
-
-void IR::vIRValueISR (void) {
-
-    // A workaround for mbed UART ISR bug
-    // Clear the RBR flag to make sure the interrupt doesn't loop
-    // UART3 for the port on pins 9/10, UART2 for pins 28/27, and UART1 for pins 13/14.
-    // UART0 for USB UART
-
-#ifdef ROBOT_PRIMARY
-    unsigned char RBR = LPC_UART3->RBR;
-#else
-    unsigned char RBR = LPC_UART1->RBR;
-#endif
-
-    // bytes packing/unpacking for IR turret serial comm
-    static union IRValue_t {
-        float IR_floats[3];
-        int IR_ints[3];
-        unsigned char IR_chars[12];
-    } IRValues;
-
-    const char Alignment_char[4] = {0xFF,0xFE,0xFD,0xFC};
-    static int Alignment_ptr = 0;
-    static bool data_flag = false;
-    static int buff_pointer = 0;
-
-    if (!data_flag) { // look for alignment bytes
-        if (RBR == Alignment_char[Alignment_ptr]) {
-            Alignment_ptr ++;
-        }
-        if (Alignment_ptr >= 4) {
-            Alignment_ptr = 0;
-            data_flag = true; // set the dataflag
-        }
-    } else { // fetch data bytes
-        IRValues.IR_chars[buff_pointer] = RBR;
-        buff_pointer ++;
-        if (buff_pointer >= 12) {
-            buff_pointer = 0;
-            data_flag = false; // dessert the dataflag
-                kalman.runupdate(Kalman::measurement_t(IRValues.IR_ints[0]+3),IRValues.IR_floats[1],IRvariance);
-
-
-        }
-
-    }
-}
\ No newline at end of file
--- a/Eurobot_shared/Kalman/IR/IR.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-
-#ifndef IR_H
-#define IR_H
-
-#include "mbed.h"
-
-//forward declaration of class Kalman to avoid cyclic include
-class Kalman;
-
-class IR {
-public:
-
-    Serial IRserial;
-
-    IR(Kalman &kalmanin);
-    void detachisr();
-    void attachisr();
-    void vIRValueISR (void);
-
-private:
-//reference to the kalman object to run the updates on
-    Kalman& kalman;
-};
-
-#endif //IR_H
\ No newline at end of file
--- a/Eurobot_shared/Kalman/Kalman.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-//***************************************************************************************
-//Kalman Filter implementation
-//***************************************************************************************
-#include "Kalman.h"
-#include "rtos.h"
-#include "RFSRF05.h"
-#include "math.h"
-#include "globals.h"
-#include "motors.h"
-#include "system.h"
-#include "geometryfuncs.h"
-
-#include <tvmet/Matrix.h>
-#include <tvmet/Vector.h>
-using namespace tvmet;
-
-Kalman::Kalman(Motors &motorsin,
-               UI &uiin,
-               PinName Sonar_Trig,
-               PinName Sonar_Echo0,
-               PinName Sonar_Echo1,
-               PinName Sonar_Echo2,
-               PinName Sonar_Echo3,
-               PinName Sonar_Echo4,
-               PinName Sonar_Echo5,
-               PinName Sonar_SDI,
-               PinName Sonar_SDO,
-               PinName Sonar_SCK,
-               PinName Sonar_NCS,
-               PinName Sonar_NIRQ) :
-        ir(*this),
-        sonararray(Sonar_Trig,
-                   Sonar_Echo0,
-                   Sonar_Echo1,
-                   Sonar_Echo2,
-                   Sonar_Echo3,
-                   Sonar_Echo4,
-                   Sonar_Echo5,
-                   Sonar_SDI,
-                   Sonar_SDO,
-                   Sonar_SCK,
-                   Sonar_NCS,
-                   Sonar_NIRQ),
-        motors(motorsin),
-        ui(uiin),
-        predictthread(predictloopwrapper, this, osPriorityNormal, 512),
-        predictticker( SIGTICKARGS(predictthread, 0x1) ),
-//        sonarthread(sonarloopwrapper, this, osPriorityNormal, 256),
-//        sonarticker( SIGTICKARGS(sonarthread, 0x1) ),
-        updatethread(updateloopwrapper, this, osPriorityNormal, 512) {
-
-    //Initilising offsets
-    InitLock.lock();
-    IR_Offset = 0;
-    Sonar_Offset = 0;
-    InitLock.unlock();
-
-
-    //Initilising matrices
-
-    // X = x, y, theta;
-    if (Colour)
-        X = 0.5, 0, 0;
-    else
-        X = 2.5, 0, PI;
-
-    P = 1, 0, 0,
-        0, 1, 0,
-        0, 0, 0.04;
-
-    //measurment variance R is provided by each sensor when calling runupdate
-
-    //attach callback
-    sonararray.callbackobj = (DummyCT*)this;
-    sonararray.mcallbackfunc = (void (DummyCT::*)(int beaconnum, float distance, float variance)) &Kalman::runupdate;
-
-
-    predictticker.start(20);
-//    sonarticker.start(50);
-
-}
-
-
-//Note: this init function assumes that the robot faces east, theta=0, in the +x direction
-void Kalman::KalmanInit() {
-    motors.stop();
-    float SonarMeasuresx1000[3];
-    float IRMeasuresloc[3];
-    int beacon_cnt = 0;
-
-
-// doesn't work since they break the ISR
-    /*
-    #ifdef ROBOT_PRIMARY
-        LPC_UART3->FCR = LPC_UART3->FCR | 0x06;       // Flush the serial FIFO buffer / OR with FCR
-    #else
-        LPC_UART1->FCR = LPC_UART1->FCR | 0x06;       // Flush the serial FIFO buffer / OR with FCR
-    #endif
-    */
-    // zeros the measurements
-    for (int i = 0; i < 3; i++) {
-        SonarMeasures[i] = 0;
-        IRMeasures[i] = 0;
-    }
-
-    InitLock.lock();
-    //zeros offsets
-    IR_Offset = 0;
-    Sonar_Offset = 0;
-    InitLock.unlock();
-
-    // attaches ir interrup
-    ir.attachisr();
-
-    //wating untill the IR has reved up and picked up some valid data
-    //Thread::wait(1000);
-    wait(2);
-
-    //temporaraly disable IR updates
-    ir.detachisr();
-
-    //lock the state throughout the computation, as we will override the state at the end
-    InitLock.lock();
-    statelock.lock();
-
-
-
-    SonarMeasuresx1000[0] = SonarMeasures[0]*1000.0f;
-    SonarMeasuresx1000[1] = SonarMeasures[1]*1000.0f;
-    SonarMeasuresx1000[2] = SonarMeasures[2]*1000.0f;
-    IRMeasuresloc[0] = IRMeasures[0];
-    IRMeasuresloc[1] = IRMeasures[1];
-    IRMeasuresloc[2] = IRMeasures[2];
-    //printf("0: %0.4f, 1: %0.4f, 2: %0.4f \n\r", IRMeasuresloc[0]*180/PI, IRMeasuresloc[1]*180/PI, IRMeasuresloc[2]*180/PI);
-
-    float d = beaconpos[2].y - beaconpos[1].y;
-    float i = beaconpos[0].y - beaconpos[1].y;
-    float j = beaconpos[0].x - beaconpos[1].x;
-    float origin_x = beaconpos[1].x;
-    float y_coor = (SonarMeasuresx1000[1]*SonarMeasuresx1000[1]- SonarMeasuresx1000[2]*SonarMeasuresx1000[2] + d*d) / (2*d);
-    float x_coor = origin_x + (SonarMeasuresx1000[1]*SonarMeasuresx1000[1] - SonarMeasuresx1000[0]*SonarMeasuresx1000[0] + i*i + j*j)/(2*j) - i*y_coor/j;
-
-    //debug for trilateration
-    printf("Cal at x: %0.4f, y: %0.4f \r\n",x_coor,y_coor );
-
-    float Dist_Exp[3];
-    for (int i = 0; i < 3; i++) {
-        //Compute sonar offset
-        Dist_Exp[i] = hypot(beaconpos[i].y - y_coor,beaconpos[i].x - x_coor);
-        Sonar_Offset += (SonarMeasuresx1000[i]-Dist_Exp[i])/3000.0f;
-
-        //Compute IR offset
-        float angle_est = atan2(beaconpos[i].y - y_coor,beaconpos[i].x - x_coor);
-        if (!Colour)
-        angle_est -= PI;
-        //printf("Angle %d : %f \n\r",i,angle_est*180/PI );
-        // take average offset angle from valid readings
-        if (IRMeasuresloc[i] != 0) {
-            beacon_cnt ++;
-            // changed to current angle - estimated angle
-            float angle_temp = IRMeasuresloc[i] - angle_est;
-            angle_temp -= (floor(angle_temp/(2*PI)))*2*PI;
-            IR_Offset += angle_temp;
-        }
-    }
-    IR_Offset /= float(beacon_cnt);
-
-    //debug
-    printf("Offsets IR: %0.4f, Sonar: %0.4f \r\n",IR_Offset*180/PI,Sonar_Offset*1000 );
-
-    //statelock already locked
-    X(0) = x_coor/1000.0f;
-    X(1) = y_coor/1000.0f;
-    
-    if (Colour)
-        X(2) = 0;
-    else
-        X(2) = PI;
-
-    // unlocks mutexes
-    InitLock.unlock();
-    statelock.unlock();
-
-
-    //reattach the IR processing
-    ir.attachisr();
-}
-
-
-void Kalman::predictloop() {
-
-    OLED4 = !ui.regid(0, 3);
-    OLED4 = !ui.regid(1, 4);
-
-    float lastleft = 0;
-    float lastright = 0;
-
-    while (1) {
-        Thread::signal_wait(0x1);
-        OLED1 = !OLED1;
-
-        int leftenc = motors.getEncoder1();
-        int rightenc = motors.getEncoder2();
-
-        float dleft = motors.encoderToDistance(leftenc-lastleft)/1000.0f;
-        float dright = motors.encoderToDistance(rightenc-lastright)/1000.0f;
-
-        lastleft = leftenc;
-        lastright = rightenc;
-
-
-        //The below calculation are in body frame (where +x is forward)
-        float dxp, dyp,d,r;
-        float thetap = (dright - dleft)*PI / (float(robotCircumference)/1000.0f);
-        if (abs(thetap) < 0.02) { //if the rotation through the integration step is small, approximate with a straight line to avoid numerical error
-            d = (dright + dleft)/2.0f;
-            dxp = d*cos(thetap/2.0f);
-            dyp = d*sin(thetap/2.0f);
-
-        } else { //calculate circle arc
-            //float r = (right + left) / (4.0f * PI * thetap);
-            r = (dright + dleft) / (2.0f*thetap);
-            dxp = abs(r)*sin(thetap);
-            dyp = r - r*cos(thetap);
-        }
-
-        statelock.lock();
-
-        float tempX2 = X(2);
-        //rotating to cartesian frame and updating state
-        X(0) += dxp * cos(X(2)) - dyp * sin(X(2));
-        X(1) += dxp * sin(X(2)) + dyp * cos(X(2));
-        X(2) = rectifyAng(X(2) + thetap);
-
-        //Linearising F around X
-        float avgX2 = (X(2) + tempX2)/2.0f;
-        Matrix<float, 3, 3> F;
-        F = 1, 0, (dxp * -sin(avgX2) - dyp * cos(avgX2)),
-            0, 1, (dxp * cos(avgX2) - dyp * sin(avgX2)),
-            0, 0, 1;
-
-        //Generating forward and rotational variance
-        float varfwd = fwdvarperunit * abs(dright + dleft) / 2.0f;
-        float varang = varperang * abs(thetap);
-        float varxydt = xyvarpertime * PREDICTPERIOD/1000.0f;
-        float varangdt = angvarpertime * PREDICTPERIOD/1000.0f;
-
-        //Rotating into cartesian frame
-        Matrix<float, 2, 2> Qsub,Qsubrot,Qrot;
-        Qsub = varfwd + varxydt, 0,
-               0, varxydt;
-
-        Qrot = Rotmatrix(X(2));
-
-        Qsubrot = Qrot * Qsub * trans(Qrot);
-
-        //Generate Q
-        Matrix<float, 3, 3> Q;//(Qsubrot);
-        Q = Qsubrot(0,0), Qsubrot(0,1), 0,
-            Qsubrot(1,0), Qsubrot(1,1), 0,
-            0, 0, varang + varangdt;
-
-        P = F * P * trans(F) + Q;
-
-        //Update UI
-        float statecpy[] = {X(0), X(1), X(2)};
-        ui.updateval(0, statecpy, 3);
-
-        float Pcpy[] = {P(0,0), P(0,1), P(1,0), P(1,1)};
-        ui.updateval(1, Pcpy, 4);
-
-        statelock.unlock();
-    }
-}
-
-//void Kalman::sonarloop() {
-//    while (1) {
-//        Thread::signal_wait(0x1);
-//        sonararray.startRange();
-//    }
-//}
-
-
-void Kalman::runupdate(measurement_t type, float value, float variance) {
-    //printf("beacon %d dist %f\r\n", sonarid, dist);
-    //led2 = !led2;
-
-    measurmentdata* measured = (measurmentdata*)measureMQ.alloc();
-    if (measured) {
-        measured->mtype = type;
-        measured->value = value;
-        measured->variance = variance;
-
-        osStatus putret = measureMQ.put(measured);
-        if (putret)
-            OLED4 = 1;
-        //    printf("putting in MQ error code %#x\r\n", putret);
-    } else {
-        OLED4 = 1;
-        //printf("MQalloc returned NULL ptr\r\n");
-    }
-
-}
-
-void Kalman::updateloop() {
-
-    //sonar Y chanels
-    ui.regid(2, 1);
-    ui.regid(3, 1);
-    ui.regid(4, 1);
-
-    //IR Y chanels
-    ui.regid(5, 1);
-    ui.regid(6, 1);
-    ui.regid(7, 1);
-
-    measurement_t type;
-    float value,variance,rbx,rby,expecdist,Y;
-    float dhdx,dhdy;
-    bool aborton2stddev = false;
-
-    Matrix<float, 1, 3> H;
-
-    float S;
-    Matrix<float, 3, 3> I3( identity< Matrix<float, 3, 3> >() );
-
-
-    while (1) {
-        OLED2 = !OLED2;
-
-        osEvent evt = measureMQ.get();
-
-        if (evt.status == osEventMail) {
-
-            measurmentdata &measured = *(measurmentdata*)evt.value.p;
-            type = measured.mtype; //Note, may support more measurment types than sonar in the future!
-            value = measured.value;
-            variance = measured.variance;
-
-            // don't forget to free the memory
-            measureMQ.free(&measured);
-
-            if (type <= maxmeasure) {
-
-                if (type <= SONAR3) {
-
-                    InitLock.lock();
-                    float dist = value / 1000.0f - Sonar_Offset; //converting to m from mm,subtract the offset
-                    InitLock.unlock();
-
-                    int sonarid = type;
-                    aborton2stddev = true;
-
-                    statelock.lock();
-                    //update the current sonar readings
-                    SonarMeasures[sonarid] = dist;
-
-                    rbx = X(0) - beaconpos[sonarid].x/1000.0f;
-                    rby = X(1) - beaconpos[sonarid].y/1000.0f;
-
-                    expecdist = hypot(rbx, rby);//sqrt(rbx*rbx + rby*rby);
-                    Y = dist - expecdist;
-
-                    //send to ui
-                    ui.updateval(sonarid+2, Y);
-
-                    dhdx = rbx / expecdist;
-                    dhdy = rby / expecdist;
-
-                    H = dhdx, dhdy, 0;
-
-                } else if (type <= IR3) {
-
-                    aborton2stddev = false;
-                    int IRidx = type-3;
-
-                    // subtract the IR offset
-                    InitLock.lock();
-                    value -= IR_Offset;
-                    InitLock.unlock();
-
-                    statelock.lock();
-                    IRMeasures[IRidx] = value;
-
-                    rbx = X(0) - beaconpos[IRidx].x/1000.0f;
-                    rby = X(1) - beaconpos[IRidx].y/1000.0f;
-
-                    float expecang = atan2(-rby, -rbx) - X(2);
-                    Y = rectifyAng(value - expecang);
-
-                    //send to ui
-                    ui.updateval(IRidx + 5, Y);
-
-                    float dstsq = rbx*rbx + rby*rby;
-                    H = -rby/dstsq, rbx/dstsq, -1;
-                }
-
-                Matrix<float, 3, 1> PH (P * trans(H));
-                S = (H * PH)(0,0) + variance;
-
-                if (aborton2stddev && Y*Y > 4 * S) {
-                    statelock.unlock();
-                    continue;
-                }
-
-                Matrix<float, 3, 1> K (PH * (1/S));
-
-                //Updating state
-                X += col(K, 0) * Y;
-                X(2) = rectifyAng(X(2));
-
-                P = (I3 - K * H) * P;
-
-                statelock.unlock();
-
-            }
-
-        } else {
-            OLED4 = 1;
-            //printf("ERROR: in updateloop, code %#x", evt);
-        }
-
-    }
-
-}
-
-// reset kalman states
-void Kalman::KalmanReset() {
-    float SonarMeasuresx1000[3];
-    statelock.lock();
-    SonarMeasuresx1000[0] = SonarMeasures[0]*1000.0f;
-    SonarMeasuresx1000[1] = SonarMeasures[1]*1000.0f;
-    SonarMeasuresx1000[2] = SonarMeasures[2]*1000.0f;
-    //printf("0: %0.4f, 1: %0.4f, 2: %0.4f \n\r", IRMeasuresloc[0]*180/PI, IRMeasuresloc[1]*180/PI, IRMeasuresloc[2]*180/PI);
-
-    float d = beaconpos[2].y - beaconpos[1].y;
-    float i = beaconpos[0].y - beaconpos[1].y;
-    float j = beaconpos[0].x - beaconpos[1].x;
-    float origin_x = beaconpos[1].x;
-    float y_coor = (SonarMeasuresx1000[1]*SonarMeasuresx1000[1]- SonarMeasuresx1000[2]*SonarMeasuresx1000[2] + d*d) / (2*d);
-    float x_coor = origin_x +(SonarMeasuresx1000[1]*SonarMeasuresx1000[1] - SonarMeasuresx1000[0]*SonarMeasuresx1000[0] + i*i + j*j)/(2*j) - i*y_coor/j;
-
-    //statelock already locked
-    X(0) = x_coor/1000.0f;
-    X(1) = y_coor/1000.0f;
-   
-    
-
-/*    if (Colour){
-        X(0) = 0.2;
-        X(1) = 0.2;
-        //X(2) = 0;
-        }
-    else {
-        X(0) = 2.8;
-        X(1) = 0.2;
-        //X(2) = PI;
-    }
-    */
-    P = 0.05, 0, 0,
-        0, 0.05, 0,
-        0, 0, 0.04;
-
-    // unlocks mutexes
-    statelock.unlock();
-
-}
\ No newline at end of file
--- a/Eurobot_shared/Kalman/Kalman.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-#ifndef KALMAN_H
-#define KALMAN_H
-
-#include "globals.h"
-
-
-#include "rtos.h"
-//#include "Matrix.h"
-#include "motors.h"
-#include "RFSRF05.h"
-#include "IR.h"
-#include "ui.h"
-
-#include <tvmet/Matrix.h>
-#include <tvmet/Vector.h>
-using namespace tvmet;
-
-
-class Kalman {
-public:
-    enum measurement_t {SONAR1 = 0, SONAR2, SONAR3, IR1, IR2, IR3};
-    static const measurement_t maxmeasure = IR3;
-
-    Kalman(Motors &motorsin,
-           UI &uiin,
-           PinName Sonar_Trig,
-           PinName Sonar_Echo0,
-           PinName Sonar_Echo1,
-           PinName Sonar_Echo2,
-           PinName Sonar_Echo3,
-           PinName Sonar_Echo4,
-           PinName Sonar_Echo5,
-           PinName Sonar_SDI,
-           PinName Sonar_SDO,
-           PinName Sonar_SCK,
-           PinName Sonar_NCS,
-           PinName Sonar_NIRQ);
-
-    void predict();
-    void runupdate(measurement_t type, float value, float variance);
-
-    //State variables
-    Vector<float, 3> X;
-    Matrix<float, 3, 3> P;
-    Mutex statelock;
-
-    float SonarMeasures[3];
-    float IRMeasures[3];
-    float IR_Offset;
-    float Sonar_Offset;
-    Mutex InitLock;
-
-    bool Kalman_init;
-
-    //The IR is public so it's possible to print the offset in the print function
-    IR ir;
-
-    //Initialises the kalman filter
-    void KalmanInit();
-    
-    // reset kalman states
-    void KalmanReset();
-
-private:
-
-    //Sensor interfaces
-    RFSRF05 sonararray;
-    Motors& motors;
-    UI& ui;
-
-    Thread predictthread;
-    void predictloop();
-    static void predictloopwrapper(void const *argument) {
-        ((Kalman*)argument)->predictloop();
-    }
-    RtosTimer predictticker;
-
-//    Thread sonarthread;
-//    void sonarloop();
-//    static void sonarloopwrapper(void const *argument){ ((Kalman*)argument)->sonarloop(); }
-//    RtosTimer sonarticker;
-
-    struct measurmentdata {
-        measurement_t mtype;
-        float value;
-        float variance;
-    } ;
-
-    Mail <measurmentdata, 16> measureMQ;
-
-    Thread updatethread;
-    void updateloop();
-    static void updateloopwrapper(void const *argument) {
-        ((Kalman*)argument)->updateloop();
-    }
-
-
-};
-
-#endif //KALMAN_H
\ No newline at end of file
--- a/Eurobot_shared/Kalman/Sonar/RF12B/RF12B.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,400 +0,0 @@
-#include "RF12B.h"
-
-#include "RF_defs.h"
-#include <algorithm>
-#include "system.h"
-#include "globals.h"
-
-
-RF12B::RF12B(PinName _SDI,
-             PinName _SDO,
-             PinName _SCK,
-             PinName _NCS,
-             PinName _NIRQ):spi(_SDI, _SDO, _SCK),
-        NCS(_NCS), NIRQ(_NIRQ), NIRQ_in(_NIRQ) {// rfled(LED3) {
-
-    // SPI frequency, word lenght, polarity and phase */
-    spi.format(16,0);
-    spi.frequency(2000000);
-
-    // Set ~CS high 
-    NCS = 1;
-
-    // Initialise RF Module 
-    init();
-
-    // Setup interrupt to happen on falling edge of NIRQ 
-    NIRQ.fall(this, &RF12B::rxISR);
-}
-
-// Returns the packet length if data is available in the receive buffer, 0 otherwise
-//unsigned int RF12B::available() {
-//    return fifo.size();
-//}
-
-// Reads a packet of data, with length "size" Returns false if read failed. TODO: make a metafifo to isolate packets
-/*bool RF12B::read(unsigned char* data, unsigned int size) {
-    if (fifo.size() == 0) {
-        return false;
-    } else {
-        unsigned int i = 0;
-        while (fifo.size() > 0 && i < size) {
-            data[i++] = fifo.front();
-            fifo.pop();
-        }
-        return true;
-    }
-}
-*/
-
-// Reads a byte of data from the receive buffer 
-/*
-unsigned char RF12B::read() {
-    if (available()) {
-        unsigned char data = fifo.front();
-        fifo.pop();
-        return data;
-    } else {
-        return 0xFF; // Error val although could also be data...
-    }
-}
-*/
-
-// Sends a packet of data to the RF module for transmission TODO: Make asych
-void RF12B::write(unsigned char *data, unsigned char length) {
-    unsigned char crc = 0;
-
-    // Transmitter mode 
-    changeMode(TX);
-
-    writeCmd(0x0000);
-    send(0xAA); // PREAMBLE
-    send(0xAA);
-    send(0xAA);
-    send(0x2D); // SYNC
-    send(0xD4);
-    // Packet Length 
-    send(length);
-    crc = crc8(crc, length);
-    send(crc);
-    crc = crc8(crc, crc);
-    // Packet Data 
-    for (unsigned char i=0; i<length; i++) {
-        send(data[i]);
-        crc = crc8(crc, data[i]);
-    }
-    send(crc);
-    send(0xAA); // DUMMY BYTES
-    send(0xAA);
-    send(0xAA);
-
-    // Back to receiver mode 
-    changeMode(RX);
-    status();
-
-
-}
-
-// Transmit a 1-byte data packet 
-void RF12B::write(unsigned char data) {
-    write(&data, 1);
-}
-/*
-void RF12B::write(queue<char> &data, int length) {
-    char crc = 0;
-    char length_byte = 0;
-
-    // -1 means try to transmit everything in the queue 
-    if (length == -1) {
-        length = data.size();
-    }
-
-    // max length of packet is 255 
-    length_byte = min(length, 255);
-
-    // Transmitter mode 
-    changeMode(TX);
-
-    writeCmd(0x0000);
-    send(0xAA); // PREAMBLE
-    send(0xAA);
-    send(0xAA);
-    send(0x2D); // SYNC
-    send(0xD4);
-    // Packet Length 
-    send(length_byte);
-    crc = crc8(crc, length_byte);
-    send(crc);
-    crc = crc8(crc, crc);
-    // Packet Data 
-    for (char i=0; i<length_byte; i++) {
-        send(data.front());
-        crc = crc8(crc, data.front());
-        data.pop();
-    }
-    send(crc);
-    send(0xAA); // DUMMY BYTES
-    send(0xAA);
-    send(0xAA);
-
-    // Back to receiver mode 
-    changeMode(RX);
-    status();
-}
-*/
-/**********************************************************************
- *  PRIVATE FUNCTIONS
- *********************************************************************/
-
-// Initialises the RF12B module 
-void RF12B::init() {
-    // writeCmd(0x80E7); //EL,EF,868band,12.0pF
-     changeMode(RX);
-     writeCmd(0xA640); //frequency select
-     writeCmd(0xC647); //4.8kbps
-     writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm
-     writeCmd(0xC2AC); //AL,!ml,DIG,DQD4
-     writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR
-     writeCmd(0xCED4); //SYNC=2DD4
-     writeCmd(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN
-     writeCmd(0x9850); //!mp,90kHz,MAX OUT
-     writeCmd(0xCC17); //OB1, COB0, LPX, Iddy, CDDIT&#65533;CBW0
-     writeCmd(0xE000); //NOT USED
-     writeCmd(0xC800); //NOT USED
-     writeCmd(0xC040); //1.66MHz,2.2V 
-
-    writeCmd(
-        RFM_CONFIG_EL           |
-        RFM_CONFIG_EF           |
-        RFM_CONFIG_BAND_433     //|
-        //RFM_CONFIG_X_11_0pf // meh, using default
-    );
-
-    // 2. Power Management Command
-    // leave everything switched off for now
-    /*
-    writeCmd(
-        RFM_POWER_MANAGEMENT     // switch all off
-    );
-    */
-
-    // 3. Frequency Setting Command
-    writeCmd(
-        RFM_FREQUENCY            |
-        RFM_FREQ_433Band(435.7)  //I totally made this value up... if someone knows where the sweetspots are in this band, tell me!
-    );
-
-
-    // 4. Data Rate Command
-    //writeCmd(RFM_DATA_RATE_9600);
-    writeCmd(RFM_DATA_RATE_57600);
-
-
-    // 5. Receiver Control Command
-    writeCmd(
-        RFM_RX_CONTROL_P20_VDI  |
-        RFM_RX_CONTROL_VDI_FAST |
-        //RFM_RX_CONTROL_BW(RFM_BAUD_RATE) |
-        RFM_RX_CONTROL_BW_134   |     // CHANGE THIS TO 67 TO IMPROVE RANGE! (though the bitrate must then be below 8kbaud, and fsk modulation changed)
-        RFM_RX_CONTROL_GAIN_0   |
-        RFM_RX_CONTROL_RSSI_103      // Might need adjustment. Datasheet says around 10^-5 bit error rate at this level and baudrate.
-    );
-
-    // 6. Data Filter Command
-    writeCmd(
-        RFM_DATA_FILTER_AL      |
-        RFM_DATA_FILTER_ML      |
-        RFM_DATA_FILTER_DIG     //|
-        //RFM_DATA_FILTER_DQD(4)
-    );
-
-    // 7. FIFO and Reset Mode Command
-    writeCmd(
-        RFM_FIFO_IT(8) |
-        RFM_FIFO_DR    |
-        0x8 //turn on 16bit sync word
-    );
-
-    // 8. FIFO Syncword
-    // Leave as default: 0xD4
-
-    // 9. Receiver FIFO Read
-    // when the interupt goes high, (and if we can assume that it was a fifo fill interrupt) we can read a byte using:
-    // result = RFM_READ_FIFO();
-
-    // 10. AFC Command
-    writeCmd(
-        //RFM_AFC_AUTO_VDI        |  //Note this might be changed to improve range. Refer to datasheet.
-        RFM_AFC_AUTO_INDEPENDENT    |
-        RFM_AFC_RANGE_LIMIT_7_8     |
-        RFM_AFC_EN                  |
-        RFM_AFC_OE                  |
-        RFM_AFC_FI
-    );
-
-    // 11. TX Configuration Control Command
-    writeCmd(
-        RFM_TX_CONTROL_MOD_60 |
-        RFM_TX_CONTROL_POW_0
-    );
-
-
-    // 12. PLL Setting Command
-    writeCmd(
-        0xCC77 & ~0x01 // Setting the PLL bandwith, less noise, but max bitrate capped at 86.2
-        // I think this will slow down the pll's reaction time. Not sure, check with someone!
-    );
-
-    changeMode(RX);
-    resetRX();
-    status();
-}
-
-/* Write a command to the RF Module */
-unsigned int RF12B::writeCmd(unsigned int cmd) {
-    NCS = 0;
-    unsigned int recv = spi.write(cmd);
-    NCS = 1;
-    return recv;
-}
-
-/* Sends a byte of data across RF */
-void RF12B::send(unsigned char data) {
-    while (NIRQ);
-    writeCmd(0xB800 + data);
-}
-
-/* Change the mode of the RF module to Transmitting or Receiving */
-void RF12B::changeMode(rfmode_t _mode) {
-    mode = _mode;
-    if (_mode == TX) {
-        writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC
-    } else { /* mode == RX */
-        writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,!ew,DC
-    }
-}
-
-// Interrupt routine for data reception */
-void RF12B::rxISR() {
-
-    unsigned int data = 0;
-    static int i = -2;
-    static unsigned char packet_length = 0;
-    static unsigned char crc = 0;
-//    #ifdef ROBOT_SECONDARY
-    static unsigned char temp;
-//    #endif
-
-    //Loop while interrupt is asserted
-    while (!NIRQ_in && mode == RX) {
-
-        // Grab the packet's length byte
-        if (i == -2) {
-            data = writeCmd(0x0000);
-            if ( (data&0x8000) ) {
-                data = writeCmd(0xB000);
-                packet_length = (data&0x00FF);
-                crc = crc8(crc, packet_length);
-                i++;
-            }
-        }
-
-        //If we exhaust the interrupt, exit
-        if (NIRQ_in)
-            break;
-
-        // Check that packet length was correct
-        if (i == -1) {
-            data = writeCmd(0x0000);
-            if ( (data&0x8000) ) {
-                data = writeCmd(0xB000);
-                unsigned char crcofsize = (data&0x00FF);
-                if (crcofsize != crc) {
-                    //It was wrong, start over
-                    i = -2;
-                    packet_length = 0;
-                    crc = 0;
-                    //temp = queue<unsigned char>();
-                    resetRX();
-                } else {
-                    crc = crc8(crc, crcofsize);
-                    i++;
-                }
-            }
-        }
-
-        //If we exhaust the interrupt, exit
-        if (NIRQ_in)
-            break;
-
-        // Grab the packet's data
-        if (i >= 0 && i < packet_length) {
-            data = writeCmd(0x0000);
-            if ( (data&0x8000) ) {
-                data = writeCmd(0xB000);
- //               #ifdef ROBOT_SECONDARY
-                temp = data&0x00FF;
- //               #endif
-                //temp.push(data&0x00FF);
-                crc = crc8(crc, (unsigned char)(data&0x00FF));
-                i++;
-            }
-        }
-
-        //If we exhaust the interrupt, exit
-        if (NIRQ_in)
-            break;
-
-        if (i >= packet_length) {
-            data = writeCmd(0x0000);
-            if ( (data&0x8000) ) {
-                data = writeCmd(0xB000);
-                if ((unsigned char)(data & 0x00FF) == crc) {
-                    //If the checksum is correct, add our data to the end of the output buffer
-                    //while (!temp.empty()) {
-                    //fifo.push(temp);
-                     //   temp.pop();
-//#ifdef ROBOT_SECONDARY
-                        if (callbackfunc)
-                            (*callbackfunc)(temp);
-
-                        if (callbackobj && mcallbackfunc)
-                            (callbackobj->*mcallbackfunc)(temp);
-//#endif
-                   // }
-                }
-
-                // Tell RF Module we are finished, and clean up
-                i = -2;
-                packet_length = 0;
-                crc = 0;
-                //temp = queue<unsigned char>();
-                resetRX();
-            }
-        }
-    }
-
-}
-
-unsigned int RF12B::status() {
-    return writeCmd(0x0000);
-}
-
-// Tell the RF Module this packet is received and wait for the next */
-void RF12B::resetRX() {
-    writeCmd(0xCA81);
-    writeCmd(0xCA83);
-};
-
-// Calculate CRC8 */
-unsigned char RF12B::crc8(unsigned char crc, unsigned char data) {
-    crc = crc ^ data;
-    for (int i = 0; i < 8; i++) {
-        if (crc & 0x01) {
-            crc = (crc >> 1) ^ 0x8C;
-        } else {
-            crc >>= 1;
-        }
-    }
-    return crc;
-}
\ No newline at end of file
--- a/Eurobot_shared/Kalman/Sonar/RF12B/RF12B.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#ifndef _RF12B_H
-#define _RF12B_H
-
-#include "mbed.h"
-//#include <queue>
-
-enum rfmode_t{RX, TX};
-
-class DummyCT;
-
-class RF12B {
-public:
-    /* Constructor */
-    RF12B(PinName SDI,
-          PinName SDO,
-          PinName SCK,
-          PinName NCS,
-          PinName NIRQ);
-     
-          
-          
-    /* Reads a packet of data. Returns false if read failed. Use available() to check how much space to allocate for buffer */
-    bool read(unsigned char* data, unsigned int size);
-
-    /* Reads a byte of data from the receive buffer 
-        Returns 0xFF if there is no data */
-    unsigned char read();
-
-    /* Transmits a packet of data */
-    void write(unsigned char* data, unsigned char length);
-    void write(unsigned char data); /* 1-byte packet */
-//    void write(std::queue<char> &data, int length = -1); /* sends a whole queue */
-    
-    /* Returns the packet length if data is available in the receive buffer, 0 otherwise*/
-    unsigned int available();
-    
-    /** A assigns a callback function when a new reading is available **/
-    void (*callbackfunc)(unsigned char rx_code);
-    DummyCT* callbackobj;
-    void (DummyCT::*mcallbackfunc)(unsigned char rx_code);    
-
-protected:
-    /* Receive FIFO buffer */
-//    std::queue<unsigned char> fifo;
-//    std::queue<unsigned char> temp; //for storing stuff mid-packet
-    
-    /* SPI module */
-    SPI spi;
-    
-    /* Other digital pins */
-    DigitalOut NCS;
-    InterruptIn NIRQ;
-    DigitalIn NIRQ_in;
-    //DigitalOut rfled;
-    
-    rfmode_t mode;
-
-    /* Initialises the RF12B module */
-    void init();
-
-    /* Write a command to the RF Module */
-    unsigned int writeCmd(unsigned int cmd);
-    
-    /* Sends a byte of data across RF */
-    void send(unsigned char data);
-    
-    /* Switch module between receive and transmit modes */
-    void changeMode(rfmode_t mode);
-    
-    /* Interrupt routine for data reception */
-    void rxISR();
-    
-    /* Tell the RF Module this packet is received and wait for the next */
-    void resetRX();
-    
-    /* Return the RF Module Status word */
-    unsigned int status();
-    
-    /* Calculate CRC8 */
-    unsigned char crc8(unsigned char crc, unsigned char data);
-};
-
-#endif /* _RF12B_H */
\ No newline at end of file
--- a/Eurobot_shared/Kalman/Sonar/RF12B/RF_defs.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,478 +0,0 @@
-/*
- *  Open HR20
- *
- *  target:     ATmega169 @ 4 MHz in Honnywell Rondostat HR20E
- *
- *  compiler:   WinAVR-20071221
- *              avr-libc 1.6.0
- *              GCC 4.2.2
- *
- *  copyright:  2008 Dario Carluccio (hr20-at-carluccio-dot-de)
- *              2008 Jiri Dobry (jdobry-at-centrum-dot-cz)
- *              2008 Mario Fischer (MarioFischer-at-gmx-dot-net)
- *              2007 Michael Smola (Michael-dot-Smola-at-gmx-dot-net)
- *
- *  license:    This program is free software; you can redistribute it and/or
- *              modify it under the terms of the GNU Library General Public
- *              License as published by the Free Software Foundation; either
- *              version 2 of the License, or (at your option) any later version.
- *
- *              This program is distributed in the hope that it will be useful,
- *              but WITHOUT ANY WARRANTY; without even the implied warranty of
- *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *              GNU General Public License for more details.
- *
- *              You should have received a copy of the GNU General Public License
- *              along with this program. If not, see http:*www.gnu.org/licenses
- */
-
-/*
- * \file       rfm.h
- * \brief      functions to control the RFM12 Radio Transceiver Module
- * \author     Mario Fischer <MarioFischer-at-gmx-dot-net>; Michael Smola <Michael-dot-Smola-at-gmx-dot-net>
- * \date       $Date: 2010/04/17 17:57:02 $
- * $Rev: 260 $
- */
-
-
-//#pragma once // multi-iclude prevention. gcc knows this pragma
-#ifndef rfm_H
-#define rfm_H
-
-
-#define RFM_SPI_16(OUTVAL)            rfm_spi16(OUTVAL) //<! a function that gets a uint16_t (clocked out value) and returns a uint16_t (clocked in value)
-
-#define RFM_CLK_OUTPUT 0
-
-/*
-#define RFM_TESTPIN_INIT
-#define RFM_TESTPIN_ON
-#define RFM_TESTPIN_OFF
-#define RFM_TESTPIN_TOG
-
-#define RFM_CONFIG_DISABLE            0x00 //<! RFM_CONFIG_*** are combinable flags, what the RFM shold do
-#define RFM_CONFIG_BROADCASTSTATUS    0x01 //<! Flag that enables the HR20's status broadcast every minute
-
-#define RFM_CONFIG_ENABLEALL        0xff
-*/
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// RFM status bits
-//
-///////////////////////////////////////////////////////////////////////////////
-
-// Interrupt bits, latched ////////////////////////////////////////////////////
-
-#define RFM_STATUS_FFIT 0x8000 // RX FIFO reached the progr. number of bits
-                               // Cleared by any FIFO read method
-
-#define RFM_STATUS_RGIT 0x8000 // TX register is ready to receive
-                               // Cleared by TX write
-
-#define RFM_STATUS_POR  0x4000 // Power On reset
-                               // Cleared by read status
-
-#define RFM_STATUS_RGUR 0x2000 // TX register underrun, register over write
-                               // Cleared by read status
-
-#define RFM_STATUS_FFOV 0x2000 // RX FIFO overflow
-                               // Cleared by read status
-
-#define RFM_STATUS_WKUP 0x1000 // Wake up timer overflow
-                               // Cleared by read status
-
-#define RFM_STATUS_EXT  0x0800 // Interupt changed to low
-                               // Cleared by read status
-
-#define RFM_STATUS_LBD  0x0400 // Low battery detect
-
-// Status bits ////////////////////////////////////////////////////////////////
-
-#define RFM_STATUS_FFEM 0x0200 // FIFO is empty
-#define RFM_STATUS_ATS  0x0100 // TX mode: Strong enough RF signal
-#define RFM_STATUS_RSSI 0x0100 // RX mode: signal strength above programmed limit
-#define RFM_STATUS_DQD  0x0080 // Data Quality detector output
-#define RFM_STATUS_CRL  0x0040 // Clock recovery lock
-#define RFM_STATUS_ATGL 0x0020 // Toggling in each AFC cycle
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 1. Configuration Setting Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_CONFIG               0x8000
-
-#define RFM_CONFIG_EL            0x8080 // Enable TX Register
-#define RFM_CONFIG_EF            0x8040 // Enable RX FIFO buffer
-#define RFM_CONFIG_BAND_315      0x8000 // Frequency band
-#define RFM_CONFIG_BAND_433      0x8010
-#define RFM_CONFIG_BAND_868      0x8020
-#define RFM_CONFIG_BAND_915      0x8030
-#define RFM_CONFIG_X_8_5pf       0x8000 // Crystal Load Capacitor
-#define RFM_CONFIG_X_9_0pf       0x8001
-#define RFM_CONFIG_X_9_5pf       0x8002
-#define RFM_CONFIG_X_10_0pf      0x8003
-#define RFM_CONFIG_X_10_5pf      0x8004
-#define RFM_CONFIG_X_11_0pf      0x8005
-#define RFM_CONFIG_X_11_5pf      0x8006
-#define RFM_CONFIG_X_12_0pf      0x8007
-#define RFM_CONFIG_X_12_5pf      0x8008
-#define RFM_CONFIG_X_13_0pf      0x8009
-#define RFM_CONFIG_X_13_5pf      0x800A
-#define RFM_CONFIG_X_14_0pf      0x800B
-#define RFM_CONFIG_X_14_5pf      0x800C
-#define RFM_CONFIG_X_15_0pf      0x800D
-#define RFM_CONFIG_X_15_5pf      0x800E
-#define RFM_CONFIG_X_16_0pf      0x800F
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 2. Power Management Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_POWER_MANAGEMENT     0x8200
-
-#define RFM_POWER_MANAGEMENT_ER  0x8280 // Enable receiver
-#define RFM_POWER_MANAGEMENT_EBB 0x8240 // Enable base band block
-#define RFM_POWER_MANAGEMENT_ET  0x8220 // Enable transmitter
-#define RFM_POWER_MANAGEMENT_ES  0x8210 // Enable synthesizer
-#define RFM_POWER_MANAGEMENT_EX  0x8208 // Enable crystal oscillator
-#define RFM_POWER_MANAGEMENT_EB  0x8204 // Enable low battery detector
-#define RFM_POWER_MANAGEMENT_EW  0x8202 // Enable wake-up timer
-#define RFM_POWER_MANAGEMENT_DC  0x8201 // Disable clock output of CLK pin
-
-#ifndef RFM_CLK_OUTPUT
-    #error RFM_CLK_OUTPUT must be defined to 0 or 1
-#endif
-#if RFM_CLK_OUTPUT
-    #define RFM_TX_ON_PRE() RFM_SPI_16( \
-                                RFM_POWER_MANAGEMENT_ES | \
-                                RFM_POWER_MANAGEMENT_EX )
-    #define RFM_TX_ON()     RFM_SPI_16( \
-                                RFM_POWER_MANAGEMENT_ET | \
-                                RFM_POWER_MANAGEMENT_ES | \
-                                RFM_POWER_MANAGEMENT_EX )
-    #define RFM_RX_ON()     RFM_SPI_16( \
-                                RFM_POWER_MANAGEMENT_ER | \
-                                RFM_POWER_MANAGEMENT_EBB | \
-                                RFM_POWER_MANAGEMENT_ES | \
-                                RFM_POWER_MANAGEMENT_EX )
-    #define RFM_OFF()       RFM_SPI_16( \
-                                RFM_POWER_MANAGEMENT_EX )
-#else
-    #define RFM_TX_ON_PRE() RFM_SPI_16( \
-                                RFM_POWER_MANAGEMENT_DC | \
-                                RFM_POWER_MANAGEMENT_ES | \
-                                RFM_POWER_MANAGEMENT_EX )
-    #define RFM_TX_ON()     RFM_SPI_16( \
-                                RFM_POWER_MANAGEMENT_DC | \
-                                RFM_POWER_MANAGEMENT_ET | \
-                                RFM_POWER_MANAGEMENT_ES | \
-                                RFM_POWER_MANAGEMENT_EX )
-    #define RFM_RX_ON()     RFM_SPI_16( \
-                                RFM_POWER_MANAGEMENT_DC  | \
-                                RFM_POWER_MANAGEMENT_ER | \
-                                RFM_POWER_MANAGEMENT_EBB | \
-                                RFM_POWER_MANAGEMENT_ES | \
-                                RFM_POWER_MANAGEMENT_EX )
-    #define RFM_OFF()       RFM_SPI_16(RFM_POWER_MANAGEMENT_DC)
-#endif
-///////////////////////////////////////////////////////////////////////////////
-//
-// 3. Frequency Setting Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_FREQUENCY            0xA000
-
-#define RFM_FREQ_315Band(v) (uint16_t)((v/10.0-31)*4000)
-#define RFM_FREQ_433Band(v) (uint16_t)((v/10.0-43)*4000)
-#define RFM_FREQ_868Band(v) (uint16_t)((v/20.0-43)*4000)
-#define RFM_FREQ_915Band(v) (uint16_t)((v/30.0-30)*4000)
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 4. Data Rate Command
-//
-/////////////////////////////////////////////////////////////////////////////////
-
-#define RFM_BAUD_RATE            9600
-
-#define RFM_DATA_RATE            0xC600
-
-#define RFM_DATA_RATE_CS         0xC680
-#define RFM_DATA_RATE_4800       0xC647
-#define RFM_DATA_RATE_9600       0xC623
-#define RFM_DATA_RATE_19200      0xC611
-#define RFM_DATA_RATE_38400      0xC608
-#define RFM_DATA_RATE_57600      0xC605
-
-#define RFM_SET_DATARATE(baud)        ( ((baud)<5400) ? (RFM_DATA_RATE_CS|((43104/(baud))-1)) : (RFM_DATA_RATE|((344828UL/(baud))-1)) )
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 5. Receiver Control Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_RX_CONTROL           0x9000
-
-#define RFM_RX_CONTROL_P20_INT   0x9000 // Pin20 = ExternalInt
-#define RFM_RX_CONTROL_P20_VDI   0x9400 // Pin20 = VDI out
-
-#define RFM_RX_CONTROL_VDI_FAST  0x9000 // fast   VDI Response time
-#define RFM_RX_CONTROL_VDI_MED   0x9100 // medium
-#define RFM_RX_CONTROL_VDI_SLOW  0x9200 // slow
-#define RFM_RX_CONTROL_VDI_ON    0x9300 // Always on
-
-#define RFM_RX_CONTROL_BW_400    0x9020 // bandwidth 400kHz
-#define RFM_RX_CONTROL_BW_340    0x9040 // bandwidth 340kHz
-#define RFM_RX_CONTROL_BW_270    0x9060 // bandwidth 270kHz
-#define RFM_RX_CONTROL_BW_200    0x9080 // bandwidth 200kHz
-#define RFM_RX_CONTROL_BW_134    0x90A0 // bandwidth 134kHz
-#define RFM_RX_CONTROL_BW_67     0x90C0 // bandwidth 67kHz
-
-#define RFM_RX_CONTROL_GAIN_0    0x9000 // LNA gain  0db
-#define RFM_RX_CONTROL_GAIN_6    0x9008 // LNA gain -6db
-#define RFM_RX_CONTROL_GAIN_14   0x9010 // LNA gain -14db
-#define RFM_RX_CONTROL_GAIN_20   0x9018 // LNA gain -20db
-
-#define RFM_RX_CONTROL_RSSI_103  0x9000 // DRSSI threshold -103dbm
-#define RFM_RX_CONTROL_RSSI_97   0x9001 // DRSSI threshold -97dbm
-#define RFM_RX_CONTROL_RSSI_91   0x9002 // DRSSI threshold -91dbm
-#define RFM_RX_CONTROL_RSSI_85   0x9003 // DRSSI threshold -85dbm
-#define RFM_RX_CONTROL_RSSI_79   0x9004 // DRSSI threshold -79dbm
-#define RFM_RX_CONTROL_RSSI_73   0x9005 // DRSSI threshold -73dbm
-//#define RFM_RX_CONTROL_RSSI_67   0x9006 // DRSSI threshold -67dbm // RF12B reserved
-//#define RFM_RX_CONTROL_RSSI_61   0x9007 // DRSSI threshold -61dbm // RF12B reserved
-
-#define RFM_RX_CONTROL_BW(baud)        (((baud)<8000) ? \
-                                    RFM_RX_CONTROL_BW_67 : \
-                                    ( \
-                                        ((baud)<30000) ? \
-                                        RFM_RX_CONTROL_BW_134 : \
-                                        RFM_RX_CONTROL_BW_200 \
-                                    ))
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 6. Data Filter Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_DATA_FILTER          0xC228
-
-#define RFM_DATA_FILTER_AL       0xC2A8 // clock recovery auto-lock
-#define RFM_DATA_FILTER_ML       0xC268 // clock recovery fast mode
-#define RFM_DATA_FILTER_DIG      0xC228 // data filter type digital
-#define RFM_DATA_FILTER_ANALOG   0xC238 // data filter type analog
-#define RFM_DATA_FILTER_DQD(level) (RFM_DATA_FILTER | (level & 0x7))
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 7. FIFO and Reset Mode Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_FIFO                 0xCA00
-
-#define RFM_FIFO_AL              0xCA04 // FIFO Start condition sync-word/always
-#define RFM_FIFO_FF              0xCA02 // Enable FIFO fill
-#define RFM_FIFO_DR              0xCA01 // Disable hi sens reset mode
-#define RFM_FIFO_IT(level)       (RFM_FIFO | (( (level) & 0xF)<<4))
-
-#define RFM_FIFO_OFF()            RFM_SPI_16(RFM_FIFO_IT(8) |               RFM_FIFO_DR)
-#define RFM_FIFO_ON()             RFM_SPI_16(RFM_FIFO_IT(8) | RFM_FIFO_FF | RFM_FIFO_DR)
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// 8. Receiver FIFO Read
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#define RFM_READ_FIFO()           (RFM_SPI_16(0xB000) & 0xFF)
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// 9. AFC Command
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#define RFM_AFC                  0xC400
-
-#define RFM_AFC_EN               0xC401
-#define RFM_AFC_OE               0xC402
-#define RFM_AFC_FI               0xC404
-#define RFM_AFC_ST               0xC408
-
-// Limits the value of the frequency offset register to the next values:
-
-#define RFM_AFC_RANGE_LIMIT_NO    0xC400 // 0: No restriction
-#define RFM_AFC_RANGE_LIMIT_15_16 0xC410 // 1: +15 fres to -16 fres
-#define RFM_AFC_RANGE_LIMIT_7_8   0xC420 // 2: +7 fres to -8 fres
-#define RFM_AFC_RANGE_LIMIT_3_4   0xC430 // 3: +3 fres to -4 fres
-
-// fres=2.5 kHz in 315MHz and 433MHz Bands
-// fres=5.0 kHz in 868MHz Band
-// fres=7.5 kHz in 915MHz Band
-
-#define RFM_AFC_AUTO_OFF         0xC400 // 0: Auto mode off (Strobe is controlled by microcontroller)
-#define RFM_AFC_AUTO_ONCE        0xC440 // 1: Runs only once after each power-up
-#define RFM_AFC_AUTO_VDI         0xC480 // 2: Keep the foffset only during receiving(VDI=high)
-#define RFM_AFC_AUTO_INDEPENDENT 0xC4C0 // 3: Keep the foffset value independently trom the state of the VDI signal
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 10. TX Configuration Control Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_TX_CONTROL           0x9800
-
-#define RFM_TX_CONTROL_POW_0     0x9800
-#define RFM_TX_CONTROL_POW_3     0x9801
-#define RFM_TX_CONTROL_POW_6     0x9802
-#define RFM_TX_CONTROL_POW_9     0x9803
-#define RFM_TX_CONTROL_POW_12    0x9804
-#define RFM_TX_CONTROL_POW_15    0x9805
-#define RFM_TX_CONTROL_POW_18    0x9806
-#define RFM_TX_CONTROL_POW_21    0x9807
-#define RFM_TX_CONTROL_MOD_15    0x9800
-#define RFM_TX_CONTROL_MOD_30    0x9810
-#define RFM_TX_CONTROL_MOD_45    0x9820
-#define RFM_TX_CONTROL_MOD_60    0x9830
-#define RFM_TX_CONTROL_MOD_75    0x9840
-#define RFM_TX_CONTROL_MOD_90    0x9850
-#define RFM_TX_CONTROL_MOD_105   0x9860
-#define RFM_TX_CONTROL_MOD_120   0x9870
-#define RFM_TX_CONTROL_MOD_135   0x9880
-#define RFM_TX_CONTROL_MOD_150   0x9890
-#define RFM_TX_CONTROL_MOD_165   0x98A0
-#define RFM_TX_CONTROL_MOD_180   0x98B0
-#define RFM_TX_CONTROL_MOD_195   0x98C0
-#define RFM_TX_CONTROL_MOD_210   0x98D0
-#define RFM_TX_CONTROL_MOD_225   0x98E0
-#define RFM_TX_CONTROL_MOD_240   0x98F0
-#define RFM_TX_CONTROL_MP        0x9900
-
-#define RFM_TX_CONTROL_MOD(baud)    (((baud)<8000) ? \
-                                    RFM_TX_CONTROL_MOD_45 : \
-                                    ( \
-                                        ((baud)<20000) ? \
-                                        RFM_TX_CONTROL_MOD_60 : \
-                                        ( \
-                                            ((baud)<30000) ? \
-                                            RFM_TX_CONTROL_MOD_75 : \
-                                            ( \
-                                                ((baud)<40000) ? \
-                                                RFM_TX_CONTROL_MOD_90 : \
-                                                RFM_TX_CONTROL_MOD_120 \
-                                            ) \
-                                        ) \
-                                    ))
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// 11. Transmitter Register Write Command
-//
-/////////////////////////////////////////////////////////////////////////////
-
-//#define RFM_WRITE(byte)  RFM_SPI_16(0xB800 | ((byte) & 0xFF))
-#define RFM_WRITE(byte)  RFM_SPI_16(0xB800 | (byte) )
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 12. Wake-up Timer Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_WAKEUP_TIMER         0xE000
-#define RFM_WAKEUP_SET(time)     RFM_SPI_16(RFM_WAKEUP_TIMER | (time))
-
-#define RFM_WAKEUP_480s          (RFM_WAKEUP_TIMER |(11 << 8)| 234)
-#define RFM_WAKEUP_240s          (RFM_WAKEUP_TIMER |(10 << 8)| 234)
-#define RFM_WAKEUP_120s          (RFM_WAKEUP_TIMER |(9  << 8)| 234)
-#define RFM_WAKEUP_119s          (RFM_WAKEUP_TIMER |(9  << 8)| 232)
-
-#define RFM_WAKEUP_60s           (RFM_WAKEUP_TIMER |(8 << 8) | 235)
-#define RFM_WAKEUP_59s           (RFM_WAKEUP_TIMER |(8 << 8) | 230)
-
-#define RFM_WAKEUP_30s           (RFM_WAKEUP_TIMER |(7 << 8) | 235)
-#define RFM_WAKEUP_29s           (RFM_WAKEUP_TIMER |(7 << 8) | 227)
-
-#define RFM_WAKEUP_8s            (RFM_WAKEUP_TIMER |(5 << 8) | 250)
-#define RFM_WAKEUP_7s            (RFM_WAKEUP_TIMER |(5 << 8) | 219)
-#define RFM_WAKEUP_6s            (RFM_WAKEUP_TIMER |(6 << 8) |  94)
-#define RFM_WAKEUP_5s            (RFM_WAKEUP_TIMER |(5 << 8) | 156)
-#define RFM_WAKEUP_4s            (RFM_WAKEUP_TIMER |(5 << 8) | 125)
-#define RFM_WAKEUP_1s            (RFM_WAKEUP_TIMER |(2 << 8) | 250)
-#define RFM_WAKEUP_900ms         (RFM_WAKEUP_TIMER |(2 << 8) | 225)
-#define RFM_WAKEUP_800ms         (RFM_WAKEUP_TIMER |(2 << 8) | 200)
-#define RFM_WAKEUP_700ms         (RFM_WAKEUP_TIMER |(2 << 8) | 175)
-#define RFM_WAKEUP_600ms         (RFM_WAKEUP_TIMER |(2 << 8) | 150)
-#define RFM_WAKEUP_500ms         (RFM_WAKEUP_TIMER |(2 << 8) | 125)
-#define RFM_WAKEUP_400ms         (RFM_WAKEUP_TIMER |(2 << 8) | 100)
-#define RFM_WAKEUP_300ms         (RFM_WAKEUP_TIMER |(2 << 8) |  75)
-#define RFM_WAKEUP_200ms         (RFM_WAKEUP_TIMER |(2 << 8) |  50)
-#define RFM_WAKEUP_100ms         (RFM_WAKEUP_TIMER |(2 << 8) |  25)
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 13. Low Duty-Cycle Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_LOW_DUTY_CYCLE       0xC800
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 14. Low Battery Detector Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_LOW_BATT_DETECT           0xC000
-#define RFM_LOW_BATT_DETECT_D_1MHZ    0xC000
-#define RFM_LOW_BATT_DETECT_D_1_25MHZ 0xC020
-#define RFM_LOW_BATT_DETECT_D_1_66MHZ 0xC040
-#define RFM_LOW_BATT_DETECT_D_2MHZ    0xC060
-#define RFM_LOW_BATT_DETECT_D_2_5MHZ  0xC080
-#define RFM_LOW_BATT_DETECT_D_3_33MHZ 0xC0A0
-#define RFM_LOW_BATT_DETECT_D_5MHZ    0xC0C0
-#define RFM_LOW_BATT_DETECT_D_10MHZ   0xC0E0
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// 15. Status Read Command
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#define RFM_READ_STATUS()       RFM_SPI_16(0x0000)
-#define RFM_READ_STATUS_FFIT()  SPI_1 (0x00)
-#define RFM_READ_STATUS_RGIT    RFM_READ_STATUS_FFIT
-
-///////////////////////////////////////////////////////////////////////////////
-
-// RFM air protocol flags:
-
-#define RFMPROTO_FLAGS_BITASK_PACKETTYPE        0b11000000 //!< the uppermost 2 bits of the flags field encode the packettype
-#define RFMPROTO_FLAGS_PACKETTYPE_BROADCAST        0b00000000 //!< broadcast packettype (message from hr20, protocol; step 1)
-#define RFMPROTO_FLAGS_PACKETTYPE_COMMAND        0b01000000 //!< command packettype (message to hr20, protocol; step 2)
-#define RFMPROTO_FLAGS_PACKETTYPE_REPLY            0b10000000 //!< reply packettype (message from hr20, protocol; step 3)
-#define RFMPROTO_FLAGS_PACKETTYPE_SPECIAL        0b11000000 //!< currently unused packettype
-
-#define RFMPROTO_FLAGS_BITASK_DEVICETYPE        0b00011111 //!< the lowermost 5 bytes denote the device type. this way other sensors and actors may coexist
-#define RFMPROTO_FLAGS_DEVICETYPE_OPENHR20        0b00010100 //!< topen HR20 device type. 10100 is for decimal 20
-
-#define RFMPROTO_IS_PACKETTYPE_BROADCAST(FLAGS)    ( RFMPROTO_FLAGS_PACKETTYPE_BROADCAST == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) )
-#define RFMPROTO_IS_PACKETTYPE_COMMAND(FLAGS)    ( RFMPROTO_FLAGS_PACKETTYPE_COMMAND   == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) )
-#define RFMPROTO_IS_PACKETTYPE_REPLY(FLAGS)        ( RFMPROTO_FLAGS_PACKETTYPE_REPLY     == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) )
-#define RFMPROTO_IS_PACKETTYPE_SPECIAL(FLAGS)    ( RFMPROTO_FLAGS_PACKETTYPE_SPECIAL   == ((FLAGS) & RFMPROTO_FLAGS_BITASK_PACKETTYPE) )
-#define RFMPROTO_IS_DEVICETYPE_OPENHR20(FLAGS)    ( RFMPROTO_FLAGS_DEVICETYPE_OPENHR20  == ((FLAGS) & RFMPROTO_FLAGS_BITASK_DEVICETYPE) )
-
-///////////////////////////////////////////////////////////////////////////////
-
-#endif
\ No newline at end of file
--- a/Eurobot_shared/Kalman/Sonar/RFSRF05.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-
-#include "RFSRF05.h"
-#include "mbed.h"
-#include "globals.h"
-#include "system.h"
-
-
-RFSRF05::RFSRF05(PinName trigger,
-                 PinName echo0,
-                 PinName echo1,
-                 PinName echo2,
-                 PinName echo3,
-                 PinName echo4,
-                 PinName echo5,
-                 PinName SDI,
-                 PinName SDO,
-                 PinName SCK,
-                 PinName NCS,
-                 PinName NIRQ)
-        : _rf(SDI,SDO,SCK,NCS,NIRQ),
-        _trigger(trigger),
-        _echo0(echo0),
-        _echo1(echo1),
-        _echo2(echo2),
-        _echo3(echo3),
-        _echo4(echo4),
-        _echo5(echo5) {
-
-    // initialises codes
-    codes[0] = CODE0;
-    codes[1] = CODE1;
-    codes[2] = CODE2;
-
-    //set callback execute to true
-    ValidPulse = false;
-
-    // Attach interrupts
-#ifdef SONAR_ECHO_INV
-    // inverted sonar inputs
-    _echo5.fall(this, &RFSRF05::_rising);
-    _echo0.rise(this, &RFSRF05::_falling);
-    _echo1.rise(this, &RFSRF05::_falling);
-    _echo2.rise(this, &RFSRF05::_falling);
-    _echo3.rise(this, &RFSRF05::_falling);
-    _echo4.rise(this, &RFSRF05::_falling);
-    _echo5.rise(this, &RFSRF05::_falling);
-#else
-    _echo5.rise(this, &RFSRF05::_rising);
-    _echo0.fall(this, &RFSRF05::_falling);
-    _echo1.fall(this, &RFSRF05::_falling);
-    _echo2.fall(this, &RFSRF05::_falling);
-    _echo3.fall(this, &RFSRF05::_falling);
-    _echo4.fall(this, &RFSRF05::_falling);
-    _echo5.fall(this, &RFSRF05::_falling);
-#endif
-
-
-    //init callabck function
-    callbackfunc = NULL;
-    callbackobj = NULL;
-    mcallbackfunc = NULL;
-
-    // innitialises beacon counter
-    _beacon_counter = 0;
-
-#ifdef ROBOT_PRIMARY
-    //Interrupts every 50ms for primary robot
-    _ticker.attach(this, &RFSRF05::_startRange, 0.05);
-#else
-    //attach callback
-    _rf.callbackobj = (DummyCT*)this;
-    _rf.mcallbackfunc = (void (DummyCT::*)(unsigned char rx_data)) &RFSRF05::startRange;
-#endif
-
-}
-
-#ifdef ROBOT_PRIMARY
-void RFSRF05::_startRange() {
-
-    //printf("Srange\r\r");
-
-    // increments counter
-    _beacon_counter = (_beacon_counter + 1) % 3;
-
-
-    // set flags
-    ValidPulse = false;
-    expValidPulse = true;
-    
-    // writes code to RF port
-    _rf.write(codes[_beacon_counter]);
-
-    // send a trigger pulse, 10uS long
-    _trigger = 1;
-    wait_us (10);
-    _trigger = 0;
-
-}
-#else
-
-void RFSRF05::startRange(unsigned char rx_code) {
-    for (int i = 0; i < 3; i++) {
-        if (rx_code == codes[i]) {
-       
-            // assign beacon_counter
-            _beacon_counter = i;
-
-            // set flags
-            ValidPulse = false;
-            expValidPulse = true;
-
-            // send a trigger pulse, 10uS long
-            _trigger = 1;
-            wait_us (10);
-            _trigger = 0;
-            break;
-        }
-    }
-}
-#endif
-
-// Clear and start the timer at the begining of the echo pulse
-void RFSRF05::_rising(void) {
-
-    _timer.reset();
-    _timer.start();
-
-    //Set callback execute to ture
-    if (expValidPulse) {
-        ValidPulse = true;
-        expValidPulse = false;
-    }
-}
-
-// Stop and read the timer at the end of the pulse
-void RFSRF05::_falling(void) {
-    _timer.stop();
-
-    if (ValidPulse) {
-        //printf("Validpulse trig!\r\n");
-        ValidPulse = false;
-
-        //Calucate distance
-        //true offset is about 100, we put 300 so circles overlap
-        _dist[_beacon_counter] =  _timer.read_us()/2.9 + 300;
-
-        if (callbackfunc)
-            (*callbackfunc)(_beacon_counter, _dist[_beacon_counter]);
-
-        if (callbackobj && mcallbackfunc)
-            (callbackobj->*mcallbackfunc)(_beacon_counter, _dist[_beacon_counter], sonarvariance);
-
-    }
-
-}
-
-float RFSRF05::read0() {
-    // returns distance
-    return (_dist[0]);
-}
-
-float RFSRF05::read1() {
-    // returns distance
-    return (_dist[1]);
-}
-
-float RFSRF05::read2() {
-    // returns distance
-    return (_dist[2]);
-}
-
-float RFSRF05::read(unsigned int beaconnum) {
-    // returns distance
-    return (_dist[beaconnum]);
-}
-
-void RFSRF05::setCode(int code_index, unsigned char code) {
-    codes[code_index] = code;
-}
-
-//SRF05::operator float() {
-//    return read();
-//}
--- a/Eurobot_shared/Kalman/Sonar/RFSRF05.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-
-#ifndef MBED_RFSRF05_H
-#define MBED_RFSRF05_H
-
-
-
-#include "mbed.h"
-#include "RF12B.h"
-#include "globals.h"
-
-
-#define CODE0 0x22
-#define CODE1 0x44
-#define CODE2 0x88
-
-/* SAMPLE IMPLEMENTATION!
-RFSRF05 my_srf(p13,p21,p22,p23,p24,p25,p26,p5,p6,p7,p8,p9);
-
-
-void callbinmain(int num, float dist) {
-    //Here is where you deal with your brand new reading ;D
-}
-
-int main() {
-    pc.printf("Hello World of RobotSonar!\r\n");
-    my_srf.callbackfunc = callbinmain;
-    
-    while (1);
-}
-
- */
- 
-class DummyCT;
- 
-class RFSRF05 {
-public:
-
-    RFSRF05(
-    PinName trigger, 
-    PinName echo0,
-    PinName echo1,
-    PinName echo2,
-    PinName echo3,
-    PinName echo4,
-    PinName echo5,
-    PinName SDI,
-    PinName SDO,
-    PinName SCK,
-    PinName NCS,
-    PinName NIRQ);
-    
-    /** A non-blocking function that will return the last measurement
-     *
-     * @returns floating point representation of distance in mm
-     */
-    float read0();
-    float read1();
-    float read2();
-    float read(unsigned int beaconnum);
-
-    
-    /** A assigns a callback function when a new reading is available **/
-    void (*callbackfunc)(int beaconnum, float distance);
-    DummyCT* callbackobj;
-    void (DummyCT::*mcallbackfunc)(int beaconnum, float distance, float variance);
-    
-    //triggers a read
-    #ifndef ROBOT_PRIMARY
-    void startRange(unsigned char rx_code);
-    #endif
-    
-    //set codes
-    void setCode(int code_index, unsigned char code);
-    unsigned char codes[3];
-
-    /** A short hand way of using the read function */
-    //operator float();
-    
-private :
-    RF12B _rf;
-    DigitalOut _trigger;
-    InterruptIn _echo0;
-    InterruptIn _echo1;
-    InterruptIn _echo2;
-    InterruptIn _echo3;
-    InterruptIn _echo4;
-    InterruptIn _echo5;
-    Timer _timer;
-    Ticker _ticker;
-    #ifdef ROBOT_PRIMARY
-    void _startRange(void);
-    #endif
-    void _rising (void);
-    void _falling (void);
-    float _dist[3];
-    int _beacon_counter;
-    bool ValidPulse;
-    bool expValidPulse;
-    
-};
-
-#endif
--- a/Eurobot_shared/Motion/motion.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-#include "motion.h"
-#include "geometryfuncs.h"
-#include "system.h"
-#include "PID.h"
-
-AnalogIn ObsAvoidPin(p20);
-
-Motion::Motion(Motors &motorsin, AI &aiin, Kalman &kalmanin):
-        thr_motion(mtwrapper,this,osPriorityNormal,1024),
-        motors(motorsin),
-        ai(aiin),
-        kalman(kalmanin) { }
-
-// motion control thread ------------------------
-void Motion::motion_thread() {
-    motors.resetEncoders();
-    motors.setSpeed(5,5);
-    motors.stop();
-    // Thread::wait(1500);
-    //ai.thr_AI.signal_set(0x01);
-
-    //PID declare
-    PID PIDControllerMotorTheta2(FWD_MOVE_P, FWD_MOVE_P/10.0f, 0.000005, MOTION_UPDATE_PERIOD/1000.0f);     //Going forward
-    PID PIDControllerMotorTheta(SPIN_MOVE_P, SPIN_MOVE_P/10.0f, 0.000005, MOTION_UPDATE_PERIOD/1000.0f);    //Spinning on the spot
-
-    //PID Initialisation
-    PIDControllerMotorTheta2.setMode(MANUAL_MODE);
-    PIDControllerMotorTheta.setMode(MANUAL_MODE);
-
-    PIDControllerMotorTheta2.setBias(0);
-    PIDControllerMotorTheta.setBias(0);
-
-    PIDControllerMotorTheta2.setOutputLimits(-1, 1);
-    PIDControllerMotorTheta.setOutputLimits(-1, 1);
-
-    PIDControllerMotorTheta2.setInputLimits(-PI, PI);
-    PIDControllerMotorTheta.setInputLimits(-PI, PI);
-
-    PIDControllerMotorTheta.setSetPoint(0);
-    PIDControllerMotorTheta2.setSetPoint(0);
-
-    float currX, currY,currTheta;
-    float speedL,speedR;
-    float diffDir;
-    float xBuffer, yBuffer;
-    float xOriginalBuffer = 0, yOriginalBuffer = 0;
-    int initiateFlag = 1;
-    int dontSpinFlag = 0;
-    int atTargetFlag = 0;
-    int atTargetDirectionFlag = 0;
-
-    while (1) {
-        //kalman.statelock.lock();
-        if (ai.flag_terminate) {
-            // stops motors and teminates the thread
-            motors.coastStop();
-            terminate();
-        }
-
-        // stops motor
-        if ((ai.flag_motorStop) || (ObsAvoidPin > 0.5)) {
-            motors.stop();
-        } else if (ai.flag_manOverride) {
-
-        } else {
-
-
-            // get kalman localization estimate ------------------------
-            kalman.statelock.lock();
-            currX = kalman.X(0)*1000.0f;
-            currY = kalman.X(1)*1000.0f;
-            currTheta = kalman.X(2);
-            kalman.statelock.unlock();
-
-            // make a local copy of the target
-            ai.targetlock.lock();
-            AI::Target loctarget = ai.gettarget();
-            ai.targetlock.unlock();
-            
-            /*
-            //PID Tuning Code
-            if (pc.readable() == 1) {
-                float cmd;
-                pc.scanf("%f", &cmd);
-                //Tune PID referece
-                PIDControllerMotorTheta2.setTunings(cmd, 0, 0);
-            }
-            */
-
-
-            if (initiateFlag == 1) {
-                xOriginalBuffer = currX;
-                yOriginalBuffer = currY;
-
-                xBuffer = ai.gettarget().x;
-                yBuffer = ai.gettarget().y;
-
-                initiateFlag = 0;
-            }
-
-            if (xBuffer != loctarget.x || yBuffer != loctarget.y) {
-                //target changed
-                //update xOriginal and yOriginal buffers
-                xOriginalBuffer = currX;
-                yOriginalBuffer = currY;
-
-                xBuffer = loctarget.x;
-                yBuffer = loctarget.y;
-
-                atTargetFlag = 0;
-                atTargetDirectionFlag = 0;
-
-            }
-
-            // check if target reached ----------------------------------
-            if (atTargetFlag || hypot(currX - loctarget.x, currY - loctarget.y) < POSITION_TOR) {
-
-                if (atTargetFlag == 0) {
-                    motors.stop();
-                    Thread::wait(100);
-                }
-
-
-                if (hypot(currX - loctarget.x, currY - loctarget.y) < POSITION_TOR) {
-                    atTargetFlag = 1;
-                }
-                OLED4 = 1;
-
-                diffDir = rectifyAng(currTheta - loctarget.theta);
-                //diffSpeed = diffDir / PI;
-
-                PIDControllerMotorTheta.setProcessValue(diffDir);
-                float tempPidVar = PIDControllerMotorTheta.compute();
-                motors.setSpeed( -int(tempPidVar*MOVE_SPEED),  int(tempPidVar*MOVE_SPEED));
-
-                if (abs(diffDir) < ANGLE_TOR) {
-
-                    if (atTargetDirectionFlag == 0) {
-                        ai.thr_AI.signal_set(0x01);
-                        atTargetDirectionFlag = 1;
-                    }
-
-                    /*
-                    if (!loctarget.reached) {
-                        static int counter = 10;
-                        // guarding counter for reaching target
-                        if (counter-- == 0) {
-                            counter = 10;
-                            ai.target.reached = true;
-                            ai.thr_AI.signal_set(0x01);
-
-                        }
-                    }
-                    */
-                }
-            }
-
-            // adjust motion to reach target ----------------------------
-            else {
-
-                OLED3 = 1;
-
-                /*
-                if ((hypot(xOriginalBuffer - loctarget.x, yOriginalBuffer - loctarget.y) - hypot(xOriginalBuffer - currX, yOriginalBuffer - currY)) < 0) {
-                    loctarget.facing = !loctarget.facing;
-                    dontSpinFlag = 1;
-                } else {
-                    dontSpinFlag = 0;
-                }
-                */
-
-                // calc direction to target
-                float targetDir = atan2(loctarget.y - currY, loctarget.x - currX);
-                if (!loctarget.facing) targetDir =  targetDir + PI;
-
-                //Angle differene in -PI to PI
-                diffDir = rectifyAng(currTheta - targetDir);
-
-                //Set PID process variable
-                PIDControllerMotorTheta.setProcessValue(diffDir);
-                PIDControllerMotorTheta2.setProcessValue(diffDir);
-
-                //if diffDIr is neg, spin right
-                //if diffDir is pos, spin left
-
-                if ((abs(diffDir) > ANGLE_TOR*4) && (dontSpinFlag == 0)) {   //roughly 32 degrees
-                    //ANGLE_TOR*4
-                    float tempPidVar = PIDControllerMotorTheta.compute();
-                    motors.setSpeed( -int(tempPidVar*MOVE_SPEED),  int(tempPidVar*MOVE_SPEED));
-                    //pc.printf("m1Cmd,%f\n",diffDir);
-
-                } else {
-                    
-
-                    float tempPidVar = PIDControllerMotorTheta2.compute();
-                    float MoveSpeedLimiter = 1;
-                    //pc.printf("m1Speed,%f\n",diffDir);
-
-                    float distanceToX = (float)abs(currX - loctarget.x);
-                    float distanceToY = (float)abs(currY - loctarget.y);
-
-                    float distanceToTarget = hypot(distanceToX, distanceToY);
-
-                    if ((distanceToTarget < 400) && (distanceToTarget > 200)) {
-                        MoveSpeedLimiter = (distanceToTarget)/400;
-                    } else if (distanceToTarget <= 200) {
-                        MoveSpeedLimiter  = 0.5;
-                    }
-
-
-
-
-                    // calculte the motor speeds
-                    if (tempPidVar >= 0) {
-                        //turn left
-                        speedL = (1-abs(tempPidVar))*MOVE_SPEED*MoveSpeedLimiter;
-                        speedR = MOVE_SPEED*MoveSpeedLimiter;
-
-                    } else {
-                        //turn right
-                        speedR = (1-abs(tempPidVar))*MOVE_SPEED*MoveSpeedLimiter;
-                        speedL = MOVE_SPEED*MoveSpeedLimiter;
-                    }
-
-
-
-
-                    if (loctarget.facing) motors.setSpeed( int(speedL),  int(speedR));
-                    else motors.setSpeed( -int(speedR),  -int(speedL));
-                    
-                }
-            }
-        }
-        //kalman.statelock.unlock();
-        // wait
-        Thread::wait(MOTION_UPDATE_PERIOD);
-    }
-}
\ No newline at end of file
--- a/Eurobot_shared/Motion/motion.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include "motors.h"
-#include "ai.h"
-#include "Kalman.h"
-
-class Motion {
-public:
-    Motion(Motors &motorsin, AI &aiin, Kalman &kalmanin);
-    Thread thr_motion;
-
-private:
-    Motors& motors;
-    AI& ai;
-    Kalman& kalman;
-    
-    void motion_thread();
-    static void mtwrapper(void const *arg){ ((Motion*)arg)->motion_thread(); }
-
-};
\ No newline at end of file
--- a/Eurobot_shared/TSH.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#ifndef TSH_H
-#define TSH_H
-
-#include "rtos.h"
-
-//Thread Safe Hardware
-
-class TSI2C : public I2C {
-public:
-
-    TSI2C( PinName sda,
-           PinName scl,
-           const char* name=NULL )
-            : I2C(sda, scl, name) { }
-
-
-    int read( int address,
-              char* data,
-              int    length,
-              bool repeated = false ) {
-
-        rlock.lock();
-        int retval = I2C::read(address, data, length, repeated);
-        rlock.unlock();
-
-        return retval;
-    }
-
-    int read(int ack) {
-        rlock.lock();
-        int retval = I2C::read(ack);
-        rlock.unlock();
-
-        return retval;
-    }
-
-    int write( int address,
-               const char*    data,
-               int length,
-               bool repeated = false ) {
-
-        wlock.lock();
-        int retval = I2C::write(address, data, length, repeated);
-        wlock.unlock();
-
-        return retval;
-    }
-
-    int write(int data) {
-        wlock.lock();
-        int retval = I2C::write(data);
-        wlock.unlock();
-
-        return retval;
-    }
-
-private:
-    Mutex rlock;
-    Mutex wlock;
-};
-
-#endif
\ No newline at end of file
--- a/Eurobot_shared/ai/ai.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-#include "ai.h"
-#include "rtos.h"
-#include "globals.h"
-
-
-
-AI::AI() :
-    thr_AI(aithreadwrapper,this,osPriorityNormal,1024) {
-    flag_terminate = false;
-    flag_motorStop = true;
-    flag_manOverride = false;
-    //printf("aistart\r\n");
-}
-
-
-void AI::settarget(float targetX, float targetY, float targetTheta, bool targetfacing, bool colour, int maxSpeed ) {
-    targetlock.lock();
-    //MOVE_SPEED = maxSpeed;
-    target.x = targetX;
-    target.y = targetY;
-    target.theta = targetTheta;
-    target.facing = targetfacing;
-    target.reached = false;
-    if (!colour) {
-        target.x = 3000 - target.x;
-        target.theta = PI - target.theta;
-
-        target.theta -= (floor(target.theta/(2*PI)))*2*PI;
-        if (target.theta < -PI) {
-            target.theta += 2*PI;
-        }
-        if (target.theta > PI) {
-            target.theta -= 2*PI;
-        }
-
-
-    }
-    targetlock.unlock();
-}
-
-void AI::settarget(Target targetin) {
-    targetlock.lock();
-    target = targetin;
-    targetlock.unlock();
-}
-
-AI::Target AI::gettarget() {
-    targetlock.lock();
-    Target temptarget = target;
-    targetlock.unlock();
-    return temptarget;
-}
\ No newline at end of file
--- a/Eurobot_shared/ai/ai.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#ifndef AI_H
-#define AI_H
-
-#include "rtos.h"
-//#include "Kalman.h"
-
-class AI {
-public:
-AI();
-
-Mutex targetlock;
-Thread thr_AI;
-
-struct Target {
-    float x;
-    float y;
-    float theta;
-    bool facing;
-    bool reached;
-} target;
-
-void settarget(float targetX, float targetY, float targetTheta, bool targetfacing = true, bool colour = true, int maxSpeed = 35);
-void settarget(Target);
-Target gettarget();
-
-bool flag_terminate;// = false;
-bool flag_motorStop; // = true;
-bool flag_manOverride; // = false;
-
-private:
-
-void ai_thread ();
-static void aithreadwrapper(void const *arg){ ((AI*)arg)->ai_thread(); }
-
-};
-
-#endif //AI_H
\ No newline at end of file
--- a/Eurobot_shared/geometryfuncs/geometryfuncs.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#ifndef GEOMETRYFUNCS_H
-#define GEOMETRYFUNCS_H
-
-#include <tvmet/Matrix.h>
-
-template <typename T>
-Matrix <T, 2, 2> Rotmatrix(T theta) {
-     Matrix <T, 2, 2> outmatrix;
-     outmatrix = cos(theta), -sin(theta),
-                 sin(theta), cos(theta);
-     return outmatrix;
-}
-
-// rectifies angle to range -PI to PI
-template <typename T>
-T rectifyAng (T ang_in) {
-    ang_in -= (floor(ang_in/(2*PI)))*2*PI;
-    if (ang_in < -PI) {
-        ang_in += 2*PI;
-    }
-    if (ang_in > PI) {
-        ang_in -= 2*PI;
-    }
-
-    return ang_in;
-}
-
-#endif //GEOMETRYFUNCS_H
\ No newline at end of file
--- a/Eurobot_shared/system/system.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#include "system.h"
-
-//Defining the externs
-DigitalOut     OLED1(LED1);
-DigitalOut     OLED2(LED2);
-DigitalOut     OLED3(LED3);
-DigitalOut     OLED4(LED4);
-
-//nop style wait function
-void nopwait(int ms){
-while(ms--)
-    for (volatile int i = 0; i < 24000; i++);
-}
-
-float cpupercent; //defining the extern
-void measureCPUidle (void const* arg) {
-    
-    Timer timer;
-    cpupercent = 0; //defined in system.h
-    
-    while(1) {
-        timer.reset();
-        timer.start();
-        wait(1);
-        
-        int thistime = timer.read_us()-1000000;
-        cpupercent = thistime;
-    }
-}
\ No newline at end of file
--- a/Eurobot_shared/system/system.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-
-#ifndef SYSTEM_H
-#define SYSTEM_H
-
-#include "globals.h"
-#include "rtos.h"
-
-//Declaring the onboard LED's for everyone to use
-extern DigitalOut     OLED1;//(LED1);
-extern DigitalOut     OLED2;//(LED2);
-extern DigitalOut     OLED3;//(LED3);
-extern DigitalOut     OLED4;//(LED4);
-
-//nop style wait function
-void nopwait(int ms);
-
-//a type which is a pointer to a rtos thread function
-typedef void (*tfuncptr_t)(void const *argument);
-
-//---------------------
-//Signal ticker stuff
-#define SIGTICKARGS(thread, signal) \
-    (tfuncptr_t) (&Signalsetter::callback), osTimerPeriodic, (void*)(new Signalsetter(thread, signal))
-
-class Signalsetter {
-public:
-    Signalsetter(Thread& inthread, int insignal) :
-            thread(inthread) {
-        signal = insignal;
-        //pc.printf("ptr saved as %#x \r\n", (int)(&(inthread)));
-    }
-
-    static void callback(void* thisin) {
-
-        Signalsetter* fthis = (Signalsetter*)thisin;
-        //pc.printf("callback will signal thread object at %#x \r\n", (int)(&(fthis->thread)));
-        fthis->thread.signal_set(fthis->signal);
-        //delete fthis; //this is useful for single fire tickers!
-    }
-
-private:
-    Thread& thread;
-    int signal;
-};
-
-//---------------------
-//cpu usage measurement function
-extern float cpupercent;
-void measureCPUidle (void const* arg);
-
-#endif
--- a/Eurobot_shared/ui/ui.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-
-#include "ui.h"
-#include <iostream>
-#include "system.h"
-
-UI::UI() :
-        tUI(printtw,this,osPriorityNormal,2048) {
-    newdataflags = 0;
-    for (int i = 0; i < NUMIDS; i++) {
-        idlist[i] = 0;
-        buffarr[i] = 0;
-    }
-
-}
-
-bool UI::regid(char id, unsigned int length) {
-
-    //check if the id is already taken
-    if (id < NUMIDS && !idlist[id]) {
-        idlist[id] = length;
-        buffarr[id] = new float[length];
-        return true;
-    } else
-        return false;
-}
-
-bool UI::updateval(char id, float* buffer, unsigned int length) {
-    
-    //check if the id is registered, and has buffer of correct length
-    if (id < NUMIDS && idlist[id] == length && buffarr[id] && !(newdataflags & (1<<id))) {
-        for (int i = 0; i < length; i++)
-            buffarr[id][i] = buffer[i];
-        newdataflags |= (1<<id);
-        return true;
-    } else{
-        return false;
-    }
-}
-
-bool UI::updateval(char id, float value) {
-
-    //check if the id is registered, and the old value has been written
-    if (id < NUMIDS && idlist[id] == 1 && buffarr[id] && !(newdataflags & (1<<id))) {
-        buffarr[id][0] = value;
-        newdataflags |= (1<<id);
-        return true;
-    } else
-        return false;
-
-}
-
-bool UI::unregid(char id) {
-    if (id < NUMIDS) {
-        idlist[id] = 0;
-        if (buffarr[id])
-            delete buffarr[id];
-        return true;
-    } else
-        return false;
-}
-
-void UI::printloop() {
-
-#ifdef UION
-    Thread::wait(1500);
-#else
-    Thread::wait(osWaitForever);
-#endif
-
-    char* sync = "ABCD";
-    std::cout.write(sync, 4);
-    //std::cout.flush();
-    std::cout << std::endl;
-    //printf("\r\n");
-
-    while (1) {
-    
-        OLED3 = !OLED3;
-    
-        //send number of packets
-        char numtosend = 0;
-        for (int id = 0; id < NUMIDS; id++)
-            if (newdataflags & (1<<id))
-                numtosend++;
-                
-        std::cout.put(numtosend);
-
-        //send packets
-        for (char id = 0; id < NUMIDS; id++) {
-            if (newdataflags & (1<<id)) {
-                std::cout.put(id);
-                std::cout.write((char*)buffarr[id], idlist[id] * sizeof(float));
-                newdataflags &= ~(1<<id);
-            }
-        }
-        
-        std::cout << std::endl;
-        //std::cout.flush();
-        Thread::wait(200);
-    }
-
-}
-
--- a/Eurobot_shared/ui/ui.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-
-#ifndef UI_H
-#define UI_H
-
-#include "rtos.h"
-
-#define NUMIDS 32
-
-class UI {
-public:
-    Thread tUI;
-    
-    UI();
-    
-    bool regid(char id, unsigned int length);
-    bool updateval(char id, float* buffer, unsigned int length);
-    bool updateval(char id, float value);
-    bool unregid(char id);
-    
-private:
-    Mutex printlock;
-    char idlist[NUMIDS];
-    float* buffarr[NUMIDS];
-    volatile int newdataflags; //Only works for NUMID = 32
-    
-    void printloop();
-    static void printtw(void const *arg){ ((UI*)arg)->printloop(); }
-};
-
-#endif //UI_H
--- a/PID.lib	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/aberk/libraries/PID/le4dor
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PID/PID.cpp	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,324 @@
+/**
+ * @author Aaron Berk
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ * 
+ * A PID controller is a widely used feedback controller commonly found in
+ * industry.
+ *
+ * This library is a port of Brett Beauregard's Arduino PID library:
+ *
+ *  http://www.arduino.cc/playground/Code/PIDLibrary
+ *
+ * The wikipedia article on PID controllers is a good place to start on
+ * understanding how they work:
+ *
+ *  http://en.wikipedia.org/wiki/PID_controller
+ *
+ * For a clear and elegant explanation of how to implement and tune a
+ * controller, the controlguru website by Douglas J. Cooper (who also happened
+ * to be Brett's controls professor) is an excellent reference:
+ *
+ *  http://www.controlguru.com/
+ */
+
+/**
+ * Includes
+ */
+#include "PID.h"
+
+PID::PID(float Kc, float tauI, float tauD, float interval) {
+
+    usingFeedForward = false;
+    inAuto           = false;
+
+    //Default the limits to the full range of I/O: 3.3V
+    //Make sure to set these to more appropriate limits for
+    //your application.
+    setInputLimits(0.0, 3.3);
+    setOutputLimits(0.0, 3.3);
+
+    tSample_ = interval;
+
+    setTunings(Kc, tauI, tauD);
+
+    setPoint_             = 0.0;
+    processVariable_      = 0.0;
+    prevProcessVariable_  = 0.0;
+    controllerOutput_     = 0.0;
+    prevControllerOutput_ = 0.0;
+
+    accError_ = 0.0;
+    bias_     = 0.0;
+    
+    realOutput_ = 0.0;
+
+}
+
+void PID::setInputLimits(float inMin, float inMax) {
+
+    //Make sure we haven't been given impossible values.
+    if (inMin >= inMax) {
+        return;
+    }
+
+    //Rescale the working variables to reflect the changes.
+    prevProcessVariable_ *= (inMax - inMin) / inSpan_;
+    accError_            *= (inMax - inMin) / inSpan_;
+
+    //Make sure the working variables are within the new limits.
+    if (prevProcessVariable_ > 1) {
+        prevProcessVariable_ = 1;
+    } else if (prevProcessVariable_ < 0) {
+        prevProcessVariable_ = 0;
+    }
+
+    inMin_  = inMin;
+    inMax_  = inMax;
+    inSpan_ = inMax - inMin;
+
+}
+
+void PID::setOutputLimits(float outMin, float outMax) {
+
+    //Make sure we haven't been given impossible values.
+    if (outMin >= outMax) {
+        return;
+    }
+
+    //Rescale the working variables to reflect the changes.
+    prevControllerOutput_ *= (outMax - outMin) / outSpan_;
+
+    //Make sure the working variables are within the new limits.
+    if (prevControllerOutput_ > 1) {
+        prevControllerOutput_ = 1;
+    } else if (prevControllerOutput_ < 0) {
+        prevControllerOutput_ = 0;
+    }
+
+    outMin_  = outMin;
+    outMax_  = outMax;
+    outSpan_ = outMax - outMin;
+
+}
+
+void PID::setTunings(float Kc, float tauI, float tauD) {
+
+    //Verify that the tunings make sense.
+    if (Kc == 0.0 || tauI < 0.0 || tauD < 0.0) {
+        return;
+    }
+
+    //Store raw values to hand back to user on request.
+    pParam_ = Kc;
+    iParam_ = tauI;
+    dParam_ = tauD;
+
+    float tempTauR;
+
+    if (tauI == 0.0) {
+        tempTauR = 0.0;
+    } else {
+        tempTauR = (1.0 / tauI) * tSample_;
+    }
+
+    //For "bumpless transfer" we need to rescale the accumulated error.
+    if (inAuto) {
+        if (tempTauR == 0.0) {
+            accError_ = 0.0;
+        } else {
+            accError_ *= (Kc_ * tauR_) / (Kc * tempTauR);
+        }
+    }
+
+    Kc_   = Kc;
+    tauR_ = tempTauR;
+    tauD_ = tauD / tSample_;
+
+}
+
+void PID::reset(void) {
+
+    float scaledBias = 0.0;
+
+    if (usingFeedForward) {
+        scaledBias = (bias_ - outMin_) / outSpan_;
+    } else {
+        scaledBias = (realOutput_ - outMin_) / outSpan_;
+    }
+
+    prevControllerOutput_ = scaledBias;
+    prevProcessVariable_  = (processVariable_ - inMin_) / inSpan_;
+
+    //Clear any error in the integral.
+    accError_ = 0;
+
+}
+
+void PID::setMode(int mode) {
+
+    //We were in manual, and we just got set to auto.
+    //Reset the controller internals.
+    if (mode != 0 && !inAuto) {
+        reset();
+    }
+
+    inAuto = (mode != 0);
+
+}
+
+void PID::setInterval(float interval) {
+
+    if (interval > 0) {
+        //Convert the time-based tunings to reflect this change.
+        tauR_     *= (interval / tSample_);
+        accError_ *= (tSample_ / interval);
+        tauD_     *= (interval / tSample_);
+        tSample_   = interval;
+    }
+
+}
+
+void PID::setSetPoint(float sp) {
+
+    setPoint_ = sp;
+
+}
+
+void PID::setProcessValue(float pv) {
+
+    processVariable_ = pv;
+
+}
+
+void PID::setBias(float bias){
+
+    bias_ = bias;
+    usingFeedForward = 1;
+
+}
+
+float PID::compute() {
+
+    //Pull in the input and setpoint, and scale them into percent span.
+    float scaledPV = (processVariable_ - inMin_) / inSpan_;
+
+    if (scaledPV > 1.0) {
+        scaledPV = 1.0;
+    } else if (scaledPV < 0.0) {
+        scaledPV = 0.0;
+    }
+
+    float scaledSP = (setPoint_ - inMin_) / inSpan_;
+    if (scaledSP > 1.0) {
+        scaledSP = 1;
+    } else if (scaledSP < 0.0) {
+        scaledSP = 0;
+    }
+
+    float error = scaledSP - scaledPV;
+
+    //Check and see if the output is pegged at a limit and only
+    //integrate if it is not. This is to prevent reset-windup.
+    if (!(prevControllerOutput_ >= 1 && error > 0) && !(prevControllerOutput_ <= 0 && error < 0)) {
+        accError_ += error;
+    }
+
+    //Compute the current slope of the input signal.
+    float dMeas = (scaledPV - prevProcessVariable_) / tSample_;
+
+    float scaledBias = 0.0;
+
+    if (usingFeedForward) {
+        scaledBias = (bias_ - outMin_) / outSpan_;
+    }
+
+    //Perform the PID calculation.
+    controllerOutput_ = scaledBias + Kc_ * (error + (tauR_ * accError_) - (tauD_ * dMeas));
+
+    //Make sure the computed output is within output constraints.
+    if (controllerOutput_ < 0.0) {
+        controllerOutput_ = 0.0;
+    } else if (controllerOutput_ > 1.0) {
+        controllerOutput_ = 1.0;
+    }
+
+    //Remember this output for the windup check next time.
+    prevControllerOutput_ = controllerOutput_;
+    //Remember the input for the derivative calculation next time.
+    prevProcessVariable_  = scaledPV;
+
+    //Scale the output from percent span back out to a real world number.
+    return ((controllerOutput_ * outSpan_) + outMin_);
+
+}
+
+float PID::getInMin() {
+
+    return inMin_;
+
+}
+
+float PID::getInMax() {
+
+    return inMax_;
+
+}
+
+float PID::getOutMin() {
+
+    return outMin_;
+
+}
+
+float PID::getOutMax() {
+
+    return outMax_;
+
+}
+
+float PID::getInterval() {
+
+    return tSample_;
+
+}
+
+float PID::getPParam() {
+
+    return pParam_;
+
+}
+
+float PID::getIParam() {
+
+    return iParam_;
+
+}
+
+float PID::getDParam() {
+
+    return dParam_;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PID/PID.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,213 @@
+/**
+ * @author Aaron Berk
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ * 
+ * A PID controller is a widely used feedback controller commonly found in
+ * industry.
+ *
+ * This library is a port of Brett Beauregard's Arduino PID library:
+ *
+ *  http://www.arduino.cc/playground/Code/PIDLibrary
+ *
+ * The wikipedia article on PID controllers is a good place to start on
+ * understanding how they work:
+ *
+ *  http://en.wikipedia.org/wiki/PID_controller
+ *
+ * For a clear and elegant explanation of how to implement and tune a
+ * controller, the controlguru website by Douglas J. Cooper (who also happened
+ * to be Brett's controls professor) is an excellent reference:
+ *
+ *  http://www.controlguru.com/
+ */
+
+#ifndef PID_H
+#define PID_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+/**
+ * Defines
+ */
+#define MANUAL_MODE 0
+#define AUTO_MODE   1
+
+/**
+ * Proportional-integral-derivative controller.
+ */
+class PID {
+
+public:
+
+    /**
+     * Constructor.
+     *
+     * Sets default limits [0-3.3V], calculates tuning parameters, and sets
+     * manual mode with no bias.
+     *
+     * @param Kc - Tuning parameter
+     * @param tauI - Tuning parameter
+     * @param tauD - Tuning parameter
+     * @param interval PID calculation performed every interval seconds.
+     */
+    PID(float Kc, float tauI, float tauD, float interval);
+
+    /**
+     * Scale from inputs to 0-100%.
+     *
+     * @param InMin The real world value corresponding to 0%.
+     * @param InMax The real world value corresponding to 100%.
+     */
+    void setInputLimits(float inMin , float inMax);
+
+    /**
+     * Scale from outputs to 0-100%.
+     *
+     * @param outMin The real world value corresponding to 0%.
+     * @param outMax The real world value corresponding to 100%.
+     */
+    void setOutputLimits(float outMin, float outMax);
+
+    /**
+     * Calculate PID constants.
+     *
+     * Allows parameters to be changed on the fly without ruining calculations.
+     *
+     * @param Kc - Tuning parameter
+     * @param tauI - Tuning parameter
+     * @param tauD - Tuning parameter
+     */
+    void setTunings(float Kc, float tauI, float tauD);
+
+    /**
+     * Reinitializes controller internals. Automatically
+     * called on a manual to auto transition.
+     */
+    void reset(void);
+    
+    /**
+     * Set PID to manual or auto mode.
+     *
+     * @param mode        0 -> Manual
+     *             Non-zero -> Auto
+     */
+    void setMode(int mode);
+    
+    /**
+     * Set how fast the PID loop is run.
+     *
+     * @param interval PID calculation peformed every interval seconds.
+     */
+    void setInterval(float interval);
+    
+    /**
+     * Set the set point.
+     *
+     * @param sp The set point as a real world value.
+     */
+    void setSetPoint(float sp);
+    
+    /**
+     * Set the process value.
+     *
+     * @param pv The process value as a real world value.
+     */
+    void setProcessValue(float pv);
+    
+    /**
+     * Set the bias.
+     *
+     * @param bias The bias for the controller output.
+     */
+    void setBias(float bias);
+
+    /**
+     * PID calculation.
+     *
+     * @return The controller output as a float between outMin and outMax.
+     */
+    float compute(void);
+
+    //Getters.
+    float getInMin();
+    float getInMax();
+    float getOutMin();
+    float getOutMax();
+    float getInterval();
+    float getPParam();
+    float getIParam();
+    float getDParam();
+
+private:
+
+    bool usingFeedForward;
+    bool inAuto;
+
+    //Actual tuning parameters used in PID calculation.
+    float Kc_;
+    float tauR_;
+    float tauD_;
+    
+    //Raw tuning parameters.
+    float pParam_;
+    float iParam_;
+    float dParam_;
+    
+    //The point we want to reach.
+    float setPoint_;         
+    //The thing we measure.
+    float processVariable_;  
+    float prevProcessVariable_;
+    //The output that affects the process variable.
+    float controllerOutput_; 
+    float prevControllerOutput_;
+
+    //We work in % for calculations so these will scale from
+    //real world values to 0-100% and back again.
+    float inMin_;
+    float inMax_;
+    float inSpan_;
+    float outMin_;
+    float outMax_;
+    float outSpan_;
+
+    //The accumulated error, i.e. integral.
+    float accError_;
+    //The controller output bias.
+    float bias_;
+
+    //The interval between samples.
+    float tSample_;          
+
+    //Controller output as a real world value.
+    volatile float realOutput_;
+
+};
+
+#endif /* PID_H */
--- a/QEI.lib	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/aberk/libraries/QEI/le4bkf
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QEI/QEI.cpp	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,289 @@
+/**
+ * @author Aaron Berk
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * Quadrature Encoder Interface.
+ *
+ * A quadrature encoder consists of two code tracks on a disc which are 90
+ * degrees out of phase. It can be used to determine how far a wheel has
+ * rotated, relative to a known starting position.
+ *
+ * Only one code track changes at a time leading to a more robust system than
+ * a single track, because any jitter around any edge won't cause a state
+ * change as the other track will remain constant.
+ *
+ * Encoders can be a homebrew affair, consisting of infrared emitters/receivers
+ * and paper code tracks consisting of alternating black and white sections;
+ * alternatively, complete disk and PCB emitter/receiver encoder systems can
+ * be bought, but the interface, regardless of implementation is the same.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |  ^  |     |     |     |     |
+ *            ---+  ^  +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  +-----+     +-----+     +-----+
+ * Channel B     ^  |     |     |     |     |     |
+ *            ------+     +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  ^
+ *               90deg
+ *
+ * The interface uses X2 encoding by default which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * channel A.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^     ^     ^     ^     ^
+ *               ^     ^     ^     ^     ^
+ * Pulse count 0 1     2     3     4     5  ...
+ *
+ * This interface can also use X4 encoding which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * either channel.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ *
+ * It defaults
+ *
+ * An optional index channel can be used which determines when a full
+ * revolution has occured.
+ *
+ * If a 4 pules per revolution encoder was used, with X4 encoding,
+ * the following would be observed.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  +--+  ^  ^  +--+  ^
+ *               ^  ^  ^  |  |  ^  ^  |  |  ^
+ * Index      ------------+  +--------+  +-----------
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ * Rev.  count 0          1           2
+ *
+ * Rotational position in degrees can be calculated by:
+ *
+ * (pulse count / X * N) * 360
+ *
+ * Where X is the encoding type [e.g. X4 encoding => X=4], and N is the number
+ * of pulses per revolution.
+ *
+ * Linear position can be calculated by:
+ *
+ * (pulse count / X * N) * (1 / PPI)
+ *
+ * Where X is encoding type [e.g. X4 encoding => X=44], N is the number of
+ * pulses per revolution, and PPI is pulses per inch, or the equivalent for
+ * any other unit of displacement. PPI can be calculated by taking the
+ * circumference of the wheel or encoder disk and dividing it by the number
+ * of pulses per revolution.
+ */
+
+/**
+ * Includes
+ */
+#include "QEI.h"
+
+QEI::QEI(PinName channelA,
+         PinName channelB,
+         PinName index,
+         int pulsesPerRev,
+         Encoding encoding) : channelA_(channelA), channelB_(channelB),
+        index_(index) {
+
+    pulses_       = 0;
+    revolutions_  = 0;
+    pulsesPerRev_ = pulsesPerRev;
+    encoding_     = encoding;
+
+    //Workout what the current state is.
+    int chanA = channelA_.read();
+    int chanB = channelB_.read();
+
+    //2-bit state.
+    currState_ = (chanA << 1) | (chanB);
+    prevState_ = currState_;
+
+    //X2 encoding uses interrupts on only channel A.
+    //X4 encoding uses interrupts on      channel A,
+    //and on channel B.
+    channelA_.rise(this, &QEI::encode);
+    channelA_.fall(this, &QEI::encode);
+
+    //If we're using X4 encoding, then attach interrupts to channel B too.
+    if (encoding == X4_ENCODING) {
+        channelB_.rise(this, &QEI::encode);
+        channelB_.fall(this, &QEI::encode);
+    }
+    //Index is optional.
+    if (index !=  NC) {
+        index_.rise(this, &QEI::index);
+    }
+
+}
+
+void QEI::reset(void) {
+
+    pulses_      = 0;
+    revolutions_ = 0;
+
+}
+
+int QEI::getCurrentState(void) {
+
+    return currState_;
+
+}
+
+int QEI::getPulses(void) {
+
+    return pulses_;
+
+}
+
+int QEI::getRevolutions(void) {
+
+    return revolutions_;
+
+}
+
+// +-------------+
+// | X2 Encoding |
+// +-------------+
+//
+// When observing states two patterns will appear:
+//
+// Counter clockwise rotation:
+//
+// 10 -> 01 -> 10 -> 01 -> ...
+//
+// Clockwise rotation:
+//
+// 11 -> 00 -> 11 -> 00 -> ...
+//
+// We consider counter clockwise rotation to be "forward" and
+// counter clockwise to be "backward". Therefore pulse count will increase
+// during counter clockwise rotation and decrease during clockwise rotation.
+//
+// +-------------+
+// | X4 Encoding |
+// +-------------+
+//
+// There are four possible states for a quadrature encoder which correspond to
+// 2-bit gray code.
+//
+// A state change is only valid if of only one bit has changed.
+// A state change is invalid if both bits have changed.
+//
+// Clockwise Rotation ->
+//
+//    00 01 11 10 00
+//
+// <- Counter Clockwise Rotation
+//
+// If we observe any valid state changes going from left to right, we have
+// moved one pulse clockwise [we will consider this "backward" or "negative"].
+//
+// If we observe any valid state changes going from right to left we have
+// moved one pulse counter clockwise [we will consider this "forward" or
+// "positive"].
+//
+// We might enter an invalid state for a number of reasons which are hard to
+// predict - if this is the case, it is generally safe to ignore it, update
+// the state and carry on, with the error correcting itself shortly after.
+void QEI::encode(void) {
+
+    int change = 0;
+    int chanA  = channelA_.read();
+    int chanB  = channelB_.read();
+
+    //2-bit state.
+    currState_ = (chanA << 1) | (chanB);
+
+    if (encoding_ == X2_ENCODING) {
+
+        //11->00->11->00 is counter clockwise rotation or "forward".
+        if ((prevState_ == 0x3 && currState_ == 0x0) ||
+                (prevState_ == 0x0 && currState_ == 0x3)) {
+
+            pulses_++;
+
+        }
+        //10->01->10->01 is clockwise rotation or "backward".
+        else if ((prevState_ == 0x2 && currState_ == 0x1) ||
+                 (prevState_ == 0x1 && currState_ == 0x2)) {
+
+            pulses_--;
+
+        }
+
+    } else if (encoding_ == X4_ENCODING) {
+
+        //Entered a new valid state.
+        if (((currState_ ^ prevState_) != INVALID) && (currState_ != prevState_)) {
+            //2 bit state. Right hand bit of prev XOR left hand bit of current
+            //gives 0 if clockwise rotation and 1 if counter clockwise rotation.
+            change = (prevState_ & PREV_MASK) ^ ((currState_ & CURR_MASK) >> 1);
+
+            if (change == 0) {
+                change = -1;
+            }
+
+            pulses_ -= change;
+        }
+
+    }
+
+    prevState_ = currState_;
+
+}
+
+void QEI::index(void) {
+
+    revolutions_++;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QEI/QEI.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,244 @@
+/**
+ * @author Aaron Berk
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * Quadrature Encoder Interface.
+ *
+ * A quadrature encoder consists of two code tracks on a disc which are 90
+ * degrees out of phase. It can be used to determine how far a wheel has
+ * rotated, relative to a known starting position.
+ *
+ * Only one code track changes at a time leading to a more robust system than
+ * a single track, because any jitter around any edge won't cause a state
+ * change as the other track will remain constant.
+ *
+ * Encoders can be a homebrew affair, consisting of infrared emitters/receivers
+ * and paper code tracks consisting of alternating black and white sections;
+ * alternatively, complete disk and PCB emitter/receiver encoder systems can
+ * be bought, but the interface, regardless of implementation is the same.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |  ^  |     |     |     |     |
+ *            ---+  ^  +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  +-----+     +-----+     +-----+
+ * Channel B     ^  |     |     |     |     |     |
+ *            ------+     +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  ^
+ *               90deg
+ *
+ * The interface uses X2 encoding by default which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * channel A.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^     ^     ^     ^     ^
+ *               ^     ^     ^     ^     ^
+ * Pulse count 0 1     2     3     4     5  ...
+ *
+ * This interface can also use X4 encoding which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * either channel.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ *
+ * It defaults
+ *
+ * An optional index channel can be used which determines when a full
+ * revolution has occured.
+ *
+ * If a 4 pules per revolution encoder was used, with X4 encoding,
+ * the following would be observed.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  +--+  ^  ^  +--+  ^
+ *               ^  ^  ^  |  |  ^  ^  |  |  ^
+ * Index      ------------+  +--------+  +-----------
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ * Rev.  count 0          1           2
+ *
+ * Rotational position in degrees can be calculated by:
+ *
+ * (pulse count / X * N) * 360
+ *
+ * Where X is the encoding type [e.g. X4 encoding => X=4], and N is the number
+ * of pulses per revolution.
+ *
+ * Linear position can be calculated by:
+ *
+ * (pulse count / X * N) * (1 / PPI)
+ *
+ * Where X is encoding type [e.g. X4 encoding => X=44], N is the number of
+ * pulses per revolution, and PPI is pulses per inch, or the equivalent for
+ * any other unit of displacement. PPI can be calculated by taking the
+ * circumference of the wheel or encoder disk and dividing it by the number
+ * of pulses per revolution.
+ */
+
+#ifndef QEI_H
+#define QEI_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+/**
+ * Defines
+ */
+#define PREV_MASK 0x1 //Mask for the previous state in determining direction
+//of rotation.
+#define CURR_MASK 0x2 //Mask for the current state in determining direction
+//of rotation.
+#define INVALID   0x3 //XORing two states where both bits have changed.
+
+/**
+ * Quadrature Encoder Interface.
+ */
+class QEI {
+
+public:
+
+    typedef enum Encoding {
+
+        X2_ENCODING,
+        X4_ENCODING
+
+    } Encoding;
+
+    /**
+     * Constructor.
+     *
+     * Reads the current values on channel A and channel B to determine the
+     * initial state.
+     *
+     * Attaches the encode function to the rise/fall interrupt edges of
+     * channels A and B to perform X4 encoding.
+     *
+     * Attaches the index function to the rise interrupt edge of channel index
+     * (if it is used) to count revolutions.
+     *
+     * @param channelA mbed pin for channel A input.
+     * @param channelB mbed pin for channel B input.
+     * @param index    mbed pin for optional index channel input,
+     *                 (pass NC if not needed).
+     * @param pulsesPerRev Number of pulses in one revolution.
+     * @param encoding The encoding to use. Uses X2 encoding by default. X2
+     *                 encoding uses interrupts on the rising and falling edges
+     *                 of only channel A where as X4 uses them on both
+     *                 channels.
+     */
+    QEI(PinName channelA, PinName channelB, PinName index, int pulsesPerRev, Encoding encoding = X2_ENCODING);
+
+    /**
+     * Reset the encoder.
+     *
+     * Sets the pulses and revolutions count to zero.
+     */
+    void reset(void);
+
+    /**
+     * Read the state of the encoder.
+     *
+     * @return The current state of the encoder as a 2-bit number, where:
+     *         bit 1 = The reading from channel B
+     *         bit 2 = The reading from channel A
+     */
+    int getCurrentState(void);
+
+    /**
+     * Read the number of pulses recorded by the encoder.
+     *
+     * @return Number of pulses which have occured.
+     */
+    int getPulses(void);
+
+    /**
+     * Read the number of revolutions recorded by the encoder on the index channel.
+     *
+     * @return Number of revolutions which have occured on the index channel.
+     */
+    int getRevolutions(void);
+
+private:
+
+    /**
+     * Update the pulse count.
+     *
+     * Called on every rising/falling edge of channels A/B.
+     *
+     * Reads the state of the channels and determines whether a pulse forward
+     * or backward has occured, updating the count appropriately.
+     */
+    void encode(void);
+
+    /**
+     * Called on every rising edge of channel index to update revolution
+     * count by one.
+     */
+    void index(void);
+
+    Encoding encoding_;
+
+    InterruptIn channelA_;
+    InterruptIn channelB_;
+    InterruptIn index_;
+
+    int          pulsesPerRev_;
+    int          prevState_;
+    int          currState_;
+
+    volatile int pulses_;
+    volatile int revolutions_;
+
+};
+
+#endif /* QEI_H */
--- a/Servo/.lib	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/jdenkers/libraries/Servo/lgfiff
\ No newline at end of file
--- a/Servo/Servo.cpp	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#include "Servo.h"
-#include "mbed.h"
-
-    Servo::Servo(PinName Pin) : ServoPin(Pin) {}
-
-    void Servo::SetPosition(int Pos) {
-        Position = Pos;
-    }
-
-    void Servo::StartPulse() {
-        ServoPin = 1;
-        PulseStop.attach_us(this, &Servo::EndPulse, Position);
-    }
-
-    void Servo::EndPulse() {
-        ServoPin = 0;
-    }
-
-    void Servo::Enable(int StartPos, int Period) {
-        Position = StartPos;
-        Pulse.attach_us(this, &Servo::StartPulse, Period);
-    }
-
-    void Servo::Disable() {
-        Pulse.detach();
-    }
\ No newline at end of file
--- a/Servo/Servo.h	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/* mbed Servo Library without using PWM pins
- * Copyright (c) 2010 Jasper Denkers
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef MBED_SERVO_H
-#define MBED_SERVO_H
-
-#include "mbed.h"
-
-/** Class to control a servo on any pin, without using pwm
- *
- * Example:
- * @code
- * // Keep sweeping servo from left to right
- * #include "mbed.h"
- * #include "Servo.h"
- * 
- * Servo Servo1(p20);
- *
- * Servo1.Enable(1500,20000);
- *
- * while(1) {
- *     for (int pos = 1000; pos < 2000; pos += 25) {
- *         Servo1.SetPosition(pos);  
- *         wait_ms(20);
- *     }
- *     for (int pos = 2000; pos > 1000; pos -= 25) {
- *         Servo1.SetPosition(pos); 
- *         wait_ms(20); 
- *     }
- * }
- * @endcode
- */
-
-class Servo {
-
-public:
-    /** Create a new Servo object on any mbed pin
-     *
-     * @param Pin Pin on mbed to connect servo to
-     */
-    Servo(PinName Pin);
-    
-    /** Change the position of the servo. Position in us
-     *
-     * @param NewPos The new value of the servos position (us)
-     */
-    void SetPosition(int NewPos);
-    
-    /** Enable the servo. Without enabling the servo won't be running. Startposition and period both in us.
-     *
-     * @param StartPos The position of the servo to start (us) 
-     * @param Period The time between every pulse. 20000 us = 50 Hz(standard) (us)
-     */
-    void Enable(int StartPos, int Period);
-    
-    /** Disable the servo. After disabling the servo won't get any signal anymore
-     *
-     */
-    void Disable();
-
-private:
-    void StartPulse();
-    void EndPulse();
-
-    int Position;
-    DigitalOut ServoPin;
-    Ticker Pulse;
-    Timeout PulseStop;
-};
-
-#endif
\ No newline at end of file
--- a/globals.h	Fri May 04 05:23:45 2012 +0000
+++ b/globals.h	Wed Oct 17 22:22:28 2012 +0000
@@ -34,8 +34,8 @@
 //Robot movement constants
 const float fwdvarperunit = 0.01; //1 std dev = 7% //NEEDS TO BE MEASURED AGAIN!
 const float varperang = 0.01; //around 1 degree stddev per 180 turn
-const float xyvarpertime = 0;//0.0005; //(very poorly) accounts for hitting things
-const float angvarpertime = 0;//0.001;
+const float xyvarpertime = 0.0005; //(very poorly) accounts for hitting things
+const float angvarpertime = 0.001;
 
 //sonar constants
 static const float sonarvariance = 0.005;
@@ -71,7 +71,7 @@
 #define RELI_BOUND_HIGH         25
 
 // Movement target tolerances
-#define POSITION_TOR            40  // in mm
+#define POSITION_TOR            20  // in mm
 #define ANGLE_TOR               0.06 // in rad
 
 // motion control
@@ -85,8 +85,8 @@
 //#define TRACK_RATE              10       // +- rate for each wheel when tracking
 
 #ifdef ROBOT_PRIMARY
-#define FWD_MOVE_P 18
-#define SPIN_MOVE_P 5.8
+#define FWD_MOVE_P 20//18
+#define SPIN_MOVE_P 7//5.8
 #else
 #define FWD_MOVE_P 3.2
 #define SPIN_MOVE_P 4
--- a/main.cpp	Fri May 04 05:23:45 2012 +0000
+++ b/main.cpp	Wed Oct 17 22:22:28 2012 +0000
@@ -11,17 +11,21 @@
 #include "ai.h"
 #include "ui.h"
 #include "front_arms.h"
+#include "motion.h"
 
 //#include <iostream>
 
 //Interface declaration
 Serial pc(USBTX, USBRX); // tx, rx
 
+
+
+
 bool Colour = 1; // 1 for red, 0 for blue
 pos beaconpos[] = {{3000, 1000},{0,0}, {0,2000}}; //predefined red start
 
 DigitalIn StartTrig(p12);
-DigitalIn ColourToggle(p16); //high for red, low for blue(purple)
+DigitalIn ColourToggle(p22); //high for red, low for blue(purple)
 Ticker StopTicker;
 
 Motors motors;
@@ -36,14 +40,17 @@
 void vStop (void);
 
 //Main loop
-int main() {      
+int main() {
+    AnalogIn ObsAvoidPin(p20);
     // no motor motions till we pull the trig
     ai.flag_motorStop = true;
-    nopwait(1000);
-    Colour = ColourToggle;
+    Colour = !(ObsAvoidPin > 0.5);
+    OLED3 = Colour;
+    //nopwait(1000);
+    //Colour = ColourToggle;
     // re-defines beacon positions by the toggle switch
     kalman.statelock.lock();
-    if (Colour) {
+    if (true) {
         beaconpos[0].x = 3000;
         beaconpos[0].y = 1000;
         beaconpos[1].x = 0;
@@ -65,7 +72,7 @@
     pc.baud(115200);
     ArmsEnable();
     ArmsClose();
-    
+
 
     //Init kalman, this should be done in the mid of the arena before the game starts
     kalman.KalmanInit();
@@ -76,9 +83,9 @@
 
     pc.printf("We got to main! ;D\r\n");
     if (Colour)
-    printf("I'm in Red \n\r");
+        printf("I'm in Red \n\r");
     else
-    printf("I'm in Blue \n\r");
+        printf("I'm in Blue \n\r");
 
     //REMEMBERT TO PUT PULL UP RESISTORS ON I2C!!!!!!!!!!!!!!
     while (1) {
@@ -103,6 +110,8 @@
 }
 
 void AI::ai_thread () {
+
+    motors.accelerationRegister = 1;
     /*
     //printf("aithreadstart\r\n");
     Thread::signal_wait(0x01);
@@ -126,91 +135,120 @@
     while (!StartTrig) {
         Thread::wait(10);
     };
-    
+
     printf("GO! \r\n");
     kalman.KalmanReset();
     Thread::wait(100);
-    
-    
+
+
 
     // attach a 87 seconds stop timer
-    
-    
+
+
     //REPLACE TICKER!!!!
     StopTicker.attach(&vStop, 87);
 
 
     // starts motors
     ai.flag_motorStop = false;
-    
+
     // no override
     ai.flag_manOverride = false;
-      
+
 
 //if (Colour){
     // strat 1 RED ==================================
     ArmsOpen();
-    //Thread::wait(500);    
-        
+    //Thread::wait(500);
+
     // goto middle x
     settarget(1500, 250, PI/2, true,Colour, 35);
     Thread::signal_wait(0x01);
     Thread::wait(2000);
-        
+
     // to palm tree
     settarget(1500, 1000, PI, true,Colour, 35);
     Thread::signal_wait(0x01);
-    Thread::wait(2000);
+    Thread::wait(4000);
 
     // run over totem
-    settarget(800,1050,PI, true,Colour, 60);
+    settarget(840,1000,PI, true,Colour, 80);
+    motors.accelerationRegister = 0;
+    Thread::wait(5000);
+    //Thread::signal_wait(0x01);
+
+    while (hypot(kalman.X(0) - 1.1f, kalman.X(1) - 1.0f) < 0.10) {
+        // to palm tree
+        settarget(1500, 1000, PI, false,Colour, 35);
+        Thread::signal_wait(0x01);
+        Thread::wait(4000);
+
+        // run over totem
+        settarget(840,1000,PI, true,Colour, 80);
+        motors.accelerationRegister = 0;
+        Thread::wait(5000);
+    }
     Thread::signal_wait(0x01);
-    Thread::wait(2000);
 
+    motors.accelerationRegister = 1;
+   
+    // back to ship
+    settarget(220,1000,0,true,Colour, 50);
+    Thread::signal_wait(0x01);
+    
     ArmsClose();
-    // back to ship
-    settarget(220,780,PI,true,Colour, 35);   
+    
+    settarget(840,1000,PI, true,Colour, 40);
     Thread::signal_wait(0x01);
-    Thread::wait(2000);
+    
+     
+     
+     settarget(220,1000,PI,true,Colour, 40);
+    Thread::signal_wait(0x01);
+    
+     settarget(840,1000,PI,false,Colour, 40);
+    Thread::signal_wait(0x01);
+    
+   
 //}
 
-/*else{
-    // strat 1 BLUE ==================================
-    // goto middle x
-    settarget(3000-1500, 250, PI/2, true);
-    Thread::signal_wait(0x01);
-    Thread::wait(2000);
-
-    // to palm tree
-    settarget(3000-1500, 1000, 0, true);
-    Thread::signal_wait(0x01);
-    Thread::wait(2000);
-
-    // run over totem
-    settarget(3000-640,1000,0, true);
-    Thread::signal_wait(0x01);
-    Thread::wait(2000);
+    /*else{
+        // strat 1 BLUE ==================================
+        // goto middle x
+        settarget(3000-1500, 250, PI/2, true);
+        Thread::signal_wait(0x01);
+        Thread::wait(2000);
 
-    // back to ship
-    settarget(3000-220,780,0,true);
-    Thread::signal_wait(0x01);
-    Thread::wait(2000); 
-}
-*/
-/*
-// going from ship to ship for the remaining secs
-    while (true){
-    // back to home, RED
-    settarget(500,400,PI,true);
-    Thread::signal_wait(0x01);
-    Thread::wait(2000);
-    
-    // back to ship, BLUE
-    settarget(500,1600,0,true);
-    Thread::signal_wait(0x01);
-    Thread::wait(2000);
+        // to palm tree
+        settarget(3000-1500, 1000, 0, true);
+        Thread::signal_wait(0x01);
+        Thread::wait(2000);
+
+        // run over totem
+        settarget(3000-640,1000,0, true);
+        Thread::signal_wait(0x01);
+        Thread::wait(2000);
+
+        // back to ship
+        settarget(3000-220,780,0,true);
+        Thread::signal_wait(0x01);
+        Thread::wait(2000);
     }
     */
+    /*
+    // going from ship to ship for the remaining secs
+        while (true){
+        // back to home, RED
+        settarget(500,400,PI,true);
+        Thread::signal_wait(0x01);
+        Thread::wait(2000);
+
+        // back to ship, BLUE
+        settarget(500,1600,0,true);
+        Thread::signal_wait(0x01);
+        Thread::wait(2000);
+        }
+        */
 
     // terminate thread, stopps motors permanently
     ai.flag_terminate = true;
@@ -274,9 +312,9 @@
 
 void vStop (void) {
 //    while (true) {
-        motors.coastStop();   
-        ai.flag_motorStop = true;
-        // terminate thread, stopps motors permanently
-        ai.flag_terminate = true;
+    motors.coastStop();
+    ai.flag_motorStop = true;
+    // terminate thread, stopps motors permanently
+    ai.flag_terminate = true;
 //    };
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479
\ No newline at end of file
--- a/mbed.lib	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/projects/libraries/svn/mbed/trunk@43
\ No newline at end of file
--- a/rtos.lib	Fri May 04 05:23:45 2012 +0000
+++ b/rtos.lib	Wed Oct 17 22:22:28 2012 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/projects/libraries-testing/svn/rtos@43
\ No newline at end of file
+http://mbed.org/users/narshu/code/Eurobot_2012_Primary/#62626fd22b30
--- a/tvmet.lib	Fri May 04 05:23:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/madcowswe/libraries/tvmet/m7lmpz
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/AliasProxy.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,128 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: AliasProxy.h,v 1.8 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_ALIAS_PROXY_H
+#define TVMET_ALIAS_PROXY_H
+
+namespace tvmet {
+
+
+/** forwards */
+template<class E> class AliasProxy;
+
+
+/**
+ * \brief Simplify syntax for alias Matrices and Vectors,
+ *        where aliasing left hand values appear in the
+ *        expression.
+ * \par Example:
+ * \code
+ * typedef tvmet::Matrix<double, 10, 10>	matrix_type;
+ * matrix_type					m;
+ * ...
+ * alias(m) += trans(m);
+ * \endcode
+ * \sa AliasProxy
+ * \sa Some Notes \ref alias
+ */
+template<class E>
+AliasProxy<E> alias(E& expr) { return AliasProxy<E>(expr); }
+
+
+/**
+ * \class AliasProxy AliasProxy.h "tvmet/AliasProxy.h"
+ * \brief Assign proxy for alias Matrices and Vectors.
+ *
+ *        A short lived object to provide simplified alias syntax.
+ *        Only the friend function alias is allowed to create
+ *        such a object. The proxy calls the appropriate member
+ *        alias_xyz() which have to use temporaries to avoid
+ *        overlapping memory regions.
+ * \sa alias
+ * \sa Some Notes \ref alias
+ * \note Thanks to ublas-dev group, where the principle idea
+ *       comes from.
+ */
+template<class E>
+class AliasProxy
+{
+  AliasProxy(const AliasProxy&);
+  AliasProxy& operator=(const AliasProxy&);
+
+  friend AliasProxy<E> alias<>(E& expr);
+
+public:
+  AliasProxy(E& expr) : m_expr(expr) { }
+
+
+  template<class E2>
+  E& operator=(const E2& expr) {
+    return m_expr.alias_assign(expr);
+  }
+
+  template<class E2>
+  E& operator+=(const E2& expr) {
+    return m_expr.alias_add_eq(expr);
+  }
+
+  template<class E2>
+  E& operator-=(const E2& expr) {
+    return m_expr.alias_sub_eq(expr);
+  }
+
+  template<class E2>
+  E& operator*=(const E2& expr) {
+    return m_expr.alias_mul_eq(expr);
+  }
+
+  template<class E2>
+  E& operator/=(const E2& expr) {
+    return m_expr.alias_div_eq(expr);
+  }
+
+private:
+  E&						m_expr;
+};
+
+
+#if 0
+namespace element_wise {
+// \todo to write
+template<class E, class E2>
+E& operator/=(AliasProxy<E>& proxy, const E2& rhs) {
+  return proxy.div_upd(rhs);
+}
+
+}
+#endif
+
+
+} // namespace tvmet
+
+
+#endif /* TVMET_ALIAS_PROXY_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/BinaryFunctionals.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,303 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: BinaryFunctionals.h,v 1.24 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_BINARY_FUNCTIONAL_H
+#define TVMET_BINARY_FUNCTIONAL_H
+
+namespace tvmet {
+
+
+/**
+ * \class Fcnl_assign BinaryFunctionals.h "tvmet/BinaryFunctionals.h"
+ * \brief Binary operator for assign operations.
+ *
+ * Unfortunally we have sometimes to cast on assign operations e.g.,
+ * on assign on different POD. So we avoid warnings.
+ */
+template <class T1, class T2>
+struct Fcnl_assign : public BinaryFunctional {
+  static inline
+  void apply_on(T1& _tvmet_restrict lhs, T2 rhs) {
+    lhs = static_cast<T1>(rhs);
+  }
+
+  static
+  void print_xpr(std::ostream& os, std::size_t l=0) {
+    os << IndentLevel(l) << "fcnl_assign<T1="
+       << typeid(T1).name() << ", T2=" << typeid(T2).name() << ">,"
+       << std::endl;
+  }
+};
+
+
+/** \class Fcnl_add_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_sub_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_mul_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_div_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_mod_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_xor_eq		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_and_eq		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_or_eq		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_shl_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_shr_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template <class T1, class T2>						\
+struct Fcnl_##NAME : public BinaryFunctional {				\
+  typedef void						value_type;	\
+									\
+  static inline								\
+  void apply_on(T1& _tvmet_restrict lhs, T2 rhs) {			\
+    lhs OP rhs;								\
+  }									\
+									\
+  static								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l)						\
+       << "Fcnl_" << #NAME << "<T1="					\
+       << typeid(T1).name() << ", T2=" << typeid(T2).name() << ">,"	\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(add_eq, +=)
+TVMET_IMPLEMENT_MACRO(sub_eq, -=)
+TVMET_IMPLEMENT_MACRO(mul_eq, *=)
+TVMET_IMPLEMENT_MACRO(div_eq, /=)
+TVMET_IMPLEMENT_MACRO(mod_eq, %=)
+TVMET_IMPLEMENT_MACRO(xor_eq, ^=)
+TVMET_IMPLEMENT_MACRO(and_eq, &=)
+TVMET_IMPLEMENT_MACRO(or_eq, |=)
+TVMET_IMPLEMENT_MACRO(shl_eq, <<=)
+TVMET_IMPLEMENT_MACRO(shr_eq, >>=)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/** \class Fcnl_add 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_sub 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_mul 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_div 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_mod 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_bitxor		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_bitand		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_bitor		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_shl 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_shr 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template <class T1, class T2>						\
+struct Fcnl_##NAME : public BinaryFunctional {				\
+  typedef typename  PromoteTraits<T1, T2>::value_type	value_type;	\
+  									\
+  static inline 							\
+  value_type apply_on(T1 lhs, T2 rhs) {					\
+    return lhs OP rhs;							\
+  }									\
+  									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l)						\
+       << "Fcnl_" << #NAME << "<T1="					\
+       << typeid(T1).name() << ", T2=" << typeid(T2).name() << ">,"	\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(add, +)
+TVMET_IMPLEMENT_MACRO(sub, -)
+TVMET_IMPLEMENT_MACRO(mul, *)
+TVMET_IMPLEMENT_MACRO(div, /)
+TVMET_IMPLEMENT_MACRO(mod, %)
+TVMET_IMPLEMENT_MACRO(bitxor, ^)
+TVMET_IMPLEMENT_MACRO(bitand, &)
+TVMET_IMPLEMENT_MACRO(bitor, |)
+TVMET_IMPLEMENT_MACRO(shl, <<)
+TVMET_IMPLEMENT_MACRO(shr, >>)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/** \class Fcnl_greater 	BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_greater_eq 	BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_less 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_less_eq 	BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_not_eq 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_and 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_or 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template <class T1, class T2>						\
+struct Fcnl_##NAME : public BinaryFunctional {				\
+  typedef bool						value_type;	\
+  									\
+  static inline								\
+  bool apply_on(T1 lhs, T2 rhs) {					\
+    return lhs OP rhs;							\
+  }									\
+  									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l)						\
+       << "Fcnl_" << #NAME << "<T1="					\
+       << typeid(T1).name() << ", T2=" << typeid(T2).name() << ">,"	\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/** \class Fcnl_atan2 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_fmod 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_pow 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template <class T1, class T2>						\
+struct Fcnl_##NAME : public BinaryFunctional {				\
+  typedef typename PromoteTraits<T1, T2>::value_type	value_type;	\
+									\
+  static inline 							\
+  value_type apply_on(T1 lhs, T2 rhs) {					\
+    return TVMET_STD_SCOPE(NAME)(lhs, rhs);				\
+  }									\
+   									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l)						\
+       << "Fcnl_" << #NAME << "<T1="					\
+       << typeid(T1).name() << ", T2=" << typeid(T2).name() << ">,"	\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(atan2)
+TVMET_IMPLEMENT_MACRO(fmod)
+TVMET_IMPLEMENT_MACRO(pow)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/** \class Fcnl_drem 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_hypot 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_jn 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+/** \class Fcnl_yn 		BinaryFunctionals.h "tvmet/BinaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template <class T1, class T2>						\
+struct Fcnl_##NAME : public BinaryFunctional {				\
+  typedef typename PromoteTraits<T1, T2>::value_type	value_type;	\
+									\
+  static inline 							\
+  value_type apply_on(T1 lhs, T2 rhs) {					\
+    return TVMET_GLOBAL_SCOPE(NAME)(lhs, rhs);				\
+  }									\
+   									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l)						\
+       << "Fcnl_" << #NAME << "<T1="					\
+       << typeid(T1).name() << ", T2=" << typeid(T2).name() << ">,"	\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(drem)
+TVMET_IMPLEMENT_MACRO(hypot)
+TVMET_IMPLEMENT_MACRO(jn)
+TVMET_IMPLEMENT_MACRO(yn)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/**
+ * \class Fcnl_polar BinaryFunctionals.h "tvmet/BinaryFunctionals.h"
+ * \brief %Functional for polar.
+ */
+template <class T1, class T2> struct Fcnl_polar : public BinaryFunctional { };
+
+
+/**
+ * \class Fcnl_polar<T,T> BinaryFunctionals.h "tvmet/BinaryFunctionals.h"
+ * \brief %Functional for polar.
+ * \note  This functional is partialy specialized due to the declaration
+ *        of %polar in namespace std <tt>complex<T> polar(T, T)</tt>.
+ *        This means especially that type promotion isn't avaible here.
+ */
+template <class T>
+struct Fcnl_polar<T,T> : public BinaryFunctional {
+  typedef std::complex<T>                               value_type;
+
+  static inline
+  value_type apply_on(T lhs, T rhs) {
+    return std::polar(lhs, rhs);
+  }
+
+  static
+  void print_xpr(std::ostream& os, std::size_t l=0) {
+    os << IndentLevel(l) << "Fcnl_polar<T1="
+       << typeid(T).name() << ", T2=" << typeid(T).name() << ">,"
+       << std::endl;
+  }
+};
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/**
+ * \class Fcnl_swap BinaryFunctionals.h "tvmet/BinaryFunctionals.h"
+ * \brief Binary operator for swapping values using temporaries.
+ */
+template <class T1, class T2>
+struct Fcnl_swap : public BinaryFunctional {
+  static inline
+  void apply_on(T1& _tvmet_restrict lhs, T2& _tvmet_restrict rhs) {
+    typedef typename  PromoteTraits<T1, T2>::value_type	temp_type;
+
+    temp_type 						temp(lhs);
+    lhs = static_cast<T1>(rhs);
+    rhs = static_cast<T2>(temp);
+  }
+
+  static
+  void print_xpr(std::ostream& os, std::size_t l=0) {
+    os << IndentLevel(l) << "Fcnl_swap<T1="
+       << typeid(T1).name() << ", T2" << typeid(T2).name() << ">,"
+       << std::endl;
+  }
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_BINARY_FUNCTIONAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/CommaInitializer.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,164 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: CommaInitializer.h,v 1.18 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_COMMA_INITIALIZER_H
+#define TVMET_COMMA_INITIALIZER_H
+
+#include <tvmet/CompileTimeError.h>
+
+namespace tvmet {
+
+
+/**
+ * \class CommaInitializer CommaInitializer.h "tvmet/CommaInitializer.h"
+ * \brief Initialize classes using a comma separated lists.
+ *
+ * The comma operator is called when it appears next to an object of
+ * the type the comma is defined for. However, "operator," is not called
+ * for function argument lists, only for objects that are out in the open,
+ * separated by commas (Thinking C++
+ * <a href=http://www.ida.liu.se/~TDDA14/online/v1ticpp/Chapter12.html>
+ * Ch.12: Operator comma</a>).
+ *
+ * This implementation uses the same technique as described in Todd Veldhuizen
+ * Techniques for Scientific C++
+ * <a href=http://extreme.indiana.edu/~tveldhui/papers/techniques/techniques01.html#l43>
+ * chapter 1.11 Comma overloading</a>.
+ *
+ * The initializer list is avaible after instanciation of the object,
+ * therefore use it like:
+ * \code
+ * vector3d t;
+ * t = 1.0, 2.0, 3.0;
+ * \endcode
+ * It's evaluated to (((t = 1.0), 2.0), 3.0)
+ *
+ * For matrizes the initilization is done row wise.
+ *
+ * If the comma separted list of values longer then the size of the vector
+ * or matrix a compile time error will occour. Otherwise the pending values
+ * will be written random into the memory.
+ *
+ */
+template<class Obj, std::size_t LEN>
+class CommaInitializer
+{
+  CommaInitializer();
+  CommaInitializer& operator=(const CommaInitializer&);
+
+private:
+  /**
+   * \class Initializer
+   * \brief Helper fo recursive overloaded comma operator.
+   */
+  template<class T, std::size_t N> class Initializer
+  {
+    Initializer();
+    Initializer& operator=(const Initializer&);
+
+  public:
+    typedef T						value_type;
+    typedef T*						iterator;
+
+  public:
+    Initializer(iterator iter) : m_iter(iter) { }
+
+    /** Overloads the comma operator for recursive assign values from comma
+	separated list. */
+    Initializer<value_type, N+1> operator,(value_type rhs)
+    {
+      TVMET_CT_CONDITION(N < LEN, CommaInitializerList_is_too_long)
+      *m_iter = rhs;
+      return Initializer<value_type, N+1>(m_iter + 1);
+    }
+
+  private:
+    iterator 						m_iter;
+  };
+
+public:
+  typedef typename Obj::value_type 			value_type;
+  typedef value_type*					iterator;
+
+public:
+  CommaInitializer(const CommaInitializer& rhs)
+    : m_object(rhs.m_object),
+      m_data(rhs.m_data),
+      m_wipeout_on_destruct(true)
+  {
+    rhs.disable();
+  }
+
+  /** Constructor used by Vector or Matrix operator(value_type rhs) */
+  CommaInitializer(Obj& obj, value_type x)
+    : m_object(obj),
+      m_data(x),
+      m_wipeout_on_destruct(true)
+  { }
+
+  /** Destructs and assigns the comma separated value. */
+  ~CommaInitializer() {
+    if(m_wipeout_on_destruct) m_object.assign_value(m_data);
+  }
+
+  /** Overloaded comma operator, called only once for the first occoured comma. This
+      means the first value is assigned by %operator=() and the 2nd value after the
+      comma. Therfore we call the %Initializer::operator,() for the list starting
+      after the 2nd. */
+  Initializer<value_type, 2> operator,(value_type rhs);
+
+  void disable() const { m_wipeout_on_destruct = false; }
+
+private:
+  Obj& 							m_object;
+  value_type 						m_data;
+  mutable bool 						m_wipeout_on_destruct;
+};
+
+
+/*
+ * Implementation
+ */
+template<class Obj, std::size_t LEN>
+typename CommaInitializer<Obj, LEN>::template Initializer<typename Obj::value_type, 2>
+CommaInitializer<Obj, LEN>::operator,(typename Obj::value_type rhs)
+{
+  m_wipeout_on_destruct = false;
+  iterator iter1 = m_object.data();
+  *iter1         = m_data;
+  iterator iter2 = iter1 + 1;
+  *iter2         = rhs;
+  return Initializer<value_type, 2>(iter2 + 1);
+}
+
+
+
+} // namespace tvmet
+
+
+#endif //  TVMET_COMMA_INITIALIZER_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/CompileTimeError.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,60 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: CompileTimeError.h,v 1.11 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_COMPILE_TIME_ERROR_H
+#define TVMET_COMPILE_TIME_ERROR_H
+
+namespace tvmet {
+
+/**
+ * \class CompileTimeError CompileTimeError.h "tvmet/CompileTimeError.h"
+ * \brief Compile Time Assertation classes.
+ */
+template<bool> struct CompileTimeError;
+
+/**
+ * \class CompileTimeError<true> CompileTimeError.h "tvmet/CompileTimeError.h"
+ * \brief Specialized Compile Time Assertation for successfully condition.
+ * This results in a compiler pass.
+ */
+template<> struct CompileTimeError<true> { };
+
+
+/**
+ * \def TVMET_CT_CONDITION(XPR, MSG)
+ * \brief Simplify the Compile Time Assertation by using an expression
+ * Xpr and an error message MSG.
+ */
+#define TVMET_CT_CONDITION(XPR, MSG) {				\
+  CompileTimeError<(XPR)> tvmet_ERROR_##MSG;			\
+  (void)tvmet_ERROR_##MSG;					\
+}
+
+} // namespace tvmet
+
+#endif // TVMET_COMPILE_TIME_ERROR_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/Extremum.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,108 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Extremum.h,v 1.10 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_EXTREMUM_H
+#define TVMET_EXTREMUM_H
+
+namespace tvmet {
+
+
+/**
+ * \class matrix_tag Extremum.h "tvmet/Extremum.h"
+ * \brief For use with Extremum to simplify max handling.
+ * This allows the min/max functions to return an Extremum object.
+ */
+struct matrix_tag { };
+
+
+/**
+ * \class vector_tag Extremum.h "tvmet/Extremum.h"
+ * \brief For use with Extremum to simplify max handling.
+ * This allows the min/max functions to return an Extremum object.
+ */
+struct vector_tag { };
+
+
+/**
+ * \class Extremum Extremum.h "tvmet/Extremum.h"
+ * \brief Generell class for storing extremums determined by min/max.
+ */
+template<class T1, class T2, class Tag>
+class Extremum { };
+
+
+/**
+ * \class Extremum<T1, T2, vector_tag> Extremum.h "tvmet/Extremum.h"
+ * \brief Partial specialzed for vectors to store extremums by value and index.
+ */
+template<class T1, class T2>
+class Extremum<T1, T2, vector_tag>
+{
+public:
+  typedef T1					value_type;
+  typedef T2					index_type;
+
+public:
+  Extremum(value_type value, index_type index)
+    : m_value(value), m_index(index) { }
+  value_type value() const { return m_value; }
+  index_type index() const { return m_index; }
+
+private:
+  value_type 					m_value;
+  index_type 					m_index;
+};
+
+
+/**
+ * \class Extremum<T1, T2, matrix_tag> Extremum.h "tvmet/Extremum.h"
+ * \brief Partial specialzed for matrix to store extremums by value, row and column.
+ */
+template<class T1, class T2>
+class Extremum<T1, T2, matrix_tag>
+{
+public:
+  typedef T1					value_type;
+  typedef T2					index_type;
+
+public:
+  Extremum(value_type value, index_type row, index_type col)
+    : m_value(value), m_row(row), m_col(col) { }
+  value_type value() const { return m_value; }
+  index_type row() const { return m_row; }
+  index_type col() const { return m_col; }
+
+private:
+  value_type 					m_value;
+  index_type 					m_row, m_col;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_EXTREMUM_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/Functional.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,88 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Functional.h,v 1.11 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_FUNCTIONAL_H
+#define TVMET_FUNCTIONAL_H
+
+#include <tvmet/TypePromotion.h>
+
+namespace tvmet {
+
+
+/**
+ * \class Functional Functional.h "tvmet/Functional.h"
+ * \brief Base class for all binary und unary functionals.
+ *
+ * All functional operators and functions have a static apply
+ * member function for evaluating the expressions inside.
+ */
+struct Functional { };
+
+
+/**
+ * \class BinaryFunctional Functional.h "tvmet/Functional.h"
+ * \brief Base class for all binary functions.
+ * \note Used for collecting classes for doxygen.
+ */
+struct BinaryFunctional : public Functional { };
+
+
+/**
+ * \class UnaryFunctional Functional.h "tvmet/Functional.h"
+ * \brief Base class for all unary functions.
+ * \note Used for collecting classes for doxygen.
+ */
+struct UnaryFunctional : public Functional { };
+
+
+/*
+ * some macro magic need below
+ */
+
+/**
+ * \def TVMET_STD_SCOPE(x)
+ * \brief Simple macro to allow using macros for namespace std functions.
+ */
+#define TVMET_STD_SCOPE(x) std::x
+
+
+/**
+ * \def TVMET_GLOBAL_SCOPE(x)
+ * \brief Simple macro to allow using macros for global namespace functions.
+ */
+#define TVMET_GLOBAL_SCOPE(x) ::x
+
+
+} // namespace tvmet
+
+
+#include <tvmet/BinaryFunctionals.h>
+#include <tvmet/UnaryFunctionals.h>
+
+
+#endif // TVMET_FUNCTIONAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/Io.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,69 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Io.h,v 1.8 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_IO_H
+#define TVMET_IO_H
+
+namespace tvmet {
+
+/**
+ * \class IoPrintHelper Io.h "tvmet/Io.h"
+ * \brief Determines the number of digits regarding the sign of the
+ *        container.
+ *        This class is nesessary due to the complex type and the
+ *        function min(), which are not defined for this type.
+ *        So we have to dispatch between pod and complex types
+ *        to get an information about the extra space for signs.
+ */
+template<class C>
+class IoPrintHelper {
+  IoPrintHelper();
+  IoPrintHelper(const IoPrintHelper&);
+  IoPrintHelper& operator=(const IoPrintHelper&);
+
+private:
+  static std::streamsize width(const C& e) {
+    std::streamsize w = static_cast<std::streamsize>(std::log10(max(abs(e)))+1);
+    return w > 0 ? w : 0;
+  }
+
+public:
+  static std::streamsize width(dispatch<true>, const C& e) {
+    return width(e);
+  }
+  static std::streamsize width(dispatch<false>, const C& e) {
+    std::streamsize w = width(e);
+    if(min(e) < 0) return w+1;
+    else return w;
+  }
+};
+
+
+}
+
+#endif /* TVMET_IO_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/Matrix.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,476 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Matrix.h,v 1.58 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_MATRIX_H
+#define TVMET_MATRIX_H
+
+#include <iterator>					// reverse_iterator
+
+#include <tvmet/tvmet.h>
+#include <tvmet/TypePromotion.h>
+#include <tvmet/CommaInitializer.h>
+#include <tvmet/RunTimeError.h>
+
+#include <tvmet/xpr/Matrix.h>
+#include <tvmet/xpr/MatrixRow.h>
+#include <tvmet/xpr/MatrixCol.h>
+#include <tvmet/xpr/MatrixDiag.h>
+
+namespace tvmet {
+
+
+/* forwards */
+template<class T, std::size_t Rows, std::size_t Cols> class Matrix;
+template<class T,
+	 std::size_t RowsBgn, std::size_t RowsEnd,
+	 std::size_t ColsBgn, std::size_t ColsEnd,
+	 std::size_t RowStride, std::size_t ColStride /*=1*/>
+class MatrixSliceConstReference; // unused here; for me only
+
+
+/**
+ * \class MatrixConstReference Matrix.h "tvmet/Matrix.h"
+ * \brief value iterator for ET
+ */
+template<class T, std::size_t NRows, std::size_t NCols>
+class MatrixConstReference
+  : public TvmetBase < MatrixConstReference<T, NRows, NCols> >
+{
+public:
+  typedef T						value_type;
+  typedef T*						pointer;
+  typedef const T*					const_pointer;
+
+  /** Dimensions. */
+  enum {
+    Rows = NRows,			/**< Number of rows. */
+    Cols = NCols,			/**< Number of cols. */
+    Size = Rows * Cols			/**< Complete Size of Matrix. */
+  };
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops       = Rows * Cols
+  };
+
+private:
+  MatrixConstReference();
+  MatrixConstReference& operator=(const MatrixConstReference&);
+
+public:
+  /** Constructor. */
+  explicit MatrixConstReference(const Matrix<T, Rows, Cols>& rhs)
+    : m_data(rhs.data())
+  { }
+
+  /** Constructor by a given memory pointer. */
+  explicit MatrixConstReference(const_pointer data)
+    : m_data(data)
+  { }
+
+public: // access operators
+  /** access by index. */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    TVMET_RT_CONDITION((i < Rows) && (j < Cols), "MatrixConstReference Bounce Violation")
+    return m_data[i * Cols + j];
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l)
+       << "MatrixConstReference[O=" << ops << "]<"
+       << "T=" << typeid(value_type).name() << ">,"
+       << std::endl;
+  }
+
+private:
+  const_pointer _tvmet_restrict 			m_data;
+};
+
+
+/**
+ * \class Matrix Matrix.h "tvmet/Matrix.h"
+ * \brief A tiny matrix class.
+ *
+ * The array syntax A[j][j] isn't supported here. The reason is that
+ * operator[] always takes exactly one parameter, but operator() can
+ * take any number of parameters (in the case of a rectangular matrix,
+ * two paramters are needed). Therefore the cleanest way to do it is
+ * with operator() rather than with operator[]. \see C++ FAQ Lite 13.8
+ */
+template<class T, std::size_t NRows, std::size_t NCols>
+class Matrix
+{
+public:
+  /** Data type of the tvmet::Matrix. */
+  typedef T						value_type;
+
+  /** Reference type of the tvmet::Matrix data elements. */
+  typedef T&     					reference;
+
+  /** const reference type of the tvmet::Matrix data elements. */
+  typedef const T&     					const_reference;
+
+  /** STL iterator interface. */
+  typedef T*     					iterator;
+
+  /** STL const_iterator interface. */
+  typedef const T*     					const_iterator;
+
+  /** STL reverse iterator interface. */
+  typedef std::reverse_iterator<iterator> 		reverse_iterator;
+
+  /** STL const reverse iterator interface. */
+  typedef std::reverse_iterator<const_iterator> 	const_reverse_iterator;
+
+public:
+  /** Dimensions. */
+  enum {
+    Rows = NRows,			/**< Number of rows. */
+    Cols = NCols,			/**< Number of cols. */
+    Size = Rows * Cols			/**< Complete Size of Matrix. */
+  };
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_assign = Rows * Cols,
+    ops        = ops_assign,
+    use_meta   = ops < TVMET_COMPLEXITY_M_ASSIGN_TRIGGER ? true : false
+  };
+
+public: // STL  interface
+  /** STL iterator interface. */
+  iterator begin() { return m_data; }
+
+  /** STL iterator interface. */
+  iterator end() { return m_data + Size; }
+
+  /** STL const_iterator interface. */
+  const_iterator begin() const { return m_data; }
+
+  /** STL const_iterator interface. */
+  const_iterator end() const { return m_data + Size; }
+
+  /** STL reverse iterator interface reverse begin. */
+  reverse_iterator rbegin() { return reverse_iterator( end() ); }
+
+  /** STL const reverse iterator interface reverse begin. */
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator( end() );
+  }
+
+  /** STL reverse iterator interface reverse end. */
+  reverse_iterator rend() { return reverse_iterator( begin() ); }
+
+  /** STL const reverse iterator interface reverse end. */
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator( begin() );
+  }
+
+  /** The size of the matrix. */
+  static std::size_t size() { return Size; }
+
+  /** STL vector max_size() - returns allways rows()*cols(). */
+  static std::size_t max_size() { return Size; }
+
+  /** STL vector empty() - returns allways false. */
+  static bool empty() { return false; }
+
+public:
+  /** The number of rows of matrix. */
+  static std::size_t rows() { return Rows; }
+
+  /** The number of columns of matrix. */
+  static std::size_t cols() { return Cols; }
+
+public:
+  /** Default Destructor */
+  ~Matrix() {
+#if defined(TVMET_DYNAMIC_MEMORY)
+    delete [] m_data;
+#endif
+  }
+
+  /** Default Constructor. The allocated memory region isn't cleared. If you want
+   a clean use the constructor argument zero. */
+  explicit Matrix()
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  { }
+
+  /** Copy Constructor, not explicit! */
+  Matrix(const Matrix& rhs)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    *this = XprMatrix<ConstReference, Rows, Cols>(rhs.const_ref());
+  }
+
+  /**
+   * Constructor with STL iterator interface. The data will be copied into the matrix
+   * self, there isn't any stored reference to the array pointer.
+   */
+  template<class InputIterator>
+  explicit Matrix(InputIterator first, InputIterator last)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_RT_CONDITION(static_cast<std::size_t>(std::distance(first, last)) <= Size,
+		       "InputIterator doesn't fits in size" )
+    std::copy(first, last, m_data);
+  }
+
+  /**
+   * Constructor with STL iterator interface. The data will be copied into the matrix
+   * self, there isn't any stored reference to the array pointer.
+   */
+  template<class InputIterator>
+  explicit Matrix(InputIterator first, std::size_t sz)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_RT_CONDITION(sz <= Size, "InputIterator doesn't fits in size" )
+    std::copy(first, first + sz, m_data);
+  }
+
+  /** Construct the matrix by value. */
+  explicit Matrix(value_type rhs)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    typedef XprLiteral<value_type> expr_type;
+    *this = XprMatrix<expr_type, Rows, Cols>(expr_type(rhs));
+  }
+
+  /** Construct a matrix by expression. */
+  template<class E>
+  explicit Matrix(const XprMatrix<E, Rows, Cols>& e)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    *this = e;
+  }
+
+  /** assign a value_type on array, this can be used for a single value
+      or a comma separeted list of values. */
+  CommaInitializer<Matrix, Size> operator=(value_type rhs) {
+    return CommaInitializer<Matrix, Size>(*this, rhs);
+  }
+
+public: // access operators
+  value_type* _tvmet_restrict data() { return m_data; }
+  const value_type* _tvmet_restrict data() const { return m_data; }
+
+public: // index access operators
+  value_type& _tvmet_restrict operator()(std::size_t i, std::size_t j) {
+    // Note: g++-2.95.3 does have problems on typedef reference
+    TVMET_RT_CONDITION((i < Rows) && (j < Cols), "Matrix Bounce Violation")
+    return m_data[i * Cols + j];
+  }
+
+  value_type operator()(std::size_t i, std::size_t j) const {
+    TVMET_RT_CONDITION((i < Rows) && (j < Cols), "Matrix Bounce Violation")
+    return m_data[i * Cols + j];
+  }
+
+public: // ET interface
+  typedef MatrixConstReference<T, Rows, Cols>   	ConstReference;
+
+  typedef MatrixSliceConstReference<
+    T,
+    0, Rows, 0, Cols,
+    Rows, 1
+  >							SliceConstReference;
+
+  /** Return a const Reference of the internal data */
+  ConstReference const_ref() const { return ConstReference(*this); }
+
+  /**
+   * Return a sliced const Reference of the internal data.
+   * \note Doesn't work since isn't implemented, but it is in
+   * progress. Therefore this is a placeholder. */
+  ConstReference const_sliceref() const { return SliceConstReference(*this); }
+
+  /** Return the vector as const expression. */
+  XprMatrix<ConstReference, Rows, Cols> as_expr() const {
+    return XprMatrix<ConstReference, Rows, Cols>(this->const_ref());
+  }
+
+private:
+  /** Wrapper for meta assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<true>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    meta::Matrix<Rows, Cols, 0, 0>::assign(dest, src, assign_fn);
+  }
+
+  /** Wrapper for loop assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<false>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    loop::Matrix<Rows, Cols>::assign(dest, src, assign_fn);
+  }
+
+private:
+  /** assign this to a matrix  of a different type T2 using
+      the functional assign_fn. */
+  template<class T2, class Assign>
+  void assign_to(Matrix<T2, Rows, Cols>& dest, const Assign& assign_fn) const {
+    do_assign(dispatch<use_meta>(), dest, *this, assign_fn);
+  }
+
+public:  // assign operations
+  /** assign a given matrix of a different type T2 element wise
+      to this matrix. The operator=(const Matrix&) is compiler
+      generated. */
+  template<class T2>
+  Matrix& operator=(const Matrix<T2, Rows, Cols>& rhs) {
+    rhs.assign_to(*this, Fcnl_assign<value_type, T2>());
+    return *this;
+  }
+
+  /** assign a given XprMatrix element wise to this matrix. */
+  template <class E>
+  Matrix& operator=(const XprMatrix<E, Rows, Cols>& rhs) {
+    rhs.assign_to(*this, Fcnl_assign<value_type, typename E::value_type>());
+    return *this;
+  }
+
+private:
+  template<class Obj, std::size_t LEN> friend class CommaInitializer;
+
+  /** This is a helper for assigning a comma separated initializer
+      list. It's equal to Matrix& operator=(value_type) which does
+      replace it. */
+  Matrix& assign_value(value_type rhs) {
+    typedef XprLiteral<value_type> 			expr_type;
+    *this = XprMatrix<expr_type, Rows, Cols>(expr_type(rhs));
+    return *this;
+  }
+
+public: // math operators with scalars
+  // NOTE: this meaning is clear - element wise ops even if not in ns element_wise
+  Matrix& operator+=(value_type) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator-=(value_type) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator*=(value_type) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator/=(value_type) TVMET_CXX_ALWAYS_INLINE;
+
+  Matrix& operator%=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator^=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator&=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator|=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator<<=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Matrix& operator>>=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+
+public: // math operators with matrizes
+  // NOTE: access using the operators in ns element_wise, since that's what is does
+  template <class T2> Matrix& M_add_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_sub_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_mul_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_div_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_mod_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_xor_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_and_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_or_eq (const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_shl_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& M_shr_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+
+public: // math operators with expressions
+  // NOTE: access using the operators in ns element_wise, since that's what is does
+  template <class E> Matrix& M_add_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_sub_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_mul_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_div_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_mod_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_xor_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_and_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_or_eq (const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_shl_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& M_shr_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+
+public: // aliased math operators with expressions
+  template <class T2> Matrix& alias_assign(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& alias_add_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& alias_sub_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& alias_mul_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Matrix& alias_div_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+
+  template <class E> Matrix& alias_assign(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& alias_add_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& alias_sub_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& alias_mul_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Matrix& alias_div_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE;
+
+public: // io
+  /** Structure for info printing as Matrix<T, Rows, Cols>. */
+  struct Info : public TvmetBase<Info> {
+    std::ostream& print_xpr(std::ostream& os) const {
+      os << "Matrix<T=" << typeid(value_type).name()
+	 << ", R=" << Rows << ", C=" << Cols << ">";
+      return os;
+    }
+  };
+
+  /** Get an info object of this matrix. */
+  static Info info() { return Info(); }
+
+  /** Member function for expression level printing. */
+  std::ostream& print_xpr(std::ostream& os, std::size_t l=0) const;
+
+  /** Member function for printing internal data. */
+  std::ostream& print_on(std::ostream& os) const;
+
+private:
+  /** The data of matrix self. */
+#if defined(TVMET_DYNAMIC_MEMORY)
+  value_type*						m_data;
+#else
+  value_type 						m_data[Size];
+#endif
+};
+
+
+} // namespace tvmet
+
+#include <tvmet/MatrixImpl.h>
+#include <tvmet/MatrixFunctions.h>
+#include <tvmet/MatrixBinaryFunctions.h>
+#include <tvmet/MatrixUnaryFunctions.h>
+#include <tvmet/MatrixOperators.h>
+#include <tvmet/MatrixEval.h>
+#include <tvmet/AliasProxy.h>
+
+#endif // TVMET_MATRIX_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/MatrixBinaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,533 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixBinaryFunctions.h,v 1.16 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_MATRIX_BINARY_FUNCTIONS_H
+#define TVMET_MATRIX_BINARY_FUNCTIONS_H
+
+namespace tvmet {
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+/*
+ * binary_function(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * binary_function(Matrix<T1, Rows, Cols>, XprMatrix<E, Rows, Cols>)
+ * binary_function(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>	\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    MatrixConstReference<T1, Rows, Cols>,				\
+    MatrixConstReference<T2, Rows, Cols>				\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const Matrix<T1, Rows, Cols>& lhs, 				\
+     const Matrix<T2, Cols, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class E, class T, std::size_t Rows, std::size_t Cols>		\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const XprMatrix<E, Rows, Cols>& lhs, 				\
+     const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+									\
+template<class E, class T, std::size_t Rows, std::size_t Cols>		\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const Matrix<T, Rows, Cols>& lhs, 					\
+     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2)
+TVMET_DECLARE_MACRO(drem)
+TVMET_DECLARE_MACRO(fmod)
+TVMET_DECLARE_MACRO(hypot)
+TVMET_DECLARE_MACRO(jn)
+TVMET_DECLARE_MACRO(yn)
+TVMET_DECLARE_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+TVMET_DECLARE_MACRO(polar)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * binary_function(Matrix<T, Rows, Cols>, POD)
+ */
+#define TVMET_DECLARE_MACRO(NAME, TP)					\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, TP >,						\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprLiteral< TP >							\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const Matrix<T, Rows, Cols>& lhs, TP rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2, int)
+TVMET_DECLARE_MACRO(drem, int)
+TVMET_DECLARE_MACRO(fmod, int)
+TVMET_DECLARE_MACRO(hypot, int)
+TVMET_DECLARE_MACRO(jn, int)
+TVMET_DECLARE_MACRO(yn, int)
+TVMET_DECLARE_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(atan2, long long int)
+TVMET_DECLARE_MACRO(drem, long long int)
+TVMET_DECLARE_MACRO(fmod, long long int)
+TVMET_DECLARE_MACRO(hypot, long long int)
+TVMET_DECLARE_MACRO(jn, long long int)
+TVMET_DECLARE_MACRO(yn, long long int)
+TVMET_DECLARE_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_DECLARE_MACRO(atan2, float)
+TVMET_DECLARE_MACRO(drem, float)
+TVMET_DECLARE_MACRO(fmod, float)
+TVMET_DECLARE_MACRO(hypot, float)
+TVMET_DECLARE_MACRO(jn, float)
+TVMET_DECLARE_MACRO(yn, float)
+TVMET_DECLARE_MACRO(pow, float)
+
+TVMET_DECLARE_MACRO(atan2, double)
+TVMET_DECLARE_MACRO(drem, double)
+TVMET_DECLARE_MACRO(fmod, double)
+TVMET_DECLARE_MACRO(hypot, double)
+TVMET_DECLARE_MACRO(jn, double)
+TVMET_DECLARE_MACRO(yn, double)
+TVMET_DECLARE_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(atan2, long double)
+TVMET_DECLARE_MACRO(drem, long double)
+TVMET_DECLARE_MACRO(fmod, long double)
+TVMET_DECLARE_MACRO(hypot, long double)
+TVMET_DECLARE_MACRO(jn, long double)
+TVMET_DECLARE_MACRO(yn, long double)
+TVMET_DECLARE_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * complex math
+ */
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow<T, std::complex<T> >,
+    MatrixConstReference<T, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  >,
+  Rows, Cols
+>
+pow(const Matrix<T, Rows, Cols>& lhs,
+    const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow< std::complex<T>, std::complex<T> >,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  >,
+  Rows, Cols
+>
+pow(const Matrix<std::complex<T>, Rows, Cols>& lhs,
+    const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/**
+ * \fn pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, const T& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, T>,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral<T>
+  >,
+  Rows, Cols
+>
+pow(const Matrix<std::complex<T>, Rows, Cols>& lhs,
+    const T& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/**
+ * \fn pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, int rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, int>,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral<int>
+  >,
+  Rows, Cols
+>
+pow(const Matrix<std::complex<T>, Rows, Cols>& lhs,
+    int rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprBinOp<
+    Fcnl_polar<T, T>,
+    MatrixConstReference<T, Rows, Cols>,
+    XprLiteral<T>
+  >,
+  Rows, Cols
+>
+polar(const Matrix<T, Rows, Cols>& lhs,
+      const T& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+// to be written (atan2)
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+/*
+ * binary_function(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * binary_function(Matrix<T1, Rows, Cols>, XprMatrix<E, Rows, Cols>)
+ * binary_function(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)						\
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>		\
+inline										\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<T1, T2>,							\
+    MatrixConstReference<T1, Rows, Cols>,					\
+    MatrixConstReference<T2, Rows, Cols>					\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME(const Matrix<T1, Rows, Cols>& lhs, const Matrix<T2, Cols, Cols>& rhs) {	\
+  typedef XprBinOp <								\
+    Fcnl_##NAME<T1, T2>,							\
+    MatrixConstReference<T1, Rows, Cols>,					\
+    MatrixConstReference<T2, Rows, Cols>					\
+  >							expr_type;		\
+  return XprMatrix<expr_type, Rows, Cols>(					\
+    expr_type(lhs.const_ref(), rhs.const_ref()));				\
+}										\
+										\
+template<class E, class T, std::size_t Rows, std::size_t Cols>			\
+inline										\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME(const XprMatrix<E, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs) {	\
+  typedef XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    XprMatrix<E, Rows, Cols>,							\
+    MatrixConstReference<T, Rows, Cols>						\
+  > 							 expr_type;		\
+  return XprMatrix<expr_type, Rows, Cols>(					\
+    expr_type(lhs, rhs.const_ref()));						\
+}										\
+										\
+template<class E, class T, std::size_t Rows, std::size_t Cols>			\
+inline										\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<T, typename E::value_type>,					\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME(const Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) {	\
+  typedef XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,					\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprMatrix<E, Rows, Cols>							\
+  > 						 	expr_type;		\
+  return XprMatrix<expr_type, Rows, Cols>(					\
+    expr_type(lhs.const_ref(), rhs));						\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2)
+TVMET_IMPLEMENT_MACRO(drem)
+TVMET_IMPLEMENT_MACRO(fmod)
+TVMET_IMPLEMENT_MACRO(hypot)
+TVMET_IMPLEMENT_MACRO(jn)
+TVMET_IMPLEMENT_MACRO(yn)
+TVMET_IMPLEMENT_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+TVMET_IMPLEMENT_MACRO(polar)
+#endif
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * binary_function(Matrix<T, Rows, Cols>, POD)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, TP)					\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, TP >,						\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprLiteral< TP >							\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const Matrix<T, Rows, Cols>& lhs, TP rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, TP >,						\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprLiteral< TP >							\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs.const_ref(), XprLiteral< TP >(rhs)));			\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2, int)
+TVMET_IMPLEMENT_MACRO(drem, int)
+TVMET_IMPLEMENT_MACRO(fmod, int)
+TVMET_IMPLEMENT_MACRO(hypot, int)
+TVMET_IMPLEMENT_MACRO(jn, int)
+TVMET_IMPLEMENT_MACRO(yn, int)
+TVMET_IMPLEMENT_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(atan2, long long int)
+TVMET_IMPLEMENT_MACRO(drem, long long int)
+TVMET_IMPLEMENT_MACRO(fmod, long long int)
+TVMET_IMPLEMENT_MACRO(hypot, long long int)
+TVMET_IMPLEMENT_MACRO(jn, long long int)
+TVMET_IMPLEMENT_MACRO(yn, long long int)
+TVMET_IMPLEMENT_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_IMPLEMENT_MACRO(atan2, float)
+TVMET_IMPLEMENT_MACRO(drem, float)
+TVMET_IMPLEMENT_MACRO(fmod, float)
+TVMET_IMPLEMENT_MACRO(hypot, float)
+TVMET_IMPLEMENT_MACRO(jn, float)
+TVMET_IMPLEMENT_MACRO(yn, float)
+TVMET_IMPLEMENT_MACRO(pow, float)
+
+TVMET_IMPLEMENT_MACRO(atan2, double)
+TVMET_IMPLEMENT_MACRO(drem, double)
+TVMET_IMPLEMENT_MACRO(fmod, double)
+TVMET_IMPLEMENT_MACRO(hypot, double)
+TVMET_IMPLEMENT_MACRO(jn, double)
+TVMET_IMPLEMENT_MACRO(yn, double)
+TVMET_IMPLEMENT_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(atan2, long double)
+TVMET_IMPLEMENT_MACRO(drem, long double)
+TVMET_IMPLEMENT_MACRO(fmod, long double)
+TVMET_IMPLEMENT_MACRO(hypot, long double)
+TVMET_IMPLEMENT_MACRO(jn, long double)
+TVMET_IMPLEMENT_MACRO(yn, long double)
+TVMET_IMPLEMENT_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * complex math
+ */
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+/**
+ * \fn pow(const Matrix<T, Rows, Cols>& lhs, const std::complex<T>& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow<T, std::complex<T> >,
+    MatrixConstReference<T, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  >,
+  Rows, Cols
+>
+pow(const Matrix<T, Rows, Cols>& lhs, const std::complex<T>& rhs) {
+  typedef XprBinOp<
+    Fcnl_pow<T, std::complex<T> >,
+    MatrixConstReference<T, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  >							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+      expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));
+}
+
+
+/**
+ * \fn pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, const std::complex<T>& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow< std::complex<T>, std::complex<T> >,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  >,
+  Rows, Cols
+>
+pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, const std::complex<T>& rhs) {
+  typedef XprBinOp<
+    Fcnl_pow< std::complex<T>, std::complex<T> >,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  >							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+      expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));
+}
+
+
+/**
+ * \fn pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, const T& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, T>,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral<T>
+  >,
+  Rows, Cols
+>
+pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, const T& rhs) {
+  typedef XprBinOp<
+    Fcnl_pow<std::complex<T>, T>,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral<T>
+  >							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+      expr_type(lhs.const_ref(), XprLiteral<T>(rhs)));
+}
+
+
+/**
+ * \fn pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, int rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, int>,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral<int>
+  >,
+  Rows, Cols
+>
+pow(const Matrix<std::complex<T>, Rows, Cols>& lhs, int rhs) {
+  typedef XprBinOp<
+    Fcnl_pow<std::complex<T>, int>,
+    MatrixConstReference<std::complex<T>, Rows, Cols>,
+    XprLiteral<int>
+  >							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+      expr_type(lhs.const_ref(), XprLiteral<int>(rhs)));
+}
+
+
+/**
+ * \fn polar(const Matrix<T, Rows, Cols>& lhs, const T& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprBinOp<
+    Fcnl_polar<T, T>,
+    MatrixConstReference<T, Rows, Cols>,
+    XprLiteral<T>
+  >,
+  Rows, Cols
+>
+polar(const Matrix<T, Rows, Cols>& lhs, const T& rhs) {
+  typedef XprBinOp<
+    Fcnl_polar<T, T>,
+    MatrixConstReference<T, Rows, Cols>,
+    XprLiteral<T>
+  >							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+      expr_type(lhs.const_ref(), XprLiteral<T>(rhs)));
+}
+
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+// to be written (atan2)
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+
+
+} // namespace tvmet
+
+#endif // TVMET_MATRIX_BINARY_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/MatrixEval.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,387 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixEval.h,v 1.18 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_MATRIX_EVAL_H
+#define TVMET_MATRIX_EVAL_H
+
+namespace tvmet {
+
+
+/**
+ * \fn bool all_elements(const XprMatrix<E, Rows, Cols>& e)
+ * \brief check on statements for all elements
+ * \ingroup _unary_function
+ * This is for use with boolean operators like
+ * \par Example:
+ * \code
+ * all_elements(matrix > 0) {
+ *     // true branch
+ * } else {
+ *     // false branch
+ * }
+ * \endcode
+ * \sa \ref compare
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+bool all_elements(const XprMatrix<E, Rows, Cols>& e) {
+  return meta::Matrix<Rows, Cols, 0, 0>::all_elements(e);
+}
+
+
+/**
+ * \fn bool any_elements(const XprMatrix<E, Rows, Cols>& e)
+ * \brief check on statements for any elements
+ * \ingroup _unary_function
+ * This is for use with boolean operators like
+ * \par Example:
+ * \code
+ * any_elements(matrix > 0) {
+ *     // true branch
+ * } else {
+ *     // false branch
+ * }
+ * \endcode
+ * \sa \ref compare
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+bool any_elements(const XprMatrix<E, Rows, Cols>& e) {
+  return meta::Matrix<Rows, Cols, 0, 0>::any_elements(e);
+}
+
+
+/*
+ * trinary evaluation functions with matrizes and xpr of
+ *
+ * XprMatrix<E1, Rows, Cols> ? Matrix<T2, Rows, Cols> : Matrix<T3, Rows, Cols>
+ * XprMatrix<E1, Rows, Cols> ? Matrix<T2, Rows, Cols> : XprMatrix<E3, Rows, Cols>
+ * XprMatrix<E1, Rows, Cols> ? XprMatrix<E2, Rows, Cols> : Matrix<T3, Rows, Cols>
+ * XprMatrix<E1, Rows, Cols> ? XprMatrix<E2, Rows, Cols> : XprMatrix<E3, Rows, Cols>
+ */
+
+/**
+ * \fn eval(const XprMatrix<E1, Rows, Cols>& e1, const Matrix<T2, Rows, Cols>& m2, const Matrix<T3, Rows, Cols>& m3)
+ * \brief Evals the matrix expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class T2, class T3, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    MatrixConstReference<T2, Rows, Cols>,
+    MatrixConstReference<T3, Rows, Cols>
+  >,
+  Rows, Cols
+>
+eval(const XprMatrix<E1, Rows, Cols>& e1,
+     const Matrix<T2, Rows, Cols>& m2,
+     const Matrix<T3, Rows, Cols>& m3) {
+  typedef XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    MatrixConstReference<T2, Rows, Cols>,
+    MatrixConstReference<T3, Rows, Cols>
+  > 							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+    expr_type(e1, m2.const_ref(), m3.const_ref()));
+}
+
+
+/**
+ * \fn eval(const XprMatrix<E1, Rows, Cols>& e1, const Matrix<T2, Rows, Cols>& m2, const XprMatrix<E3, Rows, Cols>& e3)
+ * \brief Evals the matrix expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class T2, class E3, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    MatrixConstReference<T2, Rows, Cols>,
+    XprMatrix<E3, Rows, Cols>
+  >,
+  Rows, Cols
+>
+eval(const XprMatrix<E1, Rows, Cols>& e1,
+     const Matrix<T2, Rows, Cols>& m2,
+     const XprMatrix<E3, Rows, Cols>& e3) {
+  typedef XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    MatrixConstReference<T2, Rows, Cols>,
+    XprMatrix<E3, Rows, Cols>
+  > 							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+    expr_type(e1, m2.const_ref(), e3));
+}
+
+
+/**
+ * \fn eval(const XprMatrix<E1, Rows, Cols>& e1, const XprMatrix<E2, Rows, Cols>& e2, const Matrix<T3, Rows, Cols>& m3)
+ * \brief Evals the matrix expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E2, class T3, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprMatrix<E2, Rows, Cols>,
+    MatrixConstReference<T3, Rows, Cols>
+  >,
+  Rows, Cols
+>
+eval(const XprMatrix<E1, Rows, Cols>& e1,
+    const  XprMatrix<E2, Rows, Cols>& e2,
+     const Matrix<T3, Rows, Cols>& m3) {
+  typedef XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprMatrix<E2, Rows, Cols>,
+    MatrixConstReference<T3, Rows, Cols>
+  > 							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+    expr_type(e1, e2, m3.const_ref()));
+}
+
+
+/**
+ * \fn eval(const XprMatrix<E1, Rows, Cols>& e1, const XprMatrix<E2, Rows, Cols>& e2, const XprMatrix<E3, Rows, Cols>& e3)
+ * \brief Evals the matrix expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E2, class E3, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprMatrix<E2, Rows, Cols>,
+    XprMatrix<E3, Rows, Cols>
+  >,
+  Rows, Cols
+>
+eval(const XprMatrix<E1, Rows, Cols>& e1,
+     const XprMatrix<E2, Rows, Cols>& e2,
+     const XprMatrix<E3, Rows, Cols>& e3) {
+  typedef XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprMatrix<E2, Rows, Cols>,
+    XprMatrix<E3, Rows, Cols>
+  > 							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(e1, e2, e3));
+}
+
+
+/*
+ * trinary evaluation functions with matrizes, xpr of and POD
+ *
+ * XprMatrix<E, Rows, Cols> ? POD1 : POD2
+ * XprMatrix<E1, Rows, Cols> ? POD : XprMatrix<E3, Rows, Cols>
+ * XprMatrix<E1, Rows, Cols> ? XprMatrix<E2, Rows, Cols> : POD
+ */
+#define TVMET_IMPLEMENT_MACRO(POD)               			\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+inline               							\
+XprMatrix<               						\
+  XprEval<               						\
+    XprMatrix<E, Rows, Cols>,               			      	\
+    XprLiteral< POD >,               					\
+    XprLiteral< POD >               					\
+  >,                							\
+  Rows, Cols								\
+>               							\
+eval(const XprMatrix<E, Rows, Cols>& e, POD x2, POD x3) {      		\
+  typedef XprEval<               					\
+    XprMatrix<E, Rows, Cols>,               				\
+    XprLiteral< POD >,                					\
+    XprLiteral< POD >                					\
+  > 							expr_type; 	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(e, XprLiteral< POD >(x2), XprLiteral< POD >(x3))); 	\
+}               							\
+               								\
+template<class E1, class E3, std::size_t Rows, std::size_t Cols> 	\
+inline               							\
+XprMatrix<               						\
+  XprEval<               						\
+    XprMatrix<E1, Rows, Cols>,               				\
+    XprLiteral< POD >,               					\
+    XprMatrix<E3, Rows, Cols>               				\
+  >,                							\
+  Rows, Cols								\
+>               							\
+eval(const XprMatrix<E1, Rows, Cols>& e1, POD x2, const XprMatrix<E3, Rows, Cols>& e3) { \
+  typedef XprEval<               					\
+    XprMatrix<E1, Rows, Cols>,               				\
+    XprLiteral< POD >,                					\
+    XprMatrix<E3, Rows, Cols>               				\
+  > 							expr_type; 	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(e1, XprLiteral< POD >(x2), e3)); 				\
+}               							\
+               								\
+template<class E1, class E2, std::size_t Rows, std::size_t Cols>	\
+inline               							\
+XprMatrix<               						\
+  XprEval<               						\
+    XprMatrix<E1, Rows, Cols>,               				\
+    XprMatrix<E2, Rows, Cols>,               				\
+    XprLiteral< POD >               					\
+  >,                							\
+  Rows, Cols								\
+>               							\
+eval(const XprMatrix<E1, Rows, Cols>& e1, const XprMatrix<E2, Rows, Cols>& e2, POD x3) { \
+  typedef XprEval<               					\
+    XprMatrix<E1, Rows, Cols>,               				\
+    XprMatrix<E2, Rows, Cols>,               				\
+    XprLiteral< POD >                					\
+  > 							expr_type; 	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(e1, e2, XprLiteral< POD >(x3))); 				\
+}
+
+TVMET_IMPLEMENT_MACRO(int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(float)
+TVMET_IMPLEMENT_MACRO(double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * trinary evaluation functions with matrizes, xpr of and complex<> types
+ *
+ * XprMatrix<E, Rows, Cols> e, std::complex<T> z2, std::complex<T> z3
+ * XprMatrix<E1, Rows, Cols> e1, std::complex<T> z2, XprMatrix<E3, Rows, Cols> e3
+ * XprMatrix<E1, Rows, Cols> e1, XprMatrix<E2, Rows, Cols> e2, std::complex<T> z3
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+
+/**
+ * \fn eval(const XprMatrix<E, Rows, Cols>& e, const std::complex<T>& x2, const std::complex<T>& x3)
+ * \brief Evals the matrix expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E, std::size_t Rows, std::size_t Cols, class T>
+inline
+XprMatrix<
+  XprEval<
+    XprMatrix<E, Rows, Cols>,
+    XprLiteral< std::complex<T> >,
+    XprLiteral< std::complex<T> >
+  >,
+  Rows, Cols
+>
+eval(const XprMatrix<E, Rows, Cols>& e, const std::complex<T>& x2, const std::complex<T>& x3) {
+  typedef XprEval<
+    XprMatrix<E, Rows, Cols>,
+    XprLiteral< std::complex<T> >,
+    XprLiteral< std::complex<T> >
+  > 							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+    expr_type(e, XprLiteral< std::complex<T> >(x2), XprLiteral< std::complex<T> >(x3)));
+}
+
+
+/**
+ * \fn eval(const XprMatrix<E1, Rows, Cols>& e1, const std::complex<T>& x2, const XprMatrix<E3, Rows, Cols>& e3)
+ * \brief Evals the matrix expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E3, std::size_t Rows, std::size_t Cols, class T>
+inline
+XprMatrix<
+  XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprLiteral< std::complex<T> >,
+    XprMatrix<E3, Rows, Cols>
+  >,
+  Rows, Cols
+>
+eval(const XprMatrix<E1, Rows, Cols>& e1, const std::complex<T>& x2, const XprMatrix<E3, Rows, Cols>& e3) {
+  typedef XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprLiteral< std::complex<T> >,
+    XprMatrix<E3, Rows, Cols>
+  > 							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+    expr_type(e1, XprLiteral< std::complex<T> >(x2), e3));
+}
+
+
+/**
+ * \fn eval(const XprMatrix<E1, Rows, Cols>& e1, const XprMatrix<E2, Rows, Cols>& e2, const std::complex<T>& x3)
+ * \brief Evals the matrix expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E2, std::size_t Rows, std::size_t Cols, class T>
+inline
+XprMatrix<
+  XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprMatrix<E2, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  >,
+  Rows, Cols
+>
+eval(const XprMatrix<E1, Rows, Cols>& e1, const XprMatrix<E2, Rows, Cols>& e2, const std::complex<T>& x3) {
+  typedef XprEval<
+    XprMatrix<E1, Rows, Cols>,
+    XprMatrix<E2, Rows, Cols>,
+    XprLiteral< std::complex<T> >
+  > 							expr_type;
+  return XprMatrix<expr_type, Rows, Cols>(
+    expr_type(e1, e2, XprLiteral< std::complex<T> >(x3)));
+}
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace tvmet
+
+#endif // TVMET_MATRIX_EVAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/MatrixFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,1377 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixFunctions.h,v 1.65 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_MATRIX_FUNCTIONS_H
+#define TVMET_MATRIX_FUNCTIONS_H
+
+#include <tvmet/Extremum.h>
+
+namespace tvmet {
+
+/* forwards */
+template<class T, std::size_t Sz> class Vector;
+template<class T, std::size_t Sz> class VectorConstReference;
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic functions add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * function(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * function(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
+ * function(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>	\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    MatrixConstReference<T1, Rows, Cols>,				\
+    MatrixConstReference<T2, Rows, Cols>				\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const Matrix<T1, Rows, Cols>& lhs,				\
+      const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class E, class T, std::size_t Rows, std::size_t Cols>		\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprMatrix<E, Rows, Cols>,						\
+    MatrixConstReference<T, Rows, Cols>					\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const XprMatrix<E, Rows, Cols>& lhs,				\
+      const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class T, class E, std::size_t Rows, std::size_t Cols>		\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const Matrix<T, Rows, Cols>& lhs,					\
+      const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)			// per se element wise
+TVMET_DECLARE_MACRO(sub)			// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mul)			// not defined for matrizes
+  TVMET_DECLARE_MACRO(div)			// not defined for matrizes
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * function(Matrix<T, Rows, Cols>, POD)
+ * function(POD, Matrix<T, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, POD)					\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, POD >,						\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprLiteral<POD >							\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const Matrix<T, Rows, Cols>& lhs, 				\
+      POD rhs) TVMET_CXX_ALWAYS_INLINE;					\
+									\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, T>,						\
+    XprLiteral< POD >,							\
+    MatrixConstReference<T, Rows, Cols>					\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (POD lhs, 								\
+      const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, int)
+TVMET_DECLARE_MACRO(sub, int)
+TVMET_DECLARE_MACRO(mul, int)
+TVMET_DECLARE_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, long long int)
+TVMET_DECLARE_MACRO(sub, long long int)
+TVMET_DECLARE_MACRO(mul, long long int)
+TVMET_DECLARE_MACRO(div, long long int)
+#endif
+
+TVMET_DECLARE_MACRO(add, float)
+TVMET_DECLARE_MACRO(sub, float)
+TVMET_DECLARE_MACRO(mul, float)
+TVMET_DECLARE_MACRO(div, float)
+
+TVMET_DECLARE_MACRO(add, double)
+TVMET_DECLARE_MACRO(sub, double)
+TVMET_DECLARE_MACRO(mul, double)
+TVMET_DECLARE_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, long double)
+TVMET_DECLARE_MACRO(sub, long double)
+TVMET_DECLARE_MACRO(mul, long double)
+TVMET_DECLARE_MACRO(div, long double)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(Matrix<T, Rows, Cols>, complex<T>)
+ * function(complex<T>, Matrix<T, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME)						\
+template<class T, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    MatrixConstReference< std::complex<T>, Rows, Cols>,				\
+    XprLiteral<std::complex<T> >						\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME (const Matrix< std::complex<T>, Rows, Cols>& lhs,				\
+      const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;			\
+										\
+template<class T, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    XprLiteral< std::complex<T> >,						\
+    MatrixConstReference< std::complex<T>, Rows, Cols>				\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME (const std::complex<T>& lhs,						\
+      const Matrix< std::complex<T>, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)
+TVMET_DECLARE_MACRO(sub)
+TVMET_DECLARE_MACRO(mul)
+TVMET_DECLARE_MACRO(div)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2 		// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2							// return Dim
+>
+prod(const Matrix<T1, Rows1, Cols1>& lhs,
+     const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,			// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2							// return Dim
+>
+prod(const XprMatrix<E1, Rows1, Cols1>& lhs,
+     const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2				// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2							// return Dim
+>
+prod(const Matrix<T1, Rows1, Cols1>& lhs,
+     const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+XprMatrix<
+  XprMMProductTransposed<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Cols2, Rows1							// return Dim
+>
+trans_prod(const Matrix<T1, Rows1, Cols1>& lhs,
+	   const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>	// Rows2 = Rows1
+XprMatrix<
+  XprMtMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Rows1, Cols2>, Cols2		// M2(Rows1, Cols2)
+  >,
+  Cols1, Cols2							// return Dim
+>
+MtM_prod(const Matrix<T1, Rows1, Cols1>& lhs,
+	 const Matrix<T2, Rows1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Rows2>
+XprMatrix<
+  XprMMtProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Rows2, Cols1>, Cols1 		// M2(Rows2, Cols1)
+  >,
+  Rows1, Rows2							// return Dim
+>
+MMt_prod(const Matrix<T1, Rows1, Cols1>& lhs,
+	 const Matrix<T2, Rows2, Cols1>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,	// M(Rows, Cols)
+    VectorConstReference<T2, Cols> 			// V
+  >,
+  Rows
+>
+prod(const Matrix<T1, Rows, Cols>& lhs,
+     const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, class E2, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+prod(const Matrix<T1, Rows, Cols>& lhs,
+     const XprVector<E2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, class T2, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,		// M(Rows, Cols)
+    VectorConstReference<T2, Cols> 			// V
+  >,
+  Rows
+>
+prod(const XprMatrix<E1, Rows, Cols>& lhs,
+     const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMtVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows,	Cols,   // M(Rows, Cols)
+    VectorConstReference<T2, Rows> 			// V
+  >,
+  Cols
+>
+Mtx_prod(const Matrix<T1, Rows, Cols>& lhs,
+	 const Vector<T2, Rows>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprMatrixTranspose<
+    MatrixConstReference<T, Rows, Cols>
+  >,
+  Cols, Rows
+>
+trans(const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+typename NumericTraits<T>::sum_type
+trace(const Matrix<T, Sz, Sz>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMatrixRow<
+    MatrixConstReference<T, Rows, Cols>,
+    Rows, Cols
+  >,
+  Cols
+>
+row(const Matrix<T, Rows, Cols>& m,
+    std::size_t no) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMatrixCol<
+    MatrixConstReference<T, Rows, Cols>,
+    Rows, Cols
+  >,
+  Rows
+>
+col(const Matrix<T, Rows, Cols>& m,
+    std::size_t no) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+XprVector<
+  XprMatrixDiag<
+    MatrixConstReference<T, Sz, Sz>,
+    Sz
+  >,
+  Sz
+>
+diag(const Matrix<T, Sz, Sz>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * min/max unary functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class E, std::size_t Rows, std::size_t Cols>
+Extremum<typename E::value_type, std::size_t, matrix_tag>
+maximum(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+Extremum<T, std::size_t, matrix_tag>
+maximum(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Rows, std::size_t Cols>
+Extremum<typename E::value_type, std::size_t, matrix_tag>
+minimum(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+Extremum<T, std::size_t, matrix_tag>
+minimum(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Rows, std::size_t Cols>
+typename E::value_type
+max(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+T max(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Rows, std::size_t Cols>
+typename E::value_type
+min(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+T min(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * other unary functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprIdentity<T, Rows, Cols>,
+  Rows, Cols
+>
+identity() TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class M>
+XprMatrix<
+  XprIdentity<
+    typename M::value_type,
+    M::Rows, M::Cols>,
+  M::Rows, M::Cols
+>
+identity() TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  MatrixConstReference<T, Rows, Cols>,
+  Rows, Cols
+>
+cmatrix_ref(const T* mem) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic functions add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * function(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * function(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
+ * function(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)						\
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>		\
+inline										\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<T1, T2>,							\
+    MatrixConstReference<T1, Rows, Cols>,					\
+    MatrixConstReference<T2, Rows, Cols>					\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME (const Matrix<T1, Rows, Cols>& lhs, const Matrix<T2, Rows, Cols>& rhs) {	\
+  typedef XprBinOp <								\
+    Fcnl_##NAME<T1, T2>,							\
+    MatrixConstReference<T1, Rows, Cols>,					\
+    MatrixConstReference<T2, Rows, Cols>					\
+  >							expr_type;		\
+  return XprMatrix<expr_type, Rows, Cols>(					\
+    expr_type(lhs.const_ref(), rhs.const_ref()));				\
+}										\
+										\
+template<class E, class T, std::size_t Rows, std::size_t Cols>			\
+inline										\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    XprMatrix<E, Rows, Cols>,							\
+    MatrixConstReference<T, Rows, Cols>						\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME (const XprMatrix<E, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs) {	\
+  typedef XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    XprMatrix<E, Rows, Cols>,							\
+    MatrixConstReference<T, Rows, Cols>						\
+  > 							 expr_type;		\
+  return XprMatrix<expr_type, Rows, Cols>(					\
+    expr_type(lhs, rhs.const_ref()));						\
+}										\
+										\
+template<class T, class E, std::size_t Rows, std::size_t Cols>			\
+inline										\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+NAME (const Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) {	\
+  typedef XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,					\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprMatrix<E, Rows, Cols>							\
+  >	 						 expr_type;		\
+  return XprMatrix<expr_type, Rows, Cols>(					\
+    expr_type(lhs.const_ref(), rhs));						\
+}
+
+TVMET_IMPLEMENT_MACRO(add)			// per se element wise
+TVMET_IMPLEMENT_MACRO(sub)			// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mul)			// not defined for matrizes
+  TVMET_IMPLEMENT_MACRO(div)			// not defined for matrizes
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * function(Matrix<T, Rows, Cols>, POD)
+ * function(POD, Matrix<T, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, POD)				\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, POD >,						\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprLiteral<POD >							\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const Matrix<T, Rows, Cols>& lhs, POD rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, POD >,						\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprLiteral< POD >							\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs.const_ref(), XprLiteral< POD >(rhs)));		\
+}									\
+									\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, T>,						\
+    XprLiteral< POD >,							\
+    MatrixConstReference<T, Rows, Cols>					\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (POD lhs, const Matrix<T, Rows, Cols>& rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< POD, T>,						\
+    XprLiteral< POD >,							\
+    MatrixConstReference<T, Rows, Cols>					\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(XprLiteral< POD >(lhs), rhs.const_ref()));		\
+}
+
+TVMET_IMPLEMENT_MACRO(add, int)
+TVMET_IMPLEMENT_MACRO(sub, int)
+TVMET_IMPLEMENT_MACRO(mul, int)
+TVMET_IMPLEMENT_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, long long int)
+TVMET_IMPLEMENT_MACRO(sub, long long int)
+TVMET_IMPLEMENT_MACRO(mul, long long int)
+TVMET_IMPLEMENT_MACRO(div, long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(add, float)
+TVMET_IMPLEMENT_MACRO(sub, float)
+TVMET_IMPLEMENT_MACRO(mul, float)
+TVMET_IMPLEMENT_MACRO(div, float)
+
+TVMET_IMPLEMENT_MACRO(add, double)
+TVMET_IMPLEMENT_MACRO(sub, double)
+TVMET_IMPLEMENT_MACRO(mul, double)
+TVMET_IMPLEMENT_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, long double)
+TVMET_IMPLEMENT_MACRO(sub, long double)
+TVMET_IMPLEMENT_MACRO(mul, long double)
+TVMET_IMPLEMENT_MACRO(div, long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(Matrix<T, Rows, Cols>, complex<T>)
+ * function(complex<T>, Matrix<T, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,			\
+    MatrixConstReference< std::complex<T>, Rows, Cols>,			\
+    XprLiteral<std::complex<T> >					\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const Matrix< std::complex<T>, Rows, Cols>& lhs,			\
+      const std::complex<T>& rhs) {					\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,			\
+    MatrixConstReference< std::complex<T>, Rows, Cols>,			\
+    XprLiteral< std::complex<T> >					\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));	\
+}									\
+									\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,			\
+    XprLiteral< std::complex<T> >,					\
+    MatrixConstReference< std::complex<T>, Rows, Cols>			\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const std::complex<T>& lhs,					\
+      const Matrix< std::complex<T>, Rows, Cols>& rhs) {		\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,			\
+    XprLiteral< std::complex<T> >,					\
+    MatrixConstReference<std::complex<T>, Rows, Cols>			\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref()));	\
+}
+
+TVMET_IMPLEMENT_MACRO(add)
+TVMET_IMPLEMENT_MACRO(sub)
+TVMET_IMPLEMENT_MACRO(mul)
+TVMET_IMPLEMENT_MACRO(div)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
+ * \brief Function for the matrix-matrix-product.
+ * \ingroup _binary_function
+ * \note The rows2 has to be equal to cols1.
+ */
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2 		// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2							// return Dim
+>
+prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
+  typedef XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Rows1, Cols2>(
+    expr_type(lhs.const_ref(), rhs.const_ref()));
+}
+
+
+/**
+ * \fn prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
+ * \brief Evaluate the product of XprMatrix and Matrix.
+ * \ingroup _binary_function
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,			// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2							// return Dim
+>
+prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
+  typedef XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Rows1, Cols2>(
+    expr_type(lhs, rhs.const_ref()));
+}
+
+
+/**
+ * \fn prod(const Matrix<T1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs)
+ * \brief Evaluate the product of Matrix and XprMatrix.
+ * \ingroup _binary_function
+ */
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2				// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2							// return Dim
+>
+prod(const Matrix<T1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
+  typedef XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    XprMatrix<E2, Cols1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Rows1, Cols2>(
+    expr_type(lhs.const_ref(), rhs));
+}
+
+
+/**
+ * \fn trans_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
+ * \brief Function for the trans(matrix-matrix-product)
+ * \ingroup _binary_function
+ * Perform on given Matrix M1 and M2:
+ * \f[
+ * (M_1\,M_2)^T
+ * \f]
+ */
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProductTransposed<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Cols2, Rows1							// return Dim
+>
+trans_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
+  typedef XprMMProductTransposed<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Cols2, Rows1>(
+    expr_type(lhs.const_ref(), rhs.const_ref()));
+}
+
+
+/**
+ * \fn MtM_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows1, Cols2>& rhs)
+ * \brief Function for the trans(matrix)-matrix-product.
+ * \ingroup _binary_function
+ *        using formula
+ *        \f[
+ *        M_1^{T}\,M_2
+ *        \f]
+ * \note The number of cols of matrix 2 have to be equal to number of rows of
+ *       matrix 1, since matrix 1 is trans - the result is a (Cols1 x Cols2)
+ *       matrix.
+ */
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>	// Rows2 = Rows1
+inline
+XprMatrix<
+  XprMtMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Rows1, Cols2>, Cols2		// M2(Rows1, Cols2)
+  >,
+  Cols1, Cols2							// return Dim
+>
+MtM_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows1, Cols2>& rhs) {
+  typedef XprMtMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Rows1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Cols1, Cols2>(
+    expr_type(lhs.const_ref(), rhs.const_ref()));
+}
+
+
+/**
+ * \fn MMt_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows2, Cols1>& rhs)
+ * \brief Function for the matrix-trans(matrix)-product.
+ * \ingroup _binary_function
+ * \note The Cols2 has to be equal to Cols1.
+ */
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Rows2>
+inline
+XprMatrix<
+  XprMMtProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    MatrixConstReference<T2, Rows2, Cols1>, Cols1 		// M2(Rows2, Cols1)
+  >,
+  Rows1, Rows2							// return Dim
+>
+MMt_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows2, Cols1>& rhs) {
+  typedef XprMMtProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Rows2, Cols1>, Cols1
+  >							expr_type;
+  return XprMatrix<expr_type, Rows1, Rows2>(
+    expr_type(lhs.const_ref(), rhs.const_ref()));
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn prod(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs)
+ * \brief Function for the matrix-vector-product
+ * \ingroup _binary_function
+ */
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,	// M(Rows, Cols)
+    VectorConstReference<T2, Cols> 			// V
+  >,
+  Rows
+>
+prod(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
+  typedef XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    VectorConstReference<T2, Cols>
+  > 							expr_type;
+  return XprVector<expr_type, Rows>(
+    expr_type(lhs.const_ref(), rhs.const_ref()));
+}
+
+
+/**
+ * \fn prod(const Matrix<T1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs)
+ * \brief Function for the matrix-vector-product
+ * \ingroup _binary_function
+ */
+template<class T1, class E2, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+prod(const Matrix<T1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs) {
+  typedef XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  > 							expr_type;
+  return XprVector<expr_type, Rows>(
+    expr_type(lhs.const_ref(), rhs));
+}
+
+
+/*
+ * \fn prod(const XprMatrix<E, Rows, Cols>& lhs, const Vector<T, Cols>& rhs)
+ * \brief Compute the product of an XprMatrix with a Vector.
+ * \ingroup _binary_function
+ */
+template<class E1, class T2, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,		// M(Rows, Cols)
+    VectorConstReference<T2, Cols> 			// V
+  >,
+  Rows
+>
+prod(const XprMatrix<E1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
+  typedef XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    VectorConstReference<T2, Cols>
+  > 							expr_type;
+  return XprVector<expr_type, Rows>(
+    expr_type(lhs, rhs.const_ref()));
+}
+
+
+/**
+ * \fn Mtx_prod(const Matrix<T1, Rows, Cols>& matrix, const Vector<T2, Rows>& vector)
+ * \brief Function for the trans(matrix)-vector-product
+ * \ingroup _binary_function
+ * Perform on given Matrix M and vector x:
+ * \f[
+ * M^T\, x
+ * \f]
+ */
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMtVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows,	Cols,   // M(Rows, Cols)
+    VectorConstReference<T2, Rows> 			// V
+  >,
+  Cols
+>
+Mtx_prod(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Rows>& rhs) {
+  typedef XprMtVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    VectorConstReference<T2, Rows>
+  > 							expr_type;
+  return XprVector<expr_type, Cols>(
+    expr_type(lhs.const_ref(), rhs.const_ref()));
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn trans(const Matrix<T, Rows, Cols>& rhs)
+ * \brief Transpose the matrix
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprMatrixTranspose<
+    MatrixConstReference<T, Rows, Cols>
+  >,
+  Cols, Rows
+>
+trans(const Matrix<T, Rows, Cols>& rhs) {
+  typedef XprMatrixTranspose<
+    MatrixConstReference<T, Rows, Cols>
+  >							expr_type;
+  return XprMatrix<expr_type, Cols, Rows>(
+    expr_type(rhs.const_ref()));
+}
+
+
+/*
+ * \fn trace(const Matrix<T, Sz, Sz>& m)
+ * \brief Compute the trace of a square matrix.
+ * \ingroup _unary_function
+ *
+ * Simply compute the trace of the given matrix as:
+ * \f[
+ *  \sum_{k = 0}^{Sz-1} m(k, k)
+ * \f]
+ */
+template<class T, std::size_t Sz>
+inline
+typename NumericTraits<T>::sum_type
+trace(const Matrix<T, Sz, Sz>& m) {
+  return meta::Matrix<Sz, Sz, 0, 0>::trace(m);
+}
+
+
+/**
+ * \fn row(const Matrix<T, Rows, Cols>& m, std::size_t no)
+ * \brief Returns a row vector of the given matrix.
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMatrixRow<
+    MatrixConstReference<T, Rows, Cols>,
+    Rows, Cols
+  >,
+  Cols
+>
+row(const Matrix<T, Rows, Cols>& m, std::size_t no) {
+  typedef XprMatrixRow<
+    MatrixConstReference<T, Rows, Cols>,
+    Rows, Cols
+  >							expr_type;
+  return XprVector<expr_type, Cols>(expr_type(m.const_ref(), no));
+}
+
+
+/**
+ * \fn col(const Matrix<T, Rows, Cols>& m, std::size_t no)
+ * \brief Returns a column vector of the given matrix.
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMatrixCol<
+    MatrixConstReference<T, Rows, Cols>,
+    Rows, Cols
+  >,
+  Rows
+>
+col(const Matrix<T, Rows, Cols>& m, std::size_t no) {
+  typedef XprMatrixCol<
+    MatrixConstReference<T, Rows, Cols>,
+    Rows, Cols
+  >							expr_type;
+  return XprVector<expr_type, Rows>(expr_type(m.const_ref(), no));
+}
+
+
+/**
+ * \fn diag(const Matrix<T, Sz, Sz>& m)
+ * \brief Returns the diagonal vector of the given square matrix.
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  XprMatrixDiag<
+    MatrixConstReference<T, Sz, Sz>,
+    Sz
+  >,
+  Sz
+>
+diag(const Matrix<T, Sz, Sz>& m) {
+  typedef XprMatrixDiag<
+    MatrixConstReference<T, Sz, Sz>,
+    Sz
+  >							expr_type;
+  return XprVector<expr_type, Sz>(expr_type(m.const_ref()));
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * min/max unary functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn maximum(const XprMatrix<E, Rows, Cols>& e)
+ * \brief Find the maximum of a matrix expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+Extremum<typename E::value_type, std::size_t, matrix_tag>
+maximum(const XprMatrix<E, Rows, Cols>& e) {
+  typedef typename E::value_type 			value_type;
+
+  value_type 						temp(e(0, 0));
+  std::size_t 						row_no(0), col_no(0);
+
+  for(std::size_t i = 0; i != Rows; ++i) {
+    for(std::size_t j = 0; j != Cols; ++j) {
+      if(e(i, j) > temp) {
+	temp = e(i, j);
+	row_no = i;
+	col_no = j;
+      }
+    }
+  }
+
+  return Extremum<value_type, std::size_t, matrix_tag>(temp, row_no, col_no);
+}
+
+
+/**
+ * \fn maximum(const Matrix<T, Rows, Cols>& m)
+ * \brief Find the maximum of a matrix
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+Extremum<T, std::size_t, matrix_tag>
+maximum(const Matrix<T, Rows, Cols>& m) { return maximum(m.as_expr()); }
+
+
+/**
+ * \fn minimum(const XprMatrix<E, Rows, Cols>& e)
+ * \brief Find the minimum of a matrix expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+Extremum<typename E::value_type, std::size_t, matrix_tag>
+minimum(const XprMatrix<E, Rows, Cols>& e) {
+  typedef typename E::value_type 			value_type;
+
+  value_type 						temp(e(0, 0));
+  std::size_t 						row_no(0), col_no(0);
+
+  for(std::size_t i = 0; i != Rows; ++i) {
+    for(std::size_t j = 0; j != Cols; ++j) {
+      if(e(i, j) < temp) {
+	temp = e(i, j);
+	row_no = i;
+	col_no = j;
+      }
+    }
+  }
+
+  return Extremum<value_type, std::size_t, matrix_tag>(temp, row_no, col_no);
+}
+
+
+/**
+ * \fn minimum(const Matrix<T, Rows, Cols>& m)
+ * \brief Find the minimum of a matrix
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+Extremum<T, std::size_t, matrix_tag>
+minimum(const Matrix<T, Rows, Cols>& m) { return minimum(m.as_expr()); }
+
+
+/**
+ * \fn max(const XprMatrix<E, Rows, Cols>& e)
+ * \brief Find the maximum of a matrix expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+typename E::value_type
+max(const XprMatrix<E, Rows, Cols>& e) {
+  typedef typename E::value_type 			value_type;
+
+  value_type 						temp(e(0, 0));
+
+  for(std::size_t i = 0; i != Rows; ++i)
+    for(std::size_t j = 0; j != Cols; ++j)
+      if(e(i, j) > temp)
+	temp = e(i, j);
+
+  return temp;
+}
+
+
+/**
+ * \fn max(const Matrix<T, Rows, Cols>& m)
+ * \brief Find the maximum of a matrix
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+T max(const Matrix<T, Rows, Cols>& m) {
+  typedef T			 			value_type;
+  typedef typename Matrix<
+   T, Rows, Cols
+  >::const_iterator					const_iterator;
+
+  const_iterator					iter(m.begin());
+  const_iterator					last(m.end());
+  value_type 						temp(*iter);
+
+  for( ; iter != last; ++iter)
+    if(*iter > temp)
+      temp = *iter;
+
+  return temp;
+}
+
+
+/**
+ * \fn min(const XprMatrix<E, Rows, Cols>& e)
+ * \brief Find the minimum of a matrix expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+typename E::value_type
+min(const XprMatrix<E, Rows, Cols>& e) {
+  typedef typename E::value_type			value_type;
+
+  value_type 						temp(e(0, 0));
+
+  for(std::size_t i = 0; i != Rows; ++i)
+    for(std::size_t j = 0; j != Cols; ++j)
+      if(e(i, j) < temp)
+	temp = e(i, j);
+
+  return temp;
+}
+
+
+/**
+ * \fn min(const Matrix<T, Rows, Cols>& m)
+ * \brief Find the minimum of a matrix
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+T min(const Matrix<T, Rows, Cols>& m) {
+  typedef T			 			value_type;
+  typedef typename Matrix<
+   T, Rows, Cols
+  >::const_iterator					const_iterator;
+
+  const_iterator					iter(m.begin());
+  const_iterator					last(m.end());
+  value_type 						temp(*iter);
+
+  for( ; iter != last; ++iter)
+    if(*iter < temp)
+      temp = *iter;
+
+  return temp;
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * other unary functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn XprMatrix<XprIdentity<typename M::value_type, M::Rows, M::Cols>, M::Rows, M::Cols>identity()
+ * \brief Fill a matrix to an identity matrix.
+ * \ingroup _unary_function
+ *
+ * \note The matrix doesn't need to be square. Only the elements
+ *       where the current number of rows are equal to columns
+ *       will be set to 1, else to 0.
+ *
+ * \par Usage:
+ * \code
+ * typedef Matrix<double,3,3>		matrix_type;
+ * ...
+ * matrix_type E( identity<double, 3, 3>() );
+ * \endcode
+ *
+ * Note, we have to specify the type, number of rows and columns
+ * since ADL can't work here.
+ *
+ *
+ *
+ * \since release 1.6.0
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprIdentity<T, Rows, Cols>,
+  Rows, Cols
+>
+identity() {
+  typedef XprIdentity<T, Rows, Cols>		expr_type;
+
+  return XprMatrix<expr_type, Rows, Cols>(expr_type());
+}
+
+/**
+ * \fn XprMatrix<XprIdentity<typename M::value_type, M::Rows, M::Cols>, M::Rows, M::Cols>identity()
+ * \brief Fill a matrix to an identity matrix (convenience wrapper
+ *        for matrix typedefs).
+ * \ingroup _unary_function
+ *
+ * \note The matrix doesn't need to be square. Only the elements
+ *       where the current number of rows are equal to columns
+ *       will be set to 1, else to 0.
+ *
+ * \par Usage:
+ * \code
+ * typedef Matrix<double,3,3>		matrix_type;
+ * ...
+ * matrix_type E( identity<matrix_type>() );
+ * \endcode
+ *
+ * Note, we have to specify the matrix type, since ADL can't work here.
+ *
+ * \since release 1.6.0
+ */
+template<class M>
+inline
+XprMatrix<
+  XprIdentity<
+    typename M::value_type,
+    M::Rows, M::Cols>,
+  M::Rows, M::Cols
+>
+identity() {
+  return identity<typename M::value_type, M::Rows, M::Cols>();
+}
+
+
+/**
+ * \fn cmatrix_ref(const T* mem)
+ * \brief Creates an expression wrapper for a C like matrices.
+ * \ingroup _unary_function
+ *
+ * This is like creating a matrix of external data, as described
+ * at \ref construct. With this function you wrap an expression
+ * around a C style matrix and you can operate directly with it
+ * as usual.
+ *
+ * \par Example:
+ * \code
+ * static float lhs[3][3] = {
+ *   {-1,  0,  1}, { 1,  0,  1}, {-1,  0, -1}
+ * };
+ * static float rhs[3][3] = {
+ *   { 0,  1,  1}, { 0,  1, -1}, { 0, -1,  1}
+ * };
+ * ...
+ *
+ * typedef Matrix<float, 3, 3>			matrix_type;
+ *
+ * matrix_type M( cmatrix_ref<float, 3, 3>(&lhs[0][0])
+ *                *  cmatrix_ref<float, 3, 3>(&rhs[0][0]) );
+ * \endcode
+ *
+ * \since release 1.6.0
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  MatrixConstReference<T, Rows, Cols>,
+  Rows, Cols
+>
+cmatrix_ref(const T* mem) {
+  typedef MatrixConstReference<T, Rows, Cols>	expr_type;
+
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(mem));
+}
+
+
+} // namespace tvmet
+
+#endif // TVMET_MATRIX_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/MatrixImpl.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,218 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixImpl.h,v 1.31 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_MATRIX_IMPL_H
+#define TVMET_MATRIX_IMPL_H
+
+#include <iomanip>			// setw
+
+#include <tvmet/Functional.h>
+#include <tvmet/Io.h>
+
+
+namespace tvmet {
+
+
+/*
+ * member operators for i/o
+ */
+template<class T, std::size_t NRows, std::size_t NCols>
+std::ostream& Matrix<T, NRows, NCols>::print_xpr(std::ostream& os, std::size_t l) const
+{
+  os << IndentLevel(l++) << "Matrix[" << ops << "]<"
+     << typeid(T).name() << ", " << Rows << ", " << Cols << ">,"
+     << IndentLevel(--l)
+     << std::endl;
+
+  return os;
+}
+
+
+template<class T, std::size_t NRows, std::size_t NCols>
+std::ostream& Matrix<T, NRows, NCols>::print_on(std::ostream& os) const
+{
+  enum {
+    complex_type = NumericTraits<value_type>::is_complex
+  };
+
+  std::streamsize w = IoPrintHelper<Matrix>::width(dispatch<complex_type>(), *this);
+
+  os << std::setw(0) << "[\n";
+  for(std::size_t i = 0; i < Rows; ++i) {
+    os << " [";
+    for(std::size_t j = 0; j < (Cols - 1); ++j) {
+      os << std::setw(w) << this->operator()(i, j) << ", ";
+    }
+    os << std::setw(w) << this->operator()(i, Cols - 1)
+       << (i != (Rows-1) ? "],\n" : "]\n");
+    }
+  os << "]";
+
+  return os;
+}
+
+
+/*
+ * member operators with scalars, per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				    \
+template<class T, std::size_t NRows, std::size_t NCols>		    \
+inline 								    \
+Matrix<T, NRows, NCols>&					    \
+Matrix<T, NRows, NCols>::operator OP (value_type rhs) {		    \
+  typedef XprLiteral<value_type> 			expr_type;  \
+  this->M_##NAME(XprMatrix<expr_type, Rows, Cols>(expr_type(rhs))); \
+  return *this;							    \
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq, +=)
+TVMET_IMPLEMENT_MACRO(sub_eq, -=)
+TVMET_IMPLEMENT_MACRO(mul_eq, *=)
+TVMET_IMPLEMENT_MACRO(div_eq, /=)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				    \
+template<class T, std::size_t NRows, std::size_t NCols>		    \
+inline 								    \
+Matrix<T, NRows, NCols>&					    \
+Matrix<T, NRows, NCols>::operator OP (std::size_t rhs) {	    \
+  typedef XprLiteral<value_type> 			expr_type;  \
+  this->M_##NAME(XprMatrix<expr_type, Rows, Cols>(expr_type(rhs))); \
+  return *this;							    \
+}
+
+TVMET_IMPLEMENT_MACRO(mod_eq, %=)
+TVMET_IMPLEMENT_MACRO(xor_eq,^=)
+TVMET_IMPLEMENT_MACRO(and_eq, &=)
+TVMET_IMPLEMENT_MACRO(or_eq, |=)
+TVMET_IMPLEMENT_MACRO(shl_eq, <<=)
+TVMET_IMPLEMENT_MACRO(shr_eq, >>=)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ *  member functions (operators) with matrizes, for use with +=,-= ... <<=
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)									     \
+template<class T1, std::size_t NRows, std::size_t NCols>						     \
+template <class T2>											     \
+inline 													     \
+Matrix<T1, NRows, NCols>&										     \
+Matrix<T1, NRows, NCols>::M_##NAME (const Matrix<T2, Rows, Cols>& rhs) {				     \
+  this->M_##NAME( XprMatrix<typename Matrix<T2, Rows, Cols>::ConstReference, Rows, Cols>(rhs.const_ref()) ); \
+  return *this;												     \
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+TVMET_IMPLEMENT_MACRO(mod_eq)
+TVMET_IMPLEMENT_MACRO(xor_eq)
+TVMET_IMPLEMENT_MACRO(and_eq)
+TVMET_IMPLEMENT_MACRO(or_eq)
+TVMET_IMPLEMENT_MACRO(shl_eq)
+TVMET_IMPLEMENT_MACRO(shr_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * member functions (operators) with expressions, for use width +=,-= ... <<=
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					   \
+template<class T, std::size_t NRows, std::size_t NCols>			   \
+template<class E>							   \
+inline 									   \
+Matrix<T, NRows, NCols>&						   \
+Matrix<T, NRows, NCols>::M_##NAME (const XprMatrix<E, Rows, Cols>& rhs) {  \
+  rhs.assign_to(*this, Fcnl_##NAME<value_type, typename E::value_type>()); \
+  return *this;								   \
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+TVMET_IMPLEMENT_MACRO(mod_eq)
+TVMET_IMPLEMENT_MACRO(xor_eq)
+TVMET_IMPLEMENT_MACRO(and_eq)
+TVMET_IMPLEMENT_MACRO(or_eq)
+TVMET_IMPLEMENT_MACRO(shl_eq)
+TVMET_IMPLEMENT_MACRO(shr_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * aliased member functions (operators) with matrizes,
+ * for use with +=,-= ... <<=
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)										 \
+template<class T1, std::size_t NRows, std::size_t NCols>							 \
+template <class T2>												 \
+inline 														 \
+Matrix<T1, NRows, NCols>&											 \
+Matrix<T1, NRows, NCols>::alias_##NAME (const Matrix<T2, Rows, Cols>& rhs) {					 \
+  this->alias_##NAME( XprMatrix<typename Matrix<T2, Rows, Cols>::ConstReference, Rows, Cols>(rhs.const_ref()) ); \
+  return *this;													 \
+}
+
+TVMET_IMPLEMENT_MACRO(assign)
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * aliased member functions (operators) with expressions,
+ * for use width +=,-= ... <<= and aliased(),
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)						      \
+template<class T, std::size_t NRows, std::size_t NCols>				      \
+template<class E>								      \
+inline 										      \
+Matrix<T, NRows, NCols>&							      \
+Matrix<T, NRows, NCols>::alias_##NAME (const XprMatrix<E, Rows, Cols>& rhs) {	      \
+  typedef Matrix<T, NRows, NCols> 			temp_type;		      \
+  temp_type(rhs).assign_to(*this, Fcnl_##NAME<value_type, typename E::value_type>()); \
+  return *this;									      \
+}
+
+TVMET_IMPLEMENT_MACRO(assign)
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+} // namespace tvmet
+
+#endif // TVMET_MATRIX_IMPL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/MatrixOperators.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,1287 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixOperators.h,v 1.37 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_MATRIX_OPERATORS_H
+#define TVMET_MATRIX_OPERATORS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+template<class T, std::size_t Rows, std::size_t Cols>
+std::ostream& operator<<(std::ostream& os,
+			 const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Member operators (arithmetic and bit ops)
+ *++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * update_operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * update_operator(Matrix<T1, Rows, Cols>, XprMatrix<E, Rows, Cols> rhs)
+ * Note: per se element wise
+ * \todo: the operator*= can have element wise mul oder product, decide!
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>		\
+Matrix<T1, Rows, Cols>&								\
+operator OP (Matrix<T1, Rows, Cols>& lhs, 					\
+	     const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+										\
+template<class T, class E, std::size_t Rows,  std::size_t Cols>			\
+Matrix<T, Rows, Cols>&								\
+operator OP (Matrix<T, Rows, Cols>& lhs, 					\
+	     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add_eq, +=)		// per se element wise
+TVMET_DECLARE_MACRO(sub_eq, -=)		// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mul_eq, *=)		// see note
+  TVMET_DECLARE_MACRO(div_eq, /=)		// not defined for vectors
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod_eq, %=)
+  TVMET_DECLARE_MACRO(xor_eq, ^=)
+  TVMET_DECLARE_MACRO(and_eq, &=)
+  TVMET_DECLARE_MACRO(or_eq, |=)
+  TVMET_DECLARE_MACRO(shl_eq, <<=)
+  TVMET_DECLARE_MACRO(shr_eq, >>=)
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * operator(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
+ * operator(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
+ * Note: per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>		\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<T1, T2>,							\
+    MatrixConstReference<T1, Rows, Cols>,					\
+    MatrixConstReference<T2, Rows, Cols>					\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const Matrix<T1, Rows, Cols>& lhs,					\
+	     const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+										\
+template<class E, class T, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    XprMatrix<E, Rows, Cols>,							\
+    MatrixConstReference<T, Rows, Cols>						\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, 				\
+	     const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+										\
+template<class T, class E, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const Matrix<T, Rows, Cols>& lhs, 					\
+	     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)			// per se element wise
+TVMET_DECLARE_MACRO(sub, -)			// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mul, *)			// see as prod()
+  TVMET_DECLARE_MACRO(div, /)			// not defined for matrizes
+}
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * operator(Matrix<T, Rows, Cols>, POD)
+ * operator(POD, Matrix<T, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, POD)				\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, POD >,						\
+    MatrixConstReference<T, Rows, Cols>,				\
+    XprLiteral<POD >							\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (const Matrix<T, Rows, Cols>& lhs, 				\
+	     POD rhs) TVMET_CXX_ALWAYS_INLINE;				\
+									\
+template<class T, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, T>,						\
+    XprLiteral< POD >,							\
+    MatrixConstReference<T, Rows, Cols>					\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (POD lhs, 							\
+	     const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +, int)
+TVMET_DECLARE_MACRO(sub, -, int)
+TVMET_DECLARE_MACRO(mul, *, int)
+TVMET_DECLARE_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, +, long long int)
+TVMET_DECLARE_MACRO(sub, -, long long int)
+TVMET_DECLARE_MACRO(mul, *, long long int)
+TVMET_DECLARE_MACRO(div, /, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_DECLARE_MACRO(add, +, float)
+TVMET_DECLARE_MACRO(sub, -, float)
+TVMET_DECLARE_MACRO(mul, *, float)
+TVMET_DECLARE_MACRO(div, /, float)
+
+TVMET_DECLARE_MACRO(add, +, double)
+TVMET_DECLARE_MACRO(sub, -, double)
+TVMET_DECLARE_MACRO(mul, *, double)
+TVMET_DECLARE_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, +, long double)
+TVMET_DECLARE_MACRO(sub, -, long double)
+TVMET_DECLARE_MACRO(mul, *, long double)
+TVMET_DECLARE_MACRO(div, /, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Matrix<T, Rows, Cols>, complex<T>)
+ * operator(complex<T>, Matrix<T, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)							\
+template<class T, std::size_t Rows, std::size_t Cols>					\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    MatrixConstReference< std::complex<T>, Rows, Cols>,					\
+    XprLiteral<std::complex<T> >							\
+  >,											\
+  Rows, Cols										\
+>											\
+operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs,				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;			\
+											\
+template<class T, std::size_t Rows, std::size_t Cols>					\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    XprLiteral< std::complex<T> >,							\
+    MatrixConstReference< std::complex<T>, Rows, Cols>					\
+  >,											\
+  Rows, Cols										\
+>											\
+operator OP (const std::complex<T>& lhs,						\
+	     const Matrix< std::complex<T>, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)
+TVMET_DECLARE_MACRO(sub, -)
+TVMET_DECLARE_MACRO(mul, *)
+TVMET_DECLARE_MACRO(div, /)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific operator*() = prod() operations
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2
+>
+operator*(const Matrix<T1, Rows1, Cols1>& lhs,
+	  const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2
+>
+operator*(const XprMatrix<E1, Rows1, Cols1>& lhs,
+	  const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    XprMatrix<E2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2
+>
+operator*(const Matrix<T1, Rows1, Cols1>& lhs,
+	  const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class T1, std::size_t Rows, std::size_t Cols, class T2>
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    VectorConstReference<T2, Cols>
+  >,
+  Rows
+>
+operator*(const Matrix<T1, Rows, Cols>& lhs,
+	  const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, class E2, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+operator*(const Matrix<T1, Rows, Cols>& lhs,
+	  const XprVector<E2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, class T2, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    VectorConstReference<T2, Cols>
+  >,
+  Rows
+>
+operator*(const XprMatrix<E1, Rows, Cols>& lhs,
+	  const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * operator(XprMatrix<E>, Matrix<T, Rows, Cols>)
+ * operator(Matrix<T, Rows, Cols>, XprMatrix<E>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class T1, std::size_t Rows, std::size_t Cols,				\
+	 class T2>								\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<T1, T2>,							\
+    MatrixConstReference<T1, Rows, Cols>,					\
+    MatrixConstReference<T2, Rows, Cols>					\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const Matrix<T1, Rows, Cols>& lhs,					\
+	     const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+										\
+template<class E,								\
+	 class T, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    XprMatrix<E, Rows, Cols>,							\
+    MatrixConstReference<T, Rows, Cols>						\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, 				\
+	     const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+										\
+template<class T, std::size_t Rows, std::size_t Cols,				\
+	 class E>								\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,					\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const Matrix<T, Rows, Cols>& lhs, 					\
+	     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %)
+  TVMET_DECLARE_MACRO(bitxor, ^)
+  TVMET_DECLARE_MACRO(bitand, &)
+  TVMET_DECLARE_MACRO(bitor, |)
+  TVMET_DECLARE_MACRO(shl, <<)
+  TVMET_DECLARE_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Matrix<T, Rows, Cols>, complex<T>)
+ * operator(complex<T>, Matrix<T, Rows, Cols>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)							\
+template<class T, std::size_t Rows, std::size_t Cols>					\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    MatrixConstReference< std::complex<T>, Rows, Cols>,					\
+    XprLiteral<std::complex<T> >							\
+  >,											\
+  Rows, Cols										\
+>											\
+operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs,				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;			\
+											\
+template<class T, std::size_t Rows, std::size_t Cols>					\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    XprLiteral< std::complex<T> >,							\
+    MatrixConstReference< std::complex<T>, Rows, Cols>					\
+  >,											\
+  Rows, Cols										\
+>											\
+operator OP (const std::complex<T>& lhs,						\
+	     const Matrix< std::complex<T>, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*
+ * operator(Matrix<T, Rows, Cols>, POD)
+ * operator(POD, Matrix<T, Rows, Cols>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, TP)					\
+template<class T, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<T, TP >,							\
+    MatrixConstReference<T, Rows, Cols>,					\
+    XprLiteral<TP >								\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const Matrix<T, Rows, Cols>& lhs, TP rhs) TVMET_CXX_ALWAYS_INLINE;	\
+										\
+template<class T, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME< TP, T>,							\
+    XprLiteral< TP >,								\
+    MatrixConstReference<T, Rows, Cols>						\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (TP lhs, const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, int)
+  TVMET_DECLARE_MACRO(bitxor, ^, int)
+  TVMET_DECLARE_MACRO(bitand, &, int)
+  TVMET_DECLARE_MACRO(bitor, |, int)
+  TVMET_DECLARE_MACRO(shl, <<, int)
+  TVMET_DECLARE_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, int)
+TVMET_DECLARE_MACRO(less, <, int)
+TVMET_DECLARE_MACRO(greater_eq, >=, int)
+TVMET_DECLARE_MACRO(less_eq, <=, int)
+TVMET_DECLARE_MACRO(eq, ==, int)
+TVMET_DECLARE_MACRO(not_eq, !=, int)
+TVMET_DECLARE_MACRO(and, &&, int)
+TVMET_DECLARE_MACRO(or, ||, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, long long int)
+  TVMET_DECLARE_MACRO(bitxor, ^, long long int)
+  TVMET_DECLARE_MACRO(bitand, &, long long int)
+  TVMET_DECLARE_MACRO(bitor, |, long long int)
+  TVMET_DECLARE_MACRO(shl, <<, long long int)
+  TVMET_DECLARE_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long long int)
+TVMET_DECLARE_MACRO(less, <, long long int)
+TVMET_DECLARE_MACRO(greater_eq, >=, long long int)
+TVMET_DECLARE_MACRO(less_eq, <=, long long int)
+TVMET_DECLARE_MACRO(eq, ==, long long int)
+TVMET_DECLARE_MACRO(not_eq, !=, long long int)
+TVMET_DECLARE_MACRO(and, &&, long long int)
+TVMET_DECLARE_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, float)
+TVMET_DECLARE_MACRO(less, <, float)
+TVMET_DECLARE_MACRO(greater_eq, >=, float)
+TVMET_DECLARE_MACRO(less_eq, <=, float)
+TVMET_DECLARE_MACRO(eq, ==, float)
+TVMET_DECLARE_MACRO(not_eq, !=, float)
+TVMET_DECLARE_MACRO(and, &&, float)
+TVMET_DECLARE_MACRO(or, ||, float)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, double)
+TVMET_DECLARE_MACRO(less, <, double)
+TVMET_DECLARE_MACRO(greater_eq, >=, double)
+TVMET_DECLARE_MACRO(less_eq, <=, double)
+TVMET_DECLARE_MACRO(eq, ==, double)
+TVMET_DECLARE_MACRO(not_eq, !=, double)
+TVMET_DECLARE_MACRO(and, &&, double)
+TVMET_DECLARE_MACRO(or, ||, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long double)
+TVMET_DECLARE_MACRO(less, <, long double)
+TVMET_DECLARE_MACRO(greater_eq, >=, long double)
+TVMET_DECLARE_MACRO(less_eq, <=, long double)
+TVMET_DECLARE_MACRO(eq, ==, long double)
+TVMET_DECLARE_MACRO(not_eq, !=, long double)
+TVMET_DECLARE_MACRO(and, &&, long double)
+TVMET_DECLARE_MACRO(or, ||, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * unary_operator(Matrix<T, Rows, Cols>)
+ * Note: per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template <class T, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprUnOp<								\
+    Fcnl_##NAME<T>,							\
+    MatrixConstReference<T, Rows, Cols>					\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(not, !)
+TVMET_DECLARE_MACRO(compl, ~)
+TVMET_DECLARE_MACRO(neg, -)
+#undef TVMET_DECLARE_MACRO
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/**
+ * \fn operator<<(std::ostream& os, const Matrix<T, Rows, Cols>& rhs)
+ * \brief Overload operator for i/o
+ * \ingroup _binary_operator
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+std::ostream& operator<<(std::ostream& os, const Matrix<T, Rows, Cols>& rhs) {
+  return rhs.print_on(os);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Member operators (arithmetic and bit ops)
+ *++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * update_operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * update_operator(Matrix<T1, Rows, Cols>, XprMatrix<E, Rows, Cols> rhs)
+ * Note: per se element wise
+ * \todo: the operator*= can have element wise mul oder product, decide!
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)						\
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>		\
+inline 										\
+Matrix<T1, Rows, Cols>&								\
+operator OP (Matrix<T1, Rows, Cols>& lhs, const Matrix<T2, Rows, Cols>& rhs) {	\
+  return lhs.M_##NAME(rhs);							\
+}										\
+										\
+template<class T, class E, std::size_t Rows,  std::size_t Cols>			\
+inline 										\
+Matrix<T, Rows, Cols>&								\
+operator OP (Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) {	\
+  return lhs.M_##NAME(rhs);							\
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq, +=)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub_eq, -=)		// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mul_eq, *=)		// see note
+  TVMET_IMPLEMENT_MACRO(div_eq, /=)		// not defined for vectors
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod_eq, %=)
+  TVMET_IMPLEMENT_MACRO(xor_eq, ^=)
+  TVMET_IMPLEMENT_MACRO(and_eq, &=)
+  TVMET_IMPLEMENT_MACRO(or_eq, |=)
+  TVMET_IMPLEMENT_MACRO(shl_eq, <<=)
+  TVMET_IMPLEMENT_MACRO(shr_eq, >>=)
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * operator(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
+ * operator(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
+ * Note: per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)						      \
+template<class T1, class T2, std::size_t Rows, std::size_t Cols>		      \
+inline										      \
+XprMatrix<									      \
+  XprBinOp<									      \
+    Fcnl_##NAME<T1, T2>,							      \
+    MatrixConstReference<T1, Rows, Cols>,					      \
+    MatrixConstReference<T2, Rows, Cols>					      \
+  >,										      \
+  Rows, Cols									      \
+>										      \
+operator OP (const Matrix<T1, Rows, Cols>& lhs,	const Matrix<T2, Rows, Cols>& rhs) {  \
+  return NAME(lhs, rhs);							      \
+}										      \
+										      \
+template<class E, class T, std::size_t Rows, std::size_t Cols>			      \
+inline										      \
+XprMatrix<									      \
+  XprBinOp<									      \
+    Fcnl_##NAME<typename E::value_type, T>,					      \
+    XprMatrix<E, Rows, Cols>,							      \
+    MatrixConstReference<T, Rows, Cols>						      \
+  >,										      \
+  Rows, Cols									      \
+>										      \
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs) { \
+  return NAME(lhs, rhs);							      \
+}										      \
+										      \
+template<class T, class E, std::size_t Rows, std::size_t Cols>			      \
+inline										      \
+XprMatrix<									      \
+  XprBinOp<									      \
+    Fcnl_##NAME<typename E::value_type, T>,					      \
+    MatrixConstReference<T, Rows, Cols>,					      \
+    XprMatrix<E, Rows, Cols>							      \
+  >,										      \
+  Rows, Cols									      \
+>										      \
+operator OP (const Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) { \
+  return NAME(lhs, rhs);							      \
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)			// per se element wise
+TVMET_IMPLEMENT_MACRO(sub, -)			// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mul, *)			// see as prod()
+  TVMET_IMPLEMENT_MACRO(div, /)			// not defined for matrizes
+}
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * operator(Matrix<T, Rows, Cols>, POD)
+ * operator(POD, Matrix<T, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, POD)			\
+template<class T, std::size_t Rows, std::size_t Cols>		\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME<T, POD >,					\
+    MatrixConstReference<T, Rows, Cols>,			\
+    XprLiteral<POD >						\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (const Matrix<T, Rows, Cols>& lhs, POD rhs) {	\
+  return NAME (lhs, rhs);					\
+}								\
+								\
+template<class T, std::size_t Rows, std::size_t Cols>		\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME< POD, T>,					\
+    XprLiteral< POD >,						\
+    MatrixConstReference<T, Rows, Cols>				\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (POD lhs, const Matrix<T, Rows, Cols>& rhs) {	\
+  return NAME (lhs, rhs);					\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +, int)
+TVMET_IMPLEMENT_MACRO(sub, -, int)
+TVMET_IMPLEMENT_MACRO(mul, *, int)
+TVMET_IMPLEMENT_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, +, long long int)
+TVMET_IMPLEMENT_MACRO(sub, -, long long int)
+TVMET_IMPLEMENT_MACRO(mul, *, long long int)
+TVMET_IMPLEMENT_MACRO(div, /, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_IMPLEMENT_MACRO(add, +, float)
+TVMET_IMPLEMENT_MACRO(sub, -, float)
+TVMET_IMPLEMENT_MACRO(mul, *, float)
+TVMET_IMPLEMENT_MACRO(div, /, float)
+
+TVMET_IMPLEMENT_MACRO(add, +, double)
+TVMET_IMPLEMENT_MACRO(sub, -, double)
+TVMET_IMPLEMENT_MACRO(mul, *, double)
+TVMET_IMPLEMENT_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, +, long double)
+TVMET_IMPLEMENT_MACRO(sub, -, long double)
+TVMET_IMPLEMENT_MACRO(mul, *, long double)
+TVMET_IMPLEMENT_MACRO(div, /, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Matrix<T, Rows, Cols>, complex<T>)
+ * operator(complex<T>, Matrix<T, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				\
+template<class T, std::size_t Rows, std::size_t Cols>		\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,		\
+    MatrixConstReference< std::complex<T>, Rows, Cols>,		\
+    XprLiteral<std::complex<T> >				\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs,	\
+	     const std::complex<T>& rhs) {			\
+  return NAME (lhs, rhs);					\
+}								\
+								\
+template<class T, std::size_t Rows, std::size_t Cols>		\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,		\
+    XprLiteral< std::complex<T> >,				\
+    MatrixConstReference< std::complex<T>, Rows, Cols>		\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (const std::complex<T>& lhs,			\
+	     const Matrix< std::complex<T>, Rows, Cols>& rhs) {	\
+  return NAME (lhs, rhs);					\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)
+TVMET_IMPLEMENT_MACRO(sub, -)
+TVMET_IMPLEMENT_MACRO(mul, *)
+TVMET_IMPLEMENT_MACRO(div, /)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific operator*() = prod() operations
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn operator*(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
+ * \brief multiply two Matrices.
+ * \ingroup _binary_operator
+ * \note The rows2 has to be equal to cols1.
+ * \sa prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
+ */
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2
+>
+operator*(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/**
+ * \fn operator*(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
+ * \brief Evaluate the product of XprMatrix and Matrix.
+ * \ingroup _binary_operator
+ * \sa prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class T2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
+    MatrixConstReference<T2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2
+>
+operator*(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/**
+ * \fn operator*(const Matrix<T1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs)
+ * \brief Evaluate the product of Matrix and XprMatrix.
+ * \ingroup _binary_operator
+ * \sa prod(const Matrix<T, Rows1, Cols1>& lhs, const XprMatrix<E, Cols1, Cols2>& rhs)
+ */
+template<class T1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
+    XprMatrix<E2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2
+>
+operator*(const Matrix<T1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn operator*(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs)
+ * \brief multiply a Matrix with a Vector.
+ * \ingroup _binary_operator
+ * \note The length of the Vector has to be equal to the number of Columns.
+ * \sa prod(const Matrix<T1, Rows, Cols>& m, const Vector<T2, Cols>& v)
+ */
+template<class T1, std::size_t Rows, std::size_t Cols, class T2>
+inline
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    VectorConstReference<T2, Cols>
+  >,
+  Rows
+>
+operator*(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/**
+ * \fn operator*(const Matrix<T1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs)
+ * \brief Function for the matrix-vector-product
+ * \ingroup _binary_operator
+ * \sa prod(const Matrix<T, Rows, Cols>& lhs, const XprVector<E, Cols>& rhs)
+ */
+template<class T1, class E2, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMVProduct<
+    MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+operator*(const Matrix<T1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/**
+ * \fn operator*(const XprMatrix<E1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs)
+ * \brief Compute the product of an XprMatrix with a Vector.
+ * \ingroup _binary_operator
+ * \sa prod(const XprMatrix<E, Rows, Cols>& lhs, const Vector<T, Cols>& rhs)
+ */
+template<class E1, class T2, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    VectorConstReference<T2, Cols>
+  >,
+  Rows
+>
+operator*(const XprMatrix<E1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
+ * operator(XprMatrix<E>, Matrix<T, Rows, Cols>)
+ * operator(Matrix<T, Rows, Cols>, XprMatrix<E>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)							\
+template<class T1, std::size_t Rows, std::size_t Cols,					\
+	 class T2>									\
+inline											\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME<T1, T2>,								\
+    MatrixConstReference<T1, Rows, Cols>,						\
+    MatrixConstReference<T2, Rows, Cols>						\
+  >,											\
+  Rows, Cols										\
+>											\
+operator OP (const Matrix<T1, Rows, Cols>& lhs,						\
+	     const Matrix<T2, Rows, Cols>& rhs) {					\
+  typedef XprBinOp <									\
+    Fcnl_##NAME<T1, T2>,								\
+    MatrixConstReference<T1, Rows, Cols>,						\
+    MatrixConstReference<T2, Rows, Cols>						\
+  >							expr_type;			\
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs.const_ref(), rhs.const_ref()));	\
+}											\
+											\
+template<class E,									\
+	 class T, std::size_t Rows, std::size_t Cols>					\
+inline											\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME<typename E::value_type, T>,						\
+    XprMatrix<E, Rows, Cols>,								\
+    MatrixConstReference<T, Rows, Cols>							\
+  >,											\
+  Rows, Cols										\
+>											\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs) {	\
+  typedef XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, T>,						\
+    XprMatrix<E, Rows, Cols>,								\
+    MatrixConstReference<T, Rows, Cols>							\
+  > 							 expr_type;			\
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs, rhs.const_ref()));		\
+}											\
+											\
+template<class T, std::size_t Rows, std::size_t Cols,					\
+	 class E>									\
+inline											\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME<typename E::value_type, T>,						\
+    MatrixConstReference<T, Rows, Cols>,						\
+    XprMatrix<E, Rows, Cols>								\
+  >,											\
+  Rows, Cols										\
+>											\
+operator OP (const Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) {	\
+  typedef XprBinOp<									\
+    Fcnl_##NAME<T, typename E::value_type>,						\
+    MatrixConstReference<T, Rows, Cols>,						\
+    XprMatrix<E, Rows, Cols>								\
+  >	 						 expr_type;			\
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs.const_ref(), rhs));		\
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^)
+  TVMET_IMPLEMENT_MACRO(bitand, &)
+  TVMET_IMPLEMENT_MACRO(bitor, |)
+  TVMET_IMPLEMENT_MACRO(shl, <<)
+  TVMET_IMPLEMENT_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Matrix<T, Rows, Cols>, complex<T>)
+ * operator(complex<T>, Matrix<T, Rows, Cols>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				     \
+template<class T, std::size_t Rows, std::size_t Cols>		     \
+inline								     \
+XprMatrix<							     \
+  XprBinOp<							     \
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,		     \
+    MatrixConstReference< std::complex<T>, Rows, Cols>,		     \
+    XprLiteral<std::complex<T> >				     \
+  >,								     \
+  Rows, Cols							     \
+>								     \
+operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs,	     \
+	     const std::complex<T>& rhs) {			     \
+  typedef XprBinOp<						     \
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,		     \
+    MatrixConstReference< std::complex<T>, Rows, Cols>,		     \
+    XprLiteral< std::complex<T> >				     \
+  >							expr_type;   \
+  return XprMatrix<expr_type, Rows, Cols>(			     \
+    expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs))); \
+}								     \
+								     \
+template<class T, std::size_t Rows, std::size_t Cols>		     \
+inline								     \
+XprMatrix<							     \
+  XprBinOp<							     \
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,		     \
+    XprLiteral< std::complex<T> >,				     \
+    MatrixConstReference< std::complex<T>, Rows, Cols>		     \
+  >,								     \
+  Rows, Cols							     \
+>								     \
+operator OP (const std::complex<T>& lhs,			     \
+	     const Matrix< std::complex<T>, Rows, Cols>& rhs) {	     \
+  typedef XprBinOp<						     \
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,		     \
+    XprLiteral< std::complex<T> >,				     \
+    MatrixConstReference<T, Rows, Cols>				     \
+  >							expr_type;   \
+  return XprMatrix<expr_type, Rows, Cols>(			     \
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref())); \
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*
+ * operator(Matrix<T, Rows, Cols>, POD)
+ * operator(POD, Matrix<T, Rows, Cols>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, TP)			   \
+template<class T, std::size_t Rows, std::size_t Cols>		   \
+inline								   \
+XprMatrix<							   \
+  XprBinOp<							   \
+    Fcnl_##NAME<T, TP >,					   \
+    MatrixConstReference<T, Rows, Cols>,			   \
+    XprLiteral<TP >						   \
+  >,								   \
+  Rows, Cols							   \
+>								   \
+operator OP (const Matrix<T, Rows, Cols>& lhs, TP rhs) {	   \
+  typedef XprBinOp<						   \
+    Fcnl_##NAME<T, TP >,					   \
+    MatrixConstReference<T, Rows, Cols>,			   \
+    XprLiteral< TP >						   \
+  >							expr_type; \
+  return XprMatrix<expr_type, Rows, Cols>(			   \
+    expr_type(lhs.const_ref(), XprLiteral< TP >(rhs)));		   \
+}								   \
+								   \
+template<class T, std::size_t Rows, std::size_t Cols>		   \
+inline								   \
+XprMatrix<							   \
+  XprBinOp<							   \
+    Fcnl_##NAME< TP, T>,					   \
+    XprLiteral< TP >,						   \
+    MatrixConstReference<T, Rows, Cols>				   \
+  >,								   \
+  Rows, Cols							   \
+>								   \
+operator OP (TP lhs, const Matrix<T, Rows, Cols>& rhs) {	   \
+  typedef XprBinOp<						   \
+    Fcnl_##NAME< TP, T>,					   \
+    XprLiteral< TP >,						   \
+    MatrixConstReference<T, Rows, Cols>				   \
+  >							expr_type; \
+  return XprMatrix<expr_type, Rows, Cols>(			   \
+    expr_type(XprLiteral< TP >(lhs), rhs.const_ref()));		   \
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, int)
+TVMET_IMPLEMENT_MACRO(less, <, int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, int)
+TVMET_IMPLEMENT_MACRO(eq, ==, int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, int)
+TVMET_IMPLEMENT_MACRO(and, &&, int)
+TVMET_IMPLEMENT_MACRO(or, ||, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, long long int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, long long int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, long long int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, long long int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long long int)
+TVMET_IMPLEMENT_MACRO(less, <, long long int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int)
+TVMET_IMPLEMENT_MACRO(eq, ==, long long int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int)
+TVMET_IMPLEMENT_MACRO(and, &&, long long int)
+TVMET_IMPLEMENT_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, float)
+TVMET_IMPLEMENT_MACRO(less, <, float)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, float)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, float)
+TVMET_IMPLEMENT_MACRO(eq, ==, float)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, float)
+TVMET_IMPLEMENT_MACRO(and, &&, float)
+TVMET_IMPLEMENT_MACRO(or, ||, float)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, double)
+TVMET_IMPLEMENT_MACRO(less, <, double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, double)
+TVMET_IMPLEMENT_MACRO(eq, ==, double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, double)
+TVMET_IMPLEMENT_MACRO(and, &&, double)
+TVMET_IMPLEMENT_MACRO(or, ||, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long double)
+TVMET_IMPLEMENT_MACRO(less, <, long double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long double)
+TVMET_IMPLEMENT_MACRO(eq, ==, long double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long double)
+TVMET_IMPLEMENT_MACRO(and, &&, long double)
+TVMET_IMPLEMENT_MACRO(or, ||, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * unary_operator(Matrix<T, Rows, Cols>)
+ * Note: per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				       \
+template <class T, std::size_t Rows, std::size_t Cols>		       \
+inline								       \
+XprMatrix<							       \
+  XprUnOp<							       \
+    Fcnl_##NAME<T>,						       \
+    MatrixConstReference<T, Rows, Cols>				       \
+  >,								       \
+  Rows, Cols							       \
+>								       \
+operator OP (const Matrix<T, Rows, Cols>& rhs) {		       \
+  typedef XprUnOp<						       \
+    Fcnl_##NAME<T>,						       \
+    MatrixConstReference<T, Rows, Cols>				       \
+  >  							 expr_type;    \
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(rhs.const_ref())); \
+}
+
+TVMET_IMPLEMENT_MACRO(not, !)
+TVMET_IMPLEMENT_MACRO(compl, ~)
+TVMET_IMPLEMENT_MACRO(neg, -)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+} // namespace tvmet
+
+#endif // TVMET_MATRIX_OPERATORS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/MatrixUnaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,222 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixUnaryFunctions.h,v 1.13 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_MATRIX_UNARY_FUNCTIONS_H
+#define TVMET_MATRIX_UNARY_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+/*
+ * unary_function(Matrix<T, Rows, Cols>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)                \
+template<class T, std::size_t Rows, std::size_t Cols>        \
+inline                                \
+XprMatrix<                            \
+  XprUnOp<                            \
+    Fcnl_##NAME<T>,                        \
+    MatrixConstReference<T, Rows, Cols>                \
+  >,                                \
+  Rows, Cols                            \
+>                                \
+NAME(const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(abs)
+TVMET_DECLARE_MACRO(cbrt)
+TVMET_DECLARE_MACRO(ceil)
+TVMET_DECLARE_MACRO(floor)
+TVMET_DECLARE_MACRO(rint)
+TVMET_DECLARE_MACRO(sin)
+TVMET_DECLARE_MACRO(cos)
+TVMET_DECLARE_MACRO(tan)
+TVMET_DECLARE_MACRO(sinh)
+TVMET_DECLARE_MACRO(cosh)
+TVMET_DECLARE_MACRO(tanh)
+TVMET_DECLARE_MACRO(asin)
+TVMET_DECLARE_MACRO(acos)
+TVMET_DECLARE_MACRO(atan)
+TVMET_DECLARE_MACRO(exp)
+TVMET_DECLARE_MACRO(log)
+TVMET_DECLARE_MACRO(log10)
+TVMET_DECLARE_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_DECLARE_MACRO(asinh)
+TVMET_DECLARE_MACRO(acosh)
+TVMET_DECLARE_MACRO(atanh)
+TVMET_DECLARE_MACRO(expm1)
+TVMET_DECLARE_MACRO(log1p)
+TVMET_DECLARE_MACRO(erf)
+TVMET_DECLARE_MACRO(erfc)
+TVMET_DECLARE_MACRO(j0)
+TVMET_DECLARE_MACRO(j1)
+TVMET_DECLARE_MACRO(y0)
+TVMET_DECLARE_MACRO(y1)
+TVMET_DECLARE_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_DECLARE_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * unary_function(Matrix<std::complex<T>, Rows, Cols>)
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+#define TVMET_DECLARE_MACRO(NAME)                        \
+template<class T, std::size_t Rows, std::size_t Cols>                \
+inline                                        \
+XprMatrix<                                    \
+  XprUnOp<                                    \
+    Fcnl_##NAME< std::complex<T> >,                        \
+    MatrixConstReference<std::complex<T>, Rows, Cols>                \
+  >,                                        \
+  Rows, Cols                                    \
+>                                        \
+NAME(const Matrix<std::complex<T>, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(real)
+TVMET_DECLARE_MACRO(imag)
+TVMET_DECLARE_MACRO(arg)
+TVMET_DECLARE_MACRO(norm)
+TVMET_DECLARE_MACRO(conj)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*
+ * unary_function(Matrix<T, Rows, Cols>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)                    \
+template<class T, std::size_t Rows, std::size_t Cols>            \
+inline                                    \
+XprMatrix<                                \
+  XprUnOp<                                \
+    Fcnl_##NAME<T>,                            \
+    MatrixConstReference<T, Rows, Cols>                    \
+  >,                                    \
+  Rows, Cols                                \
+>                                    \
+NAME(const Matrix<T, Rows, Cols>& rhs) {                \
+  typedef XprUnOp<                            \
+    Fcnl_##NAME<T>,                            \
+    MatrixConstReference<T, Rows, Cols>                    \
+  >                             expr_type;    \
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(rhs.const_ref()));    \
+}
+
+TVMET_IMPLEMENT_MACRO(abs)
+TVMET_IMPLEMENT_MACRO(cbrt)
+TVMET_IMPLEMENT_MACRO(ceil)
+TVMET_IMPLEMENT_MACRO(floor)
+TVMET_IMPLEMENT_MACRO(rint)
+TVMET_IMPLEMENT_MACRO(sin)
+TVMET_IMPLEMENT_MACRO(cos)
+TVMET_IMPLEMENT_MACRO(tan)
+TVMET_IMPLEMENT_MACRO(sinh)
+TVMET_IMPLEMENT_MACRO(cosh)
+TVMET_IMPLEMENT_MACRO(tanh)
+TVMET_IMPLEMENT_MACRO(asin)
+TVMET_IMPLEMENT_MACRO(acos)
+TVMET_IMPLEMENT_MACRO(atan)
+TVMET_IMPLEMENT_MACRO(exp)
+TVMET_IMPLEMENT_MACRO(log)
+TVMET_IMPLEMENT_MACRO(log10)
+TVMET_IMPLEMENT_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_IMPLEMENT_MACRO(asinh)
+TVMET_IMPLEMENT_MACRO(acosh)
+TVMET_IMPLEMENT_MACRO(atanh)
+TVMET_IMPLEMENT_MACRO(expm1)
+TVMET_IMPLEMENT_MACRO(log1p)
+TVMET_IMPLEMENT_MACRO(erf)
+TVMET_IMPLEMENT_MACRO(erfc)
+TVMET_IMPLEMENT_MACRO(j0)
+TVMET_IMPLEMENT_MACRO(j1)
+TVMET_IMPLEMENT_MACRO(y0)
+TVMET_IMPLEMENT_MACRO(y1)
+TVMET_IMPLEMENT_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_IMPLEMENT_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * unary_function(Matrix<std::complex<T>, Rows, Cols>)
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+#define TVMET_IMPLEMENT_MACRO(NAME)                    \
+template<class T, std::size_t Rows, std::size_t Cols>            \
+inline                                    \
+XprMatrix<                                \
+  XprUnOp<                                \
+    Fcnl_##NAME< std::complex<T> >,                    \
+    MatrixConstReference<std::complex<T>, Rows, Cols>            \
+  >,                                    \
+  Rows, Cols                                \
+>                                    \
+NAME(const Matrix<std::complex<T>, Rows, Cols>& rhs) {            \
+  typedef XprUnOp<                            \
+    Fcnl_##NAME< std::complex<T> >,                    \
+    MatrixConstReference<std::complex<T>, Rows, Cols>            \
+  >                             expr_type;    \
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(rhs.const_ref()));    \
+}
+
+TVMET_IMPLEMENT_MACRO(real)
+TVMET_IMPLEMENT_MACRO(imag)
+TVMET_IMPLEMENT_MACRO(arg)
+TVMET_IMPLEMENT_MACRO(norm)
+TVMET_IMPLEMENT_MACRO(conj)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace tvmet
+
+#endif // TVMET_MATRIX_UNARY_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/NumericTraits.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,1363 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: NumericTraits.h,v 1.16 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_NUMERIC_TRAITS_H
+#define TVMET_NUMERIC_TRAITS_H
+
+#if defined(TVMET_HAVE_COMPLEX)
+#  include <complex>
+#endif
+#include <cmath>
+#include <limits>
+
+#include <tvmet/CompileTimeError.h>
+
+
+namespace tvmet {
+
+
+/**
+ * \class NumericTraits NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits for integral types for operations.
+ *
+ * For each type we have to specialize this traits.
+ *
+ * \note Keep in mind that the long types long long and long double doesn't
+ *       have traits. This is due to the sum_type. We can't give a guarantee
+ *       that there is a type of holding the sum. Therefore using this traits
+ *       is only safe if you have long long resp. long double types by
+ *       working on long ints and doubles. Otherwise you will get not expected
+ *       result for some circumstances. Anyway, you can use big integer/float
+ *       libraries and specialize the traits by your own.
+ *
+ * \todo The abs function of complex<non_float_type> can have an
+ *       overrun due to numeric computation. Solve it (someone
+ *       using value_type=long here?)
+ */
+template<class T>
+struct NumericTraits {
+  typedef T					base_type;
+  typedef T					value_type;
+  typedef value_type				sum_type;
+  typedef value_type				diff_type;
+  typedef value_type				float_type;
+  typedef value_type				signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type x);
+
+  static inline
+  base_type imag(argument_type x);
+
+  static inline
+  value_type conj(argument_type x);
+
+  static inline
+  base_type abs(argument_type x);
+
+  static inline
+  value_type sqrt(argument_type x);
+
+  static inline
+  base_type norm_1(argument_type x) {
+    return NumericTraits<base_type>::abs(traits_type::real(x))
+         + NumericTraits<base_type>::abs(traits_type::imag(x));
+  }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(x)),
+		    NumericTraits<base_type>::abs(traits_type::imag(x)));
+   }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    static base_type sqrt_epsilon(
+      NumericTraits<base_type>::sqrt(
+        std::numeric_limits<base_type>::epsilon()));
+
+    return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
+      std::max(std::max(traits_type::norm_inf(lhs),
+			traits_type::norm_inf(rhs)),
+	       std::numeric_limits<base_type>::min());
+  }
+};
+
+
+/*
+ * numeric traits for standard types
+ */
+
+
+/**
+ * \class NumericTraits<char> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for char.
+ */
+template<>
+struct NumericTraits<char> {
+  typedef char					value_type;
+  typedef value_type				base_type;
+  typedef long					sum_type;
+  typedef int					diff_type;
+  typedef float					float_type;
+  typedef char					signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  value_type conj(argument_type x) { return x; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<unsigned char> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for unsigned char.
+ *
+ * \note Normally it doesn't make sense to call <tt>conj</tt>
+ *       for an unsigned type! An unary minus operator
+ *       applied to unsigned type will result unsigned. Therefore
+ *       this function is missing here.
+ */
+template<>
+struct NumericTraits<unsigned char> {
+  typedef unsigned char 			value_type;
+  typedef value_type				base_type;
+  typedef unsigned long	 			sum_type;
+  typedef int		 			diff_type;
+  typedef float		 			float_type;
+  typedef int					signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<short int> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for short int.
+ */
+template<>
+struct NumericTraits<short int> {
+  typedef short int 				value_type;
+  typedef value_type				base_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef long long		 		sum_type;
+#else
+  typedef long 					sum_type;
+#endif
+  typedef int			 		diff_type;
+  typedef float 				float_type;
+  typedef short int				signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  value_type conj(argument_type x) { return x; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<short unsigned int> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for short unsigned int.
+ *
+ * \note Normally it doesn't make sense to call <tt>conj</tt>
+ *       for an unsigned type! An unary minus operator
+ *       applied to unsigned type will result unsigned. Therefore
+ *       this function is missing here.
+ */
+template<>
+struct NumericTraits<short unsigned int> {
+  typedef short unsigned int			value_type;
+  typedef value_type				base_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef unsigned long long			sum_type;
+#else
+  typedef unsigned long 			sum_type;
+#endif
+  typedef int 					diff_type;
+  typedef float 				float_type;
+  typedef int					signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<int> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for int.
+ */
+template<>
+struct NumericTraits<int> {
+  typedef int 					value_type;
+  typedef value_type				base_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef long long		 		sum_type;
+#else
+  typedef long 					sum_type;
+#endif
+  typedef int			 		diff_type;
+  typedef double			 	float_type;
+  typedef int					signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  value_type conj(argument_type x) { return x; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<unsigned int> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for unsigned int.
+ *
+ * \note Normally it doesn't make sense to call <tt>conj</tt>
+ *       for an unsigned type! An unary minus operator
+ *       applied to unsigned type will result unsigned. Therefore
+ *       this function is missing here.
+ */
+template<>
+struct NumericTraits<unsigned int> {
+  typedef unsigned int 		 		value_type;
+  typedef value_type				base_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef unsigned long long			sum_type;
+#else
+  typedef unsigned long 			sum_type;
+#endif
+  typedef int 			 		diff_type;
+  typedef double 				float_type;
+  typedef long			 		signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  base_type abs(argument_type x) { return x; }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<long> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for long.
+ */
+template<>
+struct NumericTraits<long> {
+  typedef long 			 		value_type;
+  typedef value_type				base_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef long long		 		sum_type;
+#else
+  typedef long			  		sum_type;
+#endif
+  typedef long 		 			diff_type;
+  typedef double 				float_type;
+  typedef long		 	 		signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  value_type conj(argument_type x) { return x; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<unsigned long> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for unsigned long.
+ *
+ * \note Normally it doesn't make sense to call <tt>conj</tt>
+ *       for an unsigned type! An unary minus operator
+ *       applied to unsigned type will result unsigned. Therefore
+ *       this function is missing here.
+ */
+template<>
+struct NumericTraits<unsigned long> {
+  typedef unsigned long 			value_type;
+  typedef value_type				base_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef unsigned long long 			sum_type;
+#else
+  typedef unsigned long 			sum_type;
+#endif
+  typedef unsigned long 			diff_type;
+  typedef double 				float_type;
+  typedef long					signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  base_type abs(argument_type x) { return x; }
+
+  static inline
+  value_type sqrt(argument_type x) {
+    return static_cast<value_type>(std::sqrt(static_cast<float_type>(x)));
+  }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) { return lhs == rhs; }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<float> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for float.
+ */
+template<>
+struct NumericTraits<float> {
+  typedef float					value_type;
+  typedef value_type				base_type;
+  typedef double 				sum_type;
+  typedef float 				diff_type;
+  typedef float 				float_type;
+  typedef float					signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  value_type conj(argument_type x) { return x; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) { return std::sqrt(x); }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    static base_type sqrt_epsilon(
+      NumericTraits<base_type>::sqrt(
+        std::numeric_limits<base_type>::epsilon()));
+
+    return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
+      std::max(std::max(traits_type::norm_inf(lhs),
+			traits_type::norm_inf(rhs)),
+	       std::numeric_limits<base_type>::min());
+  }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits<double> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for double.
+ */
+template<>
+struct NumericTraits<double> {
+  typedef double 				value_type;
+  typedef value_type				base_type;
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+  typedef long double		 		sum_type;
+#else
+  typedef double 				sum_type;
+#endif
+  typedef double				diff_type;
+  typedef double 				float_type;
+  typedef double				signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  value_type conj(argument_type x) { return x; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) { return std::sqrt(x); }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    static base_type sqrt_epsilon(
+      NumericTraits<base_type>::sqrt(
+        std::numeric_limits<base_type>::epsilon()));
+
+    return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
+      std::max(std::max(traits_type::norm_inf(lhs),
+			traits_type::norm_inf(rhs)),
+	       std::numeric_limits<base_type>::min());
+  }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+/**
+ * \class NumericTraits<long double> NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for long double.
+ */
+template<>
+struct NumericTraits<long double> {
+  typedef long double 				value_type;
+  typedef value_type				base_type;
+  typedef long double		 		sum_type;
+  typedef long double				diff_type;
+  typedef long double 				float_type;
+  typedef long double				signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef value_type				argument_type;
+
+  static inline
+  base_type real(argument_type x) { return x; }
+
+  static inline
+  base_type imag(argument_type) { return 0; }
+
+  static inline
+  value_type conj(argument_type x) { return x; }
+
+  static inline
+  base_type abs(argument_type x) { return std::abs(x); }
+
+  static inline
+  value_type sqrt(argument_type x) { return std::sqrt(x); }
+
+  static inline
+  base_type norm_1(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_2(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  base_type norm_inf(argument_type x) { return traits_type::abs(x); }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    static base_type sqrt_epsilon(
+      NumericTraits<base_type>::sqrt(
+        std::numeric_limits<base_type>::epsilon()));
+
+    return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
+      std::max(std::max(traits_type::norm_inf(lhs),
+			traits_type::norm_inf(rhs)),
+	       std::numeric_limits<base_type>::min());
+  }
+
+  enum { is_complex = false };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 1,	/**< Complexity on plus/minus ops. */
+    ops_muls = 1	/**< Complexity on multiplications. */
+  };
+};
+#endif // TVMET_HAVE_LONG_DOUBLE
+
+
+/*
+ * numeric traits for complex types
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+
+/**
+ * \class NumericTraits< std::complex<int> > NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for std::complex<int>.
+ */
+template<>
+struct NumericTraits< std::complex<int> > {
+  typedef int					base_type;
+  typedef std::complex<int>			value_type;
+  typedef std::complex<long> 			sum_type;
+  typedef std::complex<int>			diff_type;
+  typedef std::complex<float>			float_type;
+  typedef std::complex<int>			signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type z) { return std::real(z); }
+
+  static inline
+  base_type imag(argument_type z) { return std::imag(z); }
+
+  static inline
+  value_type conj(argument_type z) { return std::conj(z); }
+
+  static inline
+  base_type abs(argument_type z) {
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    // XXX probably case of overrun; header complex uses scaling
+    return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
+  }
+
+  static /* inline */
+  value_type sqrt(argument_type z) {
+    // borrowed and adapted from header complex
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    if(x == base_type()) {
+	base_type t = NumericTraits<base_type>::sqrt(
+                        NumericTraits<base_type>::abs(y) / 2);
+	return value_type(t, y < base_type() ? -t : t);
+    }
+    else {
+      base_type t = NumericTraits<base_type>::sqrt(
+		      2 * (traits_type::abs(z)
+		            + NumericTraits<base_type>::abs(x)));
+      base_type u = t / 2;
+      return x > base_type()
+	? value_type(u, y / t)
+	: value_type(NumericTraits<base_type>::abs(y) / t, y < base_type() ? -u : u);
+    }
+  }
+
+  static inline
+  base_type norm_1(argument_type z) {
+    return NumericTraits<base_type>::abs((traits_type::real(z)))
+         + NumericTraits<base_type>::abs((traits_type::imag(z)));
+  }
+
+  static inline
+  base_type norm_2(argument_type z) { return traits_type::abs(z); }
+
+  static inline
+  base_type norm_inf(argument_type z) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
+		    NumericTraits<base_type>::abs(traits_type::imag(z)));
+  }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    return (traits_type::real(lhs) == traits_type::real(rhs))
+        && (traits_type::imag(lhs) == traits_type::imag(rhs));
+  }
+
+  enum { is_complex = true };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 2,	/**< Complexity on plus/minus ops. */
+    ops_muls = 6	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits< std::complex<unsigned int> > NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for std::complex<unsigned int>.
+ *
+ * \note Normally it doesn't make sense to call <tt>conj</tt>
+ *       for an unsigned type! An unary minus operator
+ *       applied to unsigned type will result unsigned. Therefore
+ *       this function is missing here.
+ */
+template<>
+struct NumericTraits< std::complex<unsigned int> > {
+  typedef unsigned int				base_type;
+  typedef std::complex<unsigned int> 		value_type;
+  typedef std::complex<unsigned long> 		sum_type;
+  typedef std::complex<int>			diff_type;
+  typedef std::complex<float>			float_type;
+  typedef std::complex<int>			signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type z) { return std::real(z); }
+
+  static inline
+  base_type imag(argument_type z) { return std::imag(z); }
+
+  static inline
+  base_type abs(argument_type z) {
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    // XXX probably case of overrun; header complex uses scaling
+    return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
+  }
+
+  static /* inline */
+  value_type sqrt(argument_type z) {
+    // borrowed and adapted from header complex
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    if(x == base_type()) {
+	base_type t = NumericTraits<base_type>::sqrt(
+                        NumericTraits<base_type>::abs(y) / 2);
+	return value_type(t, t);
+    }
+    else {
+      base_type t = NumericTraits<base_type>::sqrt(
+		      2 * (traits_type::abs(z)
+		            + NumericTraits<base_type>::abs(x)));
+      return value_type(t / 2, y / t);
+    }
+  }
+
+  static inline
+  base_type norm_1(argument_type z) {
+    return NumericTraits<base_type>::abs((traits_type::real(z)))
+         + NumericTraits<base_type>::abs((traits_type::imag(z)));
+  }
+
+  static inline
+  base_type norm_2(argument_type z) { return traits_type::abs(z); }
+
+  static inline
+  base_type norm_inf(argument_type z) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
+		    NumericTraits<base_type>::abs(traits_type::imag(z)));
+  }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    return (traits_type::real(lhs) == traits_type::real(rhs))
+        && (traits_type::imag(lhs) == traits_type::imag(rhs));
+  }
+
+  enum { is_complex = true };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 2,	/**< Complexity on plus/minus ops. */
+    ops_muls = 6	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits< std::complex<long> > NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for std::complex<long>.
+ */
+template<>
+struct NumericTraits< std::complex<long> > {
+  typedef long					base_type;
+  typedef std::complex<long>			value_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef std::complex<long long>		sum_type;
+#else
+  typedef std::complex<long>			sum_type;
+#endif
+  typedef std::complex<int>			diff_type;
+  typedef std::complex<float>			float_type;
+  typedef std::complex<int>			signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type z) { return std::real(z); }
+
+  static inline
+  base_type imag(argument_type z) { return std::imag(z); }
+
+  static inline
+  value_type conj(argument_type z) { return std::conj(z); }
+
+  static inline
+  base_type abs(argument_type z) {
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    // XXX probably case of overrun; header complex uses scaling
+    return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
+  }
+
+  static /* inline */
+  value_type sqrt(argument_type z) {
+    // borrowed and adapted from header complex
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    if(x == base_type()) {
+	base_type t = NumericTraits<base_type>::sqrt(
+                        NumericTraits<base_type>::abs(y) / 2);
+	return value_type(t, y < base_type() ? -t : t);
+    }
+    else {
+      base_type t = NumericTraits<base_type>::sqrt(
+		      2 * (traits_type::abs(z)
+		            + NumericTraits<base_type>::abs(x)));
+      base_type u = t / 2;
+      return x > base_type()
+	? value_type(u, y / t)
+	: value_type(NumericTraits<base_type>::abs(y) / t, y < base_type() ? -u : u);
+    }
+  }
+
+  static inline
+  base_type norm_1(argument_type z) {
+    return NumericTraits<base_type>::abs((traits_type::real(z)))
+         + NumericTraits<base_type>::abs((traits_type::imag(z)));
+  }
+
+  static inline
+  base_type norm_2(argument_type z) { return traits_type::abs(z); }
+
+  static inline
+  base_type norm_inf(argument_type z) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
+		    NumericTraits<base_type>::abs(traits_type::imag(z)));
+  }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    return (traits_type::real(lhs) == traits_type::real(rhs))
+        && (traits_type::imag(lhs) == traits_type::imag(rhs));
+  }
+
+  enum { is_complex = true };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 2,	/**< Complexity on plus/minus ops. */
+    ops_muls = 6	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits< std::complex<unsigned long> > NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for std::complex<unsigned long>.
+ *
+ * \note Normally it doesn't make sense to call <tt>conj</tt>
+ *       for an unsigned type! An unary minus operator
+ *       applied to unsigned type will result unsigned. Therefore
+ *       this function is missing here.
+ */
+template<>
+struct NumericTraits< std::complex<unsigned long> > {
+  typedef unsigned long				base_type;
+  typedef std::complex<unsigned long>		value_type;
+#if defined(TVMET_HAVE_LONG_LONG)
+  typedef std::complex<unsigned long long>	sum_type;
+#else
+  typedef std::complex<unsigned long>		sum_type;
+#endif
+  typedef std::complex<long>			diff_type;
+  typedef std::complex<float>			float_type;
+  typedef std::complex<long>			signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type z) { return std::real(z); }
+
+  static inline
+  base_type imag(argument_type z) { return std::imag(z); }
+
+  static inline
+  base_type abs(argument_type z) {
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    // XXX probably case of overrun; header complex uses scaling
+    return static_cast<base_type>(NumericTraits<base_type>::sqrt(x * x + y * y));
+  }
+
+  static /* inline */
+  value_type sqrt(argument_type z) {
+    // borrowed and adapted from header complex
+    base_type x = z.real();
+    base_type y = z.imag();
+
+    if(x == base_type()) {
+	base_type t = NumericTraits<base_type>::sqrt(
+                        NumericTraits<base_type>::abs(y) / 2);
+	return value_type(t, t);
+    }
+    else {
+      base_type t = NumericTraits<base_type>::sqrt(
+		      2 * (traits_type::abs(z)
+		            + NumericTraits<base_type>::abs(x)));
+      return value_type(t / 2, y / t);
+    }
+  }
+
+  static inline
+  base_type norm_1(argument_type z) {
+    return NumericTraits<base_type>::abs((traits_type::real(z)))
+         + NumericTraits<base_type>::abs((traits_type::imag(z)));
+  }
+
+  static inline
+  base_type norm_2(argument_type z) { return traits_type::abs(z); }
+
+  static inline
+  base_type norm_inf(argument_type z) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
+		    NumericTraits<base_type>::abs(traits_type::imag(z)));
+  }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    return (traits_type::real(lhs) == traits_type::real(rhs))
+        && (traits_type::imag(lhs) == traits_type::imag(rhs));
+  }
+
+  enum { is_complex = true };
+
+  /** Complexity  on operations.*/
+  enum {
+    ops_plus = 2,	/**< Complexity on plus/minus ops. */
+    ops_muls = 6	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits< std::complex<float> > NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for std::complex<float>.
+ */
+template<>
+struct NumericTraits< std::complex<float> > {
+  typedef float					base_type;
+  typedef std::complex<float>			value_type;
+  typedef std::complex<double>			sum_type;
+  typedef std::complex<float>			diff_type;
+  typedef std::complex<float>			float_type;
+  typedef std::complex<float>			signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type z) { return std::real(z); }
+
+  static inline
+  base_type imag(argument_type z) { return std::imag(z); }
+
+  static inline
+  value_type conj(argument_type z) { return std::conj(z); }
+
+  static inline
+  base_type abs(argument_type z) { return std::abs(z); }
+
+  static inline
+  value_type sqrt(argument_type z) { return std::sqrt(z); }
+
+  static inline
+  base_type norm_1(argument_type z) {
+    return NumericTraits<base_type>::abs((traits_type::real(z)))
+         + NumericTraits<base_type>::abs((traits_type::imag(z)));
+  }
+
+  static inline
+  base_type norm_2(argument_type z) { return traits_type::abs(z); }
+
+  static inline
+  base_type norm_inf(argument_type z) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
+	            NumericTraits<base_type>::abs(traits_type::imag(z)));
+  }
+
+ static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    static base_type sqrt_epsilon(
+      NumericTraits<base_type>::sqrt(
+        std::numeric_limits<base_type>::epsilon()));
+
+    return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
+      std::max(std::max(traits_type::norm_inf(lhs),
+			traits_type::norm_inf(rhs)),
+	       std::numeric_limits<base_type>::min());
+  }
+
+  enum { is_complex = true };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 2,	/**< Complexity on plus/minus ops. */
+    ops_muls = 6	/**< Complexity on multiplications. */
+  };
+};
+
+
+/**
+ * \class NumericTraits< std::complex<double> > NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for std::complex<double>.
+ */
+template<>
+struct NumericTraits< std::complex<double> > {
+  typedef double				base_type;
+  typedef std::complex<double>			value_type;
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+  typedef std::complex<long double> 		sum_type;
+#else
+  typedef std::complex<double>			sum_type;
+#endif
+  typedef std::complex<double>			diff_type;
+  typedef std::complex<double>			float_type;
+  typedef std::complex<double>			signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type z) { return std::real(z); }
+
+  static inline
+  base_type imag(argument_type z) { return std::imag(z); }
+
+  static inline
+  value_type conj(argument_type z) { return std::conj(z); }
+
+  static inline
+  base_type abs(argument_type z) { return std::abs(z); }
+
+  static inline
+  value_type sqrt(argument_type z) { return std::sqrt(z); }
+
+  static inline
+  base_type norm_1(argument_type z) {
+    return NumericTraits<base_type>::abs((traits_type::real(z)))
+         + NumericTraits<base_type>::abs((traits_type::imag(z)));
+  }
+
+  static inline
+  base_type norm_2(argument_type z) { return traits_type::abs(z); }
+
+  static inline
+  base_type norm_inf(argument_type z) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
+	            NumericTraits<base_type>::abs(traits_type::imag(z)));
+  }
+
+ static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    static base_type sqrt_epsilon(
+      NumericTraits<base_type>::sqrt(
+        std::numeric_limits<base_type>::epsilon()));
+
+    return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
+      std::max(std::max(traits_type::norm_inf(lhs),
+			traits_type::norm_inf(rhs)),
+	       std::numeric_limits<base_type>::min());
+  }
+
+  enum { is_complex = true };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 2,	/**< Complexity on plus/minus ops. */
+    ops_muls = 6	/**< Complexity on multiplications. */
+  };
+};
+
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+/**
+ * \class NumericTraits< std::complex<long double> > NumericTraits.h "tvmet/NumericTraits.h"
+ * \brief Traits specialized for std::complex<double>.
+ */
+template<>
+struct NumericTraits< std::complex<long double> > {
+  typedef long double				base_type;
+  typedef std::complex<long double>		value_type;
+  typedef std::complex<long double> 		sum_type;
+  typedef std::complex<long double>		diff_type;
+  typedef std::complex<long double>		float_type;
+  typedef std::complex<long double>		signed_type;
+
+  typedef NumericTraits<value_type>		traits_type;
+  typedef const value_type&			argument_type;
+
+  static inline
+  base_type real(argument_type z) { return std::real(z); }
+
+  static inline
+  base_type imag(argument_type z) { return std::imag(z); }
+
+  static inline
+  value_type conj(argument_type z) { return std::conj(z); }
+
+  static inline
+  base_type abs(argument_type z) { return std::abs(z); }
+
+  static inline
+  value_type sqrt(argument_type z) { return std::sqrt(z); }
+
+  static inline
+  base_type norm_1(argument_type z) {
+    return NumericTraits<base_type>::abs((traits_type::real(z)))
+         + NumericTraits<base_type>::abs((traits_type::imag(z)));
+  }
+
+  static inline
+  base_type norm_2(argument_type z) { return traits_type::abs(z); }
+
+  static inline
+  base_type norm_inf(argument_type z) {
+    return std::max(NumericTraits<base_type>::abs(traits_type::real(z)),
+	            NumericTraits<base_type>::abs(traits_type::imag(z)));
+  }
+
+  static inline
+  bool equals(argument_type lhs, argument_type rhs) {
+    static base_type sqrt_epsilon(
+      NumericTraits<base_type>::sqrt(
+        std::numeric_limits<base_type>::epsilon()));
+
+    return traits_type::norm_inf(lhs - rhs) < sqrt_epsilon *
+      std::max(std::max(traits_type::norm_inf(lhs),
+			traits_type::norm_inf(rhs)),
+	       std::numeric_limits<base_type>::min());
+  }
+
+  enum { is_complex = true };
+
+  /** Complexity on operations. */
+  enum {
+    ops_plus = 2,	/**< Complexity on plus/minus ops. */
+    ops_muls = 6	/**< Complexity on multiplications. */
+  };
+};
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace tvmet
+
+
+#endif //  TVMET_NUMERIC_TRAITS_H
+
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/RunTimeError.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,66 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: RunTimeError.h,v 1.13 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_RUN_TIME_ERROR_H
+#define TVMET_RUN_TIME_ERROR_H
+
+#include <cassert>
+
+
+namespace tvmet {
+
+
+/**
+ * \def TVMET_RT_CONDITION(XPR, MSG)
+ * \brief If TVMET_DEBUG is defined it checks the condition XPR and prints
+ * an error message MSG at runtime.
+ */
+#if defined(TVMET_DEBUG)
+
+#define TVMET_RT_CONDITION(XPR, MSG) {					\
+  if(!(XPR)) {								\
+    std::cerr << "[tvmet] Precondition failure in " << __FILE__		\
+              << ", line " << __LINE__ << ": "				\
+              << MSG << std::endl;					\
+    std::cerr.flush();							\
+    assert(0);								\
+  }									\
+}
+
+#else
+
+#define TVMET_RT_CONDITION(XPR, MSG)
+
+#endif
+
+
+} // namespace tvmet
+
+
+#endif // TVMET_RUN_TIME_ERROR_H
+
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/TvmetBase.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,112 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: TvmetBase.h,v 1.17 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_BASE_H
+#define TVMET_BASE_H
+
+#include <iostream>//<iosfwd>                // io streams forward declaration
+#include <typeinfo>                // rtti: used by Xpr.h level printing
+#include <cmath>                // unary and binary math
+#include <cstdlib>                // labs
+
+#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER == 1310)
+#include <string>                // operator<<(ostream) here defined
+#endif
+
+#if defined(__APPLE_CC__)
+// Mac OS X builds seems to miss these functions inside cmath
+extern "C" int isnan(double);
+extern "C" int isinf(double);
+#endif
+
+namespace tvmet {
+
+
+/**
+ * \class TvmetBase TvmetBase.h "tvmet/TvmetBase.h"
+ * \brief Base class
+ * Used for static polymorph call of print_xpr
+ */
+template<class E> class TvmetBase { };
+
+
+/**
+ * \class IndentLevel TvmetBase.h "tvmet/TvmetBase.h"
+ * \brief Prints the level indent.
+ */
+class IndentLevel : public TvmetBase< IndentLevel >
+{
+public:
+  IndentLevel(std::size_t level) : m_level(level) { }
+
+  std::ostream& print_xpr(std::ostream& os) const {
+    for(std::size_t i = 0; i != m_level; ++i) os << "   ";
+    return os;
+  }
+
+private:
+  std::size_t                     m_level;
+};
+
+
+/**
+ * \fn operator<<(std::ostream& os, const TvmetBase<E>& e)
+ * \brief overloaded ostream operator using static polymorphic.
+ * \ingroup _binary_operator
+ */
+template<class E>
+inline
+std::ostream& operator<<(std::ostream& os, const TvmetBase<E>& e) {
+  static_cast<const E&>(e).print_xpr(os);
+  return os;
+}
+
+
+/**
+ * \class dispatch TvmetBase.h "tvmet/TvmetBase.h"
+ * \brief Class helper to distuingish between e.g. meta
+ *        and loop strategy used.
+ */
+template<bool> struct dispatch;
+
+/**
+ * \class dispatch<true> TvmetBase.h "tvmet/TvmetBase.h"
+ * \brief specialized.
+ */
+template<> struct dispatch<true>  { };
+
+/**
+ * \class dispatch<false> TvmetBase.h "tvmet/TvmetBase.h"
+ * \brief specialized.
+ */
+template<> struct dispatch<false> { };
+
+
+} // namespace tvmet
+
+#endif // TVMET_BASE_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/TypePromotion.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,232 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: TypePromotion.h,v 1.10 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_TYPE_PROMOTION_H
+#define TVMET_TYPE_PROMOTION_H
+
+namespace tvmet {
+
+
+/**
+ * \class PrecisionTraits TypePromotion.h "tvmet/TypePromotion.h"
+ * \brief Declaring ranks of types to avoid specializing
+ *
+ * All possible promoted types. For example, bool=1, int=2, float=3, double=4,
+ * etc. We can use a traits class to map from a type such as float onto its
+ * "precision rank". We will promote to whichever type has a higher
+ * "precision rank". f there is no "precision rank" for a type, we'll
+ * promote to whichever type requires more storage space
+ * (and hopefully more precision).
+ */
+template<class T>
+struct PrecisionTraits {
+  enum {
+    rank = 0,			/**< the rank of type. */
+    known = 0 			/**< true, if the rank is specialized = known. */
+  };
+};
+
+
+#define TVMET_PRECISION(T,R)      					\
+template<>                          					\
+struct PrecisionTraits< T > {        					\
+  enum {                          					\
+    rank = R,                   					\
+    known = 1                   					\
+  };                              					\
+};
+
+
+/*
+ * pod types
+ */
+TVMET_PRECISION(int, 100)
+TVMET_PRECISION(unsigned int, 200)
+TVMET_PRECISION(long, 300)
+TVMET_PRECISION(unsigned long, 400)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_PRECISION(long long, 500)
+TVMET_PRECISION(unsigned long long, 600)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_PRECISION(float, 700)
+TVMET_PRECISION(double, 800)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_PRECISION(long double, 900)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+
+/*
+ * complex types
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+TVMET_PRECISION(std::complex<int>, 1000)
+TVMET_PRECISION(std::complex<unsigned int>, 1100)
+TVMET_PRECISION(std::complex<long>, 1200)
+TVMET_PRECISION(std::complex<unsigned long>, 1300)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_PRECISION(std::complex<long long>, 1400)
+TVMET_PRECISION(std::complex<unsigned long long>, 1500)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_PRECISION(std::complex<float>, 1600)
+TVMET_PRECISION(std::complex<double>, 1700)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_PRECISION(std::complex<long double>, 1800)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/** \class PrecisionTraits<int>				TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<unsigned int> 		TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<long>			TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<unsigned long> 		TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<long long>			TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<unsigned long long> 		TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<float>			TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<double>			TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits<long double>			TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<int> >		TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<unsigned int> > TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<long> >	TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<unsigned long> > TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<long long> >	TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<unsigned long long> > TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<float> >	TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<double> >	TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class PrecisionTraits< std::complex<long double> >	TypePromotion.h "tvmet/TypePromotion.h" */
+
+#undef TVMET_PRECISION
+
+
+/**
+ * \class AutopromoteTraits TypePromotion.h "tvmet/TypePromotion.h"
+ * \brief The promoted types traits.
+ */
+template<class T>
+struct AutopromoteTraits {
+  typedef T value_type;
+};
+
+
+/*
+ * Defines a macro for specializing/defining
+ * the promotion traits. bool, char, unsigned char, short int, etc. will
+ * be autopromote to int, as in C and C++.
+ */
+#define TVMET_AUTOPROMOTE(T1,T2)   					\
+template<>                          				 	\
+struct AutopromoteTraits<T1> {     					\
+  typedef T2 value_type;          					\
+};
+
+TVMET_AUTOPROMOTE(bool, int)
+TVMET_AUTOPROMOTE(char, int)
+TVMET_AUTOPROMOTE(unsigned char, int)
+TVMET_AUTOPROMOTE(short int, int)
+TVMET_AUTOPROMOTE(short unsigned int, unsigned int)
+
+/** \class AutopromoteTraits<bool>	TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class AutopromoteTraits<char>	TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class AutopromoteTraits<unsigned char> TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class AutopromoteTraits<short int>	TypePromotion.h "tvmet/TypePromotion.h" */
+/** \class AutopromoteTraits<short unsigned int> TypePromotion.h "tvmet/TypePromotion.h" */
+
+#undef TVMET_AUTOPROMOTE
+
+
+/**
+ * \class promoteTo TypePromotion.h "tvmet/TypePromotion.h"
+ * \brief Promote to T1.
+ */
+template<class T1, class T2, int promoteToT1>
+struct promoteTo {
+  typedef T1 value_type;
+};
+
+
+/**
+ * \class promoteTo<T1,T2,0> TypePromotion.h "tvmet/TypePromotion.h"
+ * \brief Promote to T2
+ */
+template<class T1, class T2>
+struct promoteTo<T1,T2,0> {
+  typedef T2 value_type;
+};
+
+
+/**
+ * \class PromoteTraits TypePromotion.h "tvmet/TypePromotion.h"
+ * \brief Promote type traits
+ */
+template<class T1org, class T2org>
+class PromoteTraits {
+  // Handle promotion of small integers to int/unsigned int
+  typedef typename AutopromoteTraits<T1org>::value_type T1;
+  typedef typename AutopromoteTraits<T2org>::value_type T2;
+
+  enum {
+    // True if T1 is higher ranked
+    T1IsBetter = int(PrecisionTraits<T1>::rank) > int(PrecisionTraits<T2>::rank),
+
+    // True if we know ranks for both T1 and T2
+    knowBothRanks = PrecisionTraits<T1>::known && PrecisionTraits<T2>::known,
+
+    // True if we know T1 but not T2
+    knowT1butNotT2 = PrecisionTraits<T1>::known && !(PrecisionTraits<T2>::known),
+
+    // True if we know T2 but not T1
+    knowT2butNotT1 =  PrecisionTraits<T2>::known && !(PrecisionTraits<T1>::known),
+
+    // True if T1 is bigger than T2
+    T1IsLarger = sizeof(T1) >= sizeof(T2),
+
+    // We know T1 but not T2: true
+    // We know T2 but not T1: false
+    // Otherwise, if T1 is bigger than T2: true
+    defaultPromotion = knowT1butNotT2 ? false : (knowT2butNotT1 ? true : T1IsLarger),
+
+    // If we have both ranks, then use them.
+    // If we have only one rank, then use the unknown type.
+    // If we have neither rank, then promote to the larger type.
+    promoteToT1 = (knowBothRanks ? T1IsBetter : defaultPromotion) ? 1 : 0
+  };
+
+ public:
+  typedef typename promoteTo<T1,T2,promoteToT1>::value_type value_type;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_TYPE_PROMOTION_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/UnaryFunctionals.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,349 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: UnaryFunctionals.h,v 1.24 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_UNARY_FUNCTIONAL_H
+#define TVMET_UNARY_FUNCTIONAL_H
+
+namespace tvmet {
+
+/** \class Fcnl_compl	UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_neg	UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_not	UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template <class T>							\
+struct Fcnl_##NAME : public UnaryFunctional {				\
+  typedef T						value_type;	\
+									\
+  static inline 							\
+  value_type apply_on(value_type rhs) {					\
+    return OP rhs;							\
+  }									\
+  									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l) << "Fcnl_" << #NAME << "<T="			\
+       << typeid(T).name() << ">,"					\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(compl, ~)
+TVMET_IMPLEMENT_MACRO(neg, -)
+TVMET_IMPLEMENT_MACRO(not, !)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/** \class Fcnl_abs		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_ceil		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_floor		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_sin		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_cos		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_tan		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_sinh		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_cosh		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_tanh		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_asin		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_acos		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_atan		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_exp		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_log		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_log10		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_sqrt		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template <class T>							\
+struct Fcnl_##NAME : public UnaryFunctional {				\
+  typedef T						value_type;	\
+  									\
+  static inline 							\
+  value_type apply_on(value_type rhs) {					\
+    return TVMET_STD_SCOPE(NAME)(rhs);					\
+  }									\
+  									\
+ static 								\
+ void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l) << "Fcnl_" << #NAME << "<T="			\
+       << typeid(value_type).name() << ">,"				\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(abs)	// specialized later, see below
+TVMET_IMPLEMENT_MACRO(ceil)
+TVMET_IMPLEMENT_MACRO(floor)
+TVMET_IMPLEMENT_MACRO(sin)
+TVMET_IMPLEMENT_MACRO(cos)
+TVMET_IMPLEMENT_MACRO(tan)
+TVMET_IMPLEMENT_MACRO(sinh)
+TVMET_IMPLEMENT_MACRO(cosh)
+TVMET_IMPLEMENT_MACRO(tanh)
+TVMET_IMPLEMENT_MACRO(asin)
+TVMET_IMPLEMENT_MACRO(acos)
+TVMET_IMPLEMENT_MACRO(atan)
+TVMET_IMPLEMENT_MACRO(exp)
+TVMET_IMPLEMENT_MACRO(log)
+TVMET_IMPLEMENT_MACRO(log10)
+TVMET_IMPLEMENT_MACRO(sqrt)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/** \class Fcnl_cbrt		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_rint		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template <class T>							\
+struct Fcnl_##NAME : public UnaryFunctional {				\
+  typedef T						value_type;	\
+									\
+  static inline								\
+  value_type apply_on(value_type rhs) {					\
+    return TVMET_GLOBAL_SCOPE(NAME)(rhs);				\
+  }									\
+									\
+ static									\
+ void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l) << "Fcnl_" << #NAME << "<T="			\
+       << typeid(value_type).name() << ">,"				\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(cbrt)
+TVMET_IMPLEMENT_MACRO(rint)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+
+/** \class Fcnl_asinh		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_acosh		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_atanh		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_expm1		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_log1p		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_erf		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_erfc		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_j0		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_j1		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_y0		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_y1		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_lgamma		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template <class T>							\
+struct Fcnl_##NAME : public UnaryFunctional {				\
+  typedef T						value_type;	\
+									\
+  static inline 							\
+  value_type apply_on(value_type rhs) {					\
+    return TVMET_GLOBAL_SCOPE(NAME)(rhs);				\
+  }									\
+  									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l) << "Fcnl_" << #NAME << "<T="			\
+       << typeid(value_type).name() << ">,"				\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(asinh)
+TVMET_IMPLEMENT_MACRO(acosh)
+TVMET_IMPLEMENT_MACRO(atanh)
+TVMET_IMPLEMENT_MACRO(expm1)
+TVMET_IMPLEMENT_MACRO(log1p)
+TVMET_IMPLEMENT_MACRO(erf)
+TVMET_IMPLEMENT_MACRO(erfc)
+TVMET_IMPLEMENT_MACRO(j0)
+TVMET_IMPLEMENT_MACRO(j1)
+TVMET_IMPLEMENT_MACRO(y0)
+TVMET_IMPLEMENT_MACRO(y1)
+TVMET_IMPLEMENT_MACRO(lgamma)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+
+/** \class Fcnl_abs<long int>		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_abs<long long int>	UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_abs<float>		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_abs<double>		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_abs<long double> 	UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME, POD)				\
+template <class T> struct Fcnl_##NAME;					\
+template <>								\
+struct Fcnl_##NAME< POD > : public UnaryFunctional {			\
+  typedef POD						value_type;	\
+									\
+  static inline 							\
+  value_type apply_on(value_type rhs) {					\
+    return TVMET_STD_SCOPE(NAME)(rhs);					\
+  }									\
+  									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l) << "Fcnl_" << #NAME << "<T="			\
+       << typeid(value_type).name() << ">,"				\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(labs, long int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(labs, long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(fabs, float)
+TVMET_IMPLEMENT_MACRO(fabs, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(fabs, long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * complex support
+ */
+
+#if defined(TVMET_HAVE_COMPLEX)
+/**
+ * \class Fcnl_abs< std::complex<T> > UnaryFunctionals.h "tvmet/UnaryFunctionals.h"
+ */
+template <class T>
+struct Fcnl_abs< std::complex<T> > : public UnaryFunctional {
+  typedef T						value_type;
+
+  static inline
+  value_type apply_on(const std::complex<T>& rhs) {
+    return std::abs(rhs);
+  }
+
+  static
+  void print_xpr(std::ostream& os, std::size_t l=0) {
+    os << IndentLevel(l) << "Fcnl_abs<T="
+       << typeid(std::complex<T>).name() << ">,"
+       << std::endl;
+  }
+};
+
+
+/**
+ * \class Fcnl_conj< std::complex<T> > UnaryFunctionals.h "tvmet/UnaryFunctionals.h"
+ * \brief %Functional for conj.
+ */
+template <class T> struct Fcnl_conj : public UnaryFunctional { };
+
+
+/** \class Fcnl_conj< std::complex<T> > UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+template <class T>
+struct Fcnl_conj< std::complex<T> > : public UnaryFunctional {
+  typedef std::complex<T>                               value_type;
+
+  static inline
+  value_type apply_on(const std::complex<T>& rhs) {
+    return std::conj(rhs);
+  }
+
+  static
+  void print_xpr(std::ostream& os, std::size_t l=0) {
+    os << IndentLevel(l) << "Fcnl_conj<T="
+       << typeid(std::complex<T>).name() << ">,"
+       << std::endl;
+  }
+};
+
+
+/** \class Fcnl_real< std::complex<T> > UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_imag< std::complex<T> > UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_arg< std::complex<T> > UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_norm< std::complex<T> > UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template <class T> struct Fcnl_##NAME;					\
+template <class T>							\
+struct Fcnl_##NAME< std::complex<T> > : public UnaryFunctional {	\
+  typedef T						value_type;	\
+									\
+  static inline 							\
+  value_type apply_on(const std::complex<T>& rhs) {			\
+    return TVMET_STD_SCOPE(NAME)(rhs);					\
+  }									\
+  									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l) << "Fcnl_" << #NAME << "<T="			\
+       << typeid(std::complex<T>).name() << ">,"			\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(real)
+TVMET_IMPLEMENT_MACRO(imag)
+TVMET_IMPLEMENT_MACRO(arg)
+TVMET_IMPLEMENT_MACRO(norm)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+
+/** \class Fcnl_isnan		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_isinf		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+/** \class Fcnl_finite		UnaryFunctionals.h "tvmet/UnaryFunctionals.h" */
+#define TVMET_IMPLEMENT_MACRO(NAME, POD)				\
+template <class T>							\
+struct Fcnl_##NAME : public UnaryFunctional {				\
+  typedef T						value_type;	\
+									\
+  static inline 							\
+  POD apply_on(T rhs) {							\
+    return TVMET_GLOBAL_SCOPE(NAME)(rhs);				\
+  }									\
+  									\
+  static 								\
+  void print_xpr(std::ostream& os, std::size_t l=0) {			\
+    os << IndentLevel(l) << "Fcnl_" << #NAME << "<T="			\
+       << typeid(POD).name() << ">,"					\
+       << std::endl;							\
+  }									\
+};
+
+TVMET_IMPLEMENT_MACRO(isnan, int)
+TVMET_IMPLEMENT_MACRO(isinf, int)
+TVMET_IMPLEMENT_MACRO(finite, int)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif //  defined(TVMET_HAVE_IEEE_MATH)
+
+} // namespace tvmet
+
+#endif // TVMET_UNARY_FUNCTIONAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/Vector.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,563 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Vector.h,v 1.48 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_VECTOR_H
+#define TVMET_VECTOR_H
+
+#include <iterator>					// reverse_iterator
+
+#include <tvmet/tvmet.h>
+#include <tvmet/TypePromotion.h>
+#include <tvmet/CommaInitializer.h>
+#include <tvmet/RunTimeError.h>
+
+#include <tvmet/xpr/Vector.h>
+
+namespace tvmet {
+
+
+/* forwards */
+template<class T, std::size_t Sz> class Vector;
+
+
+/**
+ * \class VectorConstReference Vector.h "tvmet/Vector.h"
+ * \brief Const value iterator for ET
+ */
+template<class T, std::size_t Sz>
+class VectorConstReference
+  : public TvmetBase< VectorConstReference<T, Sz> >
+{
+public: // types
+  typedef T 						value_type;
+  typedef T*						pointer;
+  typedef const T*					const_pointer;
+
+public:
+  /** Dimensions. */
+  enum {
+    Size = Sz			/**< The size of the vector. */
+  };
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops        = Size
+  };
+
+private:
+  VectorConstReference();
+  VectorConstReference& operator=(const VectorConstReference&);
+
+public:
+  /** Constructor. */
+  explicit VectorConstReference(const Vector<T, Size>& rhs)
+    : m_data(rhs.data())
+  { }
+
+  /** Constructor by a given memory pointer. */
+  explicit VectorConstReference(const_pointer data)
+    : m_data(data)
+  { }
+
+public: // access operators
+  /** access by index. */
+  value_type operator()(std::size_t i) const {
+    TVMET_RT_CONDITION(i < Size, "VectorConstReference Bounce Violation")
+    return m_data[i];
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l)
+       << "VectorConstReference[O=" << ops << "]<"
+       << "T=" << typeid(T).name() << ">,"
+       << std::endl;
+  }
+
+private:
+  const_pointer _tvmet_restrict 			m_data;
+};
+
+
+/**
+ * \class Vector Vector.h "tvmet/Vector.h"
+ * \brief Compile time fixed length vector with evaluation on compile time.
+ */
+template<class T, std::size_t Sz>
+class Vector
+{
+public:
+  /** Data type of the tvmet::Vector. */
+  typedef T     					value_type;
+
+  /** Reference type of the tvmet::Vector data elements. */
+  typedef T&     					reference;
+
+  /** const reference type of the tvmet::Vector data elements. */
+  typedef const T&     					const_reference;
+
+  /** STL iterator interface. */
+  typedef T*     					iterator;
+
+  /** STL const_iterator interface. */
+  typedef const T*     					const_iterator;
+
+  /** STL reverse iterator interface. */
+  typedef std::reverse_iterator<iterator> 		reverse_iterator;
+
+  /** STL const reverse iterator interface. */
+  typedef std::reverse_iterator<const_iterator> 	const_reverse_iterator;
+
+public:
+  /** Dimensions. */
+  enum {
+    Size = Sz			/**< The size of the vector. */
+  };
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_assign = Size,
+    ops        = ops_assign,
+    use_meta   = ops < TVMET_COMPLEXITY_V_ASSIGN_TRIGGER ? true : false
+  };
+
+public: // STL  interface
+  /** STL iterator interface. */
+  iterator begin() { return m_data; }
+
+  /** STL iterator interface. */
+  iterator end() { return m_data + Size; }
+
+  /** STL const_iterator interface. */
+  const_iterator begin() const { return m_data; }
+
+  /** STL const_iterator interface. */
+  const_iterator end() const { return m_data + Size; }
+
+  /** STL reverse iterator interface reverse begin. */
+  reverse_iterator rbegin() { return reverse_iterator( end() ); }
+
+  /** STL const reverse iterator interface reverse begin. */
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator( end() );
+  }
+
+  /** STL reverse iterator interface reverse end. */
+  reverse_iterator rend() { return reverse_iterator( begin() ); }
+
+  /** STL const reverse iterator interface reverse end. */
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator( begin() );
+  }
+
+  /** STL vector front element. */
+  value_type front() { return m_data[0]; }
+
+  /** STL vector const front element. */
+  const_reference front() const { return m_data[0]; }
+
+  /** STL vector back element. */
+  value_type back() { return m_data[Size-1]; }
+
+  /** STL vector const back element. */
+  const_reference back() const { return m_data[Size-1]; }
+
+  /** STL vector empty() - returns allways false. */
+  static bool empty() { return false; }
+
+  /** The size of the vector. */
+  static std::size_t size() { return Size; }
+
+  /** STL vector max_size() - returns allways Size. */
+  static std::size_t max_size() { return Size; }
+
+public:
+  /** Default Destructor */
+  ~Vector() {
+#if defined(TVMET_DYNAMIC_MEMORY)
+    delete [] m_data;
+#endif
+  }
+
+  /** Default Constructor. The allocated memory region isn't cleared. If you want
+   a clean use the constructor argument zero. */
+  explicit Vector()
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  { }
+
+  /** Copy Constructor, not explicit! */
+  Vector(const Vector& rhs)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    *this = XprVector<ConstReference, Size>(rhs.const_ref());
+  }
+
+  /**
+   * Constructor with STL iterator interface. The data will be copied into the
+   * vector self, there isn't any stored reference to the array pointer.
+   */
+  template<class InputIterator>
+  explicit Vector(InputIterator first, InputIterator last)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_RT_CONDITION( static_cast<std::size_t>(std::distance(first, last)) <= Size,
+			"InputIterator doesn't fits in size" )
+    std::copy(first, last, m_data);
+  }
+
+  /**
+   * Constructor with STL iterator interface. The data will be copied into the
+   * vector self, there isn't any stored reference to the array pointer.
+   */
+  template<class InputIterator>
+  explicit Vector(InputIterator first, std::size_t sz)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_RT_CONDITION( sz <= Size, "InputIterator doesn't fits in size" )
+    std::copy(first, first + sz, m_data);
+  }
+
+  /** Constructor with initializer for all elements.  */
+  explicit Vector(value_type rhs)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    typedef XprLiteral<value_type> expr_type;
+    *this = XprVector<expr_type, Size>(expr_type(rhs));
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(2 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(3 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(4 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
+		  value_type x4)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(5 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
+		  value_type x4, value_type x5)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(6 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
+    m_data[5] = x5;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
+		  value_type x4, value_type x5, value_type x6)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(7 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
+    m_data[5] = x5; m_data[6] = x6;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
+		  value_type x4, value_type x5, value_type x6, value_type x7)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(8 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
+    m_data[5] = x5; m_data[6] = x6; m_data[7] = x7;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
+		  value_type x4, value_type x5, value_type x6, value_type x7,
+		  value_type x8)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(9 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
+    m_data[5] = x5; m_data[6] = x6; m_data[7] = x7; m_data[8] = x8;
+  }
+
+  /** Default Constructor with initializer list. */
+  explicit Vector(value_type x0, value_type x1, value_type x2, value_type x3,
+		  value_type x4, value_type x5, value_type x6, value_type x7,
+		  value_type x8, value_type x9)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    TVMET_CT_CONDITION(10 <= Size, ArgumentList_is_too_long)
+    m_data[0] = x0; m_data[1] = x1; m_data[2] = x2; m_data[3] = x3; m_data[4] = x4;
+    m_data[5] = x5; m_data[6] = x6; m_data[7] = x7; m_data[8] = x8; m_data[9] = x9;
+  }
+
+  /** Construct a vector by expression. */
+  template <class E>
+  explicit Vector(const XprVector<E, Size>& e)
+#if defined(TVMET_DYNAMIC_MEMORY)
+    : m_data( new value_type[Size] )
+#endif
+  {
+    *this = e;
+  }
+
+  /** Assign a value_type on array, this can be used for a single value
+      or a comma separeted list of values. */
+  CommaInitializer<Vector, Size> operator=(value_type rhs) {
+    return CommaInitializer<Vector, Size>(*this, rhs);
+  }
+
+public: // access operators
+  value_type* _tvmet_restrict data() { return m_data; }
+  const value_type* _tvmet_restrict data() const { return m_data; }
+
+public: // index access operators
+  value_type& _tvmet_restrict operator()(std::size_t i) {
+    // Note: g++-2.95.3 does have problems on typedef reference
+    TVMET_RT_CONDITION(i < Size, "Vector Bounce Violation")
+    return m_data[i];
+  }
+
+  value_type operator()(std::size_t i) const {
+    TVMET_RT_CONDITION(i < Size, "Vector Bounce Violation")
+    return m_data[i];
+  }
+
+  value_type& _tvmet_restrict operator[](std::size_t i) {
+    // Note: g++-2.95.3 does have problems on typedef reference
+    return this->operator()(i);
+  }
+
+  value_type operator[](std::size_t i) const {
+    return this->operator()(i);
+  }
+
+public: // ET interface
+  typedef VectorConstReference<T, Size>    		ConstReference;
+
+  /** Return a const Reference of the internal data */
+  ConstReference const_ref() const { return ConstReference(*this); }
+
+  /** Return the vector as const expression. */
+  XprVector<ConstReference, Size> as_expr() const {
+    return XprVector<ConstReference, Size>(this->const_ref());
+  }
+
+private:
+  /** Wrapper for meta assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<true>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    meta::Vector<Size, 0>::assign(dest, src, assign_fn);
+  }
+
+  /** Wrapper for loop assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<false>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    loop::Vector<Size>::assign(dest, src, assign_fn);
+  }
+
+public:
+  /** assign this to a vector expression using the functional assign_fn. */
+  template<class T2, class Assign>
+  void assign_to(Vector<T2, Size>& dest, const Assign& assign_fn) const {
+    do_assign(dispatch<use_meta>(), dest, *this, assign_fn);
+  }
+
+public:   // assign operations
+  /** assign a given Vector element wise to this vector.
+      The operator=(const Vector&) is compiler generated. */
+  template<class T2>
+  Vector& operator=(const Vector<T2, Size>& rhs) {
+    rhs.assign_to(*this, Fcnl_assign<value_type, T2>());
+    return *this;
+  }
+
+  /** assign a given XprVector element wise to this vector. */
+  template<class E>
+  Vector& operator=(const XprVector<E, Size>& rhs) {
+    rhs.assign_to(*this, Fcnl_assign<value_type, typename E::value_type>());
+    return *this;
+  }
+
+private:
+  template<class Obj, std::size_t LEN> friend class CommaInitializer;
+
+  /** This is a helper for assigning a comma separated initializer
+      list. It's equal to Vector& operator=(value_type) which does
+      replace it. */
+  Vector& assign_value(value_type rhs) {
+    typedef XprLiteral<value_type> 			expr_type;
+    *this = XprVector<expr_type, Size>(expr_type(rhs));
+    return *this;
+  }
+
+public: // math operators with scalars
+  // NOTE: this meaning is clear - element wise ops even if not in ns element_wise
+  Vector& operator+=(value_type) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator-=(value_type) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator*=(value_type) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator/=(value_type) TVMET_CXX_ALWAYS_INLINE;
+
+  Vector& operator%=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator^=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator&=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator|=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator<<=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+  Vector& operator>>=(std::size_t) TVMET_CXX_ALWAYS_INLINE;
+
+public: // math assign operators with vectors
+  // NOTE: access using the operators in ns element_wise, since that's what is does
+  template <class T2> Vector& M_add_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_sub_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_mul_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_div_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_mod_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_xor_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_and_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_or_eq (const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_shl_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& M_shr_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+
+public: // math operators with expressions
+  // NOTE: access using the operators in ns element_wise, since that's what is does
+  template <class E> Vector& M_add_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_sub_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_mul_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_div_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_mod_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_xor_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_and_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_or_eq (const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_shl_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& M_shr_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+
+public: // aliased math operators with expressions, used with proxy
+  template <class T2> Vector& alias_assign(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& alias_add_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& alias_sub_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& alias_mul_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class T2> Vector& alias_div_eq(const Vector<T2, Size>&) TVMET_CXX_ALWAYS_INLINE;
+
+  template <class E> Vector& alias_assign(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& alias_add_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& alias_sub_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& alias_mul_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+  template <class E> Vector& alias_div_eq(const XprVector<E, Size>&) TVMET_CXX_ALWAYS_INLINE;
+
+public: // io
+  /** Structure for info printing as Vector<T, Size>. */
+  struct Info : public TvmetBase<Info> {
+    std::ostream& print_xpr(std::ostream& os) const {
+      os << "Vector<T=" << typeid(value_type).name()
+	 << ", Sz=" << Size << ">";
+      return os;
+    }
+  };
+
+  /** Get an info object of this vector. */
+  static Info info() { return Info(); }
+
+  /** Member function for expression level printing. */
+  std::ostream& print_xpr(std::ostream& os, std::size_t l=0) const;
+
+  /** Member function for printing internal data. */
+  std::ostream& print_on(std::ostream& os) const;
+
+private:
+  /** The data of vector self. */
+
+#if defined(TVMET_DYNAMIC_MEMORY)
+  value_type*						m_data;
+#else
+  value_type 						m_data[Size];
+#endif
+};
+
+
+} // namespace tvmet
+
+#include <tvmet/VectorImpl.h>
+#include <tvmet/VectorFunctions.h>
+#include <tvmet/VectorBinaryFunctions.h>
+#include <tvmet/VectorUnaryFunctions.h>
+#include <tvmet/VectorOperators.h>
+#include <tvmet/VectorEval.h>
+#include <tvmet/AliasProxy.h>
+
+#endif // TVMET_VECTOR_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/VectorBinaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,531 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorBinaryFunctions.h,v 1.17 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_VECTOR_BINARY_FUNCTIONS_H
+#define TVMET_VECTOR_BINARY_FUNCTIONS_H
+
+#include <tvmet/NumericTraits.h>
+#include <tvmet/Extremum.h>
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+/*
+ * binary_function(Vector<T1, Sz>, Vector<T1, Sz>)
+ * binary_function(Vector<T, Sz>, XprVector<E>)
+ * binary_function(XprVector<E>, Vector<T, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)				\
+template<class T1, class T2, std::size_t Sz>			\
+inline								\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<T1, T2>,					\
+    VectorConstReference<T1, Sz>,				\
+    VectorConstReference<T2, Sz>				\
+  >,								\
+  Sz								\
+>								\
+NAME(const Vector<T1, Sz>& lhs, 				\
+     const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+								\
+template<class E, class T, std::size_t Sz>			\
+inline								\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, T>,			\
+    VectorConstReference<T, Sz>,				\
+    XprVector<E, Sz>						\
+  >,								\
+  Sz								\
+>								\
+NAME(const XprVector<E, Sz>& lhs, 				\
+     const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+								\
+template<class E, class T, std::size_t Sz>			\
+inline								\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<T, typename E::value_type>,			\
+    VectorConstReference<T, Sz>,				\
+    XprVector<E, Sz>						\
+  >,								\
+  Sz								\
+>								\
+NAME(const Vector<T, Sz>& lhs, 					\
+     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2)
+TVMET_DECLARE_MACRO(drem)
+TVMET_DECLARE_MACRO(fmod)
+TVMET_DECLARE_MACRO(hypot)
+TVMET_DECLARE_MACRO(jn)
+TVMET_DECLARE_MACRO(yn)
+TVMET_DECLARE_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+TVMET_DECLARE_MACRO(polar)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * binary_function(Vector<T, Sz>, POD)
+ */
+#define TVMET_DECLARE_MACRO(NAME, TP)				\
+template<class T, std::size_t Sz>				\
+inline								\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<T, TP >,					\
+    VectorConstReference<T, Sz>,				\
+    XprLiteral< TP >						\
+  >,								\
+  Sz								\
+>								\
+NAME(const Vector<T, Sz>& lhs, TP rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2, int)
+TVMET_DECLARE_MACRO(drem, int)
+TVMET_DECLARE_MACRO(fmod, int)
+TVMET_DECLARE_MACRO(hypot, int)
+TVMET_DECLARE_MACRO(jn, int)
+TVMET_DECLARE_MACRO(yn, int)
+TVMET_DECLARE_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(atan2, long long int)
+TVMET_DECLARE_MACRO(drem, long long int)
+TVMET_DECLARE_MACRO(fmod, long long int)
+TVMET_DECLARE_MACRO(hypot, long long int)
+TVMET_DECLARE_MACRO(jn, long long int)
+TVMET_DECLARE_MACRO(yn, long long int)
+TVMET_DECLARE_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_DECLARE_MACRO(atan2, float)
+TVMET_DECLARE_MACRO(drem, float)
+TVMET_DECLARE_MACRO(fmod, float)
+TVMET_DECLARE_MACRO(hypot, float)
+TVMET_DECLARE_MACRO(jn, float)
+TVMET_DECLARE_MACRO(yn, float)
+TVMET_DECLARE_MACRO(pow, float)
+
+TVMET_DECLARE_MACRO(atan2, double)
+TVMET_DECLARE_MACRO(drem, double)
+TVMET_DECLARE_MACRO(fmod, double)
+TVMET_DECLARE_MACRO(hypot, double)
+TVMET_DECLARE_MACRO(jn, double)
+TVMET_DECLARE_MACRO(yn, double)
+TVMET_DECLARE_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(atan2, long double)
+TVMET_DECLARE_MACRO(drem, long double)
+TVMET_DECLARE_MACRO(fmod, long double)
+TVMET_DECLARE_MACRO(hypot, long double)
+TVMET_DECLARE_MACRO(jn, long double)
+TVMET_DECLARE_MACRO(yn, long double)
+TVMET_DECLARE_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * complex support
+ */
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+template<class T, std::size_t Sz>
+XprVector<
+  XprBinOp<
+    Fcnl_pow<T, std::complex<T> >,
+    VectorConstReference<T, Sz>,
+    XprLiteral< std::complex<T> >
+  >,
+  Sz
+>
+pow(const Vector<T, Sz>& lhs,
+    const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+XprVector<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, std::complex<T> >,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral< std::complex<T> >
+  >,
+  Sz
+>
+pow(const Vector<std::complex<T>, Sz>& lhs,
+    const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+XprVector<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, T>,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral<T>
+  >,
+  Sz
+>
+pow(const Vector<std::complex<T>, Sz>& lhs,
+    const T& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+XprVector<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, int>,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral<int>
+  >,
+  Sz
+>
+pow(const Vector<std::complex<T>, Sz>& lhs,
+    int rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+XprVector<
+  XprBinOp<
+    Fcnl_polar<T, T>,
+    VectorConstReference<T, Sz>,
+    XprLiteral<T>
+  >,
+  Sz
+>
+polar(const Vector<T, Sz>& lhs, const T& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+// to be written (atan2)
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+/*
+ * binary_function(Vector<T1, Sz>, Vector<T1, Sz>)
+ * binary_function(Vector<T, Sz>, XprVector<E>)
+ * binary_function(XprVector<E>, Vector<T, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class T1, class T2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >,									\
+  Sz									\
+>									\
+NAME(const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {		\
+  typedef XprBinOp <							\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), rhs.const_ref()));			\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME(const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) {		\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  > 							 expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, rhs.const_ref()));					\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME(const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) {		\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  > 						 	expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), rhs));					\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2)
+TVMET_IMPLEMENT_MACRO(drem)
+TVMET_IMPLEMENT_MACRO(fmod)
+TVMET_IMPLEMENT_MACRO(hypot)
+TVMET_IMPLEMENT_MACRO(jn)
+TVMET_IMPLEMENT_MACRO(yn)
+TVMET_IMPLEMENT_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+TVMET_IMPLEMENT_MACRO(polar)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * binary_function(Vector<T, Sz>, POD)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, TP)					\
+template<class T, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, TP >,						\
+    VectorConstReference<T, Sz>,					\
+    XprLiteral< TP >							\
+  >,									\
+  Sz									\
+>									\
+NAME(const Vector<T, Sz>& lhs, TP rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, TP >,						\
+    VectorConstReference<T, Sz>,					\
+    XprLiteral< TP >							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), XprLiteral< TP >(rhs)));			\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2, int)
+TVMET_IMPLEMENT_MACRO(drem, int)
+TVMET_IMPLEMENT_MACRO(fmod, int)
+TVMET_IMPLEMENT_MACRO(hypot, int)
+TVMET_IMPLEMENT_MACRO(jn, int)
+TVMET_IMPLEMENT_MACRO(yn, int)
+TVMET_IMPLEMENT_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(atan2, long long int)
+TVMET_IMPLEMENT_MACRO(drem, long long int)
+TVMET_IMPLEMENT_MACRO(fmod, long long int)
+TVMET_IMPLEMENT_MACRO(hypot, long long int)
+TVMET_IMPLEMENT_MACRO(jn, long long int)
+TVMET_IMPLEMENT_MACRO(yn, long long int)
+TVMET_IMPLEMENT_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_IMPLEMENT_MACRO(atan2, float)
+TVMET_IMPLEMENT_MACRO(drem, float)
+TVMET_IMPLEMENT_MACRO(fmod, float)
+TVMET_IMPLEMENT_MACRO(hypot, float)
+TVMET_IMPLEMENT_MACRO(jn, float)
+TVMET_IMPLEMENT_MACRO(yn, float)
+TVMET_IMPLEMENT_MACRO(pow, float)
+
+TVMET_IMPLEMENT_MACRO(atan2, double)
+TVMET_IMPLEMENT_MACRO(drem, double)
+TVMET_IMPLEMENT_MACRO(fmod, double)
+TVMET_IMPLEMENT_MACRO(hypot, double)
+TVMET_IMPLEMENT_MACRO(jn, double)
+TVMET_IMPLEMENT_MACRO(yn, double)
+TVMET_IMPLEMENT_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(atan2, long double)
+TVMET_IMPLEMENT_MACRO(drem, long double)
+TVMET_IMPLEMENT_MACRO(fmod, long double)
+TVMET_IMPLEMENT_MACRO(hypot, long double)
+TVMET_IMPLEMENT_MACRO(jn, long double)
+TVMET_IMPLEMENT_MACRO(yn, long double)
+TVMET_IMPLEMENT_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * complex support
+ */
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+/**
+ * \fn pow(const Vector<T, Sz>& lhs, const std::complex<T>& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  XprBinOp<
+    Fcnl_pow<T, std::complex<T> >,
+    VectorConstReference<T, Sz>,
+    XprLiteral< std::complex<T> >
+  >,
+  Sz
+>
+pow(const Vector<T, Sz>& lhs, const std::complex<T>& rhs) {
+  typedef XprBinOp<
+    Fcnl_pow<T, std::complex<T> >,
+    VectorConstReference<T, Sz>,
+    XprLiteral< std::complex<T> >
+  >							expr_type;
+  return XprVector<expr_type, Sz>(
+      expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));
+}
+
+
+/**
+ * \fn pow(const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, std::complex<T> >,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral< std::complex<T> >
+  >,
+  Sz
+>
+pow(const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs) {
+  typedef XprBinOp<
+    Fcnl_pow<std::complex<T>, std::complex<T> >,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral< std::complex<T> >
+  >							expr_type;
+  return XprVector<expr_type, Sz>(
+      expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));
+}
+
+
+/**
+ * \fn pow(const Vector<std::complex<T>, Sz>& lhs, const T& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, T>,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral<T>
+  >,
+  Sz
+>
+pow(const Vector<std::complex<T>, Sz>& lhs, const T& rhs) {
+  typedef XprBinOp<
+    Fcnl_pow<std::complex<T>, T>,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral<T>
+  >							expr_type;
+  return XprVector<expr_type, Sz>(
+      expr_type(lhs.const_ref(), XprLiteral<T>(rhs)));
+}
+
+
+/**
+ * \fn pow(const Vector<std::complex<T>, Sz>& lhs, int rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  XprBinOp<
+    Fcnl_pow<std::complex<T>, int>,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral<int>
+  >,
+  Sz
+>
+pow(const Vector<std::complex<T>, Sz>& lhs, int rhs) {
+  typedef XprBinOp<
+    Fcnl_pow<std::complex<T>, int>,
+    VectorConstReference<std::complex<T>, Sz>,
+    XprLiteral<int>
+  >							expr_type;
+  return XprVector<expr_type, Sz>(
+      expr_type(lhs.const_ref(), XprLiteral<int>(rhs)));
+}
+
+
+/**
+ * \fn polar(const Vector<T, Sz>& lhs, const T& rhs)
+ * \ingroup _binary_function
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  XprBinOp<
+    Fcnl_polar<T, T>,
+    VectorConstReference<T, Sz>,
+    XprLiteral<T>
+  >,
+  Sz
+>
+polar(const Vector<T, Sz>& lhs, const T& rhs) {
+  typedef XprBinOp<
+    Fcnl_polar<T, T>,
+    VectorConstReference<T, Sz>,
+    XprLiteral<T>
+  >							expr_type;
+  return XprVector<expr_type, Sz>(
+      expr_type(lhs.const_ref(), XprLiteral<T>(rhs)));
+}
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH1)
+
+#if defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+// to be written (atan2)
+#endif // defined(TVMET_HAVE_COMPLEX) && defined(TVMET_HAVE_COMPLEX_MATH2)
+
+
+} // namespace tvmet
+
+#endif // TVMET_VECTOR_BINARY_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/VectorEval.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,382 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorEval.h,v 1.18 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_VECTOR_EVAL_H
+#define TVMET_VECTOR_EVAL_H
+
+namespace tvmet {
+
+
+/********************************************************************
+ * functions all_elements/any_elements
+ ********************************************************************/
+
+
+/**
+ * \fn bool all_elements(const XprVector<E, Sz>& e)
+ * \brief check on statements for all elements
+ * \ingroup _unary_function
+ * This is for use with boolean operators like
+ * \par Example:
+ * \code
+ * all_elements(vector > 0) {
+ *     // true branch
+ * } else {
+ *     // false branch
+ * }
+ * \endcode
+ * \sa \ref compare
+ */
+template<class E, std::size_t Sz>
+inline
+bool all_elements(const XprVector<E, Sz>& e) {
+  return meta::Vector<Sz>::all_elements(e);
+}
+
+
+/**
+ * \fn bool any_elements(const XprVector<E, Sz>& e)
+ * \brief check on statements for any elements
+ * \ingroup _unary_function
+ * This is for use with boolean operators like
+ * \par Example:
+ * \code
+ * any_elements(vector > 0) {
+ *     // true branch
+ * } else {
+ *     // false branch
+ * }
+ * \endcode
+ * \sa \ref compare
+ */
+template<class E, std::size_t Sz>
+inline
+bool any_elements(const XprVector<E, Sz>& e) {
+  return meta::Vector<Sz>::any_elements(e);
+}
+
+
+/*
+ * trinary evaluation functions with vectors and xpr of
+ * XprVector<E1, Sz> ? Vector<T2, Sz> : Vector<T3, Sz>
+ * XprVector<E1, Sz> ? Vector<T2, Sz> : XprVector<E3, Sz>
+ * XprVector<E1, Sz> ? XprVector<E2, Sz> : Vector<T3, Sz>
+ * XprVector<E1, Sz> ? XprVector<E2, Sz> : XprVector<E3, Sz>
+ */
+
+/**
+ * eval(const XprVector<E1, Sz>& e1, const Vector<T2, Sz>& v2, const Vector<T3, Sz>& v3)
+ * \brief Evals the vector expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class T2, class T3, std::size_t Sz>
+inline
+XprVector<
+  XprEval<
+    XprVector<E1, Sz>,
+    VectorConstReference<T2, Sz>,
+    VectorConstReference<T3, Sz>
+  >,
+  Sz
+>
+eval(const XprVector<E1, Sz>& e1, const Vector<T2, Sz>& v2, const Vector<T3, Sz>& v3) {
+  typedef XprEval<
+    XprVector<E1, Sz>,
+    VectorConstReference<T2, Sz>,
+    VectorConstReference<T3, Sz>
+  > 							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(e1, v2.const_ref(), v3.const_ref()));
+}
+
+
+/**
+ * eval(const XprVector<E1, Sz>& e1, const Vector<T2, Sz>& v2, const XprVector<E3, Sz>& e3)
+ * \brief Evals the vector expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class T2, class E3, std::size_t Sz>
+inline
+XprVector<
+  XprEval<
+    XprVector<E1, Sz>,
+    VectorConstReference<T2, Sz>,
+    XprVector<E3, Sz>
+  >,
+  Sz
+>
+eval(const XprVector<E1, Sz>& e1, const Vector<T2, Sz>& v2, const XprVector<E3, Sz>& e3) {
+  typedef XprEval<
+    XprVector<E1, Sz>,
+    VectorConstReference<T2, Sz>,
+    XprVector<E3, Sz>
+  > 							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(e1, v2.const_ref(), e3));
+}
+
+
+/**
+ * eval(const XprVector<E1, Sz>& e1, const XprVector<E2, Sz>& e2, const Vector<T3, Sz>& v3)
+ * \brief Evals the vector expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E2, class T3, std::size_t Sz>
+inline
+XprVector<
+  XprEval<
+    XprVector<E1, Sz>,
+    XprVector<E2, Sz>,
+    VectorConstReference<T3, Sz>
+  >,
+  Sz
+>
+eval(const XprVector<E1, Sz>& e1, const XprVector<E2, Sz>& e2, const Vector<T3, Sz>& v3) {
+  typedef XprEval<
+    XprVector<E1, Sz>,
+    XprVector<E2, Sz>,
+    VectorConstReference<T3, Sz>
+  > 							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(e1, e2, v3.const_ref()));
+}
+
+
+/**
+ * eval(const XprVector<E1, Sz>& e1, const XprVector<E2, Sz>& e2, const XprVector<E3, Sz>& e3)
+ * \brief Evals the vector expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E2, class E3, std::size_t Sz>
+inline
+XprVector<
+  XprEval<
+    XprVector<E1, Sz>,
+    XprVector<E2, Sz>,
+    XprVector<E3, Sz>
+  >,
+  Sz
+>
+eval(const XprVector<E1, Sz>& e1, const XprVector<E2, Sz>& e2, const XprVector<E3, Sz>& e3) {
+  typedef XprEval<
+    XprVector<E1, Sz>,
+    XprVector<E2, Sz>,
+    XprVector<E3, Sz>
+  > 							expr_type;
+  return XprVector<expr_type, Sz>(expr_type(e1, e2, e3));
+}
+
+
+/*
+ * trinary evaluation functions with vectors, xpr of and POD
+ *
+ * XprVector<E, Sz> ? POD1 : POD2
+ * XprVector<E1, Sz> ? POD : XprVector<E3, Sz>
+ * XprVector<E1, Sz> ? XprVector<E2, Sz> : POD
+ */
+#define TVMET_IMPLEMENT_MACRO(POD)         				\
+template<class E, std::size_t Sz>      					\
+inline               							\
+XprVector<               						\
+  XprEval<               						\
+    XprVector<E, Sz>,               					\
+    XprLiteral< POD >,               					\
+    XprLiteral< POD >               					\
+  >,                							\
+  Sz									\
+>               							\
+eval(const XprVector<E, Sz>& e, POD x2, POD x3) {      			\
+  typedef XprEval<               					\
+    XprVector<E, Sz>,               					\
+    XprLiteral< POD >,                					\
+    XprLiteral< POD >                					\
+  > 							expr_type; 	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(e, XprLiteral< POD >(x2), XprLiteral< POD >(x3))); 	\
+}               							\
+               								\
+template<class E1, class E3, std::size_t Sz>   				\
+inline               							\
+XprVector<               						\
+  XprEval<               						\
+    XprVector<E1, Sz>,               					\
+    XprLiteral< POD >,               					\
+    XprVector<E3, Sz>               					\
+  >,                							\
+  Sz									\
+>               							\
+eval(const XprVector<E1, Sz>& e1, POD x2, const XprVector<E3, Sz>& e3) { \
+  typedef XprEval<               					\
+    XprVector<E1, Sz>,               					\
+    XprLiteral< POD >,                					\
+    XprVector<E3, Sz>               					\
+  > 							expr_type; 	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(e1, XprLiteral< POD >(x2), e3)); 				\
+}               							\
+               								\
+template<class E1, class E2, std::size_t Sz>   				\
+inline               							\
+XprVector<               						\
+  XprEval<               						\
+    XprVector<E1, Sz>,               					\
+    XprVector<E2, Sz>,               					\
+    XprLiteral< POD >               					\
+  >,                							\
+  Sz									\
+>               							\
+eval(const XprVector<E1, Sz>& e1, const XprVector<E2, Sz>& e2, POD x3) { \
+  typedef XprEval<               					\
+    XprVector<E1, Sz>,               					\
+    XprVector<E2, Sz>,               					\
+    XprLiteral< POD >                					\
+  > 							expr_type; 	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(e1, e2, XprLiteral< POD >(x3))); 				\
+}
+
+TVMET_IMPLEMENT_MACRO(int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_IMPLEMENT_MACRO(float)
+TVMET_IMPLEMENT_MACRO(double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * trinary evaluation functions with vectors, xpr of and complex<> types
+ *
+ * XprVector<E, Sz> e, std::complex<T> z2, std::complex<T> z3
+ * XprVector<E1, Sz> e1, std::complex<T> z2, XprVector<E3, Sz> e3
+ * XprVector<E1, Sz> e1, XprVector<E2, Sz> e2, std::complex<T> z3
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+
+
+/**
+ * eval(const XprVector<E, Sz>& e, std::complex<T> z2, std::complex<T> z3)
+ * \brief Evals the vector expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E, std::size_t Sz, class T>
+inline
+XprVector<
+  XprEval<
+    XprVector<E, Sz>,
+    XprLiteral< std::complex<T> >,
+    XprLiteral< std::complex<T> >
+  >,
+  Sz
+>
+eval(const XprVector<E, Sz>& e, std::complex<T> z2, std::complex<T> z3) {
+  typedef XprEval<
+    XprVector<E, Sz>,
+    XprLiteral< std::complex<T> >,
+    XprLiteral< std::complex<T> >
+  > 							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(e, XprLiteral< std::complex<T> >(z2), XprLiteral< std::complex<T> >(z3)));
+}
+
+/**
+ * eval(const XprVector<E1, Sz>& e1, std::complex<T> z2, const XprVector<E3, Sz>& e3)
+ * \brief Evals the vector expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E3, std::size_t Sz, class T>
+inline
+XprVector<
+  XprEval<
+    XprVector<E1, Sz>,
+    XprLiteral< std::complex<T> >,
+    XprVector<E3, Sz>
+  >,
+  Sz
+>
+eval(const XprVector<E1, Sz>& e1, std::complex<T> z2, const XprVector<E3, Sz>& e3) {
+  typedef XprEval<
+    XprVector<E1, Sz>,
+    XprLiteral< std::complex<T> >,
+    XprVector<E3, Sz>
+  > 							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(e1, XprLiteral< std::complex<T> >(z2), e3));
+}
+
+/**
+ * eval(const XprVector<E1, Sz>& e1, const XprVector<E2, Sz>& e2, std::complex<T> z3)
+ * \brief Evals the vector expressions.
+ * \ingroup _trinary_function
+ * This eval is for the a?b:c syntax, since it's not allowed to overload
+ * these operators.
+ */
+template<class E1, class E2, std::size_t Sz, class T>
+inline
+XprVector<
+  XprEval<
+    XprVector<E1, Sz>,
+    XprVector<E2, Sz>,
+    XprLiteral< std::complex<T> >
+  >,
+  Sz
+>
+eval(const XprVector<E1, Sz>& e1, const XprVector<E2, Sz>& e2, std::complex<T> z3) {
+  typedef XprEval<
+    XprVector<E1, Sz>,
+    XprVector<E2, Sz>,
+    XprLiteral< std::complex<T> >
+  > 							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(e1, e2, XprLiteral< std::complex<T> >(z3)));
+}
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace tvmet
+
+#endif // TVMET_VECTOR_EVAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/VectorFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,883 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorFunctions.h,v 1.37 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_VECTOR_FUNCTIONS_H
+#define TVMET_VECTOR_FUNCTIONS_H
+
+#include <tvmet/Extremum.h>
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic functions add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * function(Vector<T1, Sz>, Vector<T2, Sz>)
+ * function(Vector<T, Sz>, XprVector<E, Sz>)
+ * function(XprVector<E, Sz>, Vector<T, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)				\
+template<class T1, class T2, std::size_t Sz>			\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<T1, T2>,					\
+    VectorConstReference<T1, Sz>,				\
+    VectorConstReference<T2, Sz>				\
+  >,								\
+  Sz								\
+>								\
+NAME (const Vector<T1, Sz>& lhs,				\
+      const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+								\
+template<class E, class T, std::size_t Sz>			\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, T>,			\
+    XprVector<E, Sz>,						\
+    VectorConstReference<T, Sz>					\
+  >,								\
+  Sz								\
+>								\
+NAME (const XprVector<E, Sz>& lhs,				\
+      const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+								\
+template<class E, class T, std::size_t Sz>			\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<T, typename E::value_type>,			\
+    VectorConstReference<T, Sz>,				\
+    XprVector<E, Sz>						\
+  >,								\
+  Sz								\
+>								\
+NAME (const Vector<T, Sz>& lhs,					\
+      const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)		// per se element wise
+TVMET_DECLARE_MACRO(sub)		// per se element wise
+TVMET_DECLARE_MACRO(mul)		// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(div)		// not defined for vectors
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * function(Vector<T, Sz>, POD)
+ * function(POD, Vector<T, Sz>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, POD)				\
+template<class T, std::size_t Sz>				\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< T, POD >,					\
+    VectorConstReference<T, Sz>,				\
+    XprLiteral< POD >						\
+  >,								\
+  Sz								\
+>								\
+NAME (const Vector<T, Sz>& lhs, 				\
+      POD rhs) TVMET_CXX_ALWAYS_INLINE;				\
+								\
+template<class T, std::size_t Sz>				\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< POD, T>,					\
+    XprLiteral< POD >,						\
+    VectorConstReference<T, Sz>					\
+  >,								\
+  Sz								\
+>								\
+NAME (POD lhs, 							\
+      const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, int)
+TVMET_DECLARE_MACRO(sub, int)
+TVMET_DECLARE_MACRO(mul, int)
+TVMET_DECLARE_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, long long int)
+TVMET_DECLARE_MACRO(sub, long long int)
+TVMET_DECLARE_MACRO(mul, long long int)
+TVMET_DECLARE_MACRO(div, long long int)
+#endif
+
+TVMET_DECLARE_MACRO(add, float)
+TVMET_DECLARE_MACRO(sub, float)
+TVMET_DECLARE_MACRO(mul, float)
+TVMET_DECLARE_MACRO(div, float)
+
+TVMET_DECLARE_MACRO(add, double)
+TVMET_DECLARE_MACRO(sub, double)
+TVMET_DECLARE_MACRO(mul, double)
+TVMET_DECLARE_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, long double)
+TVMET_DECLARE_MACRO(sub, long double)
+TVMET_DECLARE_MACRO(mul, long double)
+TVMET_DECLARE_MACRO(div, long double)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * function(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: per se element wise
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class T, std::size_t Sz>					\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,			\
+    VectorConstReference< std::complex<T>, Sz>,				\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Sz									\
+>									\
+NAME (const Vector<std::complex<T>, Sz>& lhs,				\
+      const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+									\
+template<class T, std::size_t Sz>					\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,			\
+    XprLiteral< std::complex<T> >,					\
+    VectorConstReference< std::complex<T>, Sz>				\
+  >,									\
+  Sz									\
+>									\
+NAME (const std::complex<T>& lhs,					\
+      const Vector< std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)
+TVMET_DECLARE_MACRO(sub)
+TVMET_DECLARE_MACRO(mul)
+TVMET_DECLARE_MACRO(div)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * vector specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class T, std::size_t Sz>
+typename NumericTraits<T>::sum_type
+sum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+typename NumericTraits<T>::sum_type
+product(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, class T2, std::size_t Sz>
+typename PromoteTraits<T1, T2>::value_type
+dot(const Vector<T1, Sz>& lhs,
+    const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T1, class T2>
+Vector<typename PromoteTraits<T1, T2>::value_type, 3>
+cross(const Vector<T1, 3>& lhs,
+      const Vector<T2, 3>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+typename NumericTraits<T>::sum_type
+norm1(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+typename NumericTraits<T>::sum_type
+norm2(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+XprVector<
+  XprBinOp<
+    Fcnl_div<T, T>,
+    VectorConstReference<T, Sz>,
+    XprLiteral< T >
+  >,
+  Sz
+>
+normalize(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * min/max unary functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+template<class E, std::size_t Sz>
+Extremum<typename E::value_type, std::size_t, vector_tag>
+maximum(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+Extremum<T, std::size_t, vector_tag>
+maximum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+Extremum<typename E::value_type, std::size_t, vector_tag>
+minimum(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+Extremum<T, std::size_t, vector_tag>
+minimum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+typename E::value_type
+max(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+T max(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+typename E::value_type
+min(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+T min(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, std::size_t Sz>
+XprVector<
+  VectorConstReference<T, Sz>,
+  Sz
+>
+cvector_ref(const T* mem) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic functions add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * function(Vector<T1, Sz>, Vector<T2, Sz>)
+ * function(Vector<T, Sz>, XprVector<E, Sz>)
+ * function(XprVector<E, Sz>, Vector<T, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class T1, class T2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >,									\
+  Sz									\
+>									\
+NAME (const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {		\
+  typedef XprBinOp <							\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), rhs.const_ref()));			\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+NAME (const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) {		\
+  typedef XprBinOp<							\
+     Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  > 							 expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, rhs.const_ref()));					\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME (const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) {		\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  > 						 	expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), rhs));					\
+}
+
+TVMET_IMPLEMENT_MACRO(add)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub)		// per se element wise
+TVMET_IMPLEMENT_MACRO(mul)		// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(div)		// not defined for vectors
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * function(Vector<T, Sz>, POD)
+ * function(POD, Vector<T, Sz>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, POD)				\
+template<class T, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< T, POD >,						\
+    VectorConstReference<T, Sz>,					\
+    XprLiteral< POD >							\
+  >,									\
+  Sz									\
+>									\
+NAME (const Vector<T, Sz>& lhs, POD rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, POD >,						\
+    VectorConstReference<T, Sz>,					\
+    XprLiteral< POD >							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), XprLiteral< POD >(rhs)));		\
+}									\
+									\
+template<class T, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, T>,						\
+    XprLiteral< POD >,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+NAME (POD lhs, const Vector<T, Sz>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< POD, T>,						\
+    XprLiteral< POD >,							\
+    VectorConstReference<T, Sz>						\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(XprLiteral< POD >(lhs), rhs.const_ref()));		\
+}
+
+TVMET_IMPLEMENT_MACRO(add, int)
+TVMET_IMPLEMENT_MACRO(sub, int)
+TVMET_IMPLEMENT_MACRO(mul, int)
+TVMET_IMPLEMENT_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, long long int)
+TVMET_IMPLEMENT_MACRO(sub, long long int)
+TVMET_IMPLEMENT_MACRO(mul, long long int)
+TVMET_IMPLEMENT_MACRO(div, long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(add, float)
+TVMET_IMPLEMENT_MACRO(sub, float)
+TVMET_IMPLEMENT_MACRO(mul, float)
+TVMET_IMPLEMENT_MACRO(div, float)
+
+TVMET_IMPLEMENT_MACRO(add, double)
+TVMET_IMPLEMENT_MACRO(sub, double)
+TVMET_IMPLEMENT_MACRO(mul, double)
+TVMET_IMPLEMENT_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, long double)
+TVMET_IMPLEMENT_MACRO(sub, long double)
+TVMET_IMPLEMENT_MACRO(mul, long double)
+TVMET_IMPLEMENT_MACRO(div, long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * function(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: per se element wise
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)						\
+template<class T, std::size_t Sz>						\
+inline										\
+XprVector<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    VectorConstReference< std::complex<T>, Sz>,					\
+    XprLiteral< std::complex<T> >						\
+  >,										\
+  Sz										\
+>										\
+NAME (const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs) {	\
+  typedef XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    VectorConstReference< std::complex<T>, Sz>,					\
+    XprLiteral< std::complex<T> >						\
+  >							expr_type;		\
+  return XprVector<expr_type, Sz>(						\
+    expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));		\
+}										\
+										\
+template<class T, std::size_t Sz>						\
+inline										\
+XprVector<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    XprLiteral< std::complex<T> >,						\
+    VectorConstReference< std::complex<T>, Sz>					\
+  >,										\
+  Sz										\
+>										\
+NAME (const std::complex<T>& lhs, const Vector< std::complex<T>, Sz>& rhs) {	\
+  typedef XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    XprLiteral< std::complex<T> >,						\
+    VectorConstReference< std::complex<T>, Sz>					\
+  >							expr_type;		\
+  return XprVector<expr_type, Sz>(						\
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref()));		\
+}
+
+TVMET_IMPLEMENT_MACRO(add)
+TVMET_IMPLEMENT_MACRO(sub)
+TVMET_IMPLEMENT_MACRO(mul)
+TVMET_IMPLEMENT_MACRO(div)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * vector specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn sum(const Vector<T, Sz>& v)
+ * \brief Compute the sum of the vector.
+ * \ingroup _unary_function
+ *
+ * Simply compute the sum of the given vector as:
+ * \f[
+ * \sum_{i = 0}^{Sz-1} v[i]
+ * \f]
+ */
+template<class T, std::size_t Sz>
+inline
+typename NumericTraits<T>::sum_type
+sum(const Vector<T, Sz>& v) {
+  return meta::Vector<Sz>::sum(v);
+}
+
+
+/**
+ * \fn product(const Vector<T, Sz>& v)
+ * \brief Compute the product of the vector elements.
+ * \ingroup _unary_function
+ *
+ * Simply computer the product of the given vector as:
+ * \f[
+ * \prod_{i = 0}^{Sz - 1} v[i]
+ * \f]
+ */
+template<class T, std::size_t Sz>
+inline
+typename NumericTraits<T>::sum_type
+product(const Vector<T, Sz>& v) {
+  return meta::Vector<Sz>::product(v);
+}
+
+
+/**
+ * \fn dot(const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs)
+ * \brief Compute the dot/inner product
+ * \ingroup _binary_function
+ *
+ * Compute the dot product as:
+ * \f[
+ * \sum_{i = 0}^{Sz - 1} ( lhs[i] * rhs[i] )
+ * \f]
+ * where lhs is a column vector and rhs is a row vector, both vectors
+ * have the same dimension.
+ */
+template<class T1, class T2, std::size_t Sz>
+inline
+typename PromoteTraits<T1, T2>::value_type
+dot(const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {
+  return meta::Vector<Sz>::dot(lhs, rhs);
+}
+
+
+/**
+ * \fn cross(const Vector<T1, 3>& lhs, const Vector<T2, 3>& rhs)
+ * \brief Compute the cross/outer product
+ * \ingroup _binary_function
+ * \note working only for vectors of size = 3
+ * \todo Implement vector outer product as ET and MT, returning a XprVector
+ */
+template<class T1, class T2>
+inline
+Vector<typename PromoteTraits<T1, T2>::value_type, 3>
+cross(const Vector<T1, 3>& lhs, const Vector<T2, 3>& rhs) {
+  typedef typename PromoteTraits<T1, T2>::value_type	value_type;
+  return Vector<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
+			       rhs(0)*lhs(2) - lhs(0)*rhs(2),
+			       lhs(0)*rhs(1) - rhs(0)*lhs(1));
+}
+
+
+/**
+ * \fn norm1(const Vector<T, Sz>& v)
+ * \brief The \f$l_1\f$ norm of a vector v.
+ * \ingroup _unary_function
+ * The norm of any vector is just the square root of the dot product of
+ * a vector with itself, or
+ *
+ * \f[
+ * |Vector<T, Sz> v| = |v| = \sum_{i=0}^{Sz-1}\,|v[i]|
+ * \f]
+ */
+template<class T, std::size_t Sz>
+inline
+typename NumericTraits<T>::sum_type
+norm1(const Vector<T, Sz>& v) {
+  return sum(abs(v));
+}
+
+
+/**
+ * \fn norm2(const Vector<T, Sz>& v)
+ * \brief The euklidian norm (or \f$l_2\f$ norm) of a vector v.
+ * \ingroup _unary_function
+ * The norm of any vector is just the square root of the dot product of
+ * a vector with itself, or
+ *
+ * \f[
+ * |Vector<T, Sz> v| = |v| = \sqrt{ \sum_{i=0}^{Sz-1}\,v[i]^2 }
+ * \f]
+ *
+ * \note The internal cast for Vector<int> avoids warnings on sqrt.
+ */
+template<class T, std::size_t Sz>
+inline
+typename NumericTraits<T>::sum_type
+norm2(const Vector<T, Sz>& v) {
+  return static_cast<T>( std::sqrt(static_cast<typename NumericTraits<T>::float_type>(dot(v, v))) );
+}
+
+
+/**
+ * \fn normalize(const Vector<T, Sz>& v)
+ * \brief Normalize the given vector.
+ * \ingroup _unary_function
+ * \sa norm2
+ *
+ * using the equation:
+ * \f[
+ * \frac{Vector<T, Sz> v}{\sqrt{ \sum_{i=0}^{Sz-1}\,v[i]^2 }}
+ * \f]
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  XprBinOp<
+    Fcnl_div<T, T>,
+    VectorConstReference<T, Sz>,
+    XprLiteral< T >
+  >,
+  Sz
+>
+normalize(const Vector<T, Sz>& v) {
+  typedef XprBinOp<
+    Fcnl_div<T, T>,
+    VectorConstReference<T, Sz>,
+    XprLiteral< T >
+  >							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(v.const_ref(), XprLiteral< T >(norm2(v))));
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * min/max unary functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn maximum(const XprVector<E, Sz>& e)
+ * \brief Find the maximum of a vector expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Sz>
+inline
+Extremum<typename E::value_type, std::size_t, vector_tag>
+maximum(const XprVector<E, Sz>& e) {
+  typedef typename E::value_type 			value_type;
+
+  value_type 						m_max(e(0));
+  std::size_t 						m_idx(0);
+
+  // this loop is faster than meta templates!
+  for(std::size_t i = 1; i != Sz; ++i) {
+    if(e(i) > m_max) {
+      m_max = e(i);
+      m_idx = i;
+    }
+  }
+
+  return Extremum<value_type, std::size_t, vector_tag>(m_max, m_idx);
+}
+
+
+/**
+ * \fn maximum(const Vector<T, Sz>& v)
+ * \brief Find the maximum of a vector
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Sz>
+inline
+Extremum<T, std::size_t, vector_tag>
+maximum(const Vector<T, Sz>& v) { return maximum(v.as_expr()); }
+
+
+/**
+ * \fn minimum(const XprVector<E, Sz>& e)
+ * \brief Find the minimum of a vector expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Sz>
+inline
+Extremum<typename E::value_type, std::size_t, vector_tag>
+minimum(const XprVector<E, Sz>& e) {
+  typedef typename E::value_type 			value_type;
+
+  value_type 						m_min(e(0));
+  std::size_t 						m_idx(0);
+
+  // this loop is faster than meta templates!
+  for(std::size_t i = 1; i != Sz; ++i) {
+    if(e(i) < m_min) {
+      m_min = e(i);
+      m_idx = i;
+    }
+  }
+
+  return Extremum<value_type, std::size_t, vector_tag>(m_min, m_idx);
+}
+
+
+/**
+ * \fn minimum(const Vector<T, Sz>& v)
+ * \brief Find the minimum of a vector
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Sz>
+inline
+Extremum<T, std::size_t, vector_tag>
+minimum(const Vector<T, Sz>& v) { return minimum(v.as_expr()); }
+
+
+/**
+ * \fn max(const XprVector<E, Sz>& e)
+ * \brief Find the maximum of a vector expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Sz>
+inline
+typename E::value_type
+max(const XprVector<E, Sz>& e) {
+  typedef typename E::value_type 			value_type;
+
+  value_type 						m_max(e(0));
+
+  // this loop is faster than meta templates!
+  for(std::size_t i = 1; i != Sz; ++i)
+    if(e(i) > m_max)
+      m_max = e(i);
+
+  return m_max;
+}
+
+
+/**
+ * \fn max(const Vector<T, Sz>& v)
+ * \brief Find the maximum of a vector
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Sz>
+inline
+T max(const Vector<T, Sz>& v) {
+  typedef T			 			value_type;
+  typedef typename Vector<T, Sz>::const_iterator	const_iterator;
+
+  const_iterator					iter(v.begin());
+  const_iterator					last(v.end());
+  value_type 						temp(*iter);
+
+  for( ; iter != last; ++iter)
+    if(*iter > temp)
+      temp = *iter;
+
+  return temp;
+}
+
+
+/**
+ * \fn min(const XprVector<E, Sz>& e)
+ * \brief Find the minimum of a vector expression
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Sz>
+inline
+typename E::value_type
+min(const XprVector<E, Sz>& e) {
+  typedef typename E::value_type 			value_type;
+
+  value_type 						m_min(e(0));
+
+  // this loop is faster than meta templates!
+  for(std::size_t i = 1; i != Sz; ++i)
+    if(e(i) < m_min)
+      m_min = e(i);
+
+  return m_min;
+}
+
+
+/**
+ * \fn min(const Vector<T, Sz>& v)
+ * \brief Find the minimum of a vector
+ * \ingroup _unary_function
+ */
+template<class T, std::size_t Sz>
+inline
+T min(const Vector<T, Sz>& v) {
+  typedef T			 			value_type;
+  typedef typename Vector<T, Sz>::const_iterator	const_iterator;
+
+  const_iterator					iter(v.begin());
+  const_iterator					last(v.end());
+  value_type 						temp(*iter);
+
+  for( ; iter != last; ++iter)
+    if(*iter < temp)
+      temp = *iter;
+
+  return temp;
+}
+
+
+/**
+ * \fn cvector_ref(const T* mem)
+ * \brief Creates an expression wrapper for a C like vector arrays.
+ * \ingroup _unary_function
+ *
+ * This is like creating a vector of external data, as described
+ * at \ref construct. With this function you wrap an expression
+ * around a C style vector array and you can operate directly with it
+ * as usual.
+ *
+ * \par Example:
+ * \code
+ * static float vertices[N][3] = {
+ *   {-1,  0,  1}, { 1,  0,  1}, ...
+ * };
+ * ...
+ * typedef Vector<float, 3>			vector_type;
+ * ...
+ * vector_type V( cross(cvector_ref<float, 3>(&vertices[0][0]),
+ *                      cvector_ref<float, 3>(&vertices[1][0])) );
+ * \endcode
+ *
+ * \since release 1.6.0
+ */
+template<class T, std::size_t Sz>
+inline
+XprVector<
+  VectorConstReference<T, Sz>,
+  Sz
+>
+cvector_ref(const T* mem) {
+  typedef VectorConstReference<T, Sz>		expr_type;
+
+  return XprVector<expr_type, Sz>(expr_type(mem));
+}
+
+
+} // namespace tvmet
+
+#endif // TVMET_VECTOR_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/VectorImpl.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,210 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorImpl.h,v 1.31 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_VECTOR_IMPL_H
+#define TVMET_VECTOR_IMPL_H
+
+#include <iomanip>			// setw
+
+#include <tvmet/Functional.h>
+#include <tvmet/Io.h>
+
+
+namespace tvmet {
+
+
+/*
+ * member operators for i/o
+ */
+template<class T, std::size_t Sz>
+std::ostream& Vector<T, Sz>::print_xpr(std::ostream& os, std::size_t l) const
+{
+  os << IndentLevel(l++) << "Vector[" << ops << "]<"
+     << typeid(T).name() << ", " << Size << ">,"
+     << IndentLevel(--l)
+     << std::endl;
+
+  return os;
+}
+
+
+template<class T, std::size_t Sz>
+std::ostream& Vector<T, Sz>::print_on(std::ostream& os) const
+{
+  enum {
+    complex_type = NumericTraits<value_type>::is_complex
+  };
+
+  std::streamsize w = IoPrintHelper<Vector>::width(dispatch<complex_type>(), *this);
+
+  os << std::setw(0) << "[\n  ";
+  for(std::size_t i = 0; i < (Size - 1); ++i) {
+    os << std::setw(w) << m_data[i] << ", ";
+  }
+  os << std::setw(w) << m_data[Size - 1] << "\n]";
+
+  return os;
+}
+
+
+/*
+ * member operators with scalars, per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class T, std::size_t Sz>					\
+inline									\
+Vector<T, Sz>& Vector<T, Sz>::operator OP (value_type rhs) {		\
+  typedef XprLiteral<value_type> 			expr_type;	\
+  this->M_##NAME(XprVector<expr_type, Size>(expr_type(rhs)));		\
+  return *this;								\
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq, +=)
+TVMET_IMPLEMENT_MACRO(sub_eq, -=)
+TVMET_IMPLEMENT_MACRO(mul_eq, *=)
+TVMET_IMPLEMENT_MACRO(div_eq, /=)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class T, std::size_t Sz>					\
+inline									\
+Vector<T, Sz>& Vector<T, Sz>::operator OP (std::size_t rhs) {		\
+  typedef XprLiteral<value_type> 			expr_type;	\
+  this->M_##NAME(XprVector<expr_type, Size>(expr_type(rhs)));		\
+  return *this;								\
+}
+
+TVMET_IMPLEMENT_MACRO(mod_eq, %=)
+TVMET_IMPLEMENT_MACRO(xor_eq,^=)
+TVMET_IMPLEMENT_MACRO(and_eq, &=)
+TVMET_IMPLEMENT_MACRO(or_eq, |=)
+TVMET_IMPLEMENT_MACRO(shl_eq, <<=)
+TVMET_IMPLEMENT_MACRO(shr_eq, >>=)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * member functions (operators) with vectors, for use with +=,-= ... <<=
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)									\
+template<class T1, std::size_t Sz>									\
+template <class T2>											\
+inline Vector<T1, Sz>&											\
+Vector<T1, Sz>::M_##NAME (const Vector<T2, Size>& rhs) {						\
+  this->M_##NAME( XprVector<typename Vector<T2, Size>::ConstReference, Size>(rhs.const_ref()) );	\
+  return *this;												\
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+TVMET_IMPLEMENT_MACRO(mod_eq)
+TVMET_IMPLEMENT_MACRO(xor_eq)
+TVMET_IMPLEMENT_MACRO(and_eq)
+TVMET_IMPLEMENT_MACRO(or_eq)
+TVMET_IMPLEMENT_MACRO(shl_eq)
+TVMET_IMPLEMENT_MACRO(shr_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * member functions (operators) with expressions, for use width +=,-= ... <<=
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					   \
+template<class T, std::size_t Sz>					   \
+template <class E>							   \
+inline 									   \
+Vector<T, Sz>&								   \
+Vector<T, Sz>::M_##NAME (const XprVector<E, Size>& rhs) {		   \
+  rhs.assign_to(*this, Fcnl_##NAME<value_type, typename E::value_type>()); \
+  return *this;								   \
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+TVMET_IMPLEMENT_MACRO(mod_eq)
+TVMET_IMPLEMENT_MACRO(xor_eq)
+TVMET_IMPLEMENT_MACRO(and_eq)
+TVMET_IMPLEMENT_MACRO(or_eq)
+TVMET_IMPLEMENT_MACRO(shl_eq)
+TVMET_IMPLEMENT_MACRO(shr_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * aliased member functions (operators) with vectors,
+ * for use with +=,-= ... <<=
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)								     \
+template<class T1, std::size_t Sz>								     \
+template <class T2>										     \
+inline 												     \
+Vector<T1, Sz>&											     \
+Vector<T1, Sz>::alias_##NAME (const Vector<T2, Size>& rhs) {					     \
+  this->alias_##NAME( XprVector<typename Vector<T2, Size>::ConstReference, Size>(rhs.const_ref()) ); \
+  return *this;											     \
+}
+
+TVMET_IMPLEMENT_MACRO(assign)
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * aliased member functions (operators) with expressions,
+ * for use width +=,-= ... <<=
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)						      \
+template<class T, std::size_t Sz>						      \
+template <class E>								      \
+inline 										      \
+Vector<T, Sz>&									      \
+Vector<T, Sz>::alias_##NAME (const XprVector<E, Size>& rhs) {			      \
+  typedef Vector<T, Sz>					temp_type;		      \
+  temp_type(rhs).assign_to(*this, Fcnl_##NAME<value_type, typename E::value_type>()); \
+  return *this;									      \
+}
+
+TVMET_IMPLEMENT_MACRO(assign)
+TVMET_IMPLEMENT_MACRO(add_eq)
+TVMET_IMPLEMENT_MACRO(sub_eq)
+TVMET_IMPLEMENT_MACRO(mul_eq)
+TVMET_IMPLEMENT_MACRO(div_eq)
+#undef TVMET_IMPLEMENT_MACRO
+
+
+} // namespace tvmet
+
+#endif // TVMET_VECTOR_IMPL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/VectorOperators.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,1055 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorOperators.h,v 1.18 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_VECTOR_OPERATORS_H
+#define TVMET_VECTOR_OPERATORS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+template<class T, std::size_t Sz>
+inline
+std::ostream& operator<<(std::ostream& os,
+			 const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Member operators (arithmetic and bit ops)
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * update_operator(Vector<T1, Sz>,  Vector<T2, Sz>)
+ * update_operator(Vector<T1, Sz>,  XprVector<E, Sz>)
+ * Note: per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template<class T1, class T2, std::size_t Sz>				\
+Vector<T1, Sz>&								\
+operator OP (Vector<T1, Sz>& lhs,					\
+	     const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class T, class E, std::size_t Sz>				\
+Vector<T, Sz>&								\
+operator OP (Vector<T, Sz>& lhs,					\
+	     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add_eq, +=)		// per se element wise
+TVMET_DECLARE_MACRO(sub_eq, -=)		// per se element wise
+TVMET_DECLARE_MACRO(mul_eq, *=)		// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(div_eq, /=)		// not defined for vectors
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod_eq, %=)
+  TVMET_DECLARE_MACRO(xor_eq, ^=)
+  TVMET_DECLARE_MACRO(and_eq, &=)
+  TVMET_DECLARE_MACRO(or_eq, |=)
+  TVMET_DECLARE_MACRO(shl_eq, <<=)
+  TVMET_DECLARE_MACRO(shr_eq, >>=)
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Vector<T1, Sz>, Vector<T2, Sz>)
+ * operator(Vector<T1, Sz>, XprVector<E, Sz>)
+ * operator(XprVector<E, Sz>, Vector<T1, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template<class T1, class T2, std::size_t Sz>				\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T1, Sz>& lhs, 				\
+	     const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class E, class T, std::size_t Sz>				\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs,				\
+	     const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+									\
+template<class E, class T, std::size_t Sz>				\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T, Sz>& lhs, 					\
+	     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)		// per se element wise
+TVMET_DECLARE_MACRO(sub, -)		// per se element wise
+TVMET_DECLARE_MACRO(mul, *)		// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(div, /)		// not defined for vectors
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * operator(Vector<T, Sz>, POD)
+ * operator(POD, Vector<T, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, POD)			\
+template<class T, std::size_t Sz>				\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< T, POD >,					\
+    VectorConstReference<T, Sz>,				\
+    XprLiteral< POD >						\
+  >,								\
+  Sz								\
+>								\
+operator OP (const Vector<T, Sz>& lhs, 				\
+	     POD rhs) TVMET_CXX_ALWAYS_INLINE;			\
+								\
+template<class T, std::size_t Sz>				\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< POD, T>,					\
+    XprLiteral< POD >,						\
+    VectorConstReference<T, Sz>					\
+  >,								\
+  Sz								\
+>								\
+operator OP (POD lhs, 						\
+	     const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +, int)
+TVMET_DECLARE_MACRO(sub, -, int)
+TVMET_DECLARE_MACRO(mul, *, int)
+TVMET_DECLARE_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, +, long long int)
+TVMET_DECLARE_MACRO(sub, -, long long int)
+TVMET_DECLARE_MACRO(mul, *, long long int)
+TVMET_DECLARE_MACRO(div, /, long long int)
+#endif
+
+TVMET_DECLARE_MACRO(add, +, float)
+TVMET_DECLARE_MACRO(sub, -, float)
+TVMET_DECLARE_MACRO(mul, *, float)
+TVMET_DECLARE_MACRO(div, /, float)
+
+TVMET_DECLARE_MACRO(add, +, double)
+TVMET_DECLARE_MACRO(sub, -, double)
+TVMET_DECLARE_MACRO(mul, *, double)
+TVMET_DECLARE_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, +, long double)
+TVMET_DECLARE_MACRO(sub, -, long double)
+TVMET_DECLARE_MACRO(mul, *, long double)
+TVMET_DECLARE_MACRO(div, /, long double)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class T, std::size_t Sz>						\
+XprVector<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    VectorConstReference< std::complex<T>, Sz>,					\
+    XprLiteral< std::complex<T> >						\
+  >,										\
+  Sz										\
+>										\
+operator OP (const Vector<std::complex<T>, Sz>& lhs, 				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+										\
+template<class T, std::size_t Sz>						\
+XprVector<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    XprLiteral< std::complex<T> >,						\
+    VectorConstReference< std::complex<T>, Sz>					\
+  >,										\
+  Sz										\
+>										\
+operator OP (const std::complex<T>& lhs, 					\
+	     const Vector< std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)		// per se element wise
+TVMET_DECLARE_MACRO(sub, -)		// per se element wise
+TVMET_DECLARE_MACRO(mul, *)		// per se element wise
+TVMET_DECLARE_MACRO(div, /)		// per se element wise
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Vector<T1, Sz>, Vector<T2, Sz>)
+ * operator(XprVector<E, Sz>, Vector<T, Sz>)
+ * operator(Vector<T, Sz>, XprVector<E, Sz>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template<class T1, class T2, std::size_t Sz>				\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T1, Sz>& lhs, 				\
+	     const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class E, class T, std::size_t Sz>				\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs, 				\
+	     const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+									\
+template<class E, class T, std::size_t Sz>				\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T, Sz>& lhs, 					\
+	     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %)
+  TVMET_DECLARE_MACRO(bitxor, ^)
+  TVMET_DECLARE_MACRO(bitand, &)
+  TVMET_DECLARE_MACRO(bitor, |)
+  TVMET_DECLARE_MACRO(shl, <<)
+  TVMET_DECLARE_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class T, std::size_t Sz>						\
+XprVector<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    VectorConstReference< std::complex<T>, Sz>,					\
+    XprLiteral< std::complex<T> >						\
+  >,										\
+  Sz										\
+>										\
+operator OP (const Vector<std::complex<T>, Sz>& lhs, 				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+										\
+template<class T, std::size_t Sz>						\
+XprVector<									\
+  XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,				\
+    XprLiteral< std::complex<T> >,						\
+    VectorConstReference< std::complex<T>, Sz>					\
+  >,										\
+  Sz										\
+>										\
+operator OP (const std::complex<T>& lhs, 					\
+	     const Vector< std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*
+ * operator(Vector<T, Sz>, POD)
+ * operator(POD, Vector<T, Sz>)
+ * Note: operations are per se element_wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, TP)				\
+template<class T, std::size_t Sz>					\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< T, TP >,						\
+    VectorConstReference<T, Sz>,					\
+    XprLiteral< TP >							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T, Sz>& lhs, TP rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class T, std::size_t Sz>					\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< TP, T>,						\
+    XprLiteral< TP >,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+operator OP (TP lhs, const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, int)
+  TVMET_DECLARE_MACRO(bitxor, ^, int)
+  TVMET_DECLARE_MACRO(bitand, &, int)
+  TVMET_DECLARE_MACRO(bitor, |, int)
+  TVMET_DECLARE_MACRO(shl, <<, int)
+  TVMET_DECLARE_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, int)
+TVMET_DECLARE_MACRO(less, <, int)
+TVMET_DECLARE_MACRO(greater_eq, >=, int)
+TVMET_DECLARE_MACRO(less_eq, <=, int)
+TVMET_DECLARE_MACRO(eq, ==, int)
+TVMET_DECLARE_MACRO(not_eq, !=, int)
+TVMET_DECLARE_MACRO(and, &&, int)
+TVMET_DECLARE_MACRO(or, ||, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, long long int)
+  TVMET_DECLARE_MACRO(bitxor, ^, long long int)
+  TVMET_DECLARE_MACRO(bitand, &, long long int)
+  TVMET_DECLARE_MACRO(bitor, |, long long int)
+  TVMET_DECLARE_MACRO(shl, <<, long long int)
+  TVMET_DECLARE_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long long int)
+TVMET_DECLARE_MACRO(less, <, long long int)
+TVMET_DECLARE_MACRO(greater_eq, >=, long long int)
+TVMET_DECLARE_MACRO(less_eq, <=, long long int)
+TVMET_DECLARE_MACRO(eq, ==, long long int)
+TVMET_DECLARE_MACRO(not_eq, !=, long long int)
+TVMET_DECLARE_MACRO(and, &&, long long int)
+TVMET_DECLARE_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, float)
+TVMET_DECLARE_MACRO(less, <, float)
+TVMET_DECLARE_MACRO(greater_eq, >=, float)
+TVMET_DECLARE_MACRO(less_eq, <=, float)
+TVMET_DECLARE_MACRO(eq, ==, float)
+TVMET_DECLARE_MACRO(not_eq, !=, float)
+TVMET_DECLARE_MACRO(and, &&, float)
+TVMET_DECLARE_MACRO(or, ||, float)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, double)
+TVMET_DECLARE_MACRO(less, <, double)
+TVMET_DECLARE_MACRO(greater_eq, >=, double)
+TVMET_DECLARE_MACRO(less_eq, <=, double)
+TVMET_DECLARE_MACRO(eq, ==, double)
+TVMET_DECLARE_MACRO(not_eq, !=, double)
+TVMET_DECLARE_MACRO(and, &&, double)
+TVMET_DECLARE_MACRO(or, ||, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long double)
+TVMET_DECLARE_MACRO(less, <, long double)
+TVMET_DECLARE_MACRO(greater_eq, >=, long double)
+TVMET_DECLARE_MACRO(less_eq, <=, long double)
+TVMET_DECLARE_MACRO(eq, ==, long double)
+TVMET_DECLARE_MACRO(not_eq, !=, long double)
+TVMET_DECLARE_MACRO(and, &&, long double)
+TVMET_DECLARE_MACRO(or, ||, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * unary_operator(Vector<T, Sz>)
+ * Note: per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)				\
+template <class T, std::size_t Sz>				\
+XprVector<							\
+  XprUnOp<							\
+    Fcnl_##NAME<T>,						\
+    VectorConstReference<T, Sz>					\
+  >,								\
+  Sz								\
+>								\
+operator OP (const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(not, !)
+TVMET_DECLARE_MACRO(compl, ~)
+TVMET_DECLARE_MACRO(neg, -)
+#undef TVMET_DECLARE_MACRO
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/**
+ * \fn operator<<(std::ostream& os, const Vector<T, Sz>& rhs)
+ * \brief Overload operator for i/o
+ * \ingroup _binary_operator
+ */
+template<class T, std::size_t Sz>
+inline
+std::ostream& operator<<(std::ostream& os, const Vector<T, Sz>& rhs) {
+  return rhs.print_on(os);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Member operators (arithmetic and bit ops)
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * update_operator(Vector<T1, Sz>,  Vector<T2, Sz>)
+ * update_operator(Vector<T1, Sz>,  XprVector<E, Sz>)
+ * Note: per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				\
+template<class T1, class T2, std::size_t Sz>			\
+inline Vector<T1, Sz>&						\
+operator OP (Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {	\
+  return lhs.M_##NAME(rhs);					\
+}								\
+								\
+template<class T, class E, std::size_t Sz>			\
+inline Vector<T, Sz>&						\
+operator OP (Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) {	\
+  return lhs.M_##NAME(rhs);					\
+}
+
+TVMET_IMPLEMENT_MACRO(add_eq, +=)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub_eq, -=)		// per se element wise
+TVMET_IMPLEMENT_MACRO(mul_eq, *=)		// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(div_eq, /=)		// not defined for vectors
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod_eq, %=)
+  TVMET_IMPLEMENT_MACRO(xor_eq, ^=)
+  TVMET_IMPLEMENT_MACRO(and_eq, &=)
+  TVMET_IMPLEMENT_MACRO(or_eq, |=)
+  TVMET_IMPLEMENT_MACRO(shl_eq, <<=)
+  TVMET_IMPLEMENT_MACRO(shr_eq, >>=)
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Vector<T1, Sz>, Vector<T2, Sz>)
+ * operator(Vector<T1, Sz>, XprVector<E, Sz>)
+ * operator(XprVector<E, Sz>, Vector<T1, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class T1, class T2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {	\
+  return NAME (lhs, rhs);						\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) {	\
+  return NAME (lhs, rhs);						\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) {	\
+  return NAME (lhs, rhs);						\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub, -)		// per se element wise
+TVMET_IMPLEMENT_MACRO(mul, *)		// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(div, /)		// not defined for vectors
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * operator(Vector<T, Sz>, POD)
+ * operator(POD, Vector<T, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, POD)		\
+template<class T, std::size_t Sz>			\
+inline							\
+XprVector<						\
+  XprBinOp<						\
+    Fcnl_##NAME< T, POD >,				\
+    VectorConstReference<T, Sz>,			\
+    XprLiteral< POD >					\
+  >,							\
+  Sz							\
+>							\
+operator OP (const Vector<T, Sz>& lhs, POD rhs) {	\
+  return NAME (lhs, rhs);				\
+}							\
+							\
+template<class T, std::size_t Sz>			\
+inline							\
+XprVector<						\
+  XprBinOp<						\
+    Fcnl_##NAME< POD, T>,				\
+    XprLiteral< POD >,					\
+    VectorConstReference<T, Sz>				\
+  >,							\
+  Sz							\
+>							\
+operator OP (POD lhs, const Vector<T, Sz>& rhs) {	\
+  return NAME (lhs, rhs);				\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +, int)
+TVMET_IMPLEMENT_MACRO(sub, -, int)
+TVMET_IMPLEMENT_MACRO(mul, *, int)
+TVMET_IMPLEMENT_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, +, long long int)
+TVMET_IMPLEMENT_MACRO(sub, -, long long int)
+TVMET_IMPLEMENT_MACRO(mul, *, long long int)
+TVMET_IMPLEMENT_MACRO(div, /, long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(add, +, float)
+TVMET_IMPLEMENT_MACRO(sub, -, float)
+TVMET_IMPLEMENT_MACRO(mul, *, float)
+TVMET_IMPLEMENT_MACRO(div, /, float)
+
+TVMET_IMPLEMENT_MACRO(add, +, double)
+TVMET_IMPLEMENT_MACRO(sub, -, double)
+TVMET_IMPLEMENT_MACRO(mul, *, double)
+TVMET_IMPLEMENT_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, +, long double)
+TVMET_IMPLEMENT_MACRO(sub, -, long double)
+TVMET_IMPLEMENT_MACRO(mul, *, long double)
+TVMET_IMPLEMENT_MACRO(div, /, long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)			\
+template<class T, std::size_t Sz>			\
+inline							\
+XprVector<						\
+  XprBinOp<						\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,	\
+    VectorConstReference< std::complex<T>, Sz>,		\
+    XprLiteral< std::complex<T> >			\
+  >,							\
+  Sz							\
+>							\
+operator OP (const Vector<std::complex<T>, Sz>& lhs, 	\
+	     const std::complex<T>& rhs) {		\
+  return NAME (lhs, rhs);				\
+}							\
+							\
+template<class T, std::size_t Sz>			\
+inline							\
+XprVector<						\
+  XprBinOp<						\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,	\
+    XprLiteral< std::complex<T> >,			\
+    VectorConstReference< std::complex<T>, Sz>		\
+  >,							\
+  Sz							\
+>							\
+operator OP (const std::complex<T>& lhs, 		\
+	     const Vector< std::complex<T>, Sz>& rhs) {	\
+  return NAME (lhs, rhs);				\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub, -)		// per se element wise
+TVMET_IMPLEMENT_MACRO(mul, *)		// per se element wise
+TVMET_IMPLEMENT_MACRO(div, /)		// per se element wise
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(Vector<T1, Sz>, Vector<T2, Sz>)
+ * operator(XprVector<E, Sz>, Vector<T, Sz>)
+ * operator(Vector<T, Sz>, XprVector<E, Sz>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class T1, class T2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {	\
+  typedef XprBinOp <							\
+    Fcnl_##NAME<T1, T2>,						\
+    VectorConstReference<T1, Sz>,					\
+    VectorConstReference<T2, Sz>					\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), rhs.const_ref()));			\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) {	\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, T>,				\
+    XprVector<E, Sz>,							\
+    VectorConstReference<T, Sz>						\
+  > 							 expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, rhs.const_ref()));					\
+}									\
+									\
+template<class E, class T, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) {	\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, typename E::value_type>,				\
+    VectorConstReference<T, Sz>,					\
+    XprVector<E, Sz>							\
+  > 						 	expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), rhs));					\
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^)
+  TVMET_IMPLEMENT_MACRO(bitand, &)
+  TVMET_IMPLEMENT_MACRO(bitor, |)
+  TVMET_IMPLEMENT_MACRO(shl, <<)
+  TVMET_IMPLEMENT_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)							\
+template<class T, std::size_t Sz>							\
+inline											\
+XprVector<										\
+  XprBinOp<										\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    VectorConstReference< std::complex<T>, Sz>,						\
+    XprLiteral< std::complex<T> >							\
+  >,											\
+  Sz											\
+>											\
+operator OP (const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs) {	\
+  typedef XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    VectorConstReference< std::complex<T>, Sz>,						\
+    XprLiteral< std::complex<T> >							\
+  >							expr_type;			\
+  return XprVector<expr_type, Sz>(							\
+    expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));			\
+}											\
+											\
+template<class T, std::size_t Sz>							\
+inline											\
+XprVector<										\
+  XprBinOp<										\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    XprLiteral< std::complex<T> >,							\
+    VectorConstReference< std::complex<T>, Sz>						\
+  >,											\
+  Sz											\
+>											\
+operator OP (const std::complex<T>& lhs, const Vector< std::complex<T>, Sz>& rhs) {	\
+  typedef XprBinOp<									\
+    Fcnl_##NAME< std::complex<T>, std::complex<T> >,					\
+    XprLiteral< std::complex<T> >,							\
+    VectorConstReference< std::complex<T>, Sz>						\
+  >							expr_type;			\
+  return XprVector<expr_type, Sz>(							\
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref()));			\
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*
+ * operator(Vector<T, Sz>, POD)
+ * operator(POD, Vector<T, Sz>)
+ * Note: operations are per se element_wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, TP)				\
+template<class T, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< T, TP >,						\
+    VectorConstReference<T, Sz>,					\
+    XprLiteral< TP >							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T, Sz>& lhs, TP rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<T, TP >,						\
+    VectorConstReference<T, Sz>,					\
+    XprLiteral< TP >							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs.const_ref(), XprLiteral< TP >(rhs)));			\
+}									\
+									\
+template<class T, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< TP, T>,						\
+    XprLiteral< TP >,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+operator OP (TP lhs, const Vector<T, Sz>& rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< TP, T>,						\
+    XprLiteral< TP >,							\
+    VectorConstReference<T, Sz>						\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(XprLiteral< TP >(lhs), rhs.const_ref()));			\
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, int)
+TVMET_IMPLEMENT_MACRO(less, <, int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, int)
+TVMET_IMPLEMENT_MACRO(eq, ==, int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, int)
+TVMET_IMPLEMENT_MACRO(and, &&, int)
+TVMET_IMPLEMENT_MACRO(or, ||, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, long long int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, long long int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, long long int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, long long int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long long int)
+TVMET_IMPLEMENT_MACRO(less, <, long long int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int)
+TVMET_IMPLEMENT_MACRO(eq, ==, long long int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int)
+TVMET_IMPLEMENT_MACRO(and, &&, long long int)
+TVMET_IMPLEMENT_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, float)
+TVMET_IMPLEMENT_MACRO(less, <, float)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, float)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, float)
+TVMET_IMPLEMENT_MACRO(eq, ==, float)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, float)
+TVMET_IMPLEMENT_MACRO(and, &&, float)
+TVMET_IMPLEMENT_MACRO(or, ||, float)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, double)
+TVMET_IMPLEMENT_MACRO(less, <, double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, double)
+TVMET_IMPLEMENT_MACRO(eq, ==, double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, double)
+TVMET_IMPLEMENT_MACRO(and, &&, double)
+TVMET_IMPLEMENT_MACRO(or, ||, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long double)
+TVMET_IMPLEMENT_MACRO(less, <, long double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long double)
+TVMET_IMPLEMENT_MACRO(eq, ==, long double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long double)
+TVMET_IMPLEMENT_MACRO(and, &&, long double)
+TVMET_IMPLEMENT_MACRO(or, ||, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * unary_operator(Vector<T, Sz>)
+ * Note: per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template <class T, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprUnOp<								\
+    Fcnl_##NAME<T>,							\
+    VectorConstReference<T, Sz>						\
+  >,									\
+  Sz									\
+>									\
+operator OP (const Vector<T, Sz>& rhs) {				\
+  typedef XprUnOp<							\
+    Fcnl_##NAME<T>,							\
+    VectorConstReference<T, Sz>						\
+  >  							 expr_type;	\
+  return XprVector<expr_type, Sz>(expr_type(rhs.const_ref()));		\
+}
+
+TVMET_IMPLEMENT_MACRO(not, !)
+TVMET_IMPLEMENT_MACRO(compl, ~)
+TVMET_IMPLEMENT_MACRO(neg, -)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+} // namespace tvmet
+
+#endif // TVMET_VECTOR_OPERATORS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/VectorUnaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,220 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorUnaryFunctions.h,v 1.13 2007-06-23 15:58:58 opetzold Exp $
+ */
+
+#ifndef TVMET_VECTOR_UNARY_FUNCTIONS_H
+#define TVMET_VECTOR_UNARY_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+/*
+ * unary_function(Vector<T, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)            \
+template<class T, std::size_t Sz>            \
+XprVector<                        \
+  XprUnOp<                        \
+    Fcnl_##NAME<T>,                    \
+    VectorConstReference<T, Sz>                \
+  >,                            \
+  Sz                            \
+>                            \
+NAME(const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(abs)
+TVMET_DECLARE_MACRO(cbrt)
+TVMET_DECLARE_MACRO(ceil)
+TVMET_DECLARE_MACRO(floor)
+TVMET_DECLARE_MACRO(rint)
+TVMET_DECLARE_MACRO(sin)
+TVMET_DECLARE_MACRO(cos)
+TVMET_DECLARE_MACRO(tan)
+TVMET_DECLARE_MACRO(sinh)
+TVMET_DECLARE_MACRO(cosh)
+TVMET_DECLARE_MACRO(tanh)
+TVMET_DECLARE_MACRO(asin)
+TVMET_DECLARE_MACRO(acos)
+TVMET_DECLARE_MACRO(atan)
+TVMET_DECLARE_MACRO(exp)
+TVMET_DECLARE_MACRO(log)
+TVMET_DECLARE_MACRO(log10)
+TVMET_DECLARE_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_DECLARE_MACRO(asinh)
+TVMET_DECLARE_MACRO(acosh)
+TVMET_DECLARE_MACRO(atanh)
+TVMET_DECLARE_MACRO(expm1)
+TVMET_DECLARE_MACRO(log1p)
+TVMET_DECLARE_MACRO(erf)
+TVMET_DECLARE_MACRO(erfc)
+TVMET_DECLARE_MACRO(j0)
+TVMET_DECLARE_MACRO(j1)
+TVMET_DECLARE_MACRO(y0)
+TVMET_DECLARE_MACRO(y1)
+TVMET_DECLARE_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_DECLARE_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * unary_function(Vector<std::complex<T>, Sz>)
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+#define TVMET_DECLARE_MACRO(NAME)                    \
+template<class T, std::size_t Sz>                    \
+XprVector<                                \
+  XprUnOp<                                \
+    Fcnl_##NAME< std::complex<T> >,                    \
+    VectorConstReference<std::complex<T>, Sz>                \
+  >,                                    \
+  Sz                                    \
+>                                    \
+NAME(const Vector<std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(real)
+TVMET_DECLARE_MACRO(imag)
+TVMET_DECLARE_MACRO(arg)
+TVMET_DECLARE_MACRO(norm)
+TVMET_DECLARE_MACRO(conj)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*
+ * unary_function(Vector<T, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)                    \
+template<class T, std::size_t Sz>                    \
+inline                                    \
+XprVector<                                \
+  XprUnOp<                                \
+    Fcnl_##NAME<T>,                            \
+    VectorConstReference<T, Sz>                        \
+  >,                                    \
+  Sz                                    \
+>                                    \
+NAME(const Vector<T, Sz>& rhs) {                    \
+  typedef XprUnOp<                            \
+      Fcnl_##NAME<T>,                            \
+      VectorConstReference<T, Sz>                    \
+    >                             expr_type;    \
+    return XprVector<expr_type, Sz>(expr_type(rhs.const_ref()));    \
+}
+
+TVMET_IMPLEMENT_MACRO(abs)
+TVMET_IMPLEMENT_MACRO(cbrt)
+TVMET_IMPLEMENT_MACRO(ceil)
+TVMET_IMPLEMENT_MACRO(floor)
+TVMET_IMPLEMENT_MACRO(rint)
+TVMET_IMPLEMENT_MACRO(sin)
+TVMET_IMPLEMENT_MACRO(cos)
+TVMET_IMPLEMENT_MACRO(tan)
+TVMET_IMPLEMENT_MACRO(sinh)
+TVMET_IMPLEMENT_MACRO(cosh)
+TVMET_IMPLEMENT_MACRO(tanh)
+TVMET_IMPLEMENT_MACRO(asin)
+TVMET_IMPLEMENT_MACRO(acos)
+TVMET_IMPLEMENT_MACRO(atan)
+TVMET_IMPLEMENT_MACRO(exp)
+TVMET_IMPLEMENT_MACRO(log)
+TVMET_IMPLEMENT_MACRO(log10)
+TVMET_IMPLEMENT_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_IMPLEMENT_MACRO(asinh)
+TVMET_IMPLEMENT_MACRO(acosh)
+TVMET_IMPLEMENT_MACRO(atanh)
+TVMET_IMPLEMENT_MACRO(expm1)
+TVMET_IMPLEMENT_MACRO(log1p)
+TVMET_IMPLEMENT_MACRO(erf)
+TVMET_IMPLEMENT_MACRO(erfc)
+TVMET_IMPLEMENT_MACRO(j0)
+TVMET_IMPLEMENT_MACRO(j1)
+TVMET_IMPLEMENT_MACRO(y0)
+TVMET_IMPLEMENT_MACRO(y1)
+TVMET_IMPLEMENT_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_IMPLEMENT_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * unary_function(Vector<std::complex<T>, Sz>)
+ */
+#if defined(TVMET_HAVE_COMPLEX)
+#define TVMET_IMPLEMENT_MACRO(NAME)                    \
+template<class T, std::size_t Sz>                    \
+inline                                    \
+XprVector<                                \
+  XprUnOp<                                \
+    Fcnl_##NAME< std::complex<T> >,                    \
+    VectorConstReference<std::complex<T>, Sz>                \
+  >,                                    \
+  Sz                                    \
+>                                    \
+NAME(const Vector<std::complex<T>, Sz>& rhs) {                \
+  typedef XprUnOp<                            \
+      Fcnl_##NAME< std::complex<T> >,                    \
+      VectorConstReference<std::complex<T>, Sz>                \
+    >                             expr_type;    \
+    return XprVector<expr_type, Sz>(expr_type(rhs.const_ref()));    \
+}
+
+TVMET_IMPLEMENT_MACRO(real)
+TVMET_IMPLEMENT_MACRO(imag)
+TVMET_IMPLEMENT_MACRO(arg)
+TVMET_IMPLEMENT_MACRO(norm)
+TVMET_IMPLEMENT_MACRO(conj)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace tvmet
+
+#endif // TVMET_VECTOR_UNARY_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/config.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,206 @@
+#ifndef _INCLUDE_TVMET_CONFIG_H
+#define _INCLUDE_TVMET_CONFIG_H 1
+ 
+/* include/tvmet/config.h. Generated automatically at end of configure. */
+/* config/config.h.  Generated from config.h.in by configure.  */
+/* config/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* define if the compiler has complex<T> */
+#ifndef TVMET_HAVE_COMPLEX 
+#define TVMET_HAVE_COMPLEX   
+#endif
+
+/* define if the compiler has complex math functions */
+#ifndef TVMET_HAVE_COMPLEX_MATH1 
+#define TVMET_HAVE_COMPLEX_MATH1   
+#endif
+
+/* define if the compiler has more complex math functions */
+/* #undef TVMET_HAVE_COMPLEX_MATH2 */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#ifndef TVMET_HAVE_DLFCN_H 
+#define TVMET_HAVE_DLFCN_H  1 
+#endif
+
+/* Define to 1 if you have the `floor' function. */
+#ifndef TVMET_HAVE_FLOOR 
+#define TVMET_HAVE_FLOOR  1 
+#endif
+
+/* Define if the compiler supports IEEE math library */
+#ifndef TVMET_HAVE_IEEE_MATH 
+#define TVMET_HAVE_IEEE_MATH   
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#ifndef TVMET_HAVE_INTTYPES_H 
+#define TVMET_HAVE_INTTYPES_H  1 
+#endif
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#ifndef TVMET_HAVE_LIBDL 
+#define TVMET_HAVE_LIBDL  1 
+#endif
+
+/* Define to 1 if the type `long double' works and has more range or precision
+   than `double'. */
+#ifndef TVMET_HAVE_LONG_DOUBLE 
+#define TVMET_HAVE_LONG_DOUBLE  1 
+#endif
+
+/* Define to 1 if the type `long double' works and has more range or precision
+   than `double'. */
+#ifndef TVMET_HAVE_LONG_DOUBLE_WIDER 
+#define TVMET_HAVE_LONG_DOUBLE_WIDER  1 
+#endif
+
+/* Define if the compiler supports the long_long type */
+#ifndef TVMET_HAVE_LONG_LONG 
+#define TVMET_HAVE_LONG_LONG   
+#endif
+
+/* Define to 1 if you have the <memory.h> header file. */
+#ifndef TVMET_HAVE_MEMORY_H 
+#define TVMET_HAVE_MEMORY_H  1 
+#endif
+
+/* Define if the compiler supports the mutable keyword */
+#ifndef TVMET_HAVE_MUTABLE 
+#define TVMET_HAVE_MUTABLE   
+#endif
+
+/* Define if the compiler implements namespaces */
+#ifndef TVMET_HAVE_NAMESPACES 
+#define TVMET_HAVE_NAMESPACES   
+#endif
+
+/* Define if the compiler supports partial specialization */
+#ifndef TVMET_HAVE_PARTIAL_SPECIALIZATION 
+#define TVMET_HAVE_PARTIAL_SPECIALIZATION   
+#endif
+
+/* Define to 1 if you have the `pow' function. */
+#ifndef TVMET_HAVE_POW 
+#define TVMET_HAVE_POW  1 
+#endif
+
+/* Define to 1 if you have the `rint' function. */
+#ifndef TVMET_HAVE_RINT 
+#define TVMET_HAVE_RINT  1 
+#endif
+
+/* Define to 1 if you have the `sqrt' function. */
+#ifndef TVMET_HAVE_SQRT 
+#define TVMET_HAVE_SQRT  1 
+#endif
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#ifndef TVMET_HAVE_STDBOOL_H 
+#define TVMET_HAVE_STDBOOL_H  1 
+#endif
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#ifndef TVMET_HAVE_STDINT_H 
+#define TVMET_HAVE_STDINT_H  1 
+#endif
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#ifndef TVMET_HAVE_STDLIB_H 
+#define TVMET_HAVE_STDLIB_H  1 
+#endif
+
+/* Define to 1 if you have the <strings.h> header file. */
+#ifndef TVMET_HAVE_STRINGS_H 
+#define TVMET_HAVE_STRINGS_H  1 
+#endif
+
+/* Define to 1 if you have the <string.h> header file. */
+#ifndef TVMET_HAVE_STRING_H 
+#define TVMET_HAVE_STRING_H  1 
+#endif
+
+/* Define if the compiler supports SYSV math library */
+/* #undef TVMET_HAVE_SYSV_MATH */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#ifndef TVMET_HAVE_SYS_STAT_H 
+#define TVMET_HAVE_SYS_STAT_H  1 
+#endif
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#ifndef TVMET_HAVE_SYS_TIME_H 
+#define TVMET_HAVE_SYS_TIME_H  1 
+#endif
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#ifndef TVMET_HAVE_SYS_TYPES_H 
+#define TVMET_HAVE_SYS_TYPES_H  1 
+#endif
+
+/* Define if the compiler recognizes typename */
+#ifndef TVMET_HAVE_TYPENAME 
+#define TVMET_HAVE_TYPENAME   
+#endif
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#ifndef TVMET_HAVE_UNISTD_H 
+#define TVMET_HAVE_UNISTD_H  1 
+#endif
+
+/* Define to 1 if the system has the type `_Bool'. */
+/* #undef TVMET_HAVE__BOOL */
+
+/* Define to the address where bug reports for this package should be sent. */
+#ifndef TVMET_PACKAGE_BUGREPORT 
+#define TVMET_PACKAGE_BUGREPORT  "opetzold@users.sourceforge.net" 
+#endif
+
+/* Define to the full name of this package. */
+#ifndef TVMET_PACKAGE_NAME 
+#define TVMET_PACKAGE_NAME  "tvmet" 
+#endif
+
+/* Define to the full name and version of this package. */
+#ifndef TVMET_PACKAGE_STRING 
+#define TVMET_PACKAGE_STRING  "tvmet 1.7.2" 
+#endif
+
+/* Define to the one symbol short name of this package. */
+#ifndef TVMET_PACKAGE_TARNAME 
+#define TVMET_PACKAGE_TARNAME  "tvmet" 
+#endif
+
+/* Define to the version of this package. */
+#ifndef TVMET_PACKAGE_VERSION 
+#define TVMET_PACKAGE_VERSION  "1.7.2" 
+#endif
+
+/* Define to 1 if you have the ANSI C header files. */
+#ifndef TVMET_STDC_HEADERS 
+#define TVMET_STDC_HEADERS  1 
+#endif
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TVMET_TM_IN_SYS_TIME */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef _tvmet_const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef _tvmet_inline */
+#endif
+
+/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
+   supported. Do not define if restrict is supported directly. */
+#ifndef _tvmet_restrict 
+#define _tvmet_restrict  __restrict 
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef _tvmet_size_t */
+ 
+/* _INCLUDE_TVMET_CONFIG_H */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/config/config-gcc.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,44 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: config-gcc.h,v 1.10 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_CONFIG_GCC_H
+#define TVMET_CONFIG_GCC_H
+
+#if defined(__GNUC__)
+
+   // force inline
+#  define TVMET_CXX_ALWAYS_INLINE __attribute__((always_inline))
+
+#else // !defined(__GNUC__)
+
+   // paranoia
+#  warning "config header for gnuc included without defined __GNUC__"
+
+#endif
+
+#endif // TVMET_CONFIG_GCC_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/config/config-icc.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,69 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: config-icc.h,v 1.12 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_CONFIG_ICC_H
+#define TVMET_CONFIG_ICC_H
+
+#if defined(__INTEL_COMPILER)
+
+  /* isnan/isinf hack
+   *
+   * The problem is related intel's 8.0 macros isnan and isinf,
+   * they are expanded in this version and they are not compileable
+   * therefore. We use a small hack here - disabling. This is
+   * not an real solution, nor forever.
+   * For a list of all defined symbols use icpc -E -dM prog1.cpp
+   * or read /opt/intel/compiler80/doc/c_ug/index.htm.
+   */
+#  if (__INTEL_COMPILER == 800) || (__INTEL_COMPILER > 800)
+#    define TVMET_NO_IEEE_MATH_ISNAN
+#    define TVMET_NO_IEEE_MATH_ISINF
+#  endif
+
+
+   /*
+    * disable compiler warnings
+    */
+#  pragma warning(disable:981) // operands are evaluated in unspecified order
+
+
+   /*
+    * force inline using gcc's compatibility mode
+    */
+#  if (__INTEL_COMPILER == 800) || (__INTEL_COMPILER > 800)
+#    define TVMET_CXX_ALWAYS_INLINE __attribute__((always_inline))
+#  endif
+
+#else // !defined(__INTEL_COMPILER)
+
+   // paranoia
+#  warning "config header included without defined __INTEL_COMPILER"
+
+#endif
+
+#endif // TVMET_CONFIG_ICC_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/config/config-kcc.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,41 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: config-kcc.h,v 1.9 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_CONFIG_KCC_H
+#define TVMET_CONFIG_KCC_H
+
+#if defined(__KCC)
+
+#else // !defined(__KCC)
+
+   // paranoia
+#  warning "config header included without defined __KCC"
+
+#endif
+
+#endif // TVMET_CONFIG_KCC_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/config/config-pgi.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,48 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: config-pgi.h,v 1.10 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_CONFIG_PGI_H
+#define TVMET_CONFIG_PGI_H
+
+#if defined(__PGI)
+
+
+   // obviously does have pgCC 5.1 (trial) no long double on sqrt
+#  if defined(TVMET_HAVE_LONG_DOUBLE)
+#    undef TVMET_HAVE_LONG_DOUBLE
+#  endif
+
+
+#else // !defined(__PGI)
+
+   // paranoia
+#  warning "config header included without defined __PGI"
+
+#endif
+
+#endif // TVMET_CONFIG_PGI_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/config/config-vc71.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,249 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2003 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: config-vc71.h.in,v 1.2 2004-11-04 16:47:12 opetzold Exp $
+ */
+
+#ifndef TVMET_CONFIG_VC71_H
+#define TVMET_CONFIG_VC71_H
+
+
+/*******************************************************************
+ * equivalent hand made header to configure.ac's autoheader.
+ ******************************************************************/
+
+
+/* define if the compiler has complex<T> */
+#ifndef TVMET_HAVE_COMPLEX
+#define TVMET_HAVE_COMPLEX 1
+#endif
+
+/* define if the compiler has complex math functions */
+#ifndef TVMET_HAVE_COMPLEX_MATH1
+#define TVMET_HAVE_COMPLEX_MATH1 1
+#endif
+
+/* define if the compiler has more complex math functions */
+/* #undef TVMET_HAVE_COMPLEX_MATH2 */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#ifdef TVMET_HAVE_DLFCN_H
+#undef TVMET_HAVE_DLFCN_H
+#endif
+
+/* Define to 1 if you have the `floor' function. */
+#ifndef TVMET_HAVE_FLOOR
+#define TVMET_HAVE_FLOOR  1
+#endif
+
+/* Define if the compiler supports IEEE math library */
+#ifndef TVMET_HAVE_IEEE_MATH
+#define TVMET_HAVE_IEEE_MATH 1
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#ifdef TVMET_HAVE_INTTYPES_H
+#undef TVMET_HAVE_INTTYPES_H
+#endif
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#ifdef TVMET_HAVE_LIBDL
+#undef TVMET_HAVE_LIBDL
+#endif
+
+/* Define to 1 if long double works and has more range or precision than
+   double. */
+#ifndef TVMET_HAVE_LONG_DOUBLE
+#define TVMET_HAVE_LONG_DOUBLE  1
+#endif
+
+/* Define if the compiler supports the long_long type */
+// enable MS extension for long long
+#ifndef TVMET_HAVE_LONG_LONG
+#define TVMET_HAVE_LONG_LONG 1
+#endif
+
+/* Define to 1 if you have the <memory.h> header file. */
+#ifndef TVMET_HAVE_MEMORY_H
+#define TVMET_HAVE_MEMORY_H  1
+#endif
+
+/* Define if the compiler supports the mutable keyword */
+#ifndef TVMET_HAVE_MUTABLE
+#define TVMET_HAVE_MUTABLE 1
+#endif
+
+/* Define if the compiler implements namespaces */
+#ifndef TVMET_HAVE_NAMESPACES
+#define TVMET_HAVE_NAMESPACES 1
+#endif
+
+/* Define if the compiler supports partial specialization */
+#ifndef TVMET_HAVE_PARTIAL_SPECIALIZATION
+#define TVMET_HAVE_PARTIAL_SPECIALIZATION 1
+#endif
+
+/* Define to 1 if you have the `pow' function. */
+#ifndef TVMET_HAVE_POW
+#define TVMET_HAVE_POW  1
+#endif
+
+/* Define to 1 if you have the `rint' function. */
+
+#ifdef TVMET_HAVE_RINT
+#undef TVMET_HAVE_RINT
+#endif
+
+/* Define to 1 if you have the `sqrt' function. */
+#ifndef TVMET_HAVE_SQRT
+#define TVMET_HAVE_SQRT  1
+#endif
+
+/* Define to 1 if stdbool.h conforms to C99. */
+/* #undef TVMET_HAVE_STDBOOL_H */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#ifdef TVMET_HAVE_STDINT_H
+#undef TVMET_HAVE_STDINT_H
+#endif
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#ifndef TVMET_HAVE_STDLIB_H
+#define TVMET_HAVE_STDLIB_H  1
+#endif
+
+/* Define to 1 if you have the <strings.h> header file. */
+#ifdef TVMET_HAVE_STRINGS_H
+#undef TVMET_HAVE_STRINGS_H
+#endif
+
+/* Define to 1 if you have the <string.h> header file. */
+#ifndef TVMET_HAVE_STRING_H
+#define TVMET_HAVE_STRING_H  1
+#endif
+
+/* Define if the compiler supports SYSV math library */
+/* #undef TVMET_HAVE_SYSV_MATH */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#ifdef TVMET_HAVE_SYS_STAT_H
+#undef TVMET_HAVE_SYS_STAT_H
+#endif
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#ifdef TVMET_HAVE_SYS_TIME_H
+#undef TVMET_HAVE_SYS_TIME_H
+#endif
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#ifdef TVMET_HAVE_SYS_TYPES_H
+#undef TVMET_HAVE_SYS_TYPES_H
+#endif
+
+/* Define if the compiler recognizes typename */
+#ifndef TVMET_HAVE_TYPENAME
+#define TVMET_HAVE_TYPENAME 1
+#endif
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#ifdef TVMET_HAVE_UNISTD_H
+#undef TVMET_HAVE_UNISTD_H
+#endif
+
+/* Define to 1 if the system has the type `_Bool'. */
+/* #undef TVMET_HAVE__BOOL */
+
+/* Define to the address where bug reports for this package should be sent. */
+#ifndef TVMET_PACKAGE_BUGREPORT
+#define TVMET_PACKAGE_BUGREPORT  "opetzold@users.sourceforge.net"
+#endif
+
+/* Define to the full name of this package. */
+#ifndef TVMET_PACKAGE_NAME
+#define TVMET_PACKAGE_NAME  "tvmet"
+#endif
+
+/* Define to the full name and version of this package. */
+#ifndef TVMET_PACKAGE_STRING
+#define TVMET_PACKAGE_STRING  "tvmet 1.7.2"
+#endif
+
+/* Define to the one symbol short name of this package. */
+#ifndef TVMET_PACKAGE_TARNAME
+#define TVMET_PACKAGE_TARNAME  "tvmet"
+#endif
+
+/* Define to the version of this package. */
+#ifndef TVMET_PACKAGE_VERSION
+#define TVMET_PACKAGE_VERSION  "1.7.2"
+#endif
+
+/* Define to 1 if you have the ANSI C header files. */
+#ifndef TVMET_STDC_HEADERS
+#define TVMET_STDC_HEADERS  1
+#endif
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TVMET_TM_IN_SYS_TIME */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef _tvmet_const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef _tvmet_inline */
+#endif
+
+/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
+   supported. Do not define if restrict is supported directly. */
+// unfortunally, VC++ 7.1 doesn't have restrict.
+#ifndef _tvmet_restrict
+#define _tvmet_restrict
+#endif
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef _tvmet_size_t */
+
+
+
+/*******************************************************************
+ * tvmet's config for special handling on MS VC
+ ******************************************************************/
+
+
+#if defined(_MSC_VER)
+
+/* The undefined case of TVMET_CXX_ALWAYS_INLINE is handled inside
+ * tvmet.h, so there there is no need to do this here! */
+
+#else // !defined(_MSC_VER)
+
+   // paranoia
+#  warning "config header for MS VC 7.1 included without defined _MSC_VER"
+
+#endif
+
+#endif // TVMET_CONFIG_VC71_H
+
+// Local Variables:
+// mode:C++
+// End:
+//  LocalWords:  autoheader
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/loop/Gemm.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,115 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemm.h,v 1.12 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_LOOP_GEMM_H
+#define TVMET_LOOP_GEMM_H
+
+namespace tvmet {
+
+namespace loop {
+
+
+/**
+ * \class gemm Gemm.h "tvmet/loop/Gemm.h"
+ * \brief class for matrix-matrix product using loop unrolling.
+ *        using formula
+ *        \f[
+ *        M_1\,M_2
+ *        \f]
+ * \par Example:
+ * \code
+ * template<class T, std::size_t Rows1, std::size_t Cols1, std::size_t Cols2>
+ * inline
+ * void
+ * prod(const Matrix<T, Rows1, Cols1>& lhs, const Matrix<T, Cols1, Cols2>& rhs,
+ * 	Matrix<T, Rows1, Cols2>& dest)
+ * {
+ *   for (std::size_t i = 0; i != Rows1; ++i) {
+ *     for (std::size_t j = 0; j != Cols2; ++j) {
+ *       dest(i, j) = tvmet::loop::gemm<Rows1, Cols1, Cols2>().prod(lhs, rhs, i, j);
+ *     }
+ *   }
+ * }
+ * \endcode
+ * \note The number of rows of rhs matrix have to be equal to cols of lhs matrix.
+ *       The result is a (Rows1 x Cols2) matrix.
+ */
+template<std::size_t Rows1, std::size_t Cols1,
+	 std::size_t Cols2>
+class gemm
+{
+  gemm(const gemm&);
+  gemm& operator=(const gemm&);
+
+private:
+  enum {
+    count 	= Cols1,
+    N 		= (count+7)/8
+  };
+
+public:
+  gemm() { }
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+    >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    typename PromoteTraits<
+      typename E1::value_type,
+      typename E2::value_type
+    >::value_type  				sum(0);
+    std::size_t 				k(0);
+    std::size_t 				n(N);
+
+    // Duff's device
+    switch(count % 8) {
+    case 0: do { sum += lhs(i, k) * rhs(k, j); ++k;
+    case 7:      sum += lhs(i, k) * rhs(k, j); ++k;
+    case 6:      sum += lhs(i, k) * rhs(k, j); ++k;
+    case 5:      sum += lhs(i, k) * rhs(k, j); ++k;
+    case 4:      sum += lhs(i, k) * rhs(k, j); ++k;
+    case 3:      sum += lhs(i, k) * rhs(k, j); ++k;
+    case 2:      sum += lhs(i, k) * rhs(k, j); ++k;
+    case 1:      sum += lhs(i, k) * rhs(k, j); ++k;
+            } while(--n != 0);
+    }
+
+    return sum;
+  }
+};
+
+
+} // namespace loop
+
+} // namespace tvmet
+
+#endif /* TVMET_LOOP_GEMM_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/loop/Gemmt.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,115 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemmt.h,v 1.9 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_LOOP_GEMMT_H
+#define TVMET_LOOP_GEMMT_H
+
+namespace tvmet {
+
+namespace loop {
+
+
+/**
+ * \class gemmt Gemmt.h "tvmet/loop/Gemmt.h"
+ * \brief class for for product matrix-transpose(matrix) operations.
+ *        using formula
+ *        \f[
+ *        M_1\,M_2^{T}
+ *        \f]
+ * \par Example:
+ * \code
+ * template<class T, std::size_t Rows1, std::size_t Cols1, std::size_t Cols2>
+ * inline
+ * void
+ * prod(const Matrix<T, Rows1, Cols1>& lhs, const Matrix<T, Rows2, Cols1>& rhs,
+ * 	Matrix<T, Rows1, Rows2>& dest)
+ * {
+ *   for (std::size_t i = 0; i != Rows1; ++i) {
+ *     for (std::size_t j = 0; j != Rows2; ++j) {
+ *       dest(i, j) = tvmet::loop::gemmt<Rows1, Cols1, Cols1>().prod(lhs, rhs, i, j);
+ *     }
+ *   }
+ * }
+ * \endcode
+ * \note The number of cols of rhs matrix have to be equal to cols of rhs matrix.
+ *       The result is a (Rows1 x Rows2) matrix.
+ */
+template<std::size_t Rows1, std::size_t Cols1,
+	 std::size_t Cols2 /* unused */>
+class gemmt
+{
+  gemmt(const gemmt&);
+  gemmt& operator=(const gemmt&);
+
+private:
+  enum {
+    count 	= Cols1,
+    N 		= (count+7)/8
+  };
+
+public:
+  gemmt() { }
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+    >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    typename PromoteTraits<
+      typename E1::value_type,
+      typename E2::value_type
+    >::value_type  				sum(0);
+    std::size_t 				k(0);
+    std::size_t 				n(N);
+
+    // Duff's device
+    switch(count % 8) {
+    case 0: do { sum += lhs(i, k) * rhs(j, k); ++k;
+    case 7:      sum += lhs(i, k) * rhs(j, k); ++k;
+    case 6:      sum += lhs(i, k) * rhs(j, k); ++k;
+    case 5:      sum += lhs(i, k) * rhs(j, k); ++k;
+    case 4:      sum += lhs(i, k) * rhs(j, k); ++k;
+    case 3:      sum += lhs(i, k) * rhs(j, k); ++k;
+    case 2:      sum += lhs(i, k) * rhs(j, k); ++k;
+    case 1:      sum += lhs(i, k) * rhs(j, k); ++k;
+            } while(--n != 0);
+    }
+
+    return sum;
+  }
+};
+
+
+} // namespace loop
+
+} // namespace tvmet
+
+#endif /* TVMET_LOOP_GEMMT_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/loop/Gemtm.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,116 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemtm.h,v 1.9 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_LOOP_GEMTM_H
+#define TVMET_LOOP_GEMTM_H
+
+namespace tvmet {
+
+namespace loop {
+
+
+/**
+ * \class gemtm Gemtm.h "tvmet/loop/Gemtm.h"
+ * \brief class for matrix-matrix product using loop unrolling.
+ *        using formula
+ *        \f[
+ *        M_1^{T}\,M_2
+ *        \f]
+ * \par Example:
+ * \code
+ * template<class T, std::size_t Rows1, std::size_t Cols1, std::size_t Cols2>
+ * inline
+ * void
+ * prod(const Matrix<T, Rows1, Cols1>& lhs, const Matrix<T, Rows1, Cols2>& rhs,
+ * 	Matrix<T, Cols2, Cols1>& dest)
+ * {
+ *   for (std::size_t i = 0; i != Cols1; ++i) {
+ *     for (std::size_t j = 0; j != Cols2; ++j) {
+ *       dest(i, j) = tvmet::loop::gemtm<Rows1, Cols1, Cols2>::prod(lhs, rhs, i, j);
+ *     }
+ *   }
+ * }
+ * \endcode
+ * \note The number of rows of rhs matrix have to be equal rows of rhs matrix,
+ *       since lhs matrix 1 is transposed.
+ *       The result is a (Cols1 x Cols2) matrix.
+ */
+template<std::size_t Rows1, std::size_t Cols1,
+	 std::size_t Cols2>
+class gemtm
+{
+  gemtm(const gemtm&);
+  gemtm& operator=(const gemtm&);
+
+private:
+  enum {
+    count 	= Cols1,
+    N 		= (count+7)/8
+  };
+
+public:
+  gemtm() { }
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+    >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    typename PromoteTraits<
+      typename E1::value_type,
+      typename E2::value_type
+    >::value_type  				sum(0);
+    std::size_t 				k(0);
+    std::size_t 				n(N);
+
+    // Duff's device
+    switch(count % 8) {
+    case 0: do { sum += lhs(k, i) * rhs(k, j); ++k;
+    case 7:      sum += lhs(k, i) * rhs(k, j); ++k;
+    case 6:      sum += lhs(k, i) * rhs(k, j); ++k;
+    case 5:      sum += lhs(k, i) * rhs(k, j); ++k;
+    case 4:      sum += lhs(k, i) * rhs(k, j); ++k;
+    case 3:      sum += lhs(k, i) * rhs(k, j); ++k;
+    case 2:      sum += lhs(k, i) * rhs(k, j); ++k;
+    case 1:      sum += lhs(k, i) * rhs(k, j); ++k;
+            } while(--n != 0);
+    }
+
+    return sum;
+  }
+};
+
+
+} // namespace loop
+
+} // namespace tvmet
+
+#endif /* TVMET_LOOP_GEMTM_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/loop/Gemtv.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,110 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemtv.h,v 1.7 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_LOOP_GEMTV_H
+#define TVMET_LOOP_GEMTV_H
+
+namespace tvmet {
+
+namespace loop {
+
+
+/**
+ * \class gemtv Gemtv.h "tvmet/loop/Gemtv.h"
+ * \brief class for transposed(matrix)-vector product using loop unrolling.
+ *        using formula
+ *        \f[
+ *        M^T\,v
+ *        \f]
+ * \par Example:
+ * \code
+ * template<class T, std::size_t Rows, std::size_t Cols>
+ * inline
+ * void
+ * prod(const Matrix<T, Rows, Cols>& lhs, const Vector<T, Rows>& rhs,
+ * 	Vector<T, Cols>& dest)
+ * {
+ *   for (std::size_t i = 0; i != Cols; ++i) {
+ *     dest(i) = tvmet::loop::gemtv<Rows, Cols>().prod(lhs, rhs, i);
+ *   }
+ * }
+ * \endcode
+ */
+template<std::size_t Rows, std::size_t Cols>
+class gemtv
+{
+  gemtv(const gemtv&);
+  gemtv& operator=(const gemtv&);
+
+private:
+  enum {
+    count 	= Rows,
+    N 		= (count+7)/8
+  };
+
+public:
+  gemtv() { }
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+    >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i) {
+    typename PromoteTraits<
+      typename E1::value_type,
+      typename E2::value_type
+    >::value_type  				sum(0);
+    std::size_t 				j(0);
+    std::size_t 				n(N);
+
+    // Duff's device
+    switch(count % 8) {
+    case 0: do { sum += lhs(j, i) * rhs(j); ++j;
+    case 7:      sum += lhs(j, i) * rhs(j); ++j;
+    case 6:      sum += lhs(j, i) * rhs(j); ++j;
+    case 5:      sum += lhs(j, i) * rhs(j); ++j;
+    case 4:      sum += lhs(j, i) * rhs(j); ++j;
+    case 3:      sum += lhs(j, i) * rhs(j); ++j;
+    case 2:      sum += lhs(j, i) * rhs(j); ++j;
+    case 1:      sum += lhs(j, i) * rhs(j); ++j;
+            } while(--n != 0);
+    }
+
+    return sum;
+  }
+};
+
+
+} // namespace loop
+
+} // namespace tvmet
+
+#endif /* TVMET_LOOP_GEMTV_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/loop/Gemv.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,110 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemv.h,v 1.7 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_LOOP_GEMV_H
+#define TVMET_LOOP_GEMV_H
+
+namespace tvmet {
+
+namespace loop {
+
+
+/**
+ * \class gemv Gemv.h "tvmet/loop/Gemv.h"
+ * \brief class for matrix-vector product using loop unrolling.
+ *        using formula
+ *        \f[
+ *        M\,v
+ *        \f]
+ * \par Example:
+ * \code
+ * template<class T, std::size_t Rows, std::size_t Cols>
+ * inline
+ * void
+ * prod(const Matrix<T, Rows, Cols>& lhs, const Vector<T, Cols>& rhs,
+ * 	Vector<T, Rows>& dest)
+ * {
+ *   for (std::size_t i = 0; i != Rows; ++i) {
+ *     dest(i) = tvmet::loop::gemv<Rows, Cols>().prod(lhs, rhs, i);
+ *   }
+ * }
+ * \endcode
+ */
+template<std::size_t Rows, std::size_t Cols>
+class gemv
+{
+  gemv(const gemv&);
+  gemv& operator=(const gemv&);
+
+private:
+  enum {
+    count 	= Cols,
+    N 		= (count+7)/8
+  };
+
+public:
+  gemv() { }
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+    >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i) {
+    typename PromoteTraits<
+      typename E1::value_type,
+      typename E2::value_type
+    >::value_type  				sum(0);
+    std::size_t 				j(0);
+    std::size_t 				n(N);
+
+    // Duff's device
+    switch(count % 8) {
+    case 0: do { sum += lhs(i, j) * rhs(j); ++j;
+    case 7:      sum += lhs(i, j) * rhs(j); ++j;
+    case 6:      sum += lhs(i, j) * rhs(j); ++j;
+    case 5:      sum += lhs(i, j) * rhs(j); ++j;
+    case 4:      sum += lhs(i, j) * rhs(j); ++j;
+    case 3:      sum += lhs(i, j) * rhs(j); ++j;
+    case 2:      sum += lhs(i, j) * rhs(j); ++j;
+    case 1:      sum += lhs(i, j) * rhs(j); ++j;
+            } while(--n != 0);
+    }
+
+    return sum;
+  }
+};
+
+
+} // namespace loop
+
+} // namespace tvmet
+
+#endif /* TVMET_LOOP_GEMV_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/loop/Matrix.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,66 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Matrix.h,v 1.11 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_LOOP_MATRIX_H
+#define TVMET_LOOP_MATRIX_H
+
+namespace tvmet {
+
+namespace loop {
+
+
+/**
+ * \class Matrix Matrix.h "tvmet/loop/Matrix.h"
+ * \brief Loop %Matrix class using expression and loop templates.
+ */
+template<std::size_t Rows, std::size_t Cols>
+class Matrix
+{
+  Matrix(const Matrix&);
+  Matrix& operator=(const Matrix&);
+
+public:
+  Matrix() { }
+
+public:
+  /** assign an expression on columns on given row using the functional fn. */
+  template<class E1, class E2, class Assign>
+  static inline
+  void assign(E1& lhs, const E2& rhs, const Assign& assign_fn) {
+    for(std::size_t i = 0; i != Rows; ++i)
+      for(std::size_t j = 0; j != Cols; ++j)
+	assign_fn.apply_on(lhs(i, j), rhs(i, j));
+  }
+};
+
+
+} // namespace loop
+
+} // namespace tvmet
+
+#endif /* TVMET_LOOP_MATRIX_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/loop/Vector.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,65 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Vector.h,v 1.9 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_LOOP_VECTOR_H
+#define TVMET_LOOP_VECTOR_H
+
+namespace tvmet {
+
+namespace loop {
+
+
+/**
+ * \class Vector Vector.h "tvmet/loop/Vector.h"
+ * \brief Loop %Vector class using expression and loop templates.
+ */
+template<std::size_t Sz>
+class Vector
+{
+  Vector(const Vector&);
+  Vector& operator=(const Vector&);
+
+public:
+  Vector() { }
+
+public:
+  /** assign an expression on columns on given row using the functional fn. */
+  template<class E1, class E2, class Assign>
+  static inline
+  void assign(E1& lhs, const E2& rhs, const Assign& assign_fn) {
+    for(std::size_t i = 0; i != Sz; ++i)
+      assign_fn.apply_on(lhs(i), rhs(i));
+  }
+};
+
+
+} // namespace loop
+
+} // namespace tvmet
+
+#endif /* TVMET_LOOP_VECTOR_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/meta/Gemm.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,102 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemm.h,v 1.15 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_META_GEMM_H
+#define TVMET_META_GEMM_H
+
+#include <tvmet/xpr/Null.h>
+
+namespace tvmet {
+
+namespace meta {
+
+
+/**
+ * \class gemm Gemm.h "tvmet/meta/Gemm.h"
+ * \brief Meta class for matrix-matrix operations, like product
+ *        using formula
+ *        \f[
+ *        M_1\,M_2
+ *        \f]
+ * \note The rows of matrix 2 have to be equal to cols of matrix 1.
+ */
+template<std::size_t Rows1, std::size_t Cols1,
+	 std::size_t Cols2,
+	 std::size_t K>
+class gemm
+{
+  gemm();
+  gemm(const gemm&);
+  gemm& operator=(const gemm&);
+
+private:
+  enum {
+    doIt = (K != Cols1 - 1) 		/**< recursive counter */
+  };
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return lhs(i, K) * rhs(K, j)
+      + gemm<Rows1 * doIt, Cols1 * doIt,
+             Cols2 * doIt,
+             (K+1) * doIt>::prod(lhs, rhs, i, j);
+  }
+};
+
+
+/**
+ * \class gemm<0,0,0,0> Gemm.h "tvmet/meta/Gemm.h"
+ * \brief gemm Specialized for recursion.
+ */
+template<>
+class gemm<0,0,0,0>
+{
+  gemm();
+  gemm(const gemm&);
+  gemm& operator=(const gemm&);
+
+public:
+  template<class E1, class E2>
+  static inline
+  XprNull prod(const E1&, const E2&, std::size_t, std::size_t) {
+    return XprNull();
+  }
+};
+
+
+} // namespace meta
+
+} // namespace tvmet
+
+#endif /* TVMET_META_GEMM_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/meta/Gemmt.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,103 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemmt.h,v 1.13 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_META_GEMMT_H
+#define TVMET_META_GEMMT_H
+
+#include <tvmet/xpr/Null.h>
+
+namespace tvmet {
+
+namespace meta {
+
+
+/**
+ * \class gemmt Gemmt.h "tvmet/meta/Gemmt.h"
+ * \brief Meta class for product matrix-transpose(matrix) operations.
+ *        using formula
+ *        \f[
+ *        M_1\,M_2^{T}
+ *        \f]
+ * \note The rows of matrix 2 have to be equal to cols of matrix 1. The result
+ *       is a rows1 * cols2 matrix.
+ */
+template<std::size_t Rows1, std::size_t Cols1,
+	 std::size_t Cols2,
+	 std::size_t K>
+class gemmt
+{
+  gemmt();
+  gemmt(const gemmt&);
+  gemmt& operator=(const gemmt&);
+
+private:
+  enum {
+    doIt = (K != Cols2 - 1) 		/**< recursive counter */
+  };
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return lhs(i, K) * rhs(j, K)
+      + gemmt<Rows1 * doIt, Cols1 * doIt,
+              Cols2 * doIt,
+              (K+1) * doIt>::prod(lhs, rhs, i, j);
+  }
+};
+
+
+/**
+ * \class gemmt<0,0,0,0> Gemmt.h "tvmet/meta/Gemmt.h"
+ * \brief gemmt Specialized for recursion.
+ */
+template<>
+class gemmt<0,0,0,0>
+{
+  gemmt();
+  gemmt(const gemmt&);
+  gemmt& operator=(const gemmt&);
+
+public:
+  template<class E1, class E2>
+  static inline
+  XprNull prod(const E1&, const E2&, std::size_t, std::size_t) {
+    return XprNull();
+  }
+};
+
+
+} // namespace meta
+
+} // namespace tvmet
+
+#endif /* TVMET_META_GEMMT_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/meta/Gemtm.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,106 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemtm.h,v 1.12 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_META_GEMTM_H
+#define TVMET_META_GEMTM_H
+
+#include <tvmet/xpr/Null.h>
+
+namespace tvmet {
+
+namespace meta {
+
+
+/**
+ * \class gemtm Gemtm.h "tvmet/meta/Gemtm.h"
+ * \brief Meta class for trans(matrix)-matrix operations, like product.
+ *        using formula
+ *        \f[
+ *        M_1^{T}\,M_2
+ *        \f]
+ * \note The number of cols of matrix 2 have to be equal to number of rows of
+ *       matrix 1, since matrix 1 is transposed - the result is a (Cols1 x Cols2)
+ *       matrix.
+ */
+
+template<std::size_t Rows1, std::size_t Cols1,
+	 std::size_t Cols2,
+	 std::size_t K>
+class gemtm
+{
+private:
+  gemtm();
+  gemtm(const gemtm&);
+  gemtm& operator=(const gemtm&);
+
+private:
+  enum {
+    doIt = (K != Rows1 - 1) 		/**< recursive counter */
+  };
+
+public:
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return lhs(K, i) * rhs(K, j)
+      + gemtm<Rows1 * doIt, Cols1 * doIt,
+              Cols2 * doIt,
+              (K+1) * doIt>::prod(lhs, rhs, i, j);
+  }
+};
+
+
+/**
+ * \class gemtm<0,0,0,0> Gemtm.h "tvmet/meta/Gemtm.h"
+ * \brief gemtm Specialized for recursion.
+ */
+template<>
+class gemtm<0,0,0,0>
+{
+  gemtm();
+  gemtm(const gemtm&);
+  gemtm& operator=(const gemtm&);
+
+public:
+  template<class E1, class E2>
+  static inline
+  XprNull prod(const E1&, const E2&, std::size_t, std::size_t) {
+    return XprNull();
+  }
+};
+
+
+} // namespace meta
+
+} // namespace tvmet
+
+#endif /* TVMET_META_GEMTM_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/meta/Gemtv.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,100 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemtv.h,v 1.8 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_META_GEMTV_H
+#define TVMET_META_GEMTV_H
+
+#include <tvmet/xpr/Null.h>
+
+namespace tvmet {
+
+namespace meta {
+
+
+/**
+ * \class gemtv Gemtv.h "tvmet/meta/Gemtv.h"
+ * \brief Meta class for matrix-transpose-vector operations.
+ *        using formula
+ *        \f[
+ *        M^T\,v
+ *        \f]
+ */
+template<std::size_t Rows, std::size_t Cols,
+	 std::size_t I>
+class gemtv
+{
+  gemtv();
+  gemtv(const gemtv&);
+  gemtv& operator=(const gemtv&);
+
+private:
+  enum {
+    doIt = I < (Rows-1)  		/**< recursive counter */
+  };
+
+public:
+  /** Meta template for %Matrix lhs %Vector rhs product. */
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t j) {
+    return lhs(I, j) * rhs(I)
+      + gemtv<Rows * doIt, Cols * doIt,
+              (I+1)* doIt>::prod(lhs, rhs, j);
+  }
+};
+
+
+/**
+ * \class gemtv<0,0,0> Gemtv.h "tvmet/meta/Gemtv.h"
+ * \brief gemtv Specialized for recursion
+ */
+template<>
+class gemtv<0,0,0>
+{
+  gemtv();
+  gemtv(const gemtv&);
+  gemtv& operator=(const gemtv&);
+
+public:
+  template<class E1, class E2>
+  static inline
+  XprNull prod(const E1&, const E2&, std::size_t) {
+    return XprNull();
+  }
+};
+
+
+} // namespace meta
+
+} // namespace tvmet
+
+#endif /* TVMET_META_GEMTV_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/meta/Gemv.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,100 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Gemv.h,v 1.13 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_META_GEMV_H
+#define TVMET_META_GEMV_H
+
+#include <tvmet/xpr/Null.h>
+
+namespace tvmet {
+
+namespace meta {
+
+
+/**
+ * \class gemv Gemv.h "tvmet/meta/Gemv.h"
+ * \brief Meta class for matrix-vector operations.
+ *        using formula
+ *        \f[
+ *        M\,v
+ *        \f]
+ */
+template<std::size_t Rows, std::size_t Cols,
+	 std::size_t J>
+class gemv
+{
+  gemv();
+  gemv(const gemv&);
+  gemv& operator=(const gemv&);
+
+private:
+  enum {
+    doIt = J < (Cols-1)  		/**< recursive counter */
+  };
+
+public:
+  /** Meta template for %Matrix lhs %Vector rhs product. */
+  template<class E1, class E2>
+  static inline
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type
+  prod(const E1& lhs, const E2& rhs, std::size_t i) {
+    return lhs(i, J) * rhs(J)
+      + gemv<Rows * doIt, Cols * doIt,
+             (J+1)* doIt>::prod(lhs, rhs, i);
+  }
+};
+
+
+/**
+ * \class gemv<0,0,0> Gemv.h "tvmet/meta/Gemv.h"
+ * \brief gemv Specialized for recursion
+ */
+template<>
+class gemv<0,0,0>
+{
+  gemv();
+  gemv(const gemv&);
+  gemv& operator=(const gemv&);
+
+public:
+  template<class E1, class E2>
+  static inline
+  XprNull prod(const E1&, const E2&, std::size_t) {
+    return XprNull();
+  }
+};
+
+
+} // namespace meta
+
+} // namespace tvmet
+
+#endif /* TVMET_META_GEMV_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/meta/Matrix.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,166 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Matrix.h,v 1.19 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_META_MATRIX_H
+#define TVMET_META_MATRIX_H
+
+#include <tvmet/NumericTraits.h>
+#include <tvmet/xpr/Null.h>
+
+namespace tvmet {
+
+namespace meta {
+
+
+/**
+ * \class Matrix Matrix.h "tvmet/meta/Matrix.h"
+ * \brief Meta %Matrix class using expression and meta templates.
+ */
+template<std::size_t Rows, std::size_t Cols,
+	 std::size_t M=0, std::size_t N=0>
+class Matrix
+{
+  Matrix();
+  Matrix(const Matrix&);
+  Matrix& operator=(const Matrix&);
+
+private:
+  enum {
+    doRows = (M < Rows - 1) ? 1 : 0,	/**< recursive counter Rows. */
+    doCols = (N < Cols - 1) ? 1 : 0	/**< recursive counter Cols. */
+  };
+
+public:
+  /** assign an expression on columns on given row using the functional assign_fn. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void assign2(Dest& lhs, const Src& rhs, const Assign& assign_fn) {
+    assign_fn.apply_on(lhs(M, N), rhs(M, N));
+    Matrix<Rows * doCols, Cols * doCols,
+           M * doCols, (N+1) * doCols>::assign2(lhs, rhs, assign_fn);
+  }
+
+  /** assign an expression on row-wise using the functional assign_fn. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void assign(Dest& lhs, const Src& rhs, const Assign& assign_fn) {
+    Matrix<Rows, Cols,
+           M, 0>::assign2(lhs, rhs, assign_fn);
+    Matrix<Rows * doRows, Cols * doRows,
+          (M+1) * doRows, 0>::assign(lhs, rhs, assign_fn);
+  }
+
+  /** evaluate a given matrix expression, column wise. */
+  template<class E>
+  static inline
+  bool all_elements2(const E& e) {
+    if(!e(M, N)) return false;
+    return Matrix<Rows * doCols, Cols * doCols,
+                  M * doCols, (N+1) * doCols>::all_elements2(e);
+  }
+
+  /** evaluate a given matrix expression, row wise. */
+  template<class E>
+  static inline
+  bool all_elements(const E& e) {
+    if(!Matrix<Rows, Cols, M, 0>::all_elements2(e) ) return false;
+    return Matrix<Rows * doRows, Cols * doRows,
+                 (M+1) * doRows, 0>::all_elements(e);
+  }
+
+  /** evaluate a given matrix expression, column wise. */
+  template<class E>
+  static inline
+  bool any_elements2(const E& e) {
+    if(e(M, N)) return true;
+    return Matrix<Rows * doCols, Cols * doCols,
+                  M * doCols, (N+1) * doCols>::any_elements2(e);
+  }
+
+  /** evaluate a given matrix expression, row wise. */
+  template<class E>
+  static inline
+  bool any_elements(const E& e) {
+    if(Matrix<Rows, Cols, M, 0>::any_elements2(e) ) return true;
+    return Matrix<Rows * doRows, Cols * doRows,
+                 (M+1) * doRows, 0>::any_elements(e);
+  }
+
+  /** trace a given matrix expression. */
+  template<class E>
+  static inline
+  typename E::value_type
+  trace(const E& e) {
+    return e(M, N)
+      + Matrix<Rows * doCols, Cols * doCols,
+              (M+1) * doCols, (N+1) * doCols>::trace(e);
+  }
+
+};
+
+
+/**
+ * \class Matrix<0, 0, 0, 0> Matrix.h "tvmet/meta/Matrix.h"
+ * \brief Meta %Matrix specialized for recursion.
+ */
+template<>
+class Matrix<0, 0, 0, 0>
+{
+  Matrix();
+  Matrix(const Matrix&);
+  Matrix& operator=(const Matrix&);
+
+public:
+  template<class Dest, class Src, class Assign>
+  static inline void assign2(Dest&, const Src&, const Assign&) { }
+
+  template<class Dest, class Src, class Assign>
+  static inline void assign(Dest&, const Src&, const Assign&) { }
+
+  template<class E>
+  static inline bool all_elements2(const E&) { return true; }
+
+  template<class E>
+  static inline bool all_elements(const E&) { return true; }
+
+  template<class E>
+  static inline bool any_elements2(const E&) { return false; }
+
+  template<class E>
+  static inline bool any_elements(const E&) { return false; }
+
+  template<class E>
+  static inline XprNull trace(const E&) { return XprNull(); }
+};
+
+
+} // namespace meta
+
+} // namespace tvmet
+
+#endif /* TVMET_META_MATRIX_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/meta/Vector.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,155 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Vector.h,v 1.24 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_META_VECTOR_H
+#define TVMET_META_VECTOR_H
+
+#include <tvmet/NumericTraits.h>
+#include <tvmet/xpr/Null.h>
+
+namespace tvmet {
+
+/* forwards */
+template<class T, std::size_t Sz> class Vector;
+
+
+namespace meta {
+
+
+/**
+ * \class Vector Vector.h "tvmet/meta/Vector.h"
+ * \brief Meta %Vector class using expression templates
+ */
+template<std::size_t Sz, std::size_t K=0>
+class Vector
+{
+  Vector();
+  Vector(const Vector&);
+  Vector& operator=(const Vector&);
+
+private:
+  enum {
+    doIt = (K < (Sz-1)) ? 1 : 0		/**< recursive counter */
+  };
+
+public:
+  /** assign an expression expr using the functional assign_fn. */
+  template <class Dest, class Src, class Assign>
+  static inline
+  void assign(Dest& lhs, const Src& rhs, const Assign& assign_fn) {
+    assign_fn.apply_on(lhs(K), rhs(K));
+    meta::Vector<Sz * doIt, (K+1) * doIt>::assign(lhs, rhs, assign_fn);
+  }
+
+  /** build the sum of the vector. */
+  template<class E>
+  static inline
+  typename E::value_type
+  sum(const E& e) {
+    return e(K) + meta::Vector<Sz * doIt, (K+1) * doIt>::sum(e);
+  }
+
+  /** build the product of the vector. */
+  template<class E>
+  static inline
+  typename NumericTraits<
+    typename E::value_type
+  >::sum_type
+  product(const E& e) {
+    return e(K) * meta::Vector<Sz * doIt, (K+1) * doIt>::product(e);
+  }
+
+  /** build the dot product of the vector. */
+  template<class Dest, class Src>
+  static inline
+  typename PromoteTraits<
+    typename Dest::value_type,
+    typename Src::value_type
+  >::value_type
+  dot(const Dest& lhs, const Src& rhs) {
+    return lhs(K) * rhs(K)
+      + meta::Vector<Sz * doIt, (K+1) * doIt>::dot(lhs, rhs);
+  }
+
+  /** check for all elements */
+  template<class E>
+  static inline
+  bool
+  all_elements(const E& e) {
+    if(!e(K)) return false;
+    return meta::Vector<Sz * doIt, (K+1) * doIt>::all_elements(e);
+  }
+
+  /** check for any elements */
+  template<class E>
+  static inline
+  bool
+  any_elements(const E& e) {
+    if(e(K)) return true;
+    return meta::Vector<Sz * doIt, (K+1) * doIt>::any_elements(e);
+  }
+};
+
+
+/**
+ * \class Vector<0,0> Vector.h "tvmet/meta/Vector.h"
+ * \brief Meta %Vector Specialized for recursion
+ */
+template<>
+class Vector<0,0>
+{
+  Vector();
+  Vector(const Vector&);
+  Vector& operator=(const Vector&);
+
+public:
+  template <class Dest, class Src, class Assign>
+  static inline void assign(Dest&, const Src&, const Assign&) { }
+
+  template<class E>
+  static inline XprNull sum(const E&) { return XprNull(); }
+
+  template<class E>
+  static inline XprNull product(const E&) { return XprNull(); }
+
+  template<class Dest, class Src>
+  static inline XprNull dot(const Dest&, const Src&) { return XprNull(); }
+
+  template<class E>
+  static inline bool all_elements(const E&) { return true; }
+
+  template<class E>
+  static inline bool any_elements(const E&) { return false; }
+};
+
+
+} // namespace meta
+
+} // namespace tvmet
+
+#endif /* TVMET_META_VECTOR_H */
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/tvmet.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,239 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: tvmet.h,v 1.21 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_H
+#define TVMET_H
+
+#include <tvmet/config.h>
+
+
+/***********************************************************************
+ * Compiler specifics
+ ***********************************************************************/
+#if defined(__GNUC__)
+#  include <tvmet/config/config-gcc.h>
+#endif
+
+#if defined(__ICC)
+#  include <tvmet/config/config-icc.h>
+#endif
+
+#if defined(__KCC)
+#  include <tvmet/config/config-kcc.h>
+#endif
+
+#if defined(__PGI)
+#  include <tvmet/config/config-pgi.h>
+#endif
+
+// vc7.1: 1310 and vc7.0 1300
+#if defined(_MSC_VER) && (_MSC_VER >= 1310)
+#  include <tvmet/config/config-vc71.h>
+#endif
+
+
+// give up for these cases
+#if !defined(TVMET_HAVE_MUTABLE)
+#  error "Your compiler doesn't support the mutable keyword! Giving up."
+#endif
+
+#if !defined(TVMET_HAVE_TYPENAME)
+#  error "Your compiler doesn't support the typename keyword! Giving up."
+#endif
+
+#if !defined(TVMET_HAVE_NAMESPACES)
+#  error "Your compiler doesn't support the namespace concept! Giving up."
+#endif
+
+#if !defined(TVMET_HAVE_PARTIAL_SPECIALIZATION)
+#  error "Your compiler doesn't support partial specialization! Giving up."
+#endif
+
+
+/*
+ * other compiler specific stuff
+ */
+
+/**
+ * \def TVMET_CXX_ALWAYS_INLINE
+ * \brief Compiler specific stuff to force inline code if supported.
+ *
+ * Mainly, this declares the functions using g++'s
+ * __attribute__((always_inline)). This features is enabled
+ * on defined TVMET_OPTIMIZE.
+ */
+#if !defined(TVMET_CXX_ALWAYS_INLINE)
+#define TVMET_CXX_ALWAYS_INLINE
+#endif
+
+
+/*
+ * Complexity triggers, compiler and architecture specific.
+ * If not defined, use defaults.
+ */
+
+/**
+ * \def TVMET_COMPLEXITY_DEFAULT_TRIGGER
+ * \brief Trigger for changing the matrix-product strategy.
+ */
+#if !defined(TVMET_COMPLEXITY_DEFAULT_TRIGGER)
+#  define TVMET_COMPLEXITY_DEFAULT_TRIGGER	1000
+#endif
+
+/**
+ * \def TVMET_COMPLEXITY_M_ASSIGN_TRIGGER
+ * \brief Trigger for changing the matrix assign strategy.
+ */
+#if !defined(TVMET_COMPLEXITY_M_ASSIGN_TRIGGER)
+#  define TVMET_COMPLEXITY_M_ASSIGN_TRIGGER	8*8
+#endif
+
+/**
+ * \def TVMET_COMPLEXITY_MM_TRIGGER
+ * \brief Trigger for changing the matrix-matrix-product strategy.
+ * One strategy to build the matrix-matrix-product is to use
+ * meta templates. The other to use looping.
+ */
+#if !defined(TVMET_COMPLEXITY_MM_TRIGGER)
+#  define TVMET_COMPLEXITY_MM_TRIGGER		8*8
+#endif
+
+/**
+ * \def TVMET_COMPLEXITY_V_ASSIGN_TRIGGER
+ * \brief Trigger for changing the vector assign strategy.
+ */
+#if !defined(TVMET_COMPLEXITY_V_ASSIGN_TRIGGER)
+#  define TVMET_COMPLEXITY_V_ASSIGN_TRIGGER	8
+#endif
+
+/**
+ * \def TVMET_COMPLEXITY_MV_TRIGGER
+ * \brief Trigger for changing the matrix-vector strategy.
+ * One strategy to build the matrix-vector-product is to use
+ * meta templates. The other to use looping.
+ */
+#if !defined(TVMET_COMPLEXITY_MV_TRIGGER)
+#  define TVMET_COMPLEXITY_MV_TRIGGER		8*8
+#endif
+
+
+/***********************************************************************
+ * other specials
+ ***********************************************************************/
+#if defined(TVMET_HAVE_IEEE_MATH)
+#  define _ALL_SOURCE
+#  if !defined(_XOPEN_SOURCE)
+#    define _XOPEN_SOURCE
+#  endif
+#  if !defined(_XOPEN_SOURCE_EXTENDED)
+#    define _XOPEN_SOURCE_EXTENDED
+#  endif
+#endif
+
+
+/**
+ * \def TVMET_DEBUG
+ * This is defined if <code>DEBUG</code> is defined. This enables runtime error
+ * bounds checking. If you compile %tvmet from another source directory
+ * which defines <code>DEBUG</code>, then <code>TVMET_DEBUG</code> will be
+ * <b>not</b> defined (This behavior differs from release less than 0.6.0).
+ */
+
+
+/**
+ * \def TVMET_OPTIMIZE
+ * If this is defined tvmet uses some compiler specific keywords.
+ *  Mainly, this declares the functions using gcc's
+ * <tt>__attribute__((always_inline))</tt>. This allows the
+ * compiler to produce high efficient code even on less
+ * optimization levels, like gcc's -O2 or even -O!
+ * This is known to work with gcc v3.3.3 (and higher).
+ * Using icc's v8 gnuc compatibility mode this may work, I've read
+ * that it's using as an hint, this means you can have static inline
+ * functions inside left.
+ */
+#if !defined(TVMET_OPTIMIZE)
+#  undef  TVMET_CXX_ALWAYS_INLINE
+#  define TVMET_CXX_ALWAYS_INLINE
+#endif
+
+
+/***********************************************************************
+ * Namespaces
+ ***********************************************************************/
+
+
+/**
+ * \namespace std
+ * \brief Imported ISO/IEC 14882:1998 functions from std namespace.
+ */
+
+/**
+ * \namespace tvmet
+ * \brief The namespace for the Tiny %Vector %Matrix using Expression Templates Libary.
+ */
+
+/**
+ * \namespace tvmet::meta
+ * \brief Meta stuff inside here.
+ */
+
+/**
+ * \namespace tvmet::loop
+ * \brief Loop stuff inside here.
+ */
+
+/**
+ * \namespace tvmet::element_wise
+ * \brief Operators inside this namespace does elementwise operations.
+ */
+
+/**
+ * \namespace tvmet::util
+ * \brief Miscellaneous utility functions used.
+ */
+
+
+/***********************************************************************
+ * forwards
+ ***********************************************************************/
+#if defined(TVMET_HAVE_COMPLEX)
+namespace std {
+  template<class T> class complex;
+}
+#endif
+
+
+/***********************************************************************
+ * other stuff
+ ***********************************************************************/
+#include <tvmet/TvmetBase.h>
+
+
+#endif // TVMET_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
+// LocalWords:  gnuc gcc's icc's std
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/util/General.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,126 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: General.h,v 1.13 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_UTIL_GENERAL_H
+#define TVMET_UTIL_GENERAL_H
+
+
+/** forward */
+namespace tvmet {
+template<class T, std::size_t Rows, std::size_t Cols> class Matrix;
+template<class T, std::size_t Sz> class Vector;
+}
+
+namespace tvmet {
+
+namespace util {
+
+/*
+ * \defgroup _util_function
+ * \brief Usefull utility functions
+ */
+
+/**
+ * \fn Gemm(const Matrix<T, Rows, Cols>& m1, const Matrix<T, Rows, Cols>& m2, Matrix<T, Rows, Cols>& m3)
+ * \brief General matrix matrix multiplication using loops.
+ * \ingroup _util_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+void
+Gemm(const Matrix<T, Rows, Cols>& m1, const Matrix<T, Rows, Cols>& m2,
+     Matrix<T, Rows, Cols>& m3)
+{
+  for (std::size_t i = 0; i < Rows; ++i) {
+    for (std::size_t j = 0; j < Cols; ++j) {
+      T sum(0);
+      for (std::size_t k = 0; k < Cols; ++k) {
+	sum += m1(i,k) * m2(k,j);
+      }
+      m3(i,j) = sum;
+    }
+  }
+}
+
+
+/**
+ * \fn Gemv(const Matrix<T, Rows, Cols>& m, const Vector<T, Cols>& v, Vector<T, Cols>& v2)
+ * \brief General matrix vector multiplication using loops.
+ * \ingroup _util_function
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+inline
+void
+Gemv(const Matrix<T, Rows, Cols>& m, const Vector<T, Cols>& v,
+     Vector<T, Cols>& v2)
+{
+  for (std::size_t i = 0; i < Rows; ++i){
+    v2(i) = T(0);	// clean up before use
+    for (std::size_t j = 0; j < Cols; ++j) {
+      v2(i) += m(i,j) * v(j);
+      }
+  }
+}
+
+
+/**
+ * \fn Gevvmul(const Vector<T, Sz>& v1, const Vector<T, Sz>& v2, Vector<T, Sz>& v3)
+ * \brief General vector vector elementwise multiplication using loop.
+ * \ingroup _util_function
+ */
+template<class T, std::size_t Sz>
+inline
+void
+Gevvmul(const Vector<T, Sz>& v1, const Vector<T, Sz>& v2,
+       Vector<T, Sz>& v3)
+{
+  for(std::size_t i = 0; i < Sz; ++i)
+    v3(i) = v1(i) * v2(i);
+}
+
+
+/**
+ * \fn Gevvadd(const Vector<T, Sz>& v1, const Vector<T, Sz>& v2, Vector<T, Sz>& v3)
+ * \brief General vector vector elementwise multiplication using loop.
+ * \ingroup _util_function
+ */
+template<class T, std::size_t Sz>
+inline
+void
+Gevvadd(const Vector<T, Sz>& v1, const Vector<T, Sz>& v2,
+	Vector<T, Sz>& v3)
+{
+  for(std::size_t i = 0; i < Sz; ++i)
+    v3(i) = v1(i) + v2(i);
+}
+
+} // namespace util
+
+} // namespace tvmet
+
+#endif // TVMET_UTIL_GENERAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/util/Incrementor.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,91 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Incrementor.h,v 1.7 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_UTIL_INCREMENTOR_H
+#define TVMET_UTIL_INCREMENTOR_H
+
+namespace tvmet {
+
+namespace util {
+
+
+/**
+ * \class Incrementor Incrementor.h "tvmet/util/Incrementor.h"
+ * \brief A simple incrementor class.
+ * The start value is given at construction time. After
+ * each access the class increments the internal counter.
+ * \ingroup _util_function
+ *
+ * \par Example:
+ * \code
+ * #include <algorithm>
+ *
+ * using namespace tvmet;
+ *
+ * ...
+ *
+ * std::generate(m1.begin(), m1.end(),
+ * util::Incrementor<typename matrix_type::value_type>());
+ * \endcode
+ */
+template<class T>
+struct Incrementor
+{
+  Incrementor(T start=0) : m_inc(start) { }
+  T operator()() { m_inc+=1; return m_inc; }
+
+private:
+  T 							m_inc;
+};
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/**
+ * \class Incrementor< std::complex<T> > Incrementor.h "tvmet/util/Incrementor.h"
+ * \brief Specialized Incrementor class.
+ * \ingroup _util_function
+ */
+template<class T>
+struct Incrementor< std::complex<T> > {
+  Incrementor(const std::complex<T>& start=0)
+    : m_inc(start) { }
+  std::complex<T> operator()() {
+    m_inc += std::complex<T>(1,1);
+    return m_inc;
+  }
+private:
+  std::complex<T>       				m_inc;
+};
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace util
+
+} // namespace tvmet
+
+#endif // TVMET_UTIL_INCREMENTOR_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/util/Random.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,101 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Random.h,v 1.7 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_UTIL_RANDOM_H
+#define TVMET_UTIL_RANDOM_H
+
+#include <tvmet/CompileTimeError.h>
+
+namespace tvmet {
+
+namespace util {
+
+
+/**
+ * \class Random Random.h "tvmet/util/Random.h"
+ * \brief A simple random class.
+ * On each access this class returns a new random number using
+ * std::rand(). The range generated is templated by MIN and
+ * MAX.
+ * \ingroup _util_function
+ *
+ * \par Example:
+ * \code
+ * #include <algorithm>
+ *
+ * tvmet::Random<int, 0, 100>				random;
+ *
+ * std::generate(m1.begin(), m1.end(), random());
+ * \endcode
+ */
+template<class T, int MIN=0, int MAX=100>
+class Random {
+  static unsigned int				s_seed;
+public:
+  typedef T					value_type;
+  Random() { TVMET_CT_CONDITION(MIN<MAX, wrong_random_range) }
+  value_type operator()() {
+    s_seed += (unsigned)std::time(0);
+    std::srand(s_seed);
+    return MIN + int(double(MAX) * std::rand()/(double(RAND_MAX)+1.0));
+  }
+};
+// instance
+template<class T, int MIN, int MAX>
+unsigned int Random<T, MIN, MAX>::s_seed;
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/**
+ * \class Random< std::complex<T> > Random.h "tvmet/util/Random.h"
+ * \brief Specialized Random class.
+ * \ingroup _util_function
+ */
+template<class T, int MIN=0, int MAX=100>
+class Random {
+  static unsigned int				s_seed;
+public:
+  typedef std::complex<T>			value_type;
+  Random() { TVMET_CT_CONDITION(MIN<MAX, wrong_random_range) }
+  value_type operator()() {
+    s_seed += (unsigned)std::time(0);
+    std::srand(s_seed);
+    return MIN + int(double(MAX) * std::rand()/(double(RAND_MAX)+1.0));
+  }
+};
+// instance
+template<class T, int MIN, int MAX>
+unsigned int Random<std::complex<T>, MIN, MAX>::s_seed;
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace util
+
+} // namespace tvmet
+
+#endif // TVMET_UTIL_RANDOM_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/util/Timer.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,98 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Timer.h,v 1.9 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_UTIL_TIMER_H
+#define TVMET_UTIL_TIMER_H
+
+#if defined(TVMET_HAVE_SYS_TIME_H) && defined(TVMET_HAVE_UNISTD_H)
+#  include <sys/time.h>
+#  include <sys/resource.h>
+#  include <unistd.h>
+#else
+#  include <ctime>
+#endif
+
+namespace tvmet {
+
+namespace util {
+
+/**
+   \class Timer Timer.h "tvmet/util/Timer.h"
+   \brief A quick& dirty portable timer, measures elapsed time.
+
+   It is recommended that implementations measure wall clock rather than CPU
+   time since the intended use is performance measurement on systems where
+   total elapsed time is more important than just process or CPU time.
+
+   The accuracy of timings depends on the accuracy of timing information
+   provided by the underlying platform, and this varies from platform to
+   platform.
+*/
+
+class Timer
+{
+  Timer(const Timer&);
+  Timer& operator=(const Timer&);
+
+public: // types
+  typedef double					time_t;
+
+public:
+  /** starts the timer immediatly. */
+  Timer() { m_start_time = getTime(); }
+
+  /** restarts the timer */
+  void restart() { m_start_time = getTime(); }
+
+  /** return elapsed time in seconds */
+  time_t elapsed() const { return (getTime() - m_start_time); }
+
+private:
+  time_t getTime() const {
+#if defined(TVMET_HAVE_SYS_TIME_H) && defined(TVMET_HAVE_UNISTD_H)
+    getrusage(RUSAGE_SELF, &m_rusage);
+    time_t sec = m_rusage.ru_utime.tv_sec; // user, no system time
+    time_t usec  = m_rusage.ru_utime.tv_usec; // user, no system time
+    return sec + usec/1e6;
+#else
+    return static_cast<time_t>(std::clock()) / static_cast<time_t>(CLOCKS_PER_SEC);
+#endif
+  }
+
+private:
+#if defined(TVMET_HAVE_SYS_TIME_H) && defined(TVMET_HAVE_UNISTD_H)
+  mutable struct rusage 				m_rusage;
+#endif
+  time_t 						m_start_time;
+};
+
+} // namespace util
+
+} // namespace tvmet
+
+#endif // TVMET_UTIL_TIMER_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/BinOperator.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,105 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: BinOperator.h,v 1.19 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_BINOPERATOR_H
+#define TVMET_XPR_BINOPERATOR_H
+
+#include <tvmet/TypePromotion.h>
+
+namespace tvmet {
+
+
+/**
+ * \class XprBinOp BinOperator.h "tvmet/xpr/BinOperator.h"
+ * \brief Binary operators working on two sub expressions.
+ *
+ * On acessing using the index operator() the binary operation will be
+ * evaluated at compile time.
+ */
+template<class BinOp, class E1, class E2>
+class XprBinOp
+  : public TvmetBase< XprBinOp<BinOp, E1, E2> >
+{
+  XprBinOp();
+  XprBinOp& operator=(const XprBinOp&);
+
+public:
+  typedef typename BinOp::value_type			value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_lhs   = E1::ops,
+    ops_rhs   = E2::ops,
+    ops       = 2 * (ops_lhs + ops_rhs) // lhs op rhs
+  };
+
+public:
+  /** Constructor for two expressions. */
+  explicit XprBinOp(const E1& lhs, const E2& rhs)
+    : m_lhs(lhs), m_rhs(rhs)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprBinOp(const XprBinOp& e)
+    : m_lhs(e.m_lhs), m_rhs(e.m_rhs)
+  { }
+#endif
+
+  /** Index operator, evaluates the expression inside. */
+  value_type operator()(std::size_t i) const {
+    return BinOp::apply_on(m_lhs(i), m_rhs(i));
+  }
+
+  /** Index operator for arrays/matrices */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    return BinOp::apply_on(m_lhs(i, j), m_rhs(i, j));
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprBinOp[O="<< ops << ", (O1=" << ops_lhs << ", O2=" << ops_rhs << ")]<"
+       << std::endl;
+    BinOp::print_xpr(os, l);
+    m_lhs.print_xpr(os, l);
+    m_rhs.print_xpr(os, l);
+    os << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E1						m_lhs;
+  const E2						m_rhs;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_BINOPERATOR_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/Eval.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,116 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Eval.h,v 1.13 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_EVAL_H
+#define TVMET_XPR_EVAL_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprEval Eval.h "tvmet/xpr/Eval.h"
+ * \brief evaluate the expression
+ *
+ * Since we can't overwrite the ? operator we have to write a wrapper
+ * for expression like return v1>v2 ? true : false
+ */
+template<class E1, class E2, class E3>
+class XprEval
+  : public TvmetBase< XprEval<E1, E2, E3> >
+{
+public:
+  typedef E1 						expr1_type;
+  typedef E2 						expr2_type;
+  typedef E3 						expr3_type;
+
+  typedef typename expr2_type::value_type 		value2_type;
+  typedef typename expr3_type::value_type 		value3_type;
+
+  typedef typename
+  PromoteTraits<value2_type, value3_type>::value_type 	value_type;
+
+public:
+  /** Complexity Counter */
+  enum {
+    ops_expr1 = E1::ops,
+    ops_expr2 = E2::ops,
+    ops_expr3 = E3::ops,
+    ops = ops_expr1	// only (e1 op e2) are evaluated
+  };
+
+private:
+  XprEval();
+  XprEval& operator=(const XprEval<expr1_type, expr2_type, expr3_type>&);
+
+public:
+  /** Constructor */
+  explicit XprEval(const expr1_type& e1, const expr2_type& e2, const expr3_type& e3)
+    : m_expr1(e1), m_expr2(e2), m_expr3(e3)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprEval(const XprEval& rhs)
+    : m_expr1(rhs.m_expr1), m_expr2(rhs.m_expr2), m_expr3(rhs.m_expr3)
+  { }
+#endif
+
+public: //access
+  /** index operator for vectors. */
+  value_type operator()(std::size_t i) const {
+    return m_expr1(i) ? m_expr2(i) : m_expr3(i);
+  }
+
+  /** index operator for matrizes. */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    return m_expr1(i, j) ? m_expr2(i, j) : m_expr3(i, j);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprEval[" << ops << ", ("
+       << ops_expr1 << ", " << ops_expr2 << ", " << ops_expr3 << ")]<"
+       << std::endl;
+    m_expr1.print_xpr(os, l);
+    m_expr2.print_xpr(os, l);
+    m_expr3.print_xpr(os, l);
+    os << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const expr1_type					m_expr1;
+  const expr2_type					m_expr2;
+  const expr3_type					m_expr3;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_EVAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/Identity.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,68 @@
+/*
+ * $Id: Identity.h,v 1.4 2006-11-21 18:43:09 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_IDENTITY_H
+#define TVMET_XPR_IDENTITY_H
+
+
+namespace tvmet {
+
+
+/**
+ * \class XprIdentity Identity.h "tvmet/xpr/Identity.h"
+ * \brief Expression for the identity matrix.
+ *
+ * This expression doesn't hold any other expression, it
+ * simply returns 1 or 0 depends where the row and column
+ * element excess is done.
+ *
+ * \since release 1.6.0
+ * \sa identity
+ */
+template<class T, std::size_t Rows, std::size_t Cols>
+struct XprIdentity
+  : public TvmetBase< XprIdentity<T, Rows, Cols> >
+{
+  XprIdentity& operator=(const XprIdentity&);
+
+public:
+  typedef T				value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_assign = Rows * Cols,
+    ops        = ops_assign
+  };
+
+public:
+  /** access by index. */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    return i==j ? 1 : 0;
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprIdentity[O="<< ops << ")]<"
+       << std::endl;
+    os << IndentLevel(l)
+       << typeid(T).name() << ","
+       << "R=" << Rows << ", C=" << Cols << std::endl;
+    os << IndentLevel(--l) << ">"
+       << ((l != 0) ? "," : "") << std::endl;
+  }
+};
+
+
+} // namespace tvmet
+
+
+#endif // TVMET_XPR_IDENTITY_H
+
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/Literal.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,90 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Literal.h,v 1.13 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_LITERAL_H
+#define TVMET_XPR_LITERAL_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprLiteral Literal.h "tvmet/xpr/Literal.h"
+ * \brief Specify literals like scalars into the expression.
+ *        This expression is used for vectors and matrices - the
+ *        decision is done by the access operator.
+ */
+template<class T>
+class XprLiteral
+  : public TvmetBase< XprLiteral<T> >
+{
+  XprLiteral();
+  XprLiteral& operator=(const XprLiteral&);
+
+public:
+  typedef T						value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops       = 1
+  };
+
+public:
+  /** Constructor by value for literals . */
+  explicit XprLiteral(value_type value)
+    : m_data(value)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprLiteral(const XprLiteral& e)
+    : m_data(e.m_data)
+  { }
+#endif
+
+  /** Index operator, gives the value for vectors. */
+  value_type operator()(std::size_t) const { return m_data; }
+
+  /** Index operator for arrays/matrices. */
+  value_type operator()(std::size_t, std::size_t) const { return m_data; }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++) << "XprLiteral[O=" << ops << "]<T="
+       << typeid(value_type).name()
+       << ">," << std::endl;
+  }
+
+private:
+  const value_type 					m_data;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_LITERAL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MMProduct.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,135 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MMProduct.h,v 1.24 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MMPRODUCT_H
+#define TVMET_XPR_MMPRODUCT_H
+
+#include <tvmet/meta/Gemm.h>
+#include <tvmet/loop/Gemm.h>
+
+namespace tvmet {
+
+
+/**
+ * \class XprMMProduct MMProduct.h "tvmet/xpr/MMProduct.h"
+ * \brief Expression for matrix-matrix product.
+ *        Using formula:
+ *        \f[
+ *        M_1\,M_2
+ *        \f]
+ * \note The Rows2 has to be  equal to Cols1.
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+class XprMMProduct
+  : public TvmetBase< XprMMProduct<E1, Rows1, Cols1, E2, Cols2> >
+{
+private:
+  XprMMProduct();
+  XprMMProduct& operator=(const XprMMProduct&);
+
+public:
+  typedef typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type							value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_lhs   = E1::ops,
+    ops_rhs   = E2::ops,
+    M         = Rows1 * Cols1 * Cols2,
+    N         = Rows1 * (Cols1 - 1) * Cols2,
+    ops_plus  = M * NumericTraits<value_type>::ops_plus,
+    ops_muls  = N * NumericTraits<value_type>::ops_muls,
+    ops       = ops_plus + ops_muls,
+    use_meta  = Rows1*Cols2 < TVMET_COMPLEXITY_MM_TRIGGER ? true : false
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMMProduct(const E1& lhs, const E2& rhs)
+    : m_lhs(lhs), m_rhs(rhs)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMMProduct(const XprMMProduct& e)
+    : m_lhs(e.m_lhs), m_rhs(e.m_rhs)
+  { }
+#endif
+
+private:
+  /** Wrapper for meta gemm. */
+  static inline
+  value_type do_gemm(dispatch<true>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return meta::gemm<Rows1, Cols1,
+                      Cols2,
+                      0>::prod(lhs, rhs, i, j);
+  }
+
+  /** Wrapper for loop gemm. */
+  static inline
+  value_type do_gemm(dispatch<false>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return loop::gemm<Rows1, Cols1, Cols2>::prod(lhs, rhs, i, j);
+  }
+
+public:
+  /** index operator for arrays/matrices */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    TVMET_RT_CONDITION((i < Rows1) && (j < Cols2), "XprMMProduct Bounce Violation")
+    return do_gemm(dispatch<use_meta>(), m_lhs, m_rhs, i, j);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMMProduct["
+       << (use_meta ? "M" :  "L") << ", O=" << ops
+       << ", (O1=" << ops_lhs << ", O2=" << ops_rhs << ")]<"
+       << std::endl;
+    m_lhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R1=" << Rows1 << ", C1=" << Cols1 << ",\n";
+    m_rhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "C2=" << Cols2 << ",\n";
+    os << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E1		 				m_lhs;
+  const E2		 				m_rhs;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MMPRODUCT_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MMProductTransposed.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,137 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MMProductTransposed.h,v 1.20 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MMPRODUCT_TRANSPOSED_H
+#define TVMET_XPR_MMPRODUCT_TRANSPOSED_H
+
+#include <tvmet/meta/Gemm.h>
+#include <tvmet/loop/Gemm.h>
+
+namespace tvmet {
+
+
+/**
+ * \class XprMMProductTransposed MMProductTransposed.h "tvmet/xpr/MMProductTransposed.h"
+ * \brief Expression for transpose(matrix-matrix product).
+ *        Using formula:
+ *        \f[
+ *        (M_1\,M_2)^T
+ *        \f]
+ * \note The Rows2 has to be  equal to Cols1.
+ *       The result is a (Cols2 x Rows1) matrix.
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+class XprMMProductTransposed
+  : public TvmetBase< XprMMProductTransposed<E1, Rows1, Cols1, E2, Cols2> >
+{
+private:
+  XprMMProductTransposed();
+  XprMMProductTransposed& operator=(const XprMMProductTransposed&);
+
+public:
+  typedef typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type							value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_lhs   = E1::ops,
+    ops_rhs   = E2::ops,
+    M = Rows1 * Cols1 * Cols2,
+    N = Rows1 * (Cols1-1) * Cols2,
+    ops_plus  = M * NumericTraits<value_type>::ops_plus,
+    ops_muls  = N * NumericTraits<value_type>::ops_muls,
+    ops       = ops_plus + ops_muls,
+    use_meta  = Cols2*Rows1 < TVMET_COMPLEXITY_MM_TRIGGER ? true : false
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMMProductTransposed(const E1& lhs, const E2& rhs)
+    : m_lhs(lhs), m_rhs(rhs) { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMMProductTransposed(const XprMMProductTransposed& e)
+    : m_lhs(e.m_lhs), m_rhs(e.m_rhs)
+  { }
+#endif
+
+private:
+  /** Wrapper for meta gemm. */
+  static inline
+  value_type do_gemm(dispatch<true>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return meta::gemm<Rows1, Cols1,
+                      Cols2,
+                      0>::prod(lhs, rhs, i, j);
+  }
+
+  /** Wrapper for loop gemm. */
+  static inline
+  value_type do_gemm(dispatch<false>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return loop::gemm<Rows1, Cols1, Cols2>::prod(lhs, rhs, i, j);
+  }
+
+public:
+  /** index operator for arrays/matrices */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    TVMET_RT_CONDITION((i < Cols2) && (j < Rows1), "XprMMProductTransposed Bounce Violation")
+    return do_gemm(dispatch<use_meta>(), m_lhs, m_rhs, j, i);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMMProductTransposed["
+       << (use_meta ? "M" :  "L") << ", O=" << ops
+       << ", (O1=" << ops_lhs << ", O2=" << ops_rhs << ")]<"
+       << std::endl;
+    m_lhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R1=" << Rows1 << ", C1=" << Cols1 << ",\n";
+    m_rhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "C2=" << Cols2 << ",\n"
+       << IndentLevel(l)
+       << "\n"
+       << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E1		 				m_lhs;
+  const E2						m_rhs;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MMPRODUCT_TRANSPOSED_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MMtProduct.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,138 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MMtProduct.h,v 1.20 2007-06-23 15:58:59 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MMTPRODUCT_H
+#define TVMET_XPR_MMTPRODUCT_H
+
+#include <tvmet/meta/Gemmt.h>
+#include <tvmet/loop/Gemmt.h>
+
+namespace tvmet {
+
+
+/**
+ * \class XprMMtProduct MMtProduct.h "tvmet/xpr/MMtProduct.h"
+ * \brief Expression for matrix-matrix product.
+ *        Using formula:
+ *        \f[
+ *        M_1\,M_2^T
+ *        \f]
+ * \note The number of cols of rhs matrix have to be equal to cols of rhs matrix.
+ *       The result is a (Rows1 x Rows2) matrix.
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+class XprMMtProduct
+  : public TvmetBase< XprMMtProduct<E1, Rows1, Cols1, E2, Cols2> >
+{
+private:
+  XprMMtProduct();
+  XprMMtProduct& operator=(const XprMMtProduct&);
+
+public:
+  typedef typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type							value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_lhs   = E1::ops,
+    ops_rhs   = E2::ops,
+    Rows2 = Cols1,
+    M = Rows1 * Cols1 * Rows1,
+    N = Rows1 * (Cols1 - 1) * Rows2,
+    ops_plus  = M * NumericTraits<value_type>::ops_plus,
+    ops_muls  = N * NumericTraits<value_type>::ops_muls,
+    ops       = ops_plus + ops_muls,
+    use_meta  = Rows1*Rows2 < TVMET_COMPLEXITY_MM_TRIGGER ? true : false
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMMtProduct(const E1& lhs, const E2& rhs)
+    : m_lhs(lhs), m_rhs(rhs)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMMtProduct(const XprMMtProduct& e)
+    : m_lhs(e.m_lhs), m_rhs(e.m_rhs)
+  { }
+#endif
+
+private:
+  /** Wrapper for meta gemm. */
+  static inline
+  value_type do_gemmt(dispatch<true>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return meta::gemmt<Rows1, Cols1,
+                       Cols2,
+                       0>::prod(lhs, rhs, i, j);
+  }
+
+  /** Wrapper for loop gemm. */
+  static inline
+  value_type do_gemmt(dispatch<false>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return loop::gemmt<Rows1, Cols1, Cols1>::prod(lhs, rhs, i, j);
+  }
+
+public:
+  /** index operator for arrays/matrices */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    TVMET_RT_CONDITION((i < Rows1) && (j < Rows2), "XprMMtProduct Bounce Violation")
+    return do_gemmt(dispatch<use_meta>(), m_lhs, m_rhs, i, j);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMMtProduct["
+       << (use_meta ? "M" :  "L") << ", O=" << ops
+       << ", (O1=" << ops_lhs << ", O2=" << ops_rhs << ")]<"
+       << std::endl;
+    m_lhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R1=" << Rows1 << ", C1=" << Cols1 << ",\n";
+    m_rhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "C2=" << Cols2 << ",\n"
+       << "\n"
+       << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E1		 				m_lhs;
+  const E2 						m_rhs;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MMTPRODUCT_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MVProduct.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,131 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MVProduct.h,v 1.21 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MVPRODUCT_H
+#define TVMET_XPR_MVPRODUCT_H
+
+#include <tvmet/meta/Gemv.h>
+#include <tvmet/loop/Gemv.h>
+
+namespace tvmet {
+
+
+/**
+ * \class XprMVProduct MVProduct.h "tvmet/xpr/MVProduct.h"
+ * \brief Expression for matrix-vector product
+ *        using formula
+ *        \f[
+ *        M\,v
+ *        \f]
+ */
+template<class E1, std::size_t Rows, std::size_t Cols,
+	 class E2>
+class XprMVProduct
+  : public TvmetBase< XprMVProduct<E1, Rows, Cols, E2> >
+{
+  XprMVProduct();
+  XprMVProduct& operator=(const XprMVProduct&);
+
+public:
+  typedef typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type							value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_lhs   = E1::ops,
+    ops_rhs   = E2::ops,
+    M         = Rows * Cols,
+    N         = Rows * (Cols - 1),
+    ops_plus  = M * NumericTraits<value_type>::ops_plus,
+    ops_muls  = N * NumericTraits<value_type>::ops_muls,
+    ops       = ops_plus + ops_muls,
+    use_meta  = Rows*Cols < TVMET_COMPLEXITY_MV_TRIGGER ? true : false
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMVProduct(const E1& lhs, const E2& rhs)
+    : m_lhs(lhs), m_rhs(rhs)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMVProduct(const XprMVProduct& e)
+    : m_lhs(e.m_lhs), m_rhs(e.m_rhs)
+  { }
+#endif
+
+private:
+  /** Wrapper for meta gemm. */
+  static inline
+  value_type do_gemv(dispatch<true>, const E1& lhs, const E2& rhs, std::size_t j) {
+    return meta::gemv<Rows, Cols,
+                      0>::prod(lhs, rhs, j);
+  }
+
+  /** Wrapper for loop gemm. */
+  static inline
+  value_type do_gemv(dispatch<false>, const E1& lhs, const E2& rhs, std::size_t j) {
+    return loop::gemv<Rows, Cols>::prod(lhs, rhs, j);
+  }
+
+public:
+  /** index operator, returns the expression by index. This is the vector
+      style since a matrix*vector gives a vector. */
+  value_type operator()(std::size_t j) const {
+    TVMET_RT_CONDITION(j < Rows , "XprMVProduct Bounce Violation")
+    return do_gemv(dispatch<use_meta>(), m_lhs, m_rhs, j);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMVProduct["
+       << (use_meta ? "M" :  "L") << ", O=" << ops
+       << ", (O1=" << ops_lhs << ", O2=" << ops_rhs << ")]<"
+       << std::endl;
+    m_lhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R=" << Rows << ", C=" << Cols << ",\n";
+    m_rhs.print_xpr(os, l);
+    os << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E1							m_lhs;
+  const E2							m_rhs;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MVPRODUCT_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/Matrix.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,165 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Matrix.h,v 1.26 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_H
+#define TVMET_XPR_MATRIX_H
+
+#include <tvmet/meta/Matrix.h>
+#include <tvmet/loop/Matrix.h>
+
+namespace tvmet {
+
+
+/* forwards */
+template <class T, std::size_t Rows, std::size_t Cols> class Matrix;
+
+/**
+ * \class XprMatrix Matrix.h "tvmet/xpr/Matrix.h"
+ * \brief Represents the expression for vectors at any node in the parse tree.
+ *
+ * Specifically, XprMatrix is the class that wraps the expression, and the
+ * expression itself is represented by the template parameter E. The
+ * class XprMatrix is known as an anonymizing expression wrapper because
+ * it can hold any subexpression of arbitrary complexity, allowing
+ * clients to work with any expression by holding on to it via the
+ * wrapper, without having to know the name of the type object that
+ * actually implements the expression.
+ * \note leave the CCtors non-explicit to allow implicit type conversation.
+ */
+template<class E, std::size_t NRows, std::size_t NCols>
+class XprMatrix
+  : public TvmetBase< XprMatrix<E, NRows, NCols> >
+{
+  XprMatrix();
+  XprMatrix& operator=(const XprMatrix&);
+
+public:
+  /** Dimensions. */
+  enum {
+    Rows = NRows,			/**< Number of rows. */
+    Cols = NCols,			/**< Number of cols. */
+    Size = Rows * Cols			/**< Complete Size of Matrix. */
+  };
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_assign = Rows * Cols,
+    ops        = E::ops,
+    use_meta   = ops_assign < TVMET_COMPLEXITY_M_ASSIGN_TRIGGER ? true : false
+  };
+
+public:
+  typedef typename E::value_type			value_type;
+
+public:
+  /** Constructor. */
+  explicit XprMatrix(const E& e)
+    : m_expr(e)
+  { }
+
+ /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMatrix(const XprMatrix& rhs)
+    : m_expr(rhs.m_expr)
+  { }
+#endif
+
+  /** access by index. */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    TVMET_RT_CONDITION((i < Rows) && (j < Cols), "XprMatrix Bounce Violation")
+    return m_expr(i, j);
+  }
+
+private:
+  /** Wrapper for meta assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<true>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    meta::Matrix<Rows, Cols, 0, 0>::assign(dest, src, assign_fn);
+  }
+
+  /** Wrapper for loop assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<false>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    loop::Matrix<Rows, Cols>::assign(dest, src, assign_fn);
+  }
+
+public:
+  /** assign this expression to Matrix dest. */
+  template<class Dest, class Assign>
+  void assign_to(Dest& dest, const Assign& assign_fn) const {
+    /* here is a way for caching, since each complex 'Node'
+       is of type XprMatrix. */
+    do_assign(dispatch<use_meta>(), dest, *this, assign_fn);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMatrix["
+       << (use_meta ? "M" :  "L") << ", O=" << ops << "]<"
+       << std::endl;
+    m_expr.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R=" << Rows << ", C=" << Cols << std::endl;
+    os << IndentLevel(--l) << ">"
+       << ((l != 0) ? "," : "") << std::endl;
+  }
+
+private:
+  const E						m_expr;
+};
+
+
+} // namespace tvmet
+
+#include <tvmet/Functional.h>
+
+#include <tvmet/xpr/BinOperator.h>
+#include <tvmet/xpr/UnOperator.h>
+#include <tvmet/xpr/Literal.h>
+
+#include <tvmet/xpr/Identity.h>
+
+#include <tvmet/xpr/MMProduct.h>
+#include <tvmet/xpr/MMProductTransposed.h>
+#include <tvmet/xpr/MMtProduct.h>
+#include <tvmet/xpr/MtMProduct.h>
+#include <tvmet/xpr/MVProduct.h>
+#include <tvmet/xpr/MtVProduct.h>
+#include <tvmet/xpr/MatrixTranspose.h>
+
+#include <tvmet/xpr/MatrixFunctions.h>
+#include <tvmet/xpr/MatrixBinaryFunctions.h>
+#include <tvmet/xpr/MatrixUnaryFunctions.h>
+#include <tvmet/xpr/MatrixOperators.h>
+#include <tvmet/xpr/Eval.h>
+
+#endif // TVMET_XPR_MATRIX_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixBinaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,318 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixBinaryFunctions.h,v 1.12 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_BINARY_FUNCTIONS_H
+#define TVMET_XPR_MATRIX_BINARY_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+/*
+ * binary_function(XprMatrix<E1, Rows, Cols>, XprMatrix<E2, Rows, Cols>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class E1, std::size_t Rows, std::size_t Cols, class E2>	\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprMatrix<E1, Rows, Cols>,						\
+    XprMatrix<E2, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const XprMatrix<E1, Rows, Cols>& lhs, 				\
+     const XprMatrix<E2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2)
+TVMET_DECLARE_MACRO(drem)
+TVMET_DECLARE_MACRO(fmod)
+TVMET_DECLARE_MACRO(hypot)
+TVMET_DECLARE_MACRO(jn)
+TVMET_DECLARE_MACRO(yn)
+TVMET_DECLARE_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+  //TVMET_DECLARE_MACRO(polar)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * binary_function(XprMatrix<E, Rows, Cols>, POD)
+ */
+#define TVMET_DECLARE_MACRO(NAME, TP)			\
+template<class E, std::size_t Rows, std::size_t Cols>	\
+XprMatrix<						\
+  XprBinOp<						\
+    Fcnl_##NAME<typename E::value_type, TP >,		\
+    XprMatrix<E, Rows, Cols>,				\
+    XprLiteral< TP >					\
+  >,							\
+  Rows, Cols						\
+>							\
+NAME(const XprMatrix<E, Rows, Cols>& lhs, 		\
+     TP rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2, int)
+TVMET_DECLARE_MACRO(drem, int)
+TVMET_DECLARE_MACRO(fmod, int)
+TVMET_DECLARE_MACRO(hypot, int)
+TVMET_DECLARE_MACRO(jn, int)
+TVMET_DECLARE_MACRO(yn, int)
+TVMET_DECLARE_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(atan2, long long int)
+TVMET_DECLARE_MACRO(drem, long long int)
+TVMET_DECLARE_MACRO(fmod, long long int)
+TVMET_DECLARE_MACRO(hypot, long long int)
+TVMET_DECLARE_MACRO(jn, long long int)
+TVMET_DECLARE_MACRO(yn,long long int)
+TVMET_DECLARE_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_DECLARE_MACRO(atan2, float)
+TVMET_DECLARE_MACRO(drem, float)
+TVMET_DECLARE_MACRO(fmod, float)
+TVMET_DECLARE_MACRO(hypot, float)
+TVMET_DECLARE_MACRO(jn, float)
+TVMET_DECLARE_MACRO(yn, float)
+TVMET_DECLARE_MACRO(pow, float)
+
+TVMET_DECLARE_MACRO(atan2, double)
+TVMET_DECLARE_MACRO(drem, double)
+TVMET_DECLARE_MACRO(fmod, double)
+TVMET_DECLARE_MACRO(hypot,double)
+TVMET_DECLARE_MACRO(jn, double)
+TVMET_DECLARE_MACRO(yn, double)
+TVMET_DECLARE_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(atan2, long double)
+TVMET_DECLARE_MACRO(drem, long double)
+TVMET_DECLARE_MACRO(fmod, long double)
+TVMET_DECLARE_MACRO(hypot, long double)
+TVMET_DECLARE_MACRO(jn, long double)
+TVMET_DECLARE_MACRO(yn, long double)
+TVMET_DECLARE_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * binary_function(XprMatrix<E, Rows, Cols>, std::complex<>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)				\
+template<class E, std::size_t Rows, std::size_t Cols, class T>	\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,	\
+    XprMatrix<E, Rows, Cols>,					\
+    XprLiteral< std::complex<T> >				\
+  >,								\
+  Rows, Cols							\
+>								\
+NAME(const XprMatrix<E, Rows, Cols>& lhs, 			\
+     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(pow)
+
+TVMET_DECLARE_MACRO(atan2)
+TVMET_DECLARE_MACRO(drem)
+TVMET_DECLARE_MACRO(fmod)
+TVMET_DECLARE_MACRO(hypot)
+TVMET_DECLARE_MACRO(jn)
+TVMET_DECLARE_MACRO(yn)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*
+ * binary_function(XprMatrix<E1, Rows, Cols>, XprMatrix<E2, Rows, Cols>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)							\
+template<class E1, std::size_t Rows, std::size_t Cols, class E2>			\
+inline											\
+XprMatrix<										\
+  XprBinOp<										\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,			\
+    XprMatrix<E1, Rows, Cols>,								\
+    XprMatrix<E2, Rows, Cols>								\
+  >,											\
+  Rows, Cols										\
+>											\
+NAME(const XprMatrix<E1, Rows, Cols>& lhs, const XprMatrix<E2, Rows, Cols>& rhs) {	\
+  typedef XprBinOp<									\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,			\
+    XprMatrix<E1, Rows, Cols>,								\
+    XprMatrix<E2, Rows, Cols>								\
+  >		    					expr_type;			\
+  return XprMatrix<expr_type, Rows, Cols>(						\
+    expr_type(lhs, rhs));								\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2)
+TVMET_IMPLEMENT_MACRO(drem)
+TVMET_IMPLEMENT_MACRO(fmod)
+TVMET_IMPLEMENT_MACRO(hypot)
+TVMET_IMPLEMENT_MACRO(jn)
+TVMET_IMPLEMENT_MACRO(yn)
+TVMET_IMPLEMENT_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+  //TVMET_IMPLEMENT_MACRO(polar)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * binary_function(XprMatrix<E, Rows, Cols>, POD)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, TP)					\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< TP >							\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const XprMatrix<E, Rows, Cols>& lhs, TP rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< TP >							\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs, XprLiteral< TP >(rhs)));				\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2, int)
+TVMET_IMPLEMENT_MACRO(drem, int)
+TVMET_IMPLEMENT_MACRO(fmod, int)
+TVMET_IMPLEMENT_MACRO(hypot, int)
+TVMET_IMPLEMENT_MACRO(jn, int)
+TVMET_IMPLEMENT_MACRO(yn, int)
+TVMET_IMPLEMENT_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(atan2, long long int)
+TVMET_IMPLEMENT_MACRO(drem, long long int)
+TVMET_IMPLEMENT_MACRO(fmod, long long int)
+TVMET_IMPLEMENT_MACRO(hypot, long long int)
+TVMET_IMPLEMENT_MACRO(jn, long long int)
+TVMET_IMPLEMENT_MACRO(yn,long long int)
+TVMET_IMPLEMENT_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_IMPLEMENT_MACRO(atan2, float)
+TVMET_IMPLEMENT_MACRO(drem, float)
+TVMET_IMPLEMENT_MACRO(fmod, float)
+TVMET_IMPLEMENT_MACRO(hypot, float)
+TVMET_IMPLEMENT_MACRO(jn, float)
+TVMET_IMPLEMENT_MACRO(yn, float)
+TVMET_IMPLEMENT_MACRO(pow, float)
+
+TVMET_IMPLEMENT_MACRO(atan2, double)
+TVMET_IMPLEMENT_MACRO(drem, double)
+TVMET_IMPLEMENT_MACRO(fmod, double)
+TVMET_IMPLEMENT_MACRO(hypot,double)
+TVMET_IMPLEMENT_MACRO(jn, double)
+TVMET_IMPLEMENT_MACRO(yn, double)
+TVMET_IMPLEMENT_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(atan2, long double)
+TVMET_IMPLEMENT_MACRO(drem, long double)
+TVMET_IMPLEMENT_MACRO(fmod, long double)
+TVMET_IMPLEMENT_MACRO(hypot, long double)
+TVMET_IMPLEMENT_MACRO(jn, long double)
+TVMET_IMPLEMENT_MACRO(yn, long double)
+TVMET_IMPLEMENT_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * binary_function(XprMatrix<E, Rows, Cols>, std::complex<>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class E, std::size_t Rows, std::size_t Cols, class T>		\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME(const XprMatrix<E, Rows, Cols>& lhs, const std::complex<T>& rhs) {	\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< std::complex<T> >					\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));		\
+}
+
+TVMET_IMPLEMENT_MACRO(pow)
+
+TVMET_IMPLEMENT_MACRO(atan2)
+TVMET_IMPLEMENT_MACRO(drem)
+TVMET_IMPLEMENT_MACRO(fmod)
+TVMET_IMPLEMENT_MACRO(hypot)
+TVMET_IMPLEMENT_MACRO(jn)
+TVMET_IMPLEMENT_MACRO(yn)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MATRIX_BINARY_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixCol.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,96 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixCol.h,v 1.19 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_COL_H
+#define TVMET_XPR_MATRIX_COL_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprMatrixCol MatrixCol.h "tvmet/xpr/MatrixCol.h"
+ * \brief Expression on matrix used for access on the column vector.
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+class XprMatrixCol
+  : public TvmetBase< XprMatrixCol<E, Rows, Cols> >
+{
+  XprMatrixCol();
+  XprMatrixCol& operator=(const XprMatrixCol&);
+
+public:
+  typedef typename E::value_type			value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_expr  = E::ops,
+    ops       = ops_expr/Cols	// equal Row accesses
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMatrixCol(const E& e, std::size_t no)
+    : m_expr(e), m_col(no)
+  {
+    TVMET_RT_CONDITION(no < Cols, "XprMatrixCol Bounce Violation")
+  }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMatrixCol(const XprMatrixCol& e)
+    : m_expr(e.m_expr), m_col(e.m_col)
+  { }
+#endif
+
+  value_type operator()(std::size_t i) const {
+    TVMET_RT_CONDITION(i < Rows, "XprMatrixCol Bounce Violation")
+    return m_expr(i, m_col);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMatrixCol[O=" << ops << ", (O=" << ops_expr << ")]<"
+       << std::endl;
+    m_expr.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R=" << Rows << ", C=" << Cols << std::endl
+       << IndentLevel(--l) << ">"
+       << ((l != 0) ? "," : "") << std::endl;
+  }
+
+private:
+  const E						m_expr;
+  const std::size_t					m_col;
+};
+
+
+}
+
+#endif // TVMET_XPR_MATRIX_COL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixDiag.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,94 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixDiag.h,v 1.17 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_DIAG_H
+#define TVMET_XPR_MATRIX_DIAG_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprMatrixDiag MatrixDiag.h "tvmet/xpr/MatrixDiag.h"
+ * \brief Expression on matrix used for access on the diagonal vector.
+ */
+template<class E, std::size_t Sz>
+class XprMatrixDiag
+  : public TvmetBase< XprMatrixDiag<E, Sz> >
+{
+  XprMatrixDiag();
+  XprMatrixDiag& operator=(const XprMatrixDiag<E, Sz>&);
+
+public:
+  typedef typename E::value_type			value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_expr  = E::ops,
+    ops       = ops_expr/Sz
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMatrixDiag(const E& e)
+    : m_expr(e)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMatrixDiag(const XprMatrixDiag& e)
+    : m_expr(e.m_expr)
+  { }
+#endif
+
+  /** index operator for arrays/matrizes */
+  value_type operator()(std::size_t i) const {
+    TVMET_RT_CONDITION(i < Sz, "XprMatrixDiag Bounce Violation")
+    return m_expr(i, i);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMatrixDiag[O=" << ops << ", (O=" << ops_expr << ")]<"
+       << std::endl;
+    m_expr.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "Sz=" << Sz << std::endl
+       << IndentLevel(--l) << ">"
+       << ((l != 0) ? "," : "") << std::endl;
+  }
+
+private:
+  const E						m_expr;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MATRIX_DIAG_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,761 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixFunctions.h,v 1.44 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_FUNCTIONS_H
+#define TVMET_XPR_MATRIX_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/* forwards */
+template<class T, std::size_t Rows, std::size_t Cols> class Matrix;
+template<class T, std::size_t Sz> class Vector;
+template<class E, std::size_t Sz> class XprVector;
+template<class E> class XprMatrixTranspose;
+template<class E, std::size_t Sz> class XprMatrixDiag;
+template<class E, std::size_t Rows, std::size_t Cols> class XprMatrixRow;
+template<class E, std::size_t Rows, std::size_t Cols> class XprMatrixCol;
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix arithmetic functions add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * function(XprMatrix<E1, Rows, Cols>, XprMatrix<E2, Rows, Cols>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class E1, class E2, std::size_t Rows, std::size_t Cols>	\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprMatrix<E1, Rows, Cols>,						\
+    XprMatrix<E2, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const XprMatrix<E1, Rows, Cols>& lhs,				\
+      const XprMatrix<E2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)			// per se element wise
+TVMET_DECLARE_MACRO(sub)			// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mul)			// not defined for matrizes
+  TVMET_DECLARE_MACRO(div)			// not defined for matrizes
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * function(XprMatrix<E, Rows, Cols>, POD)
+ * function(POD, XprMatrix<E, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, POD)					\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, POD >,				\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< POD >							\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const XprMatrix<E, Rows, Cols>& lhs, 				\
+      POD rhs) TVMET_CXX_ALWAYS_INLINE;					\
+									\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, typename E::value_type>,				\
+    XprLiteral< POD >,							\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (POD lhs, 								\
+      const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, int)
+TVMET_DECLARE_MACRO(sub, int)
+TVMET_DECLARE_MACRO(mul, int)
+TVMET_DECLARE_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, long long int)
+TVMET_DECLARE_MACRO(sub, long long int)
+TVMET_DECLARE_MACRO(mul, long long int)
+TVMET_DECLARE_MACRO(div, long long int)
+#endif
+
+TVMET_DECLARE_MACRO(add, float)
+TVMET_DECLARE_MACRO(sub, float)
+TVMET_DECLARE_MACRO(mul, float)
+TVMET_DECLARE_MACRO(div, float)
+
+TVMET_DECLARE_MACRO(add, double)
+TVMET_DECLARE_MACRO(sub, double)
+TVMET_DECLARE_MACRO(mul, double)
+TVMET_DECLARE_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, long double)
+TVMET_DECLARE_MACRO(sub, long double)
+TVMET_DECLARE_MACRO(mul, long double)
+TVMET_DECLARE_MACRO(div, long double)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(XprMatrix<E, Rows, Cols>, complex<T>)
+ * function(complex<T>, XprMatrix<E, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class E, class T, std::size_t Rows, std::size_t Cols>		\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const XprMatrix<E, Rows, Cols>& lhs,				\
+      const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+									\
+template<class T, class E, std::size_t Rows, std::size_t Cols>		\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const std::complex<T>& lhs,					\
+      const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)
+TVMET_DECLARE_MACRO(sub)
+TVMET_DECLARE_MACRO(mul)
+TVMET_DECLARE_MACRO(div)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2					// return Dim
+>
+prod(const XprMatrix<E1, Rows1, Cols1>& lhs,
+     const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+XprMatrix<
+  XprMMProductTransposed<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Cols2, Rows1					// return Dim
+>
+trans_prod(const XprMatrix<E1, Rows1, Cols1>& lhs,
+	   const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>	// Rows2 = Rows1
+XprMatrix<
+  XprMtMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Rows1, Cols2>, Cols2		// M2(Rows1, Cols2)
+  >,
+  Cols1, Cols2					// return Dim
+>
+MtM_prod(const XprMatrix<E1, Rows1, Cols1>& lhs,
+	 const XprMatrix<E2, Rows1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Rows2> 		// Cols2 = Cols1
+XprMatrix<
+  XprMMtProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Rows2, Cols1>, Cols1 		// M2(Rows2, Cols1)
+  >,
+  Rows1, Rows2					// return Dim
+>
+MMt_prod(const XprMatrix<E1, Rows1, Cols1>& lhs,
+	 const XprMatrix<E2, Rows2, Cols1>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class E1, std::size_t Rows, std::size_t Cols,
+	 class E2>
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+prod(const XprMatrix<E1, Rows, Cols>& lhs,
+     const XprVector<E2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class E, std::size_t Rows, std::size_t Cols>
+XprMatrix<
+  XprMatrixTranspose<
+    XprMatrix<E, Rows, Cols>
+  >,
+  Cols, Rows
+>
+trans(const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+typename NumericTraits<typename E::value_type>::sum_type
+trace(const XprMatrix<E, Sz, Sz>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMatrixRow<
+    XprMatrix<E, Rows, Cols>,
+    Rows, Cols
+  >,
+  Cols
+>
+row(const XprMatrix<E, Rows, Cols>& m,
+    std::size_t no) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Rows, std::size_t Cols>
+XprVector<
+  XprMatrixCol<
+    XprMatrix<E, Rows, Cols>,
+    Rows, Cols
+  >,
+  Rows
+>
+col(const XprMatrix<E, Rows, Cols>& m, std::size_t no) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+XprVector<
+  XprMatrixDiag<
+    XprMatrix<E, Sz, Sz>,
+    Sz
+  >,
+  Sz
+>
+diag(const XprMatrix<E, Sz, Sz>& m) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix arithmetic functions add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * function(XprMatrix<E1, Rows, Cols>, XprMatrix<E2, Rows, Cols>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class E1, class E2, std::size_t Rows, std::size_t Cols>	\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprMatrix<E1, Rows, Cols>,						\
+    XprMatrix<E2, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const XprMatrix<E1, Rows, Cols>& lhs, 				\
+      const XprMatrix<E2, Rows, Cols>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprMatrix<E1, Rows, Cols>,						\
+    XprMatrix<E2, Rows, Cols>						\
+  > 							 expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs, rhs));		\
+}
+
+TVMET_IMPLEMENT_MACRO(add)			// per se element wise
+TVMET_IMPLEMENT_MACRO(sub)			// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mul)			// not defined for matrizes
+  TVMET_IMPLEMENT_MACRO(div)			// not defined for matrizes
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * function(XprMatrix<E, Rows, Cols>, POD)
+ * function(POD, XprMatrix<E, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, POD)				\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, POD >,				\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< POD >							\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const XprMatrix<E, Rows, Cols>& lhs, POD rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, POD >,				\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< POD >							\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs, XprLiteral< POD >(rhs)));				\
+}									\
+									\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, typename E::value_type>,				\
+    XprLiteral< POD >,							\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (POD lhs, const XprMatrix<E, Rows, Cols>& rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< POD, typename E::value_type>,				\
+    XprLiteral< POD >,							\
+    XprMatrix<E, Rows, Cols>						\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(XprLiteral< POD >(lhs), rhs));				\
+}
+
+TVMET_IMPLEMENT_MACRO(add, int)
+TVMET_IMPLEMENT_MACRO(sub, int)
+TVMET_IMPLEMENT_MACRO(mul, int)
+TVMET_IMPLEMENT_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, long long int)
+TVMET_IMPLEMENT_MACRO(sub, long long int)
+TVMET_IMPLEMENT_MACRO(mul, long long int)
+TVMET_IMPLEMENT_MACRO(div, long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(add, float)
+TVMET_IMPLEMENT_MACRO(sub, float)
+TVMET_IMPLEMENT_MACRO(mul, float)
+TVMET_IMPLEMENT_MACRO(div, float)
+
+TVMET_IMPLEMENT_MACRO(add, double)
+TVMET_IMPLEMENT_MACRO(sub, double)
+TVMET_IMPLEMENT_MACRO(mul, double)
+TVMET_IMPLEMENT_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, long double)
+TVMET_IMPLEMENT_MACRO(sub, long double)
+TVMET_IMPLEMENT_MACRO(mul, long double)
+TVMET_IMPLEMENT_MACRO(div, long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(XprMatrix<E, Rows, Cols>, complex<T>)
+ * function(complex<T>, XprMatrix<E, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class E, class T, std::size_t Rows, std::size_t Cols>		\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const XprMatrix<E, Rows, Cols>& lhs, 				\
+      const std::complex<T>& rhs) {					\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< std::complex<T> >					\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));		\
+}									\
+									\
+template<class T, class E, std::size_t Rows, std::size_t Cols>		\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+NAME (const std::complex<T>& lhs, 					\
+      const XprMatrix<E, Rows, Cols>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprMatrix<E, Rows, Cols>						\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs));		\
+}
+
+TVMET_IMPLEMENT_MACRO(add)
+TVMET_IMPLEMENT_MACRO(sub)
+TVMET_IMPLEMENT_MACRO(mul)
+TVMET_IMPLEMENT_MACRO(div)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs)
+ * \brief Evaluate the product of two XprMatrix.
+ * Perform on given Matrix M1 and M2:
+ * \f[
+ * M_1\,M_2
+ * \f]
+ * \note The numer of Rows2 has to be equal to Cols1.
+ * \ingroup _binary_function
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2
+  >,
+  Rows1, Cols2					// return Dim
+>
+prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
+  typedef XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
+    XprMatrix<E2, Cols1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Rows1, Cols2>(expr_type(lhs, rhs));
+}
+
+
+/**
+ * \fn trans_prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs)
+ * \brief Function for the trans(matrix-matrix-product)
+ * Perform on given Matrix M1 and M2:
+ * \f[
+ * (M_1\,M_2)^T
+ * \f]
+ * \note The numer of Rows2 has to be equal to Cols1.
+ * \ingroup _binary_function
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProductTransposed<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Cols2, Rows1					// return Dim
+>
+trans_prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
+  typedef XprMMProductTransposed<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
+    XprMatrix<E2, Cols1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Cols2, Rows1>(expr_type(lhs, rhs));
+}
+
+
+/**
+ * \fn MtM_prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Rows1, Cols2>& rhs)
+ * \brief Function for the trans(matrix)-matrix-product.
+ *        using formula
+ *        \f[
+ *        M_1^{T}\,M_2
+ *        \f]
+ * \note The number of cols of matrix 2 have to be equal to number of rows of
+ *       matrix 1, since matrix 1 is trans - the result is a (Cols1 x Cols2)
+ *       matrix.
+ * \ingroup _binary_function
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>	// Rows2 = Rows1
+inline
+XprMatrix<
+  XprMtMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Rows1, Cols2>, Cols2		// M2(Rows1, Cols2)
+  >,
+  Cols1, Cols2					// return Dim
+>
+MtM_prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Rows1, Cols2>& rhs) {
+  typedef XprMtMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
+    XprMatrix<E2, Rows1, Cols2>, Cols2
+  >							expr_type;
+  return XprMatrix<expr_type, Cols1, Cols2>(expr_type(lhs, rhs));
+}
+
+
+/**
+ * \fn MMt_prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Rows2, Cols1>& rhs)
+ * \brief Function for the matrix-trans(matrix)-product.
+ * \ingroup _binary_function
+ * \note The cols2 has to be equal to cols1.
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Rows2> // Cols2 = Cols1
+inline
+XprMatrix<
+  XprMMtProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Rows2, Cols1>, Cols1	 	// M2(Rows2, Cols1)
+  >,
+  Rows1, Rows2					// return Dim
+>
+MMt_prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Rows2, Cols1>& rhs) {
+  typedef XprMMtProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
+    XprMatrix<E2, Rows2, Cols1>, Cols1
+  >							expr_type;
+  return XprMatrix<expr_type, Rows1, Rows2>(expr_type(lhs, rhs));
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn prod(const XprMatrix<E1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs)
+ * \brief Evaluate the product of XprMatrix and XprVector.
+ * \ingroup _binary_function
+ */
+template<class E1, std::size_t Rows, std::size_t Cols,
+	 class E2>
+inline
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+prod(const XprMatrix<E1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs) {
+  typedef XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >							expr_type;
+  return XprVector<expr_type, Rows>(expr_type(lhs, rhs));
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn trans(const XprMatrix<E, Rows, Cols>& rhs)
+ * \brief Transpose an expression matrix.
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+XprMatrix<
+  XprMatrixTranspose<
+    XprMatrix<E, Rows, Cols>
+  >,
+  Cols, Rows
+>
+trans(const XprMatrix<E, Rows, Cols>& rhs) {
+  typedef XprMatrixTranspose<
+    XprMatrix<E, Rows, Cols>
+  >							expr_type;
+  return XprMatrix<expr_type, Cols, Rows>(expr_type(rhs));
+}
+
+
+/*
+ * \fn trace(const XprMatrix<E, Sz, Sz>& m)
+ * \brief Compute the trace of a square matrix.
+ * \ingroup _unary_function
+ *
+ * Simply compute the trace of the given matrix expression as:
+ * \f[
+ *  \sum_{k = 0}^{Sz-1} m(k, k)
+ * \f]
+ */
+template<class E, std::size_t Sz>
+inline
+typename NumericTraits<typename E::value_type>::sum_type
+trace(const XprMatrix<E, Sz, Sz>& m) {
+  return meta::Matrix<Sz, Sz, 0, 0>::trace(m);
+}
+
+
+/**
+ * \fn row(const XprMatrix<E, Rows, Cols>& m, std::size_t no)
+ * \brief Returns a row vector of the given matrix.
+ * \ingroup _binary_function
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMatrixRow<
+    XprMatrix<E, Rows, Cols>,
+    Rows, Cols
+  >,
+  Cols
+>
+row(const XprMatrix<E, Rows, Cols>& m, std::size_t no) {
+  typedef XprMatrixRow<
+    XprMatrix<E, Rows, Cols>,
+    Rows, Cols
+  >							expr_type;
+
+  return XprVector<expr_type, Cols>(expr_type(m, no));
+}
+
+
+/**
+ * \fn col(const XprMatrix<E, Rows, Cols>& m, std::size_t no)
+ * \brief Returns a column vector of the given matrix.
+ * \ingroup _binary_function
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+inline
+XprVector<
+  XprMatrixCol<
+    XprMatrix<E, Rows, Cols>,
+    Rows, Cols
+  >,
+  Rows
+>
+col(const XprMatrix<E, Rows, Cols>& m, std::size_t no) {
+  typedef XprMatrixCol<
+    XprMatrix<E, Rows, Cols>,
+    Rows, Cols
+  >							expr_type;
+
+  return XprVector<expr_type, Cols>(expr_type(m, no));
+}
+
+
+/**
+ * \fn diag(const XprMatrix<E, Sz, Sz>& m)
+ * \brief Returns the diagonal vector of the given square matrix.
+ * \ingroup _unary_function
+ */
+template<class E, std::size_t Sz>
+inline
+XprVector<
+  XprMatrixDiag<
+    XprMatrix<E, Sz, Sz>,
+    Sz
+  >,
+  Sz
+>
+diag(const XprMatrix<E, Sz, Sz>& m) {
+  typedef XprMatrixDiag<
+    XprMatrix<E, Sz, Sz>,
+  Sz> 						expr_type;
+
+  return XprVector<expr_type, Sz>(expr_type(m));
+}
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MATRIX_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixOperators.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,947 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixOperators.h,v 1.23 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_OPERATORS_H
+#define TVMET_XPR_MATRIX_OPERATORS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1,Cols2>& rhs)
+ *
+ * Note: operations +,-,*,/ are per se element wise. Further more,
+ * element wise operations make sense only for matrices of the same
+ * size [varg].
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class E1, std::size_t Rows1, std::size_t Cols1,			\
+         class E2>								\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,		\
+    XprMatrix<E1, Rows1, Cols1>,						\
+    XprMatrix<E2, Rows1, Cols1>							\
+  >,										\
+  Rows1, Cols1									\
+>										\
+operator OP (const XprMatrix<E1, Rows1, Cols1>& lhs,				\
+	     const XprMatrix<E2, Rows1, Cols1>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)		// per se element wise
+TVMET_DECLARE_MACRO(sub, -)		// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mul, *)		// see as prod()
+  TVMET_DECLARE_MACRO(div, /)		// not defined for matrizes, must be element_wise
+}
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * operator(XprMatrix<E, Rows, Cols>,  POD)
+ * operator(POD, XprMatrix<E, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, POD)					\
+template<class E, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, POD >,					\
+    XprMatrix<E, Rows, Cols>,							\
+    XprLiteral< POD >								\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, 				\
+	     POD rhs) TVMET_CXX_ALWAYS_INLINE;					\
+										\
+template<class E,std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<POD, typename E::value_type>,					\
+    XprLiteral< POD >,								\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (POD lhs, 								\
+	     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +, int)
+TVMET_DECLARE_MACRO(sub, -, int)
+TVMET_DECLARE_MACRO(mul, *, int)
+TVMET_DECLARE_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, +, long long int)
+TVMET_DECLARE_MACRO(sub, -, long long int)
+TVMET_DECLARE_MACRO(mul, *, long long int)
+TVMET_DECLARE_MACRO(div, /, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_DECLARE_MACRO(add, +, float)
+TVMET_DECLARE_MACRO(sub, -, float)
+TVMET_DECLARE_MACRO(mul, *, float)
+TVMET_DECLARE_MACRO(div, /, float)
+
+TVMET_DECLARE_MACRO(add, +, double)
+TVMET_DECLARE_MACRO(sub, -, double)
+TVMET_DECLARE_MACRO(mul, *, double)
+TVMET_DECLARE_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, +, long double)
+TVMET_DECLARE_MACRO(sub, -, long double)
+TVMET_DECLARE_MACRO(mul, *, long double)
+TVMET_DECLARE_MACRO(div, /, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(XprMatrix<E, Rows, Cols>, complex<>)
+ * operator(complex<>, XprMatrix<E, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class E, std::size_t Rows, std::size_t Cols, class T>			\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,			\
+    XprMatrix<E, Rows, Cols>,							\
+    XprLiteral< std::complex<T> >						\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs,				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+										\
+template<class E, std::size_t Rows, std::size_t Cols, class T>			\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<std::complex<T>, typename E::value_type>,			\
+    XprLiteral< std::complex<T> >,						\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const std::complex<T>& lhs,					\
+	     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)
+TVMET_DECLARE_MACRO(sub, -)
+TVMET_DECLARE_MACRO(mul, *)
+TVMET_DECLARE_MACRO(div, /)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific operator*() = prod() operations
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn operator*(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs)
+ * \brief Evaluate the product of two XprMatrix.
+ * \ingroup _binary_operator
+ * \sa prod(XprMatrix<E1, Rows1, Cols1> lhs, XprMatrix<E2, Cols1, Cols2> rhs)
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2
+>
+operator*(const XprMatrix<E1, Rows1, Cols1>& lhs,
+	  const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn operator*(const XprMatrix<E1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs)
+ * \brief Evaluate the product of XprMatrix and XprVector.
+ * \ingroup _binary_operator
+ * \sa prod(XprMatrix<E1, Rows, Cols> lhs, XprVector<E2, Cols> rhs)
+ */
+template<class E1, std::size_t Rows, std::size_t Cols,
+	 class E2>
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+operator*(const XprMatrix<E1, Rows, Cols>& lhs,
+	  const XprVector<E2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(XprMatrix<>, XprMatrix<>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class E1, std::size_t Rows, std::size_t Cols,				\
+         class E2>								\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,		\
+    XprMatrix<E1, Rows, Cols>,							\
+    XprMatrix<E2, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E1, Rows, Cols>& lhs, 				\
+	     const XprMatrix<E2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you will get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %)
+  TVMET_DECLARE_MACRO(bitxor, ^)
+  TVMET_DECLARE_MACRO(bitand, &)
+  TVMET_DECLARE_MACRO(bitor, |)
+  TVMET_DECLARE_MACRO(shl, <<)
+  TVMET_DECLARE_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(XprMatrix<E, Rows, Cols>, std::complex<>)
+ * operator(std::complex<>, XprMatrix<E, Rows, Cols>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template<class E, std::size_t Rows, std::size_t Cols, class T>			\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,			\
+    XprMatrix<E, Rows, Cols>,							\
+    XprLiteral< std::complex<T> >						\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, 				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;		\
+										\
+template<class E, std::size_t Rows, std::size_t Cols, class T>			\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<std::complex<T>, typename E::value_type>,			\
+    XprLiteral< std::complex<T> >,						\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const std::complex<T>& lhs, 					\
+	     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*
+ * operator(XprMatrix<E, Rows, Cols>, POD)
+ * operator(POD, XprMatrix<E, Rows, Cols>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, TP)					\
+template<class E, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<typename E::value_type, TP >,					\
+    XprMatrix<E, Rows, Cols>,							\
+    XprLiteral< TP >								\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, 				\
+	     TP rhs) TVMET_CXX_ALWAYS_INLINE;					\
+										\
+template<class E, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprBinOp<									\
+    Fcnl_##NAME<TP, typename E::value_type>,					\
+    XprLiteral< TP >,								\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (TP lhs, 								\
+	     const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you will get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, int)
+  TVMET_DECLARE_MACRO(bitxor, ^, int)
+  TVMET_DECLARE_MACRO(bitand, &, int)
+  TVMET_DECLARE_MACRO(bitor, |, int)
+  TVMET_DECLARE_MACRO(shl, <<, int)
+  TVMET_DECLARE_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, int)
+TVMET_DECLARE_MACRO(less, <, int)
+TVMET_DECLARE_MACRO(greater_eq, >=, int)
+TVMET_DECLARE_MACRO(less_eq, <=, int)
+TVMET_DECLARE_MACRO(eq, ==, int)
+TVMET_DECLARE_MACRO(not_eq, !=, int)
+TVMET_DECLARE_MACRO(and, &&, int)
+TVMET_DECLARE_MACRO(or, ||, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, long long int)
+  TVMET_DECLARE_MACRO(bitxor, ^, long long int)
+  TVMET_DECLARE_MACRO(bitand, &, long long int)
+  TVMET_DECLARE_MACRO(bitor, |, long long int)
+  TVMET_DECLARE_MACRO(shl, <<, long long int)
+  TVMET_DECLARE_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long long int)
+TVMET_DECLARE_MACRO(less, <, long long int)
+TVMET_DECLARE_MACRO(greater_eq, >=, long long int)
+TVMET_DECLARE_MACRO(less_eq, <=, long long int)
+TVMET_DECLARE_MACRO(eq, ==, long long int)
+TVMET_DECLARE_MACRO(not_eq, !=, long long int)
+TVMET_DECLARE_MACRO(and, &&, long long int)
+TVMET_DECLARE_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, float)
+TVMET_DECLARE_MACRO(less, <, float)
+TVMET_DECLARE_MACRO(greater_eq, >=, float)
+TVMET_DECLARE_MACRO(less_eq, <=, float)
+TVMET_DECLARE_MACRO(eq, ==, float)
+TVMET_DECLARE_MACRO(not_eq, !=, float)
+TVMET_DECLARE_MACRO(and, &&, float)
+TVMET_DECLARE_MACRO(or, ||, float)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, double)
+TVMET_DECLARE_MACRO(less, <, double)
+TVMET_DECLARE_MACRO(greater_eq, >=, double)
+TVMET_DECLARE_MACRO(less_eq, <=, double)
+TVMET_DECLARE_MACRO(eq, ==, double)
+TVMET_DECLARE_MACRO(not_eq, !=, double)
+TVMET_DECLARE_MACRO(and, &&, double)
+TVMET_DECLARE_MACRO(or, ||, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long double)
+TVMET_DECLARE_MACRO(less, <, long double)
+TVMET_DECLARE_MACRO(greater_eq, >=, long double)
+TVMET_DECLARE_MACRO(less_eq, <=, long double)
+TVMET_DECLARE_MACRO(eq, ==, long double)
+TVMET_DECLARE_MACRO(not_eq, !=, long double)
+TVMET_DECLARE_MACRO(and, &&, long double)
+TVMET_DECLARE_MACRO(or, ||, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * unary_operator(const XprMatrix<E, Rows, Cols>& m)
+ * Note: per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)						\
+template <class E, std::size_t Rows, std::size_t Cols>				\
+XprMatrix<									\
+  XprUnOp<									\
+    Fcnl_##NAME<typename E::value_type>,					\
+    XprMatrix<E, Rows, Cols>							\
+  >,										\
+  Rows, Cols									\
+>										\
+operator OP (const XprMatrix<E, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(not, !)
+TVMET_DECLARE_MACRO(compl, ~)
+TVMET_DECLARE_MACRO(neg, -)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1,Cols2>& rhs)
+ *
+ * Note: operations +,-,*,/ are per se element wise. Further more,
+ * element wise operations make sense only for matrices of the same
+ * size [varg].
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class E1, std::size_t Rows1, std::size_t Cols1,		\
+         class E2>							\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprMatrix<E1, Rows1, Cols1>,					\
+    XprMatrix<E2, Rows1, Cols1>						\
+  >,									\
+  Rows1, Cols1								\
+>									\
+operator OP (const XprMatrix<E1, Rows1, Cols1>& lhs, 			\
+	     const XprMatrix<E2, Rows1, Cols1>& rhs) {			\
+  return NAME (lhs, rhs);						\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub, -)		// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mul, *)		// see as prod()
+  TVMET_IMPLEMENT_MACRO(div, /)		// not defined for matrizes, must be element_wise
+}
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * operator(XprMatrix<E, Rows, Cols>,  POD)
+ * operator(POD, XprMatrix<E, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, POD)			\
+template<class E, std::size_t Rows, std::size_t Cols>		\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, POD >,			\
+    XprMatrix<E, Rows, Cols>,					\
+    XprLiteral< POD >						\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, POD rhs) {	\
+  return NAME (lhs, rhs);					\
+}								\
+								\
+template<class E,std::size_t Rows, std::size_t Cols>		\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME<POD, typename E::value_type>,			\
+    XprLiteral< POD >,						\
+    XprMatrix<E, Rows, Cols>					\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (POD lhs, const XprMatrix<E, Rows, Cols>& rhs) {	\
+  return NAME (lhs, rhs);					\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +, int)
+TVMET_IMPLEMENT_MACRO(sub, -, int)
+TVMET_IMPLEMENT_MACRO(mul, *, int)
+TVMET_IMPLEMENT_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, +, long long int)
+TVMET_IMPLEMENT_MACRO(sub, -, long long int)
+TVMET_IMPLEMENT_MACRO(mul, *, long long int)
+TVMET_IMPLEMENT_MACRO(div, /, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_IMPLEMENT_MACRO(add, +, float)
+TVMET_IMPLEMENT_MACRO(sub, -, float)
+TVMET_IMPLEMENT_MACRO(mul, *, float)
+TVMET_IMPLEMENT_MACRO(div, /, float)
+
+TVMET_IMPLEMENT_MACRO(add, +, double)
+TVMET_IMPLEMENT_MACRO(sub, -, double)
+TVMET_IMPLEMENT_MACRO(mul, *, double)
+TVMET_IMPLEMENT_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, +, long double)
+TVMET_IMPLEMENT_MACRO(sub, -, long double)
+TVMET_IMPLEMENT_MACRO(mul, *, long double)
+TVMET_IMPLEMENT_MACRO(div, /, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(XprMatrix<E, Rows, Cols>, complex<>)
+ * operator(complex<>, XprMatrix<E, Rows, Cols>)
+ * Note: operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				\
+template<class E, std::size_t Rows, std::size_t Cols, class T>	\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,	\
+    XprMatrix<E, Rows, Cols>,					\
+    XprLiteral< std::complex<T> >				\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs,		\
+	     const std::complex<T>& rhs) {			\
+  return NAME (lhs, rhs);					\
+}								\
+								\
+template<class E, std::size_t Rows, std::size_t Cols, class T>	\
+inline								\
+XprMatrix<							\
+  XprBinOp<							\
+    Fcnl_##NAME<std::complex<T>, typename E::value_type>,	\
+    XprLiteral< std::complex<T> >,				\
+    XprMatrix<E, Rows, Cols>					\
+  >,								\
+  Rows, Cols							\
+>								\
+operator OP (const std::complex<T>& lhs,			\
+	     const XprMatrix<E, Rows, Cols>& rhs) {		\
+  return NAME (lhs, rhs);					\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)
+TVMET_IMPLEMENT_MACRO(sub, -)
+TVMET_IMPLEMENT_MACRO(mul, *)
+TVMET_IMPLEMENT_MACRO(div, /)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix specific operator*() = prod() operations
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn operator*(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs)
+ * \brief Evaluate the product of two XprMatrix.
+ * \ingroup _binary_operator
+ * \sa prod(XprMatrix<E1, Rows1, Cols1> lhs, XprMatrix<E2, Cols1, Cols2> rhs)
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+inline
+XprMatrix<
+  XprMMProduct<
+    XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,	// M1(Rows1, Cols1)
+    XprMatrix<E2, Cols1, Cols2>, Cols2		// M2(Cols1, Cols2)
+  >,
+  Rows1, Cols2
+>
+operator*(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * matrix-vector specific prod( ... ) operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn operator*(const XprMatrix<E1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs)
+ * \brief Evaluate the product of XprMatrix and XprVector.
+ * \ingroup _binary_operator
+ * \sa prod(XprMatrix<E1, Rows, Cols> lhs, XprVector<E2, Cols> rhs)
+ */
+template<class E1, std::size_t Rows, std::size_t Cols,
+	 class E2>
+inline
+XprVector<
+  XprMVProduct<
+    XprMatrix<E1, Rows, Cols>, Rows, Cols,
+    XprVector<E2, Cols>
+  >,
+  Rows
+>
+operator*(const XprMatrix<E1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs) {
+  return prod(lhs, rhs);
+}
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Matrix integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(XprMatrix<>, XprMatrix<>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class E1, std::size_t Rows, std::size_t Cols,			\
+         class E2>							\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprMatrix<E1, Rows, Cols>,						\
+    XprMatrix<E2, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (const XprMatrix<E1, Rows, Cols>& lhs, 			\
+	     const XprMatrix<E2, Rows, Cols>& rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprMatrix<E1, Rows, Cols>,						\
+    XprMatrix<E2, Rows, Cols>						\
+  >		    					expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs, rhs));		\
+}
+
+// integer operators only, e.g used on double you will get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^)
+  TVMET_IMPLEMENT_MACRO(bitand, &)
+  TVMET_IMPLEMENT_MACRO(bitor, |)
+  TVMET_IMPLEMENT_MACRO(shl, <<)
+  TVMET_IMPLEMENT_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(XprMatrix<E, Rows, Cols>, std::complex<>)
+ * operator(std::complex<>, XprMatrix<E, Rows, Cols>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class E, std::size_t Rows, std::size_t Cols, class T>		\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, 			\
+	     const std::complex<T>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< std::complex<T> >					\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));		\
+}									\
+									\
+template<class E, std::size_t Rows, std::size_t Cols, class T>		\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (const std::complex<T>& lhs, 				\
+	     const XprMatrix<E, Rows, Cols>& rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprMatrix<E, Rows, Cols>						\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs));		\
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*
+ * operator(XprMatrix<E, Rows, Cols>, POD)
+ * operator(POD, XprMatrix<E, Rows, Cols>)
+ * Note: operations are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, TP)				\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< TP >							\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (const XprMatrix<E, Rows, Cols>& lhs, TP rhs) {		\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprMatrix<E, Rows, Cols>,						\
+    XprLiteral< TP >							\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(lhs, XprLiteral< TP >(rhs)));				\
+}									\
+									\
+template<class E, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprBinOp<								\
+    Fcnl_##NAME<TP, typename E::value_type>,				\
+    XprLiteral< TP >,							\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (TP lhs, const XprMatrix<E, Rows, Cols>& rhs) {		\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< TP, typename E::value_type>,				\
+    XprLiteral< TP >,							\
+    XprMatrix<E, Rows, Cols>						\
+  >							expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(				\
+    expr_type(XprLiteral< TP >(lhs), rhs));				\
+}
+
+
+// integer operators only, e.g used on double you will get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, int)
+TVMET_IMPLEMENT_MACRO(less, <, int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, int)
+TVMET_IMPLEMENT_MACRO(eq, ==, int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, int)
+TVMET_IMPLEMENT_MACRO(and, &&, int)
+TVMET_IMPLEMENT_MACRO(or, ||, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, long long int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, long long int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, long long int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, long long int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long long int)
+TVMET_IMPLEMENT_MACRO(less, <, long long int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int)
+TVMET_IMPLEMENT_MACRO(eq, ==, long long int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int)
+TVMET_IMPLEMENT_MACRO(and, &&, long long int)
+TVMET_IMPLEMENT_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, float)
+TVMET_IMPLEMENT_MACRO(less, <, float)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, float)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, float)
+TVMET_IMPLEMENT_MACRO(eq, ==, float)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, float)
+TVMET_IMPLEMENT_MACRO(and, &&, float)
+TVMET_IMPLEMENT_MACRO(or, ||, float)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, double)
+TVMET_IMPLEMENT_MACRO(less, <, double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, double)
+TVMET_IMPLEMENT_MACRO(eq, ==, double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, double)
+TVMET_IMPLEMENT_MACRO(and, &&, double)
+TVMET_IMPLEMENT_MACRO(or, ||, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long double)
+TVMET_IMPLEMENT_MACRO(less, <, long double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long double)
+TVMET_IMPLEMENT_MACRO(eq, ==, long double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long double)
+TVMET_IMPLEMENT_MACRO(and, &&, long double)
+TVMET_IMPLEMENT_MACRO(or, ||, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * unary_operator(const XprMatrix<E, Rows, Cols>& m)
+ * Note: per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template <class E, std::size_t Rows, std::size_t Cols>			\
+inline									\
+XprMatrix<								\
+  XprUnOp<								\
+    Fcnl_##NAME<typename E::value_type>,				\
+    XprMatrix<E, Rows, Cols>						\
+  >,									\
+  Rows, Cols								\
+>									\
+operator OP (const XprMatrix<E, Rows, Cols>& m) {			\
+  typedef XprUnOp<							\
+    Fcnl_##NAME<typename E::value_type>,				\
+    XprMatrix<E, Rows, Cols>						\
+  >  							 expr_type;	\
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(m));		\
+}
+
+TVMET_IMPLEMENT_MACRO(not, !)
+TVMET_IMPLEMENT_MACRO(compl, ~)
+TVMET_IMPLEMENT_MACRO(neg, -)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MATRIX_OPERATORS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixRow.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,96 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixRow.h,v 1.18 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_ROW_H
+#define TVMET_XPR_MATRIX_ROW_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprMatrixRow MatrixRow.h "tvmet/xpr/MatrixRow.h"
+ * \brief Expression on matrix used for access on the row vector.
+ */
+template<class E, std::size_t Rows, std::size_t Cols>
+class XprMatrixRow
+  : public TvmetBase< XprMatrixRow<E, Rows, Cols> >
+{
+  XprMatrixRow();
+  XprMatrixRow& operator=(const XprMatrixRow&);
+
+public:
+  typedef typename E::value_type			value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_expr  = E::ops,
+    ops       = ops_expr/Rows	// equal Col accesses
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMatrixRow(const E& e, std::size_t no)
+    : m_expr(e), m_row(no)
+  {
+    TVMET_RT_CONDITION(no < Rows, "XprMatrixRow Bounce Violation")
+  }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMatrixRow(const XprMatrixRow& rhs)
+    : m_expr(rhs.m_expr), m_row(rhs.m_row)
+  { }
+#endif
+
+  value_type operator()(std::size_t j) const {
+    TVMET_RT_CONDITION(j < Cols, "XprMatrixRow Bounce Violation")
+    return m_expr(m_row, j);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMatrixRow[O=" << ops << ", (O=" << ops_expr << ")]<"
+       << std::endl;
+    m_expr.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R=" << Rows << ", C=" << Cols << std::endl
+       << IndentLevel(--l) << ">"
+       << ((l != 0) ? "," : "") << std::endl;
+  }
+
+private:
+  const E		 				m_expr;
+  const std::size_t					m_row;
+};
+
+
+}
+
+#endif // TVMET_XPR_MATRIX_ROW_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixTranspose.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,89 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixTranspose.h,v 1.15 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_TRANSPOSE_H
+#define TVMET_XPR_MATRIX_TRANSPOSE_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprMatrixTranspose MatrixTranspose.h "tvmet/xpr/MatrixTranspose.h"
+ * \brief Expression for transpose matrix
+ */
+template<class E>
+class XprMatrixTranspose
+  : public TvmetBase< XprMatrixTranspose<E> >
+{
+  XprMatrixTranspose();
+  XprMatrixTranspose& operator=(const XprMatrixTranspose&);
+
+public:
+  typedef typename E::value_type			value_type;
+
+  /** Complexity counter. */
+  enum {
+    ops_expr  = E::ops,
+    ops       = 1 * ops_expr
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMatrixTranspose(const E& e)
+    : m_expr(e)
+  { }
+
+ /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMatrixTranspose(const XprMatrixTranspose& e)
+    : m_expr(e.m_expr)
+  { }
+#endif
+
+  /** index operator for arrays/matrices. This simple swap the index
+      access for transpose. */
+  value_type operator()(std::size_t i, std::size_t j) const { return m_expr(j, i); }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMatrixTranspose[O=" << ops << ", (O=" << ops_expr << ")]<"
+       << std::endl;
+    m_expr.print_xpr(os, l);
+    os << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E						m_expr;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MATRIX_TRANSPOSE_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MatrixUnaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,163 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MatrixUnaryFunctions.h,v 1.11 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MATRIX_UNARY_FUNCTIONS_H
+#define TVMET_XPR_MATRIX_UNARY_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*
+ * unary_function(XprMatrix<E, Rows, Cols>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)                    \
+template<class E, std::size_t Rows, std::size_t Cols>            \
+inline                                    \
+XprMatrix<                                \
+  XprUnOp<                                \
+    Fcnl_##NAME<typename E::value_type>,                \
+    XprMatrix<E, Rows, Cols>                        \
+  >,                                    \
+  Rows, Cols                                \
+>                                    \
+NAME(const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(abs)
+TVMET_DECLARE_MACRO(cbrt)
+TVMET_DECLARE_MACRO(ceil)
+TVMET_DECLARE_MACRO(floor)
+TVMET_DECLARE_MACRO(rint)
+TVMET_DECLARE_MACRO(sin)
+TVMET_DECLARE_MACRO(cos)
+TVMET_DECLARE_MACRO(tan)
+TVMET_DECLARE_MACRO(sinh)
+TVMET_DECLARE_MACRO(cosh)
+TVMET_DECLARE_MACRO(tanh)
+TVMET_DECLARE_MACRO(asin)
+TVMET_DECLARE_MACRO(acos)
+TVMET_DECLARE_MACRO(atan)
+TVMET_DECLARE_MACRO(exp)
+TVMET_DECLARE_MACRO(log)
+TVMET_DECLARE_MACRO(log10)
+TVMET_DECLARE_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_DECLARE_MACRO(asinh)
+TVMET_DECLARE_MACRO(acosh)
+TVMET_DECLARE_MACRO(atanh)
+TVMET_DECLARE_MACRO(expm1)
+TVMET_DECLARE_MACRO(log1p)
+TVMET_DECLARE_MACRO(erf)
+TVMET_DECLARE_MACRO(erfc)
+TVMET_DECLARE_MACRO(j0)
+TVMET_DECLARE_MACRO(j1)
+TVMET_DECLARE_MACRO(y0)
+TVMET_DECLARE_MACRO(y1)
+TVMET_DECLARE_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_DECLARE_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*
+ * unary_function(XprMatrix<E, Rows, Cols>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)                   \
+template<class E, std::size_t Rows, std::size_t Cols>           \
+inline                                   \
+XprMatrix<                               \
+  XprUnOp<                               \
+    Fcnl_##NAME<typename E::value_type>,               \
+    XprMatrix<E, Rows, Cols>                       \
+  >,                                   \
+  Rows, Cols                               \
+>                                   \
+NAME(const XprMatrix<E, Rows, Cols>& rhs) {               \
+  typedef XprUnOp<                           \
+    Fcnl_##NAME<typename E::value_type>,               \
+    XprMatrix<E, Rows, Cols>                       \
+  >                             expr_type; \
+  return XprMatrix<expr_type, Rows, Cols>(expr_type(rhs));       \
+}
+
+TVMET_IMPLEMENT_MACRO(abs)
+TVMET_IMPLEMENT_MACRO(cbrt)
+TVMET_IMPLEMENT_MACRO(ceil)
+TVMET_IMPLEMENT_MACRO(floor)
+TVMET_IMPLEMENT_MACRO(rint)
+TVMET_IMPLEMENT_MACRO(sin)
+TVMET_IMPLEMENT_MACRO(cos)
+TVMET_IMPLEMENT_MACRO(tan)
+TVMET_IMPLEMENT_MACRO(sinh)
+TVMET_IMPLEMENT_MACRO(cosh)
+TVMET_IMPLEMENT_MACRO(tanh)
+TVMET_IMPLEMENT_MACRO(asin)
+TVMET_IMPLEMENT_MACRO(acos)
+TVMET_IMPLEMENT_MACRO(atan)
+TVMET_IMPLEMENT_MACRO(exp)
+TVMET_IMPLEMENT_MACRO(log)
+TVMET_IMPLEMENT_MACRO(log10)
+TVMET_IMPLEMENT_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_IMPLEMENT_MACRO(asinh)
+TVMET_IMPLEMENT_MACRO(acosh)
+TVMET_IMPLEMENT_MACRO(atanh)
+TVMET_IMPLEMENT_MACRO(expm1)
+TVMET_IMPLEMENT_MACRO(log1p)
+TVMET_IMPLEMENT_MACRO(erf)
+TVMET_IMPLEMENT_MACRO(erfc)
+TVMET_IMPLEMENT_MACRO(j0)
+TVMET_IMPLEMENT_MACRO(j1)
+TVMET_IMPLEMENT_MACRO(y0)
+TVMET_IMPLEMENT_MACRO(y1)
+TVMET_IMPLEMENT_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_IMPLEMENT_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MATRIX_UNARY_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MtMProduct.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,139 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MtMProduct.h,v 1.19 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MTMPRODUCT_H
+#define TVMET_XPR_MTMPRODUCT_H
+
+#include <tvmet/meta/Gemtm.h>
+#include <tvmet/loop/Gemtm.h>
+
+namespace tvmet {
+
+
+/**
+ * \class XprMtMProduct MtMProduct.h "tvmet/xpr/MtMProduct.h"
+ * \brief Expression for product of transposed(matrix)-matrix product.
+ *        using formula
+ *        \f[
+ *        M_1^{T}\,M_2
+ *        \f]
+ * \note The number of rows of rhs matrix have to be equal rows of rhs matrix,
+ *       since lhs matrix 1 is transposed.
+ *       The result is a (Cols1 x Cols2) matrix.
+ */
+template<class E1, std::size_t Rows1, std::size_t Cols1,
+	 class E2, std::size_t Cols2>
+class XprMtMProduct
+  : public TvmetBase< XprMtMProduct<E1, Rows1, Cols1, E2, Cols2> >
+{
+private:
+  XprMtMProduct();
+  XprMtMProduct& operator=(const XprMtMProduct&);
+
+public:
+  typedef typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type							value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_lhs   = E1::ops,
+    ops_rhs   = E2::ops,
+    M = Rows1 * Cols1 * Cols2,
+    N = (Rows1-1) * Cols1 * Cols2,
+    ops_plus  = M * NumericTraits<value_type>::ops_plus,
+    ops_muls  = N * NumericTraits<value_type>::ops_muls,
+    ops       = ops_plus + ops_muls,
+    use_meta  = Cols1*Cols2 < TVMET_COMPLEXITY_MM_TRIGGER ? true : false
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMtMProduct(const E1& lhs, const E2& rhs)
+    : m_lhs(lhs), m_rhs(rhs)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMtMProduct(const XprMtMProduct& e)
+    : m_lhs(e.m_lhs), m_rhs(e.m_rhs) { }
+#endif
+
+private:
+  /** Wrapper for meta gemm. */
+  static inline
+  value_type do_gemtm(dispatch<true>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return meta::gemtm<Rows1, Cols1,
+                       Cols2,
+                       0>::prod(lhs, rhs, i, j);
+  }
+
+  /** Wrapper for loop gemm. */
+  static inline
+  value_type do_gemtm(dispatch<false>, const E1& lhs, const E2& rhs, std::size_t i, std::size_t j) {
+    return loop::gemtm<Rows1, Cols1,
+	               Cols2>::prod(lhs, rhs, i, j);
+  }
+
+public:
+  /** index operator for arrays/matrices */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    TVMET_RT_CONDITION((i < Cols1) && (j < Cols2), "XprMtMProduct Bounce Violation")
+    return do_gemtm(dispatch<use_meta>(), m_lhs, m_rhs, i, j);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMtMProduct["
+       << (use_meta ? "M" :  "L") << ", O=" << ops
+       << ", (O1=" << ops_lhs << ", O2=" << ops_rhs << ")]<"
+       << std::endl;
+    m_lhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R1=" << Rows1 << ", C1=" << Cols1 << ",\n";
+    m_rhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "C2=" << Cols2 << ",\n"
+       << IndentLevel(l)
+       << "\n"
+       << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E1							m_lhs;
+  const E2							m_rhs;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MTMPRODUCT_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/MtVProduct.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,128 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: MtVProduct.h,v 1.14 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_MTVPRODUCT_H
+#define TVMET_XPR_MTVPRODUCT_H
+
+#include <tvmet/meta/Gemtv.h>
+#include <tvmet/loop/Gemtv.h>
+
+namespace tvmet {
+
+
+/**
+ * \class XprMtVProduct MtVProduct.h "tvmet/xpr/MtVProduct.h"
+ * \brief Expression for matrix-transposed vector product
+ *        using formula
+ *        \f[
+ *        M^T\,v
+ *        \f]
+ */
+template<class E1, std::size_t Rows, std::size_t Cols,
+	 class E2>
+class XprMtVProduct
+  : public TvmetBase< XprMtVProduct<E1, Rows, Cols, E2> >
+{
+  XprMtVProduct();
+  XprMtVProduct& operator=(const XprMtVProduct&);
+
+public:
+  typedef typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type							value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_lhs   = E1::ops,
+    ops_rhs   = E2::ops,
+    M         = Cols * Rows,
+    N         = Cols * (Rows - 1),
+    ops_plus  = M * NumericTraits<value_type>::ops_plus,
+    ops_muls  = N * NumericTraits<value_type>::ops_muls,
+    ops       = ops_plus + ops_muls,
+    use_meta  = Rows*Cols < TVMET_COMPLEXITY_MV_TRIGGER ? true : false
+  };
+
+public:
+  /** Constructor. */
+  explicit XprMtVProduct(const E1& lhs, const E2& rhs)
+    : m_lhs(lhs), m_rhs(rhs)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprMtVProduct(const XprMtVProduct& e)
+    : m_lhs(e.m_lhs), m_rhs(e.m_rhs)
+  { }
+#endif
+
+private:
+  /** Wrapper for meta gemm. */
+  static inline
+  value_type do_gemtv(dispatch<true>, const E1& lhs, const E2& rhs, std::size_t i) {
+    return meta::gemtv<Rows, Cols, 0>::prod(lhs, rhs, i);
+  }
+
+  /** Wrapper for loop gemm. */
+  static inline
+  value_type do_gemtv(dispatch<false>, const E1& lhs, const E2& rhs, std::size_t i) {
+    return loop::gemtv<Rows, Cols>::prod(lhs, rhs, i);
+  }
+
+public:
+  /** index operator, returns the expression by index. This is the vector
+      style since a matrix*vector gives a vector. */
+  value_type operator()(std::size_t j) const {
+    TVMET_RT_CONDITION(j < Cols , "XprMtVProduct Bounce Violation")
+    return do_gemtv(dispatch<use_meta>(), m_lhs, m_rhs, j);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprMtVProduct[O=" << ops << ", (O1=" << ops_lhs << ", O2=" << ops_rhs << ")]<"
+       << std::endl;
+    m_lhs.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "R=" << Rows << ", C=" << Cols << ",\n";
+    m_rhs.print_xpr(os, l);
+    os << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E1							m_lhs;
+  const E2							m_rhs;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_MTVPRODUCT_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/Null.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,69 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Null.h,v 1.11 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_NULL_H
+#define TVMET_XPR_NULL_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprNull Null.h "tvmet/xpr/Null.h"
+ * \brief Null object design pattern
+ */
+class XprNull
+  : public TvmetBase< XprNull >
+{
+  XprNull& operator=(const XprNull&);
+
+public:
+  explicit XprNull() { }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l) << "XprNull[O=0]" << std::endl;
+  }
+};
+
+
+#define TVMET_BINARY_OPERATOR(OP)                   			\
+template< class T >                    					\
+inline                     						\
+T operator OP (const T& lhs, XprNull) { return lhs; }
+
+TVMET_BINARY_OPERATOR(+)
+TVMET_BINARY_OPERATOR(-)
+TVMET_BINARY_OPERATOR(*)
+TVMET_BINARY_OPERATOR(/)
+
+#undef TVMET_BINARY_OPERATOR
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_NULL_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/UnOperator.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,99 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: UnOperator.h,v 1.17 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_UNOPERATOR_H
+#define TVMET_XPR_UNOPERATOR_H
+
+namespace tvmet {
+
+
+/**
+ * \class XprUnOp UnOperator.h "tvmet/xpr/UnOperator.h"
+ * \brief Unary operator working on one subexpression.
+ *
+ * Using the access operator() the unary operation will be evaluated.
+ */
+template<class UnOp, class E>
+class XprUnOp
+  : public TvmetBase< XprUnOp<UnOp, E> >
+{
+  XprUnOp();
+  XprUnOp& operator=(const XprUnOp&);
+
+public:
+  typedef typename UnOp::value_type				value_type;
+
+public:
+  /** Complexity counter. */
+  enum {
+    ops_expr  = E::ops,
+    ops       = 1 * ops_expr
+  };
+
+public:
+  /** Constructor for an expressions. */
+  explicit XprUnOp(const E& e)
+    : m_expr(e)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprUnOp(const XprUnOp& e)
+    : m_expr(e.m_expr)
+  { }
+#endif
+
+  /** Index operator, evaluates the expression inside. */
+  value_type operator()(std::size_t i) const {
+    return UnOp::apply_on(m_expr(i));
+  }
+
+  /** index operator for arrays/matrices. */
+  value_type operator()(std::size_t i, std::size_t j) const {
+    return UnOp::apply_on(m_expr(i, j));
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprUnOp[O="<< ops << ", (O=" << ops_expr << ")]<"
+       << std::endl;
+    UnOp::print_xpr(os, l);
+    m_expr.print_xpr(os, l);
+    os << IndentLevel(--l)
+       << ">," << std::endl;
+  }
+
+private:
+  const E							m_expr;
+};
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_UNOPERATOR_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/Vector.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,157 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: Vector.h,v 1.28 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_VECTOR_H
+#define TVMET_XPR_VECTOR_H
+
+#include <tvmet/meta/Vector.h>
+#include <tvmet/loop/Vector.h>
+
+namespace tvmet {
+
+
+/* forwards */
+template <class T, std::size_t Sz> class Vector;
+
+/**
+ * \class XprVector Vector.h "tvmet/xpr/Vector.h"
+ * \brief Represents the expression for vectors at any node in the parse tree.
+ *
+ * Specifically, XprVector is the class that wraps the expression, and the
+ * expression itself is represented by the template parameter E. The
+ * class XprVector is known as an anonymizing expression wrapper because
+ * it can hold any subexpression of arbitrary complexity, allowing
+ * clients to work with any expression by holding on to it via the
+ * wrapper, without having to know the name of the type object that
+ * actually implements the expression.
+ * \note leave the Ctors non-explicit to allow implicit type conversation.
+ */
+template<class E, std::size_t Sz>
+class XprVector : public TvmetBase< XprVector<E, Sz> >
+{
+  XprVector();
+  XprVector& operator=(const XprVector&);
+
+public:
+  typedef typename E::value_type			value_type;
+
+public:
+  /** Dimensions. */
+  enum {
+    Size = Sz			/**< The size of the vector. */
+  };
+
+public:
+  /** Complexity counter */
+  enum {
+    ops_assign = Size,
+    ops        = E::ops,
+    use_meta   = ops_assign < TVMET_COMPLEXITY_V_ASSIGN_TRIGGER ? true : false
+  };
+
+public:
+  /** Constructor. */
+  explicit XprVector(const E& e)
+    : m_expr(e)
+  { }
+
+  /** Copy Constructor. Not explicit! */
+#if defined(TVMET_OPTIMIZE_XPR_MANUAL_CCTOR)
+  XprVector(const XprVector& e)
+    : m_expr(e.m_expr)
+  { }
+#endif
+
+ /** const index operator for vectors. */
+  value_type operator()(std::size_t i) const {
+    TVMET_RT_CONDITION(i < Size, "XprVector Bounce Violation")
+    return m_expr(i);
+  }
+
+  /** const index operator for vectors. */
+  value_type operator[](std::size_t i) const {
+    return this->operator()(i);
+  }
+
+private:
+  /** Wrapper for meta assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<true>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    meta::Vector<Size, 0>::assign(dest, src, assign_fn);
+  }
+
+  /** Wrapper for loop assign. */
+  template<class Dest, class Src, class Assign>
+  static inline
+  void do_assign(dispatch<false>, Dest& dest, const Src& src, const Assign& assign_fn) {
+    loop::Vector<Size>::assign(dest, src, assign_fn);
+  }
+
+public:
+  /** assign this expression to Vector dest. */
+  template<class Dest, class Assign>
+  void assign_to(Dest& dest, const Assign& assign_fn) const {
+    /* here is a way for caching, since each complex 'Node'
+       is of type XprVector. */
+    do_assign(dispatch<use_meta>(), dest, *this, assign_fn);
+  }
+
+public: // debugging Xpr parse tree
+  void print_xpr(std::ostream& os, std::size_t l=0) const {
+    os << IndentLevel(l++)
+       << "XprVector["
+       << (use_meta ? "M" :  "L") << ", O=" << ops << "]<"
+       << std::endl;
+    m_expr.print_xpr(os, l);
+    os << IndentLevel(l)
+       << "Sz=" << Size << std::endl;
+    os << IndentLevel(--l) << ">"
+       << ((l != 0) ? "," : "") << std::endl;
+  }
+
+private:
+  const E						m_expr;
+};
+
+
+} // namespace tvmet
+
+#include <tvmet/Functional.h>
+
+#include <tvmet/xpr/BinOperator.h>
+#include <tvmet/xpr/UnOperator.h>
+#include <tvmet/xpr/Literal.h>
+
+#include <tvmet/xpr/VectorFunctions.h>
+#include <tvmet/xpr/VectorBinaryFunctions.h>
+#include <tvmet/xpr/VectorUnaryFunctions.h>
+#include <tvmet/xpr/VectorOperators.h>
+#include <tvmet/xpr/Eval.h>
+
+#endif // TVMET_XPR_VECTOR_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/VectorBinaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,320 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorBinaryFunctions.h,v 1.12 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_VECTOR_BINARY_FUNCTIONS_H
+#define TVMET_XPR_VECTOR_BINARY_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*
+ * binary_function(XprVector<E1, Sz>, XprVector<E2, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class E1, class E2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME(const XprVector<E1, Sz>& lhs, 					\
+     const XprVector<E2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2)
+TVMET_DECLARE_MACRO(drem)
+TVMET_DECLARE_MACRO(fmod)
+TVMET_DECLARE_MACRO(hypot)
+TVMET_DECLARE_MACRO(jn)
+TVMET_DECLARE_MACRO(yn)
+TVMET_DECLARE_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+TVMET_DECLARE_MACRO(polar)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * binary_function(XprVector<E, Sz>, POD)
+ */
+#define TVMET_DECLARE_MACRO(NAME, TP)		\
+template<class E, std::size_t Sz>		\
+inline						\
+XprVector<					\
+  XprBinOp<					\
+    Fcnl_##NAME<typename E::value_type, TP >,	\
+    XprVector<E, Sz>,				\
+    XprLiteral< TP >				\
+  >,						\
+  Sz						\
+>						\
+NAME(const XprVector<E, Sz>& lhs, 		\
+     TP rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2, int)
+TVMET_DECLARE_MACRO(drem, int)
+TVMET_DECLARE_MACRO(fmod, int)
+TVMET_DECLARE_MACRO(hypot, int)
+TVMET_DECLARE_MACRO(jn, int)
+TVMET_DECLARE_MACRO(yn, int)
+TVMET_DECLARE_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(atan2, long long int)
+TVMET_DECLARE_MACRO(drem, long long int)
+TVMET_DECLARE_MACRO(fmod, long long int)
+TVMET_DECLARE_MACRO(hypot, long long int)
+TVMET_DECLARE_MACRO(jn, long long int)
+TVMET_DECLARE_MACRO(yn, long long int)
+TVMET_DECLARE_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_DECLARE_MACRO(atan2, float)
+TVMET_DECLARE_MACRO(drem, float)
+TVMET_DECLARE_MACRO(fmod, float)
+TVMET_DECLARE_MACRO(hypot, float)
+TVMET_DECLARE_MACRO(jn, float)
+TVMET_DECLARE_MACRO(yn, float)
+TVMET_DECLARE_MACRO(pow, float)
+
+TVMET_DECLARE_MACRO(atan2, double)
+TVMET_DECLARE_MACRO(drem, double)
+TVMET_DECLARE_MACRO(fmod, double)
+TVMET_DECLARE_MACRO(hypot, double)
+TVMET_DECLARE_MACRO(jn, double)
+TVMET_DECLARE_MACRO(yn, double)
+TVMET_DECLARE_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(atan2, long double)
+TVMET_DECLARE_MACRO(drem, long double)
+TVMET_DECLARE_MACRO(fmod, long double)
+TVMET_DECLARE_MACRO(hypot, long double)
+TVMET_DECLARE_MACRO(jn, long double)
+TVMET_DECLARE_MACRO(yn, long double)
+TVMET_DECLARE_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * binary_function(XprVector<E, Sz>, std::complex<>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)				\
+template<class E, std::size_t Sz, class T>			\
+inline								\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,	\
+    XprVector<E, Sz>,						\
+    XprLiteral< std::complex<T> >				\
+  >,								\
+  Sz								\
+>								\
+NAME(const XprVector<E, Sz>& lhs, 				\
+     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(atan2)
+TVMET_DECLARE_MACRO(drem)
+TVMET_DECLARE_MACRO(fmod)
+TVMET_DECLARE_MACRO(hypot)
+TVMET_DECLARE_MACRO(jn)
+TVMET_DECLARE_MACRO(yn)
+TVMET_DECLARE_MACRO(pow)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*
+ * binary_function(XprVector<E1, Sz>, XprVector<E2, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class E1, class E2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME(const XprVector<E1, Sz>& lhs, const XprVector<E2, Sz>& rhs) {	\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >		    					expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, rhs));						\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2)
+TVMET_IMPLEMENT_MACRO(drem)
+TVMET_IMPLEMENT_MACRO(fmod)
+TVMET_IMPLEMENT_MACRO(hypot)
+TVMET_IMPLEMENT_MACRO(jn)
+TVMET_IMPLEMENT_MACRO(yn)
+TVMET_IMPLEMENT_MACRO(pow)
+#if defined(TVMET_HAVE_COMPLEX)
+TVMET_IMPLEMENT_MACRO(polar)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * binary_function(XprVector<E, Sz>, POD)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, TP)					\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< TP >							\
+  >,									\
+  Sz									\
+>									\
+NAME(const XprVector<E, Sz>& lhs, TP rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< TP >							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, XprLiteral< TP >(rhs)));				\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2, int)
+TVMET_IMPLEMENT_MACRO(drem, int)
+TVMET_IMPLEMENT_MACRO(fmod, int)
+TVMET_IMPLEMENT_MACRO(hypot, int)
+TVMET_IMPLEMENT_MACRO(jn, int)
+TVMET_IMPLEMENT_MACRO(yn, int)
+TVMET_IMPLEMENT_MACRO(pow, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(atan2, long long int)
+TVMET_IMPLEMENT_MACRO(drem, long long int)
+TVMET_IMPLEMENT_MACRO(fmod, long long int)
+TVMET_IMPLEMENT_MACRO(hypot, long long int)
+TVMET_IMPLEMENT_MACRO(jn, long long int)
+TVMET_IMPLEMENT_MACRO(yn, long long int)
+TVMET_IMPLEMENT_MACRO(pow, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+TVMET_IMPLEMENT_MACRO(atan2, float)
+TVMET_IMPLEMENT_MACRO(drem, float)
+TVMET_IMPLEMENT_MACRO(fmod, float)
+TVMET_IMPLEMENT_MACRO(hypot, float)
+TVMET_IMPLEMENT_MACRO(jn, float)
+TVMET_IMPLEMENT_MACRO(yn, float)
+TVMET_IMPLEMENT_MACRO(pow, float)
+
+TVMET_IMPLEMENT_MACRO(atan2, double)
+TVMET_IMPLEMENT_MACRO(drem, double)
+TVMET_IMPLEMENT_MACRO(fmod, double)
+TVMET_IMPLEMENT_MACRO(hypot, double)
+TVMET_IMPLEMENT_MACRO(jn, double)
+TVMET_IMPLEMENT_MACRO(yn, double)
+TVMET_IMPLEMENT_MACRO(pow, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(atan2, long double)
+TVMET_IMPLEMENT_MACRO(drem, long double)
+TVMET_IMPLEMENT_MACRO(fmod, long double)
+TVMET_IMPLEMENT_MACRO(hypot, long double)
+TVMET_IMPLEMENT_MACRO(jn, long double)
+TVMET_IMPLEMENT_MACRO(yn, long double)
+TVMET_IMPLEMENT_MACRO(pow, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * binary_function(XprVector<E, Sz>, std::complex<>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Sz									\
+>									\
+NAME(const XprVector<E, Sz>& lhs, const std::complex<T>& rhs) {		\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));		\
+}
+
+TVMET_IMPLEMENT_MACRO(atan2)
+TVMET_IMPLEMENT_MACRO(drem)
+TVMET_IMPLEMENT_MACRO(fmod)
+TVMET_IMPLEMENT_MACRO(hypot)
+TVMET_IMPLEMENT_MACRO(jn)
+TVMET_IMPLEMENT_MACRO(yn)
+TVMET_IMPLEMENT_MACRO(pow)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_VECTOR_BINARY_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/VectorFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,684 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorFunctions.h,v 1.21 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_VECTOR_FUNCTIONS_H
+#define TVMET_XPR_VECTOR_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/* forwards */
+template<class T, std::size_t Sz> class Vector;
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic functions add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * function(XprVector<E1, Sz>, XprVector<E2, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)					\
+template<class E1, class E2, std::size_t Sz>				\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME (const XprVector<E1, Sz>& lhs,					\
+      const XprVector<E2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)		// per se element wise
+TVMET_DECLARE_MACRO(sub)		// per se element wise
+TVMET_DECLARE_MACRO(mul)		// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(div)		// not defined for vectors
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * function(XprVector<E, Sz>, POD)
+ * function(POD, XprVector<E, Sz>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, POD)				\
+template<class E, std::size_t Sz>				\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< typename E::value_type, POD >,			\
+    XprVector<E, Sz>,						\
+    XprLiteral< POD >						\
+  >,								\
+  Sz								\
+>								\
+NAME (const XprVector<E, Sz>& lhs, 				\
+      POD rhs) TVMET_CXX_ALWAYS_INLINE;				\
+								\
+template<class E, std::size_t Sz>				\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< POD, typename E::value_type>,			\
+    XprLiteral< POD >,						\
+    XprVector<E, Sz>						\
+  >,								\
+  Sz								\
+>								\
+NAME (POD lhs, 							\
+      const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, int)
+TVMET_DECLARE_MACRO(sub, int)
+TVMET_DECLARE_MACRO(mul, int)
+TVMET_DECLARE_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, long long int)
+TVMET_DECLARE_MACRO(sub, long long int)
+TVMET_DECLARE_MACRO(mul, long long int)
+TVMET_DECLARE_MACRO(div, long long int)
+#endif
+
+TVMET_DECLARE_MACRO(add, float)
+TVMET_DECLARE_MACRO(sub, float)
+TVMET_DECLARE_MACRO(mul, float)
+TVMET_DECLARE_MACRO(div, float)
+
+TVMET_DECLARE_MACRO(add, double)
+TVMET_DECLARE_MACRO(sub, double)
+TVMET_DECLARE_MACRO(mul, double)
+TVMET_DECLARE_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, long double)
+TVMET_DECLARE_MACRO(sub, long double)
+TVMET_DECLARE_MACRO(mul, long double)
+TVMET_DECLARE_MACRO(div, long double)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(XprMatrix<E, Rows, Cols>, complex<T>)
+ * function(complex<T>, XprMatrix<E, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME)				\
+template<class E, std::size_t Sz, class T>			\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< typename E::value_type, std::complex<T> >,	\
+    XprVector<E, Sz>,						\
+    XprLiteral< std::complex<T> >				\
+  >,								\
+  Sz								\
+>								\
+NAME (const XprVector<E, Sz>& lhs,				\
+      const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+								\
+template<class E, std::size_t Sz, class T>			\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,	\
+    XprLiteral< std::complex<T> >,				\
+    XprVector<E, Sz>						\
+  >,								\
+  Sz								\
+>								\
+NAME (const std::complex<T>& lhs, 				\
+      const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add)
+TVMET_DECLARE_MACRO(sub)
+TVMET_DECLARE_MACRO(mul)
+TVMET_DECLARE_MACRO(div)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * vector specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+template<class E, std::size_t Sz>
+typename NumericTraits<typename E::value_type>::sum_type
+sum(const XprVector<E, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+typename NumericTraits<typename E::value_type>::sum_type
+product(const XprVector<E, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, class E2, std::size_t Sz>
+typename PromoteTraits<
+  typename E1::value_type,
+  typename E2::value_type
+>::value_type
+dot(const XprVector<E1, Sz>& lhs,
+    const XprVector<E2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, class E, std::size_t Sz>
+typename PromoteTraits<T, typename E::value_type>::value_type
+dot(const Vector<T, Sz>& lhs,
+    const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, class T, std::size_t Sz>
+typename PromoteTraits<T, typename E::value_type>::value_type
+dot(const XprVector<E, Sz>& lhs,
+    const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E1, class E2>
+Vector<
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type,
+  3
+>
+cross(const XprVector<E1, 3>& lhs,
+      const XprVector<E2, 3>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class T, class E>
+Vector<
+  typename PromoteTraits<T, typename E::value_type>::value_type, 3>
+cross(const Vector<T, 3>& lhs,
+      const XprVector<E, 3>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, class T>
+Vector<
+  typename PromoteTraits<T, typename E::value_type>::value_type, 3>
+cross(const XprVector<E, 3>& lhs,
+      const Vector<T, 3>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+typename NumericTraits<typename E::value_type>::sum_type
+norm1(const XprVector<E, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+typename NumericTraits<typename E::value_type>::sum_type
+norm2(const XprVector<E, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+template<class E, std::size_t Sz>
+XprVector<
+  XprBinOp<
+    Fcnl_div<typename E::value_type, typename E::value_type>,
+    XprVector<E, Sz>,
+    XprLiteral<typename E::value_type>
+  >,
+  Sz
+>
+normalize(const XprVector<E, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*
+ * function(XprVector<E1, Sz>, XprVector<E2, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)					\
+template<class E1, class E2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME (const XprVector<E1, Sz>& lhs, const XprVector<E2, Sz>& rhs) {	\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  > 							 expr_type;	\
+  return XprVector<expr_type, Sz>(expr_type(lhs, rhs));			\
+}
+
+TVMET_IMPLEMENT_MACRO(add)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub)		// per se element wise
+TVMET_IMPLEMENT_MACRO(mul)		// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(div)		// not defined for vectors
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * function(XprVector<E, Sz>, POD)
+ * function(POD, XprVector<E, Sz>)
+ * Note: - operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, POD)				\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< typename E::value_type, POD >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< POD >							\
+  >,									\
+  Sz									\
+>									\
+NAME (const XprVector<E, Sz>& lhs, POD rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< typename E::value_type, POD >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< POD >							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, XprLiteral< POD >(rhs)));				\
+}									\
+									\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, typename E::value_type>,				\
+    XprLiteral< POD >,							\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME (POD lhs, const XprVector<E, Sz>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< POD, typename E::value_type>,				\
+    XprLiteral< POD >,							\
+    XprVector<E, Sz>							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(XprLiteral< POD >(lhs), rhs));				\
+}
+
+TVMET_IMPLEMENT_MACRO(add, int)
+TVMET_IMPLEMENT_MACRO(sub, int)
+TVMET_IMPLEMENT_MACRO(mul, int)
+TVMET_IMPLEMENT_MACRO(div, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, long long int)
+TVMET_IMPLEMENT_MACRO(sub, long long int)
+TVMET_IMPLEMENT_MACRO(mul, long long int)
+TVMET_IMPLEMENT_MACRO(div, long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(add, float)
+TVMET_IMPLEMENT_MACRO(sub, float)
+TVMET_IMPLEMENT_MACRO(mul, float)
+TVMET_IMPLEMENT_MACRO(div, float)
+
+TVMET_IMPLEMENT_MACRO(add, double)
+TVMET_IMPLEMENT_MACRO(sub, double)
+TVMET_IMPLEMENT_MACRO(mul, double)
+TVMET_IMPLEMENT_MACRO(div, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, long double)
+TVMET_IMPLEMENT_MACRO(sub, long double)
+TVMET_IMPLEMENT_MACRO(mul, long double)
+TVMET_IMPLEMENT_MACRO(div, long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * function(XprMatrix<E, Rows, Cols>, complex<T>)
+ * function(complex<T>, XprMatrix<E, Rows, Cols>)
+ * Note: - operations +,-,*,/ are per se element wise
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)				   \
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Sz									\
+>									\
+NAME (const XprVector<E, Sz>& lhs, const std::complex<T>& rhs) {	\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));		\
+}									\
+									\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+NAME (const std::complex<T>& lhs, const XprVector<E, Sz>& rhs) {	\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprVector<E, Sz>							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs));		\
+}
+
+TVMET_IMPLEMENT_MACRO(add)
+TVMET_IMPLEMENT_MACRO(sub)
+TVMET_IMPLEMENT_MACRO(mul)
+TVMET_IMPLEMENT_MACRO(div)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * vector specific functions
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/**
+ * \fn sum(const XprVector<E, Sz>& v)
+ * \brief Compute the sum of the vector expression.
+ * \ingroup _unary_function
+ *
+ * Simply compute the sum of the given vector as:
+ * \f[
+ * \sum_{i = 0}^{Sz-1} v[i]
+ * \f]
+ */
+template<class E, std::size_t Sz>
+inline
+typename NumericTraits<typename E::value_type>::sum_type
+sum(const XprVector<E, Sz>& v) {
+  return meta::Vector<Sz>::sum(v);
+}
+
+
+/**
+ * \fn product(const XprVector<E, Sz>& v)
+ * \brief Compute the product of the vector elements.
+ * \ingroup _unary_function
+ *
+ * Simply computer the product of the given vector expression as:
+ * \f[
+ * \prod_{i = 0}^{Sz - 1} v[i]
+ * \f]
+ */
+template<class E, std::size_t Sz>
+inline
+typename NumericTraits<typename E::value_type>::sum_type
+product(const XprVector<E, Sz>& v) {
+  return meta::Vector<Sz>::product(v);
+}
+
+
+/**
+ * \fn dot(const XprVector<E1, Sz>& lhs, const XprVector<E2, Sz>& rhs)
+ * \brief Compute the dot/inner product
+ * \ingroup _binary_function
+ *
+ * Compute the dot product as:
+ * \f[
+ * \sum_{i = 0}^{Sz - 1} ( lhs[i] * rhs[i] )
+ * \f]
+ * where lhs is a column vector and rhs is a row vector, both vectors
+ * have the same dimension.
+ */
+template<class E1, class E2, std::size_t Sz>
+inline
+typename PromoteTraits<
+  typename E1::value_type,
+  typename E2::value_type
+>::value_type
+dot(const XprVector<E1, Sz>& lhs, const XprVector<E2, Sz>& rhs) {
+  return meta::Vector<Sz>::dot(lhs, rhs);
+}
+
+
+/**
+ * \fn dot(const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs)
+ * \brief Compute the dot/inner product
+ * \ingroup _binary_function
+ *
+ * Compute the dot product as:
+ * \f[
+ * \sum_{i = 0}^{Sz - 1} ( lhs[i] * rhs[i] )
+ * \f]
+ * where lhs is a column vector and rhs is a row vector, both vectors
+ * have the same dimension.
+ */
+template<class T, class E, std::size_t Sz>
+inline
+typename PromoteTraits<T, typename E::value_type>::value_type
+dot(const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) {
+  return meta::Vector<Sz>::dot(lhs, rhs);
+}
+
+
+/**
+ * \fn dot(const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs)
+ * \brief Compute the dot/inner product
+ * \ingroup _binary_function
+ *
+ * Compute the dot product as:
+ * \f[
+ * \sum_{i = 0}^{Sz - 1} ( lhs[i] * rhs[i] )
+ * \f]
+ * where lhs is a column vector and rhs is a row vector, both vectors
+ * have the same dimension.
+ */
+template<class E, class T, std::size_t Sz>
+inline
+typename PromoteTraits<T, typename E::value_type>::value_type
+dot(const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) {
+  return meta::Vector<Sz>::dot(lhs, rhs);
+}
+
+
+/**
+ * \fn cross(const XprVector<E1, 3>& lhs, const XprVector<E2, 3>& rhs)
+ * \brief Compute the cross/outer product
+ * \ingroup _binary_function
+ * \note working only for vectors of size = 3
+ * \todo Implement vector outer product as ET and MT, returning a XprVector
+ */
+template<class E1, class E2>
+inline
+Vector<
+  typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type,
+  3
+>
+cross(const XprVector<E1, 3>& lhs, const XprVector<E2, 3>& rhs) {
+  typedef typename PromoteTraits<
+    typename E1::value_type,
+    typename E2::value_type
+  >::value_type						value_type;
+  return Vector<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
+			       rhs(0)*lhs(2) - lhs(0)*rhs(2),
+			       lhs(0)*rhs(1) - rhs(0)*lhs(1));
+}
+
+
+/**
+ * \fn cross(const XprVector<E, 3>& lhs, const Vector<T, 3>& rhs)
+ * \brief Compute the cross/outer product
+ * \ingroup _binary_function
+ * \note working only for vectors of size = 3
+ * \todo Implement vector outer product as ET and MT, returning a XprVector
+ */
+template<class E, class T>
+inline
+Vector<
+  typename PromoteTraits<T, typename E::value_type>::value_type, 3>
+cross(const XprVector<E, 3>& lhs, const Vector<T, 3>& rhs) {
+  typedef typename PromoteTraits<
+    typename E::value_type, T>::value_type 		value_type;
+  return Vector<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
+			       rhs(0)*lhs(2) - lhs(0)*rhs(2),
+			       lhs(0)*rhs(1) - rhs(0)*lhs(1));
+}
+
+
+/**
+ * \fn cross(const Vector<T, 3>& lhs, const XprVector<E, 3>& rhs)
+ * \brief Compute the cross/outer product
+ * \ingroup _binary_function
+ * \note working only for vectors of size = 3
+ * \todo Implement vector outer product as ET and MT, returning a XprVector
+ */
+template<class T1, class E2>
+inline
+Vector<
+  typename PromoteTraits<T1, typename E2::value_type>::value_type, 3>
+cross(const Vector<T1, 3>& lhs, const XprVector<E2, 3>& rhs) {
+  typedef typename PromoteTraits<
+    typename E2::value_type, T1>::value_type 		value_type;
+  return Vector<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
+			       rhs(0)*lhs(2) - lhs(0)*rhs(2),
+			       lhs(0)*rhs(1) - rhs(0)*lhs(1));
+}
+
+
+/**
+ * \fn norm1(const XprVector<E, Sz>& v)
+ * \brief The \f$l_1\f$ norm of a vector expression.
+ * \ingroup _unary_function
+ * The norm of any vector is just the square root of the dot product of
+ * a vector with itself, or
+ *
+ * \f[
+ * |Vector<T, Sz> v| = |v| = \sum_{i=0}^{Sz-1}\,|v[i]|
+ * \f]
+ */
+template<class E, std::size_t Sz>
+inline
+typename NumericTraits<typename E::value_type>::sum_type
+norm1(const XprVector<E, Sz>& v) {
+  return sum(abs(v));
+}
+
+
+/**
+ * \fn norm2(const XprVector<E, Sz>& v)
+ * \brief The euklidian norm (or \f$l_2\f$ norm) of a vector expression.
+ * \ingroup _unary_function
+ * The norm of any vector is just the square root of the dot product of
+ * a vector with itself, or
+ *
+ * \f[
+ * |Vector<T, Sz> v| = |v| = \sqrt{ \sum_{i=0}^{Sz-1}\,v[i]^2 }
+ * \f]
+ *
+ * \note The internal cast for Vector<int> avoids warnings on sqrt.
+ */
+template<class E, std::size_t Sz>
+inline
+typename NumericTraits<typename E::value_type>::sum_type
+norm2(const XprVector<E, Sz>& v) {
+  typedef typename E::value_type			value_type;
+  return static_cast<value_type>( std::sqrt(static_cast<value_type>(dot(v, v))) );
+}
+
+
+/**
+ * \fn normalize(const XprVector<E, Sz>& v)
+ * \brief Normalize the given vector expression.
+ * \ingroup _unary_function
+ * \sa norm2
+ *
+ * using the equation:
+ * \f[
+ * \frac{Vector<T, Sz> v}{\sqrt{ \sum_{i=0}^{Sz-1}\,v[i]^2 }}
+ * \f]
+ */
+template<class E, std::size_t Sz>
+inline
+XprVector<
+  XprBinOp<
+    Fcnl_div<typename E::value_type, typename E::value_type>,
+    XprVector<E, Sz>,
+    XprLiteral<typename E::value_type>
+  >,
+  Sz
+>
+normalize(const XprVector<E, Sz>& v) {
+  typedef typename E::value_type			value_type;
+  typedef XprBinOp<
+    Fcnl_div<value_type, value_type>,
+    XprVector<E, Sz>,
+    XprLiteral<value_type>
+  >							expr_type;
+  return XprVector<expr_type, Sz>(
+    expr_type(v, XprLiteral< value_type >(norm2(v))));
+}
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_VECTOR_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/VectorOperators.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,830 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorOperators.h,v 1.17 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_VECTOR_OPERATORS_H
+#define TVMET_XPR_VECTOR_OPERATORS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(XprVector<E1, Sz>, XprVector<E2, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template<class E1, class E2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E1, Sz>& lhs, 				\
+	     const XprVector<E2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)		// per se element wise
+TVMET_DECLARE_MACRO(sub, -)		// per se element wise
+TVMET_DECLARE_MACRO(mul, *)		// per se element wise
+namespace element_wise {
+  TVMET_DECLARE_MACRO(div, /)		// not defined for vectors
+}
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * operator(XprVector<E, Sz>, POD)
+ * operator(POD, XprVector<E, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, POD)				\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, POD >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< POD >							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs, 				\
+	     POD rhs) TVMET_CXX_ALWAYS_INLINE;				\
+									\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< POD, typename E::value_type >,				\
+    XprLiteral< POD >,							\
+    XprVector< E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (POD lhs, 							\
+	     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +, int)
+TVMET_DECLARE_MACRO(sub, -, int)
+TVMET_DECLARE_MACRO(mul, *, int)
+TVMET_DECLARE_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_DECLARE_MACRO(add, +, long long int)
+TVMET_DECLARE_MACRO(sub, -, long long int)
+TVMET_DECLARE_MACRO(mul, *, long long int)
+TVMET_DECLARE_MACRO(div, /, long long int)
+#endif
+
+TVMET_DECLARE_MACRO(add, +, float)
+TVMET_DECLARE_MACRO(sub, -, float)
+TVMET_DECLARE_MACRO(mul, *, float)
+TVMET_DECLARE_MACRO(div, /, float)
+
+TVMET_DECLARE_MACRO(add, +, double)
+TVMET_DECLARE_MACRO(sub, -, double)
+TVMET_DECLARE_MACRO(mul, *, double)
+TVMET_DECLARE_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_DECLARE_MACRO(add, +, long double)
+TVMET_DECLARE_MACRO(sub, -, long double)
+TVMET_DECLARE_MACRO(mul, *, long double)
+TVMET_DECLARE_MACRO(div, /, long double)
+#endif
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(XprVector<E, Sz>, complex<T>)
+ * operator(complex<T>, XprVector<E, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs,				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type >,		\
+    XprLiteral< std::complex<T> >,					\
+    XprVector< E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const std::complex<T>& lhs,				\
+	     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(add, +)		// per se element wise
+TVMET_DECLARE_MACRO(sub, -)		// per se element wise
+TVMET_DECLARE_MACRO(mul, *)		// per se element wise
+TVMET_DECLARE_MACRO(div, /)		// per se element wise
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(XprVector, XprVector)
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template<class E1, class E2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E1, Sz>& lhs,				\
+	     const XprVector<E2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %)
+  TVMET_DECLARE_MACRO(bitxor, ^)
+  TVMET_DECLARE_MACRO(bitand, &)
+  TVMET_DECLARE_MACRO(bitor, |)
+  TVMET_DECLARE_MACRO(shl, <<)
+  TVMET_DECLARE_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*
+ * operator(Vector<T, Sz>, POD)
+ * operator(POD, Vector<T, Sz>)
+ * Note: operations are per se element_wise
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP, TP)				\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< TP >							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs, 				\
+	     TP rhs) TVMET_CXX_ALWAYS_INLINE;				\
+									\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<TP, typename E::value_type>,				\
+    XprLiteral< TP >,							\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (TP lhs, 							\
+	     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, int)
+  TVMET_DECLARE_MACRO(bitxor, ^, int)
+  TVMET_DECLARE_MACRO(bitand, &, int)
+  TVMET_DECLARE_MACRO(bitor, |, int)
+  TVMET_DECLARE_MACRO(shl, <<, int)
+  TVMET_DECLARE_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, int)
+TVMET_DECLARE_MACRO(less, <, int)
+TVMET_DECLARE_MACRO(greater_eq, >=, int)
+TVMET_DECLARE_MACRO(less_eq, <=, int)
+TVMET_DECLARE_MACRO(eq, ==, int)
+TVMET_DECLARE_MACRO(not_eq, !=, int)
+TVMET_DECLARE_MACRO(and, &&, int)
+TVMET_DECLARE_MACRO(or, ||, int)
+
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_DECLARE_MACRO(mod, %, long long int)
+  TVMET_DECLARE_MACRO(bitxor, ^, long long int)
+  TVMET_DECLARE_MACRO(bitand, &, long long int)
+  TVMET_DECLARE_MACRO(bitor, |, long long int)
+  TVMET_DECLARE_MACRO(shl, <<, long long int)
+  TVMET_DECLARE_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long long int)
+TVMET_DECLARE_MACRO(less, <, long long int)
+TVMET_DECLARE_MACRO(greater_eq, >=, long long int)
+TVMET_DECLARE_MACRO(less_eq, <=, long long int)
+TVMET_DECLARE_MACRO(eq, ==, long long int)
+TVMET_DECLARE_MACRO(not_eq, !=, long long int)
+TVMET_DECLARE_MACRO(and, &&, long long int)
+TVMET_DECLARE_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, float)
+TVMET_DECLARE_MACRO(less, <, float)
+TVMET_DECLARE_MACRO(greater_eq, >=, float)
+TVMET_DECLARE_MACRO(less_eq, <=, float)
+TVMET_DECLARE_MACRO(eq, ==, float)
+TVMET_DECLARE_MACRO(not_eq, !=, float)
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, double)
+TVMET_DECLARE_MACRO(less, <, double)
+TVMET_DECLARE_MACRO(greater_eq, >=, double)
+TVMET_DECLARE_MACRO(less_eq, <=, double)
+TVMET_DECLARE_MACRO(eq, ==, double)
+TVMET_DECLARE_MACRO(not_eq, !=, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >, long double)
+TVMET_DECLARE_MACRO(less, <, long double)
+TVMET_DECLARE_MACRO(greater_eq, >=, long double)
+TVMET_DECLARE_MACRO(less_eq, <=, long double)
+TVMET_DECLARE_MACRO(eq, ==, long double)
+TVMET_DECLARE_MACRO(not_eq, !=, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_DECLARE_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs,				\
+	     const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;	\
+									\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const std::complex<T>& lhs,				\
+	     const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+// necessary operators for eval functions
+TVMET_DECLARE_MACRO(greater, >)
+TVMET_DECLARE_MACRO(less, <)
+TVMET_DECLARE_MACRO(greater_eq, >=)
+TVMET_DECLARE_MACRO(less_eq, <=)
+TVMET_DECLARE_MACRO(eq, ==)
+TVMET_DECLARE_MACRO(not_eq, !=)
+TVMET_DECLARE_MACRO(and, &&)
+TVMET_DECLARE_MACRO(or, ||)
+
+#undef TVMET_DECLARE_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * Unary Operator on XprVector<E, Sz>
+ */
+#define TVMET_DECLARE_MACRO(NAME, OP)					\
+template <class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprUnOp<								\
+    Fcnl_##NAME<typename E::value_type>,				\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(not, !)
+TVMET_DECLARE_MACRO(compl, ~)
+TVMET_DECLARE_MACRO(neg, -)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector arithmetic operators implemented by functions
+ * add, sub, mul and div
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(XprVector<E1, Sz>, XprVector<E2, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class E1, class E2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E1, Sz>& lhs, 				\
+	     const XprVector<E2, Sz>& rhs) {				\
+  return NAME (lhs, rhs);						\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub, -)		// per se element wise
+TVMET_IMPLEMENT_MACRO(mul, *)		// per se element wise
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(div, /)		// not defined for vectors
+}
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * operator(XprVector<E, Sz>, POD)
+ * operator(POD, XprVector<E, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, POD)		\
+template<class E, std::size_t Sz>			\
+inline							\
+XprVector<						\
+  XprBinOp<						\
+    Fcnl_##NAME<typename E::value_type, POD >,		\
+    XprVector<E, Sz>,					\
+    XprLiteral< POD >					\
+  >,							\
+  Sz							\
+>							\
+operator OP (const XprVector<E, Sz>& lhs, POD rhs) {	\
+  return NAME (lhs, rhs);				\
+}							\
+							\
+template<class E, std::size_t Sz>			\
+inline							\
+XprVector<						\
+  XprBinOp<						\
+    Fcnl_##NAME< POD, typename E::value_type >,		\
+    XprLiteral< POD >,					\
+    XprVector< E, Sz>					\
+  >,							\
+  Sz							\
+>							\
+operator OP (POD lhs, const XprVector<E, Sz>& rhs) {	\
+  return NAME (lhs, rhs);				\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +, int)
+TVMET_IMPLEMENT_MACRO(sub, -, int)
+TVMET_IMPLEMENT_MACRO(mul, *, int)
+TVMET_IMPLEMENT_MACRO(div, /, int)
+
+#if defined(TVMET_HAVE_LONG_LONG)
+TVMET_IMPLEMENT_MACRO(add, +, long long int)
+TVMET_IMPLEMENT_MACRO(sub, -, long long int)
+TVMET_IMPLEMENT_MACRO(mul, *, long long int)
+TVMET_IMPLEMENT_MACRO(div, /, long long int)
+#endif
+
+TVMET_IMPLEMENT_MACRO(add, +, float)
+TVMET_IMPLEMENT_MACRO(sub, -, float)
+TVMET_IMPLEMENT_MACRO(mul, *, float)
+TVMET_IMPLEMENT_MACRO(div, /, float)
+
+TVMET_IMPLEMENT_MACRO(add, +, double)
+TVMET_IMPLEMENT_MACRO(sub, -, double)
+TVMET_IMPLEMENT_MACRO(mul, *, double)
+TVMET_IMPLEMENT_MACRO(div, /, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+TVMET_IMPLEMENT_MACRO(add, +, long double)
+TVMET_IMPLEMENT_MACRO(sub, -, long double)
+TVMET_IMPLEMENT_MACRO(mul, *, long double)
+TVMET_IMPLEMENT_MACRO(div, /, long double)
+#endif
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(XprVector<E, Sz>, complex<T>)
+ * operator(complex<T>, XprVector<E, Sz>)
+ * Note: operations +,-,*,/ are per se element wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)				\
+template<class E, std::size_t Sz, class T>			\
+inline								\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,	\
+    XprVector<E, Sz>,						\
+    XprLiteral< std::complex<T> >				\
+  >,								\
+  Sz								\
+>								\
+operator OP (const XprVector<E, Sz>& lhs,			\
+	     const std::complex<T>& rhs) {			\
+  return NAME (lhs, rhs);					\
+}								\
+								\
+template<class E, std::size_t Sz, class T>			\
+inline								\
+XprVector<							\
+  XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type >,	\
+    XprLiteral< std::complex<T> >,				\
+    XprVector< E, Sz>						\
+  >,								\
+  Sz								\
+>								\
+operator OP (const std::complex<T>& lhs,			\
+	     const XprVector<E, Sz>& rhs) {			\
+  return NAME (lhs, rhs);					\
+}
+
+TVMET_IMPLEMENT_MACRO(add, +)		// per se element wise
+TVMET_IMPLEMENT_MACRO(sub, -)		// per se element wise
+TVMET_IMPLEMENT_MACRO(mul, *)		// per se element wise
+TVMET_IMPLEMENT_MACRO(div, /)		// per se element wise
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Vector integer and compare operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * operator(XprVector, XprVector)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class E1, class E2, std::size_t Sz>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E1, Sz>& lhs,				\
+	     const XprVector<E2, Sz>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,	\
+    XprVector<E1, Sz>,							\
+    XprVector<E2, Sz>							\
+  >		    					expr_type;	\
+  return XprVector<expr_type, Sz>(expr_type(lhs, rhs));			\
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^)
+  TVMET_IMPLEMENT_MACRO(bitand, &)
+  TVMET_IMPLEMENT_MACRO(bitor, |)
+  TVMET_IMPLEMENT_MACRO(shl, <<)
+  TVMET_IMPLEMENT_MACRO(shr, >>)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+/*
+ * operator(Vector<T, Sz>, POD)
+ * operator(POD, Vector<T, Sz>)
+ * Note: operations are per se element_wise
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP, TP)				\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< TP >							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs, TP rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, TP >,				\
+    XprVector<E, Sz>,							\
+    XprLiteral< TP >							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, XprLiteral< TP >(rhs)));				\
+}									\
+									\
+template<class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<TP, typename E::value_type>,				\
+    XprLiteral< TP >,							\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (TP lhs, const XprVector<E, Sz>& rhs) {			\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< TP, typename E::value_type>,				\
+    XprLiteral< TP >,							\
+    XprVector<E, Sz>							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(XprLiteral< TP >(lhs), rhs));				\
+}
+
+// integer operators only, e.g used on double you wil get an error
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, int)
+TVMET_IMPLEMENT_MACRO(less, <, int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, int)
+TVMET_IMPLEMENT_MACRO(eq, ==, int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, int)
+TVMET_IMPLEMENT_MACRO(and, &&, int)
+TVMET_IMPLEMENT_MACRO(or, ||, int)
+
+
+#if defined(TVMET_HAVE_LONG_LONG)
+// integer operators only
+namespace element_wise {
+  TVMET_IMPLEMENT_MACRO(mod, %, long long int)
+  TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int)
+  TVMET_IMPLEMENT_MACRO(bitand, &, long long int)
+  TVMET_IMPLEMENT_MACRO(bitor, |, long long int)
+  TVMET_IMPLEMENT_MACRO(shl, <<, long long int)
+  TVMET_IMPLEMENT_MACRO(shr, >>, long long int)
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long long int)
+TVMET_IMPLEMENT_MACRO(less, <, long long int)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int)
+TVMET_IMPLEMENT_MACRO(eq, ==, long long int)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int)
+TVMET_IMPLEMENT_MACRO(and, &&, long long int)
+TVMET_IMPLEMENT_MACRO(or, ||, long long int)
+#endif // defined(TVMET_HAVE_LONG_LONG)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, float)
+TVMET_IMPLEMENT_MACRO(less, <, float)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, float)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, float)
+TVMET_IMPLEMENT_MACRO(eq, ==, float)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, float)
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, double)
+TVMET_IMPLEMENT_MACRO(less, <, double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, double)
+TVMET_IMPLEMENT_MACRO(eq, ==, double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, double)
+
+#if defined(TVMET_HAVE_LONG_DOUBLE)
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >, long double)
+TVMET_IMPLEMENT_MACRO(less, <, long double)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double)
+TVMET_IMPLEMENT_MACRO(less_eq, <=, long double)
+TVMET_IMPLEMENT_MACRO(eq, ==, long double)
+TVMET_IMPLEMENT_MACRO(not_eq, !=, long double)
+#endif // defined(TVMET_HAVE_LONG_DOUBLE)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+#if defined(TVMET_HAVE_COMPLEX)
+/*
+ * operator(Vector<std::complex<T>, Sz>, std::complex<T>)
+ * operator(std::complex<T>, Vector<std::complex<T>, Sz>)
+ * Note: - per se element wise
+ *       - bit ops on complex<int> doesn't make sense, stay away
+ * \todo type promotion
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& lhs,				\
+	     const std::complex<T>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME<typename E::value_type, std::complex<T> >,		\
+    XprVector<E, Sz>,							\
+    XprLiteral< std::complex<T> >					\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));		\
+}									\
+									\
+template<class E, std::size_t Sz, class T>				\
+inline									\
+XprVector<								\
+  XprBinOp<								\
+    Fcnl_##NAME<std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const std::complex<T>& lhs,				\
+	     const XprVector<E, Sz>& rhs) {				\
+  typedef XprBinOp<							\
+    Fcnl_##NAME< std::complex<T>, typename E::value_type>,		\
+    XprLiteral< std::complex<T> >,					\
+    XprVector<E, Sz>							\
+  >							expr_type;	\
+  return XprVector<expr_type, Sz>(					\
+    expr_type(XprLiteral< std::complex<T> >(lhs), rhs));		\
+}
+
+// necessary operators for eval functions
+TVMET_IMPLEMENT_MACRO(greater, >)
+TVMET_IMPLEMENT_MACRO(less, <)
+TVMET_IMPLEMENT_MACRO(greater_eq, >=)
+TVMET_IMPLEMENT_MACRO(less_eq, <=)
+TVMET_IMPLEMENT_MACRO(eq, ==)
+TVMET_IMPLEMENT_MACRO(not_eq, !=)
+TVMET_IMPLEMENT_MACRO(and, &&)
+TVMET_IMPLEMENT_MACRO(or, ||)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+#endif // defined(TVMET_HAVE_COMPLEX)
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * global unary operators
+ *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+
+/*
+ * Unary Operator on XprVector<E, Sz>
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME, OP)					\
+template <class E, std::size_t Sz>					\
+inline									\
+XprVector<								\
+  XprUnOp<								\
+    Fcnl_##NAME<typename E::value_type>,				\
+    XprVector<E, Sz>							\
+  >,									\
+  Sz									\
+>									\
+operator OP (const XprVector<E, Sz>& rhs) {				\
+  typedef XprUnOp<							\
+    Fcnl_##NAME<typename E::value_type>,				\
+    XprVector<E, Sz>							\
+  >  							 expr_type;	\
+  return XprVector<expr_type, Sz>(expr_type(rhs));			\
+}
+
+TVMET_IMPLEMENT_MACRO(not, !)
+TVMET_IMPLEMENT_MACRO(compl, ~)
+TVMET_IMPLEMENT_MACRO(neg, -)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_VECTOR_OPERATORS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/xpr/VectorUnaryFunctions.h	Wed Oct 17 22:22:28 2012 +0000
@@ -0,0 +1,163 @@
+/*
+ * Tiny Vector Matrix Library
+ * Dense Vector Matrix Libary of Tiny size using Expression Templates
+ *
+ * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * $Id: VectorUnaryFunctions.h,v 1.11 2007-06-23 15:59:00 opetzold Exp $
+ */
+
+#ifndef TVMET_XPR_VECTOR_UNARY_FUNCTIONS_H
+#define TVMET_XPR_VECTOR_UNARY_FUNCTIONS_H
+
+namespace tvmet {
+
+
+/*********************************************************
+ * PART I: DECLARATION
+ *********************************************************/
+
+/*
+ * unary_function(XprVector<E, Sz>)
+ */
+#define TVMET_DECLARE_MACRO(NAME)                \
+template<class E, std::size_t Sz>                \
+inline                                \
+XprVector<                            \
+  XprUnOp<                            \
+    Fcnl_##NAME<typename E::value_type>,            \
+    XprVector<E, Sz>                        \
+  >,                                \
+  Sz                                \
+>                                \
+NAME(const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
+
+TVMET_DECLARE_MACRO(abs)
+TVMET_DECLARE_MACRO(cbrt)
+TVMET_DECLARE_MACRO(ceil)
+TVMET_DECLARE_MACRO(floor)
+TVMET_DECLARE_MACRO(rint)
+TVMET_DECLARE_MACRO(sin)
+TVMET_DECLARE_MACRO(cos)
+TVMET_DECLARE_MACRO(tan)
+TVMET_DECLARE_MACRO(sinh)
+TVMET_DECLARE_MACRO(cosh)
+TVMET_DECLARE_MACRO(tanh)
+TVMET_DECLARE_MACRO(asin)
+TVMET_DECLARE_MACRO(acos)
+TVMET_DECLARE_MACRO(atan)
+TVMET_DECLARE_MACRO(exp)
+TVMET_DECLARE_MACRO(log)
+TVMET_DECLARE_MACRO(log10)
+TVMET_DECLARE_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_DECLARE_MACRO(asinh)
+TVMET_DECLARE_MACRO(acosh)
+TVMET_DECLARE_MACRO(atanh)
+TVMET_DECLARE_MACRO(expm1)
+TVMET_DECLARE_MACRO(log1p)
+TVMET_DECLARE_MACRO(erf)
+TVMET_DECLARE_MACRO(erfc)
+TVMET_DECLARE_MACRO(j0)
+TVMET_DECLARE_MACRO(j1)
+TVMET_DECLARE_MACRO(y0)
+TVMET_DECLARE_MACRO(y1)
+TVMET_DECLARE_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_DECLARE_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_DECLARE_MACRO
+
+
+/*********************************************************
+ * PART II: IMPLEMENTATION
+ *********************************************************/
+
+
+/*
+ * unary_function(XprVector<E, Sz>)
+ */
+#define TVMET_IMPLEMENT_MACRO(NAME)                    \
+template<class E, std::size_t Sz>                    \
+inline                                    \
+XprVector<                                \
+  XprUnOp<                                \
+    Fcnl_##NAME<typename E::value_type>,                \
+    XprVector<E, Sz>                            \
+  >,                                    \
+  Sz                                    \
+>                                    \
+NAME(const XprVector<E, Sz>& rhs) {                    \
+  typedef XprUnOp<                            \
+    Fcnl_##NAME<typename E::value_type>,                \
+    XprVector<E, Sz>                            \
+  >                             expr_type;    \
+  return XprVector<expr_type, Sz>(expr_type(rhs));            \
+}
+
+TVMET_IMPLEMENT_MACRO(abs)
+TVMET_IMPLEMENT_MACRO(cbrt)
+TVMET_IMPLEMENT_MACRO(ceil)
+TVMET_IMPLEMENT_MACRO(floor)
+TVMET_IMPLEMENT_MACRO(rint)
+TVMET_IMPLEMENT_MACRO(sin)
+TVMET_IMPLEMENT_MACRO(cos)
+TVMET_IMPLEMENT_MACRO(tan)
+TVMET_IMPLEMENT_MACRO(sinh)
+TVMET_IMPLEMENT_MACRO(cosh)
+TVMET_IMPLEMENT_MACRO(tanh)
+TVMET_IMPLEMENT_MACRO(asin)
+TVMET_IMPLEMENT_MACRO(acos)
+TVMET_IMPLEMENT_MACRO(atan)
+TVMET_IMPLEMENT_MACRO(exp)
+TVMET_IMPLEMENT_MACRO(log)
+TVMET_IMPLEMENT_MACRO(log10)
+TVMET_IMPLEMENT_MACRO(sqrt)
+
+#if defined(TVMET_HAVE_IEEE_MATH)
+TVMET_IMPLEMENT_MACRO(asinh)
+TVMET_IMPLEMENT_MACRO(acosh)
+TVMET_IMPLEMENT_MACRO(atanh)
+TVMET_IMPLEMENT_MACRO(expm1)
+TVMET_IMPLEMENT_MACRO(log1p)
+TVMET_IMPLEMENT_MACRO(erf)
+TVMET_IMPLEMENT_MACRO(erfc)
+TVMET_IMPLEMENT_MACRO(j0)
+TVMET_IMPLEMENT_MACRO(j1)
+TVMET_IMPLEMENT_MACRO(y0)
+TVMET_IMPLEMENT_MACRO(y1)
+TVMET_IMPLEMENT_MACRO(lgamma)
+/** \todo isnan etc. - default return is only an int! */
+
+TVMET_IMPLEMENT_MACRO(finite)
+#endif // defined(TVMET_HAVE_IEEE_MATH)
+
+#undef TVMET_IMPLEMENT_MACRO
+
+
+
+} // namespace tvmet
+
+#endif // TVMET_XPR_VECTOR_FUNCTIONS_H
+
+// Local Variables:
+// mode:C++
+// tab-width:8
+// End: