We are going to win! wohoo
Revision 1:6799c07fe510, committed 2012-11-07
- Comitter:
- sv
- Date:
- Wed Nov 07 14:37:35 2012 +0000
- Parent:
- 0:92019d8564a7
- Child:
- 2:10e2b1b9c588
- Commit message:
- Preliminary copy of 2012 code
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/IR/IR.cpp Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,74 @@
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/IR/IR.h Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,25 @@
+
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/Kalman.cpp Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,467 @@
+//***************************************************************************************
+//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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/Kalman.h Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,100 @@
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/Sonar/RF12B/RF12B.cpp Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,400 @@
+#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�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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/Sonar/RF12B/RF12B.h Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,83 @@
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Kalman/Sonar/RF12B/RF_defs.h Wed Nov 07 14:37:35 2012 +0000 @@ -0,0 +1,478 @@ +/* + * 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/Sonar/RFSRF05.cpp Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,183 @@
+
+#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();
+//}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Kalman/Sonar/RFSRF05.h Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,102 @@
+
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/globals.h Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,99 @@
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include "mbed.h"
+#define PI 3.14159265
+
+
+//#define ROBOT_SECONDARY
+
+//enables ui
+//#define UION
+
+#ifdef ROBOT_SECONDARY
+//Secondary Robot constants in mm
+const int robot_width = 260;
+const int encoderRevCount = 360;
+const int wheelmm = 229;
+const int robotCircumference = 816;
+
+
+#else
+#define ROBOT_PRIMARY
+// invert echo polarity for primary
+#define SONAR_ECHO_INV
+// Primary Robot constants
+const int robot_width = 390;
+const int encoderRevCount = 1856;
+const int wheelmm = 308;
+const int robotCircumference = 1150;
+#endif
+
+
+
+//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.0005; //(very poorly) accounts for hitting things
+const float angvarpertime = 0.001;
+
+//sonar constants
+static const float sonarvariance = 0.005;
+
+//IR constants
+static const float IRvariance = 0.001;
+
+//Arena constants
+struct pos {
+ int x;
+ int y;
+};
+
+//beacon positions
+extern pos beaconpos[];
+
+//Colour
+extern bool Colour; // 1 for red, 0 for blue
+
+//System constants
+const int PREDICTPERIOD = 20; //ms
+
+//High speed serial port
+extern Serial pc;
+
+//I2C mutex
+//extern Mutex i2c_rlock;
+//extern Mutex i2c_wlock;
+
+
+// IR angle calc
+#define RELI_BOUND_LOW 4
+#define RELI_BOUND_HIGH 25
+
+// Movement target tolerances
+#define POSITION_TOR 20 // in mm
+#define ANGLE_TOR 0.06 // in rad
+
+// motion control
+
+#ifndef MOVE_SPEED_DEF
+#define MOVE_SPEED_DEF
+static int MOVE_SPEED = 35;
+#endif
+
+#define MAX_STEP_RATIO 0.10 //maximum change in the speed
+//#define TRACK_RATE 10 // +- rate for each wheel when tracking
+
+#ifdef ROBOT_PRIMARY
+#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
+#endif
+
+// Task suspend periods
+#define IR_TURRET_PERIOD 200
+#define MOTION_UPDATE_PERIOD 20
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtos.lib Wed Nov 07 14:37:35 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/narshu/code/Eurobot_2012_Primary/#bba76c8b8cf7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tvmet/AliasProxy.h Wed Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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 Nov 07 14:37:35 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:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/ui.cpp Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,103 @@
+
+#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(3500);
+#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);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/ui.h Wed Nov 07 14:37:35 2012 +0000
@@ -0,0 +1,30 @@
+
+#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