Re: [ROOT] TMatrix

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Wed Dec 04 2002 - 20:31:51 MET


Hi Giuseppe

"giuseppe.foggi@libero.it" <giuseppe.foggi@libero.it> wrote concerning
  [ROOT] TMatrix [Wed,  4 Dec 2002 17:57:05 +0100] 
----------------------------------------------------------------------
> Hi,
>  I have defined a TMatrix m(n,n) in my class .
>  
>  I have to pass it like parameter in a fuction,but when I declare the
>  fuction in my header file, like
>  
>  void Function(TMatrix matrix(n,n));
>  
>  I get  error!! Why?

'Cause it's not valid C++!  (That is, this has nothing to do with
ROOT, but is purely a C++ matter.) Declare your function as 

  void Function(TMatrix matrix) { 
    // Do what ever to matrix
  }

Note, however, that you pass the matrix object _by_value_, which means
that you create a copy and the function operates on that copy, not the
original.  This may not be what you want, supposing you want to change
the matrix.  If you want to avoid the copy (because you want to change
the matrix, or for efficiency reasons), you should declare your
function as 

  void Function(TMatrix& matrix) { 
    // Do what ever to matrix - changes propagate out too 
  }

Now, matrix is passed _by_reference, meaning that you get the original
matrix, not a copy, and so changes will persist after the function
exits.   

If your function should not change the passed matrix, it is still
better to pass the matrix _by_reference_ rather than by value, as you
don't have to go through an expensive copy (Suppose you have n=10,000,
m=10,0000, then you have to allocate a 10,000x10,000=100,000,000 array
of floats - pretty damn expensive).  In that case, you should pass a
constant reference to the function, like 

  void Function(const TMatrix& matrix) { 
    // Do what ever to matrix - changes are not allowed 
  }

The compiler will catch any use of  non-const member functions of
TMatrix, and flag that as an error. 

Here's some code that illustrates the above 

  #include <vector> 
  #include <iostream>
  
  using namespace std;

  /// Function that get's a copy of a vector 
  void function(vector<int> v) { 
    for (int i = 0; i < v.size(); i++) v[i] = 0;
  }
    
  /// Function that get's a reference to a vector
  void function(vector<int>& v, int x) { 
    for (int i = 0; i < v.size(); i++) v[i] = x;
  }

  /// Function that get's a constant reference to a vector
  void printit(const vector<int>& v) { 
    for (int i = 0; i < v.size(); i++) cout << v[i] << " ";
    cout << endl;
  }

  /// Function that get's a constant reference to a vector
  #ifdef SHOW_COMP_ERROR
  void cannot(const vector<int>& v) { 
    for (int i = 0; i < v.size(); i++) v[i] = 0;
  }
  #endif 

  int main(int argc, char** argv) {
    vector<int> v(3); 
    v[0] = 1;
    v[1] = 2;
    v[2] = 3;

    printit(v);      // Print initial values

    function(v);     // The vector hasn't changed  
    printit(v);  

    function(v, 10); // Change the vector 		 
    printit(v);  

    return 0;
  }

The example uses plain C++ to illustrate the point. 
 
Try compile and link this, and then run it to see the effect:

  > g++ foo.cc -o foo 
  > ./foo

Then try to compile it, defining SHOW_COMP_ERROR, and see the error in
`cannot'

  > g++ -DSHOW_COMP_ERROR foo.cc -o foo 

Also, try running it through plain CINT 

  > cint foo.cc 

Yours, 

 ___  |  Christian Holm Christensen 
  |_| |	 -------------------------------------------------------------
    | |	 Address: Sankt Hansgade 23, 1. th.  Phone:  (+45) 35 35 96 91
     _|	          DK-2200 Copenhagen N       Cell:   (+45) 24 61 85 91
    _|	          Denmark                    Office: (+45) 353  25 305
 ____|	 Email:   cholm@nbi.dk               Web:    www.nbi.dk/~cholm
 | |



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:22 MET