Chris@49
|
1 // Copyright (C) 2012 NICTA (www.nicta.com.au)
|
Chris@49
|
2 // Copyright (C) 2012 Conrad Sanderson
|
Chris@49
|
3 // Copyright (C) 2012 Arnold Wiliem
|
Chris@49
|
4 //
|
Chris@49
|
5 // This Source Code Form is subject to the terms of the Mozilla Public
|
Chris@49
|
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
|
Chris@49
|
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
Chris@49
|
8
|
Chris@49
|
9
|
Chris@49
|
10
|
Chris@49
|
11 //! \addtogroup op_unique
|
Chris@49
|
12 //! @{
|
Chris@49
|
13
|
Chris@49
|
14
|
Chris@49
|
15
|
Chris@49
|
16 // TODO: add an efficient implementation for complex numbers
|
Chris@49
|
17
|
Chris@49
|
18 template<typename T1>
|
Chris@49
|
19 inline
|
Chris@49
|
20 void
|
Chris@49
|
21 op_unique::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_unique>& X)
|
Chris@49
|
22 {
|
Chris@49
|
23 arma_extra_debug_sigprint();
|
Chris@49
|
24
|
Chris@49
|
25 typedef typename T1::elem_type eT;
|
Chris@49
|
26
|
Chris@49
|
27 const Proxy<T1> P(X.m);
|
Chris@49
|
28
|
Chris@49
|
29 const uword in_n_rows = P.get_n_rows();
|
Chris@49
|
30 const uword in_n_cols = P.get_n_cols();
|
Chris@49
|
31 const uword in_n_elem = P.get_n_elem();
|
Chris@49
|
32
|
Chris@49
|
33
|
Chris@49
|
34 if(in_n_elem <= 1)
|
Chris@49
|
35 {
|
Chris@49
|
36 if(in_n_elem == 1)
|
Chris@49
|
37 {
|
Chris@49
|
38 const eT tmp = P[0];
|
Chris@49
|
39
|
Chris@49
|
40 out.set_size(in_n_rows, in_n_cols);
|
Chris@49
|
41
|
Chris@49
|
42 out[0] = tmp;
|
Chris@49
|
43 }
|
Chris@49
|
44 else
|
Chris@49
|
45 {
|
Chris@49
|
46 out.set_size(in_n_rows, in_n_cols);
|
Chris@49
|
47 }
|
Chris@49
|
48
|
Chris@49
|
49 return;
|
Chris@49
|
50 }
|
Chris@49
|
51
|
Chris@49
|
52
|
Chris@49
|
53 std::vector<eT> lvec(in_n_elem);
|
Chris@49
|
54
|
Chris@49
|
55
|
Chris@49
|
56 if(Proxy<T1>::prefer_at_accessor == false)
|
Chris@49
|
57 {
|
Chris@49
|
58 typename Proxy<T1>::ea_type Pea = P.get_ea();
|
Chris@49
|
59
|
Chris@49
|
60 uword i,j;
|
Chris@49
|
61 for(i=0, j=1; j < in_n_elem; i+=2, j+=2)
|
Chris@49
|
62 {
|
Chris@49
|
63 const eT tmp_i = Pea[i];
|
Chris@49
|
64 const eT tmp_j = Pea[j];
|
Chris@49
|
65
|
Chris@49
|
66 lvec[i] = tmp_i;
|
Chris@49
|
67 lvec[j] = tmp_j;
|
Chris@49
|
68 }
|
Chris@49
|
69
|
Chris@49
|
70 if(i < in_n_elem)
|
Chris@49
|
71 {
|
Chris@49
|
72 lvec[i] = Pea[i];
|
Chris@49
|
73 }
|
Chris@49
|
74 }
|
Chris@49
|
75 else
|
Chris@49
|
76 {
|
Chris@49
|
77 uword i = 0;
|
Chris@49
|
78
|
Chris@49
|
79 for(uword col=0; col < in_n_cols; ++col)
|
Chris@49
|
80 for(uword row=0; row < in_n_rows; ++row, ++i)
|
Chris@49
|
81 {
|
Chris@49
|
82 lvec[i] = P.at(row,col);
|
Chris@49
|
83 }
|
Chris@49
|
84 }
|
Chris@49
|
85
|
Chris@49
|
86 std::sort( lvec.begin(), lvec.end() );
|
Chris@49
|
87
|
Chris@49
|
88 uword N_unique = 1;
|
Chris@49
|
89
|
Chris@49
|
90 for(uword i=1; i < in_n_elem; ++i)
|
Chris@49
|
91 {
|
Chris@49
|
92 const eT a = lvec[i-1];
|
Chris@49
|
93 const eT b = lvec[i ];
|
Chris@49
|
94
|
Chris@49
|
95 const eT diff = a - b;
|
Chris@49
|
96
|
Chris@49
|
97 if(diff != eT(0)) { ++N_unique; }
|
Chris@49
|
98 }
|
Chris@49
|
99
|
Chris@49
|
100 uword out_n_rows;
|
Chris@49
|
101 uword out_n_cols;
|
Chris@49
|
102
|
Chris@49
|
103 if( (in_n_rows == 1) || (in_n_cols == 1) )
|
Chris@49
|
104 {
|
Chris@49
|
105 if(in_n_rows == 1)
|
Chris@49
|
106 {
|
Chris@49
|
107 out_n_rows = 1;
|
Chris@49
|
108 out_n_cols = N_unique;
|
Chris@49
|
109 }
|
Chris@49
|
110 else
|
Chris@49
|
111 {
|
Chris@49
|
112 out_n_rows = N_unique;
|
Chris@49
|
113 out_n_cols = 1;
|
Chris@49
|
114 }
|
Chris@49
|
115 }
|
Chris@49
|
116 else
|
Chris@49
|
117 {
|
Chris@49
|
118 out_n_rows = N_unique;
|
Chris@49
|
119 out_n_cols = 1;
|
Chris@49
|
120 }
|
Chris@49
|
121
|
Chris@49
|
122 // we don't need to worry about aliasing at this stage, as all the data is stored in lvec
|
Chris@49
|
123 out.set_size(out_n_rows, out_n_cols);
|
Chris@49
|
124
|
Chris@49
|
125 eT* out_mem = out.memptr();
|
Chris@49
|
126
|
Chris@49
|
127 if(in_n_elem > 0) { out_mem[0] = lvec[0]; }
|
Chris@49
|
128
|
Chris@49
|
129 N_unique = 1;
|
Chris@49
|
130
|
Chris@49
|
131 for(uword i=1; i < in_n_elem; ++i)
|
Chris@49
|
132 {
|
Chris@49
|
133 const eT a = lvec[i-1];
|
Chris@49
|
134 const eT b = lvec[i ];
|
Chris@49
|
135
|
Chris@49
|
136 const eT diff = a - b;
|
Chris@49
|
137
|
Chris@49
|
138 if(diff != eT(0))
|
Chris@49
|
139 {
|
Chris@49
|
140 out_mem[N_unique] = b;
|
Chris@49
|
141 ++N_unique;
|
Chris@49
|
142 }
|
Chris@49
|
143 }
|
Chris@49
|
144
|
Chris@49
|
145 }
|
Chris@49
|
146
|
Chris@49
|
147
|
Chris@49
|
148
|
Chris@49
|
149 //! @}
|