glue_kron_meat.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
  2. // Copyright 2008-2016 National ICT Australia (NICTA)
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // ------------------------------------------------------------------------
  15. //! \addtogroup glue_kron
  16. //! @{
  17. //! \brief
  18. //! both input matrices have the same element type
  19. template<typename eT>
  20. inline
  21. void
  22. glue_kron::direct_kron(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
  23. {
  24. arma_extra_debug_sigprint();
  25. const uword A_rows = A.n_rows;
  26. const uword A_cols = A.n_cols;
  27. const uword B_rows = B.n_rows;
  28. const uword B_cols = B.n_cols;
  29. out.set_size(A_rows*B_rows, A_cols*B_cols);
  30. if(out.is_empty()) { return; }
  31. for(uword j = 0; j < A_cols; j++)
  32. {
  33. for(uword i = 0; i < A_rows; i++)
  34. {
  35. out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A.at(i,j) * B;
  36. }
  37. }
  38. }
  39. //! \brief
  40. //! different types of input matrices
  41. //! A -> complex, B -> basic element type
  42. template<typename T>
  43. inline
  44. void
  45. glue_kron::direct_kron(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>& B)
  46. {
  47. arma_extra_debug_sigprint();
  48. typedef typename std::complex<T> eT;
  49. const uword A_rows = A.n_rows;
  50. const uword A_cols = A.n_cols;
  51. const uword B_rows = B.n_rows;
  52. const uword B_cols = B.n_cols;
  53. out.set_size(A_rows*B_rows, A_cols*B_cols);
  54. if(out.is_empty()) { return; }
  55. Mat<eT> tmp_B = conv_to< Mat<eT> >::from(B);
  56. for(uword j = 0; j < A_cols; j++)
  57. {
  58. for(uword i = 0; i < A_rows; i++)
  59. {
  60. out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A.at(i,j) * tmp_B;
  61. }
  62. }
  63. }
  64. //! \brief
  65. //! different types of input matrices
  66. //! A -> basic element type, B -> complex
  67. template<typename T>
  68. inline
  69. void
  70. glue_kron::direct_kron(Mat< std::complex<T> >& out, const Mat<T>& A, const Mat< std::complex<T> >& B)
  71. {
  72. arma_extra_debug_sigprint();
  73. const uword A_rows = A.n_rows;
  74. const uword A_cols = A.n_cols;
  75. const uword B_rows = B.n_rows;
  76. const uword B_cols = B.n_cols;
  77. out.set_size(A_rows*B_rows, A_cols*B_cols);
  78. if(out.is_empty()) { return; }
  79. for(uword j = 0; j < A_cols; j++)
  80. {
  81. for(uword i = 0; i < A_rows; i++)
  82. {
  83. out.submat(i*B_rows, j*B_cols, (i+1)*B_rows-1, (j+1)*B_cols-1) = A.at(i,j) * B;
  84. }
  85. }
  86. }
  87. //! \brief
  88. //! apply Kronecker product for two objects with same element type
  89. template<typename T1, typename T2>
  90. inline
  91. void
  92. glue_kron::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_kron>& X)
  93. {
  94. arma_extra_debug_sigprint();
  95. typedef typename T1::elem_type eT;
  96. const unwrap<T1> A_tmp(X.A);
  97. const unwrap<T2> B_tmp(X.B);
  98. const Mat<eT>& A = A_tmp.M;
  99. const Mat<eT>& B = B_tmp.M;
  100. if( (&out != &A) && (&out != &B) )
  101. {
  102. glue_kron::direct_kron(out, A, B);
  103. }
  104. else
  105. {
  106. Mat<eT> tmp;
  107. glue_kron::direct_kron(tmp, A, B);
  108. out.steal_mem(tmp);
  109. }
  110. }
  111. //! @}