Why matrices get copied while passing through Ref & in Eigen











up vote
0
down vote

favorite












I tested whether the variables get copied by writing the following pieces of code. This piece of code comes from the official documentation: https://eigen.tuxfamily.org/dox/classEigen_1_1Ref.html



void cov(const Ref<const MatrixXf> & x, const Ref<const MatrixXf> & y, Ref<MatrixXf> C)
{
cout << "address of x : " << &x << endl;
cout << "address of C : " << &C << endl;
}

int main(int argc, const char * argv) {
MatrixXf m1(3,3);
MatrixXf m2(3,3);
MatrixXf m3(3,3);
m1 << 1,2,3,4,5,6,7,8,9;
m2 << 1,2,3,4,5,6,7,8,9;
m3 << 1,2,3,4,5,6,7,8,9;
cout << "address of m1 : " << &m1 << endl;
cout << "address of m3 : " << &m3 << endl;
cov(m1, m2, m3);
}


The output is as followed.



address of m1 : 0x7ffeefbff4e8 
address of m3 : 0x7ffeefbff498
address of x : 0x7ffeefbff370
address of C : 0x7ffeefbff308


The address of x and m1, m3 and C are different (I supposed that they should be the same, since I am passing the variables through reference). Could anyone explain to me why?



Thanks to @Nelfeal's answer. I tried to use debugger to prove this.
The following is the debugging info for the above code. We could see that within m1 and x. The "m_data" shared the same address 0x329f800.
enter image description hereenter image description here



However, could someone please tell me the difference btw the following 2 pieces of code? I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?



void cov(const Ref<const MatrixXf> x, const Ref<const MatrixXf> y, Ref<MatrixXf> C)

void cov(const Ref<const MatrixXf> &x, const Ref<const MatrixXf> &y, Ref<MatrixXf> C)









