1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17 
18 
19 //! \addtogroup fn_trimat_ind
20 //! @{
21 
22 
23 arma_warn_unused
24 inline
25 uvec
trimatu_ind(const SizeMat & s,const sword k=0)26 trimatu_ind(const SizeMat& s, const sword k = 0)
27   {
28   arma_extra_debug_sigprint();
29 
30   const uword n_rows = s.n_rows;
31   const uword n_cols = s.n_cols;
32 
33   const uword row_offset = (k < 0) ? uword(-k) : uword(0);
34   const uword col_offset = (k > 0) ? uword( k) : uword(0);
35 
36   arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatu_ind(): requested diagonal is out of bounds" );
37 
38   const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset);
39 
40   uvec   tmp(n_rows * n_cols, arma_nozeros_indicator());  // worst case scenario
41   uword* tmp_mem = tmp.memptr();
42   uword  count   = 0;
43 
44   for(uword i=0; i < n_cols; ++i)
45     {
46     const uword col = i + col_offset;
47 
48     if(i < N)
49       {
50       const uword end_row = i + row_offset;
51 
52       const uword index_offset = (n_rows * col);
53 
54       for(uword row=0; row <= end_row; ++row)
55         {
56         tmp_mem[count] = index_offset + row;
57         ++count;
58         }
59       }
60     else
61       {
62       if(col < n_cols)
63         {
64         const uword index_offset = (n_rows * col);
65 
66         for(uword row=0; row < n_rows; ++row)
67           {
68           tmp_mem[count] = index_offset + row;
69           ++count;
70           }
71         }
72       }
73     }
74 
75   uvec out;
76 
77   out.steal_mem_col(tmp, count);
78 
79   return out;
80   }
81 
82 
83 
84 arma_warn_unused
85 inline
86 uvec
trimatl_ind(const SizeMat & s,const sword k=0)87 trimatl_ind(const SizeMat& s, const sword k = 0)
88   {
89   arma_extra_debug_sigprint();
90 
91   const uword n_rows = s.n_rows;
92   const uword n_cols = s.n_cols;
93 
94   const uword row_offset = (k < 0) ? uword(-k) : uword(0);
95   const uword col_offset = (k > 0) ? uword( k) : uword(0);
96 
97   arma_debug_check_bounds( ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)), "trimatl_ind(): requested diagonal is out of bounds" );
98 
99   const uword N = (std::min)(n_rows - row_offset, n_cols - col_offset);
100 
101   uvec   tmp(n_rows * n_cols, arma_nozeros_indicator());  // worst case scenario
102   uword* tmp_mem = tmp.memptr();
103   uword  count   = 0;
104 
105   for(uword col=0; col < col_offset; ++col)
106     {
107     const uword index_offset = (n_rows * col);
108 
109     for(uword row=0; row < n_rows; ++row)
110       {
111       tmp_mem[count] = index_offset + row;
112       ++count;
113       }
114     }
115 
116   for(uword i=0; i<N; ++i)
117     {
118     const uword start_row = i + row_offset;
119     const uword       col = i + col_offset;
120 
121     const uword index_offset = (n_rows * col);
122 
123     for(uword row=start_row; row < n_rows; ++row)
124       {
125       tmp_mem[count] = index_offset + row;
126       ++count;
127       }
128     }
129 
130   uvec out;
131 
132   out.steal_mem_col(tmp, count);
133 
134   return out;
135   }
136 
137 
138 
139 //! @}
140