share|improve this question




























    up vote
    0
    down vote

    favorite












    I tested whether the variables get copied by writing the following pieces of code. This piece of code comes from the official documentation: https://eigen.tuxfamily.org/dox/classEigen_1_1Ref.html



    void cov(const Ref<const MatrixXf> & x, const Ref<const MatrixXf> & y, Ref<MatrixXf> C)
    {
    cout << "address of x : " << &x << endl;
    cout << "address of C : " << &C << endl;
    }

    int main(int argc, const char * argv) {
    MatrixXf m1(3,3);
    MatrixXf m2(3,3);
    MatrixXf m3(3,3);
    m1 << 1,2,3,4,5,6,7,8,9;
    m2 << 1,2,3,4,5,6,7,8,9;
    m3 << 1,2,3,4,5,6,7,8,9;
    cout << "address of m1 : " << &m1 << endl;
    cout << "address of m3 : " << &m3 << endl;
    cov(m1, m2, m3);
    }


    The output is as followed.



    address of m1 : 0x7ffeefbff4e8 
    address of m3 : 0x7ffeefbff498
    address of x : 0x7ffeefbff370
    address of C : 0x7ffeefbff308


    The address of x and m1, m3 and C are different (I supposed that they should be the same, since I am passing the variables through reference). Could anyone explain to me why?



    Thanks to @Nelfeal's answer. I tried to use debugger to prove this.
    The following is the debugging info for the above code. We could see that within m1 and x. The "m_data" shared the same address 0x329f800.
    enter image description hereenter image description here



    However, could someone please tell me the difference btw the following 2 pieces of code? I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?



    void cov(const Ref<const MatrixXf> x, const Ref<const MatrixXf> y, Ref<MatrixXf> C)

    void cov(const Ref<const MatrixXf> &x, const Ref<const MatrixXf> &y, Ref<MatrixXf> C)









    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I tested whether the variables get copied by writing the following pieces of code. This piece of code comes from the official documentation: https://eigen.tuxfamily.org/dox/classEigen_1_1Ref.html



      void cov(const Ref<const MatrixXf> & x, const Ref<const MatrixXf> & y, Ref<MatrixXf> C)
      {
      cout << "address of x : " << &x << endl;
      cout << "address of C : " << &C << endl;
      }

      int main(int argc, const char * argv) {
      MatrixXf m1(3,3);
      MatrixXf m2(3,3);
      MatrixXf m3(3,3);
      m1 << 1,2,3,4,5,6,7,8,9;
      m2 << 1,2,3,4,5,6,7,8,9;
      m3 << 1,2,3,4,5,6,7,8,9;
      cout << "address of m1 : " << &m1 << endl;
      cout << "address of m3 : " << &m3 << endl;
      cov(m1, m2, m3);
      }


      The output is as followed.



      address of m1 : 0x7ffeefbff4e8 
      address of m3 : 0x7ffeefbff498
      address of x : 0x7ffeefbff370
      address of C : 0x7ffeefbff308


      The address of x and m1, m3 and C are different (I supposed that they should be the same, since I am passing the variables through reference). Could anyone explain to me why?



      Thanks to @Nelfeal's answer. I tried to use debugger to prove this.
      The following is the debugging info for the above code. We could see that within m1 and x. The "m_data" shared the same address 0x329f800.
      enter image description hereenter image description here



      However, could someone please tell me the difference btw the following 2 pieces of code? I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?



      void cov(const Ref<const MatrixXf> x, const Ref<const MatrixXf> y, Ref<MatrixXf> C)

      void cov(const Ref<const MatrixXf> &x, const Ref<const MatrixXf> &y, Ref<MatrixXf> C)









      share|improve this question















      I tested whether the variables get copied by writing the following pieces of code. This piece of code comes from the official documentation: https://eigen.tuxfamily.org/dox/classEigen_1_1Ref.html



      void cov(const Ref<const MatrixXf> & x, const Ref<const MatrixXf> & y, Ref<MatrixXf> C)
      {
      cout << "address of x : " << &x << endl;
      cout << "address of C : " << &C << endl;
      }

      int main(int argc, const char * argv) {
      MatrixXf m1(3,3);
      MatrixXf m2(3,3);
      MatrixXf m3(3,3);
      m1 << 1,2,3,4,5,6,7,8,9;
      m2 << 1,2,3,4,5,6,7,8,9;
      m3 << 1,2,3,4,5,6,7,8,9;
      cout << "address of m1 : " << &m1 << endl;
      cout << "address of m3 : " << &m3 << endl;
      cov(m1, m2, m3);
      }


      The output is as followed.



      address of m1 : 0x7ffeefbff4e8 
      address of m3 : 0x7ffeefbff498
      address of x : 0x7ffeefbff370
      address of C : 0x7ffeefbff308


      The address of x and m1, m3 and C are different (I supposed that they should be the same, since I am passing the variables through reference). Could anyone explain to me why?



      Thanks to @Nelfeal's answer. I tried to use debugger to prove this.
      The following is the debugging info for the above code. We could see that within m1 and x. The "m_data" shared the same address 0x329f800.
      enter image description hereenter image description here



      However, could someone please tell me the difference btw the following 2 pieces of code? I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?



      void cov(const Ref<const MatrixXf> x, const Ref<const MatrixXf> y, Ref<MatrixXf> C)

      void cov(const Ref<const MatrixXf> &x, const Ref<const MatrixXf> &y, Ref<MatrixXf> C)






      c++ eigen eigen3






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 at 1:23

























      asked Nov 11 at 13:53









      JackieLam

      190215




      190215
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          A Ref and a MatrixXf are still different objects, and are going to be at different addresses. That doesn't mean the whole matrix gets copied: only that a Ref object gets created.




          I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?




          No, a Ref is not a reference. At least not from the language's perspective. A Ref is an object that happens to be used in Eigen like a C++ reference. When you pass a const Ref<const T>, you are making a copy of (are creating by conversion) the Ref object because you are still passing by value, but hopefully you are not copying the corresponding T (that's kind of the point). When you pass a const Ref<const T>&, you are not making any copy since you are passing by reference.



          Now, whether one way is better than the other depends largely on what exactly a Ref is, and I don't know enough about that to make any assumption other than "it's probably small". Because that's the point: a reference in the general sense, whether it is a pointer, a C++ reference, or a Ref object, is supposed to be very lightweight, easy and fast to copy, so that you don't have to copy the whole referenced object when you want to access it in another function.



          In the end, it probably doesn't matter what you choose between const Ref<const T> and const Ref<const T>&, especially since you most likely don't have a preexisting Ref object to pass around (so it's going to be created in both cases anyway). However, it doesn't hurt to go for const Ref<const T>&. and be consistant with how objects are passed around in general in C++.



          Worth a read.






          share|improve this answer























          • Thanks Nelfeal! I edited my question after inspired by ur answer. But do you know why should we add "&" since Ref is already a reference itself?
            – JackieLam
            Nov 12 at 1:26










          • @JackieLam Edited.
            – Nelfeal
            Nov 12 at 6:28










          • thanks again for your thorough answer! Now I think I fully understand it.
            – JackieLam
            Nov 12 at 7:46










          • Ref<const T> includes a temporary object (which is used, only if the passed object can't actually be passed by just passing the pointer), that's why it usually should be passed by reference.
            – chtz
            Nov 13 at 17:17











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53249433%2fwhy-matrices-get-copied-while-passing-through-ref-in-eigen%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          A Ref and a MatrixXf are still different objects, and are going to be at different addresses. That doesn't mean the whole matrix gets copied: only that a Ref object gets created.




          I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?




          No, a Ref is not a reference. At least not from the language's perspective. A Ref is an object that happens to be used in Eigen like a C++ reference. When you pass a const Ref<const T>, you are making a copy of (are creating by conversion) the Ref object because you are still passing by value, but hopefully you are not copying the corresponding T (that's kind of the point). When you pass a const Ref<const T>&, you are not making any copy since you are passing by reference.



          Now, whether one way is better than the other depends largely on what exactly a Ref is, and I don't know enough about that to make any assumption other than "it's probably small". Because that's the point: a reference in the general sense, whether it is a pointer, a C++ reference, or a Ref object, is supposed to be very lightweight, easy and fast to copy, so that you don't have to copy the whole referenced object when you want to access it in another function.



          In the end, it probably doesn't matter what you choose between const Ref<const T> and const Ref<const T>&, especially since you most likely don't have a preexisting Ref object to pass around (so it's going to be created in both cases anyway). However, it doesn't hurt to go for const Ref<const T>&. and be consistant with how objects are passed around in general in C++.



          Worth a read.






          share|improve this answer























          • Thanks Nelfeal! I edited my question after inspired by ur answer. But do you know why should we add "&" since Ref is already a reference itself?
            – JackieLam
            Nov 12 at 1:26










          • @JackieLam Edited.
            – Nelfeal
            Nov 12 at 6:28










          • thanks again for your thorough answer! Now I think I fully understand it.
            – JackieLam
            Nov 12 at 7:46










          • Ref<const T> includes a temporary object (which is used, only if the passed object can't actually be passed by just passing the pointer), that's why it usually should be passed by reference.
            – chtz
            Nov 13 at 17:17















          up vote
          3
          down vote



          accepted










          A Ref and a MatrixXf are still different objects, and are going to be at different addresses. That doesn't mean the whole matrix gets copied: only that a Ref object gets created.




          I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?




          No, a Ref is not a reference. At least not from the language's perspective. A Ref is an object that happens to be used in Eigen like a C++ reference. When you pass a const Ref<const T>, you are making a copy of (are creating by conversion) the Ref object because you are still passing by value, but hopefully you are not copying the corresponding T (that's kind of the point). When you pass a const Ref<const T>&, you are not making any copy since you are passing by reference.



          Now, whether one way is better than the other depends largely on what exactly a Ref is, and I don't know enough about that to make any assumption other than "it's probably small". Because that's the point: a reference in the general sense, whether it is a pointer, a C++ reference, or a Ref object, is supposed to be very lightweight, easy and fast to copy, so that you don't have to copy the whole referenced object when you want to access it in another function.



          In the end, it probably doesn't matter what you choose between const Ref<const T> and const Ref<const T>&, especially since you most likely don't have a preexisting Ref object to pass around (so it's going to be created in both cases anyway). However, it doesn't hurt to go for const Ref<const T>&. and be consistant with how objects are passed around in general in C++.



          Worth a read.






          share|improve this answer























          • Thanks Nelfeal! I edited my question after inspired by ur answer. But do you know why should we add "&" since Ref is already a reference itself?
            – JackieLam
            Nov 12 at 1:26










          • @JackieLam Edited.
            – Nelfeal
            Nov 12 at 6:28










          • thanks again for your thorough answer! Now I think I fully understand it.
            – JackieLam
            Nov 12 at 7:46










          • Ref<const T> includes a temporary object (which is used, only if the passed object can't actually be passed by just passing the pointer), that's why it usually should be passed by reference.
            – chtz
            Nov 13 at 17:17













          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          A Ref and a MatrixXf are still different objects, and are going to be at different addresses. That doesn't mean the whole matrix gets copied: only that a Ref object gets created.




          I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?




          No, a Ref is not a reference. At least not from the language's perspective. A Ref is an object that happens to be used in Eigen like a C++ reference. When you pass a const Ref<const T>, you are making a copy of (are creating by conversion) the Ref object because you are still passing by value, but hopefully you are not copying the corresponding T (that's kind of the point). When you pass a const Ref<const T>&, you are not making any copy since you are passing by reference.



          Now, whether one way is better than the other depends largely on what exactly a Ref is, and I don't know enough about that to make any assumption other than "it's probably small". Because that's the point: a reference in the general sense, whether it is a pointer, a C++ reference, or a Ref object, is supposed to be very lightweight, easy and fast to copy, so that you don't have to copy the whole referenced object when you want to access it in another function.



          In the end, it probably doesn't matter what you choose between const Ref<const T> and const Ref<const T>&, especially since you most likely don't have a preexisting Ref object to pass around (so it's going to be created in both cases anyway). However, it doesn't hurt to go for const Ref<const T>&. and be consistant with how objects are passed around in general in C++.



          Worth a read.






          share|improve this answer














          A Ref and a MatrixXf are still different objects, and are going to be at different addresses. That doesn't mean the whole matrix gets copied: only that a Ref object gets created.




          I supposed "Ref" is already a reference itself then why do we still have to add the reference mark "&"?




          No, a Ref is not a reference. At least not from the language's perspective. A Ref is an object that happens to be used in Eigen like a C++ reference. When you pass a const Ref<const T>, you are making a copy of (are creating by conversion) the Ref object because you are still passing by value, but hopefully you are not copying the corresponding T (that's kind of the point). When you pass a const Ref<const T>&, you are not making any copy since you are passing by reference.



          Now, whether one way is better than the other depends largely on what exactly a Ref is, and I don't know enough about that to make any assumption other than "it's probably small". Because that's the point: a reference in the general sense, whether it is a pointer, a C++ reference, or a Ref object, is supposed to be very lightweight, easy and fast to copy, so that you don't have to copy the whole referenced object when you want to access it in another function.



          In the end, it probably doesn't matter what you choose between const Ref<const T> and const Ref<const T>&, especially since you most likely don't have a preexisting Ref object to pass around (so it's going to be created in both cases anyway). However, it doesn't hurt to go for const Ref<const T>&. and be consistant with how objects are passed around in general in C++.



          Worth a read.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 12 at 6:28

























          answered Nov 11 at 14:04









          Nelfeal

          3,908621




          3,908621












          • Thanks Nelfeal! I edited my question after inspired by ur answer. But do you know why should we add "&" since Ref is already a reference itself?
            – JackieLam
            Nov 12 at 1:26










          • @JackieLam Edited.
            – Nelfeal
            Nov 12 at 6:28










          • thanks again for your thorough answer! Now I think I fully understand it.
            – JackieLam
            Nov 12 at 7:46










          • Ref<const T> includes a temporary object (which is used, only if the passed object can't actually be passed by just passing the pointer), that's why it usually should be passed by reference.
            – chtz
            Nov 13 at 17:17


















          • Thanks Nelfeal! I edited my question after inspired by ur answer. But do you know why should we add "&" since Ref is already a reference itself?
            – JackieLam
            Nov 12 at 1:26










          • @JackieLam Edited.
            – Nelfeal
            Nov 12 at 6:28










          • thanks again for your thorough answer! Now I think I fully understand it.
            – JackieLam
            Nov 12 at 7:46










          • Ref<const T> includes a temporary object (which is used, only if the passed object can't actually be passed by just passing the pointer), that's why it usually should be passed by reference.
            – chtz
            Nov 13 at 17:17
















          Thanks Nelfeal! I edited my question after inspired by ur answer. But do you know why should we add "&" since Ref is already a reference itself?
          – JackieLam
          Nov 12 at 1:26




          Thanks Nelfeal! I edited my question after inspired by ur answer. But do you know why should we add "&" since Ref is already a reference itself?
          – JackieLam
          Nov 12 at 1:26












          @JackieLam Edited.
          – Nelfeal
          Nov 12 at 6:28




          @JackieLam Edited.
          – Nelfeal
          Nov 12 at 6:28












          thanks again for your thorough answer! Now I think I fully understand it.
          – JackieLam
          Nov 12 at 7:46




          thanks again for your thorough answer! Now I think I fully understand it.
          – JackieLam
          Nov 12 at 7:46












          Ref<const T> includes a temporary object (which is used, only if the passed object can't actually be passed by just passing the pointer), that's why it usually should be passed by reference.
          – chtz
          Nov 13 at 17:17




          Ref<const T> includes a temporary object (which is used, only if the passed object can't actually be passed by just passing the pointer), that's why it usually should be passed by reference.
          – chtz
          Nov 13 at 17:17


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53249433%2fwhy-matrices-get-copied-while-passing-through-ref-in-eigen%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python