"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "include/armadillo_bits/op_median_meat.hpp" between
armadillo-10.8.2.tar.xz and armadillo-11.0.0.tar.xz

About: Armadillo is a C++ linear algebra library (matrix maths) aiming towards a good balance between speed and ease of use.

op_median_meat.hpp  (armadillo-10.8.2.tar.xz):op_median_meat.hpp  (armadillo-11.0.0.tar.xz)
skipping to change at line 21 skipping to change at line 21
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
//! \addtogroup op_median //! \addtogroup op_median
//! @{ //! @{
//! \brief template<typename T1>
//! For each row or for each column, find the median value.
//! The result is stored in a dense matrix that has either one column or one row
.
//! The dimension, for which the medians are found, is set via the median() func
tion.
template<typename eT, typename T1>
inline inline
void void
op_median::apply(Mat<eT>& out, const Op<T1,op_median>& in, const typename arma_n ot_cx<eT>::result* junk) op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& expr)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk);
// typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
const uword dim = in.aux_uword_a;
arma_debug_check( (dim > 1), "median(): parameter 'dim' must be 0 or 1" );
const Proxy<T1> P(in.m); const quasi_unwrap<T1> U(expr.m);
typedef typename Proxy<T1>::stored_type P_stored_type; const uword dim = expr.aux_uword_a;
const bool is_alias = P.is_alias(out); arma_debug_check( U.M.has_nan(), "median(): detected NaN" );
arma_debug_check( (dim > 1), "median(): parameter 'dim' must be 0 or 1" );
if(is_Mat<P_stored_type>::value || is_alias) if(U.is_alias(out))
{ {
const unwrap_check<P_stored_type> tmp(P.Q, is_alias); Mat<eT> tmp;
const typename unwrap_check<P_stored_type>::stored_type& X = tmp.M; op_median::apply_noalias(out, U.M, dim);
const uword X_n_rows = X.n_rows; out.steal_mem(tmp);
const uword X_n_cols = X.n_cols; }
else
{
op_median::apply_noalias(out, U.M, dim);
}
}
if(dim == 0) // in each column template<typename eT>
{ inline
arma_extra_debug_print("op_median::apply(): dim = 0"); void
op_median::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const uword dim, const
typename arma_not_cx<eT>::result* junk)
{
arma_extra_debug_sigprint();
arma_ignore(junk);
out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); const uword X_n_rows = X.n_rows;
const uword X_n_cols = X.n_cols;
if(X_n_rows > 0) if(dim == 0) // in each column
{ {
std::vector<eT> tmp_vec(X_n_rows); arma_extra_debug_print("op_median::apply(): dim = 0");
for(uword col=0; col < X_n_cols; ++col) out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols);
{
arrayops::copy( &(tmp_vec[0]), X.colptr(col), X_n_rows );
out[col] = op_median::direct_median(tmp_vec); if(X_n_rows > 0)
}
}
}
else // in each row
{ {
arma_extra_debug_print("op_median::apply(): dim = 1"); std::vector<eT> tmp_vec(X_n_rows);
out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0); for(uword col=0; col < X_n_cols; ++col)
if(X_n_cols > 0)
{ {
std::vector<eT> tmp_vec(X_n_cols); arrayops::copy( &(tmp_vec[0]), X.colptr(col), X_n_rows );
for(uword row=0; row < X_n_rows; ++row) out[col] = op_median::direct_median(tmp_vec);
{
for(uword col=0; col < X_n_cols; ++col) { tmp_vec[col] = X.at(row,col
); }
out[row] = op_median::direct_median(tmp_vec);
}
} }
} }
} }
else else
if(dim == 1) // in each row
{ {
const uword P_n_rows = P.get_n_rows(); arma_extra_debug_print("op_median::apply(): dim = 1");
const uword P_n_cols = P.get_n_cols();
if(dim == 0) // in each column
{
arma_extra_debug_print("op_median::apply(): dim = 0");
out.set_size((P_n_rows > 0) ? 1 : 0, P_n_cols);
if(P_n_rows > 0)
{
std::vector<eT> tmp_vec(P_n_rows);
for(uword col=0; col < P_n_cols; ++col) out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0);
{
for(uword row=0; row < P_n_rows; ++row) { tmp_vec[row] = P.at(row,col
); }
out[col] = op_median::direct_median(tmp_vec); if(X_n_cols > 0)
}
}
}
else // in each row
{ {
arma_extra_debug_print("op_median::apply(): dim = 1"); std::vector<eT> tmp_vec(X_n_cols);
out.set_size(P_n_rows, (P_n_cols > 0) ? 1 : 0); for(uword row=0; row < X_n_rows; ++row)
if(P_n_cols > 0)
{ {
std::vector<eT> tmp_vec(P_n_cols); for(uword col=0; col < X_n_cols; ++col) { tmp_vec[col] = X.at(row,col);
}
for(uword row=0; row < P_n_rows; ++row)
{
for(uword col=0; col < P_n_cols; ++col) { tmp_vec[col] = P.at(row,col
); }
out[row] = op_median::direct_median(tmp_vec); out[row] = op_median::direct_median(tmp_vec);
}
} }
} }
} }
} }
//! Implementation for complex numbers template<typename eT>
template<typename eT, typename T1>
inline inline
void void
op_median::apply(Mat<eT>& out, const Op<T1,op_median>& in, const typename arma_c x_only<eT>::result* junk) op_median::apply_noalias(Mat<eT>& out, const Mat<eT>& X, const uword dim, const typename arma_cx_only<eT>::result* junk)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
// typedef typename std::complex<T> eT;
typedef typename get_pod_type<eT>::result T; typedef typename get_pod_type<eT>::result T;
arma_type_check(( is_same_type<eT, typename T1::elem_type>::no ));
const unwrap_check<T1> tmp(in.m, out);
const Mat<eT>& X = tmp.M;
const uword X_n_rows = X.n_rows; const uword X_n_rows = X.n_rows;
const uword X_n_cols = X.n_cols; const uword X_n_cols = X.n_cols;
const uword dim = in.aux_uword_a;
arma_debug_check( (dim > 1), "median(): parameter 'dim' must be 0 or 1" );
if(dim == 0) // in each column if(dim == 0) // in each column
{ {
arma_extra_debug_print("op_median::apply(): dim = 0"); arma_extra_debug_print("op_median::apply(): dim = 0");
out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols); out.set_size((X_n_rows > 0) ? 1 : 0, X_n_cols);
if(X_n_rows > 0) if(X_n_rows > 0)
{ {
std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows); std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows);
for(uword col=0; col<X_n_cols; ++col) for(uword col=0; col<X_n_cols; ++col)
{ {
const eT* colmem = X.colptr(col); const eT* colmem = X.colptr(col);
for(uword row=0; row<X_n_rows; ++row) for(uword row=0; row<X_n_rows; ++row)
{ {
tmp_vec[row].val = std::abs(colmem[row]); tmp_vec[row].val = std::abs(colmem[row]);
tmp_vec[row].index = row; tmp_vec[row].index = row;
} }
uword index1; uword index1 = 0;
uword index2; uword index2 = 0;
op_median::direct_cx_median_index(index1, index2, tmp_vec); op_median::direct_cx_median_index(index1, index2, tmp_vec);
out[col] = op_mean::robust_mean(colmem[index1], colmem[index2]); out[col] = op_mean::robust_mean(colmem[index1], colmem[index2]);
} }
} }
} }
else else
if(dim == 1) // in each row if(dim == 1) // in each row
{ {
arma_extra_debug_print("op_median::apply(): dim = 1"); arma_extra_debug_print("op_median::apply(): dim = 1");
skipping to change at line 204 skipping to change at line 161
std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols); std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols);
for(uword row=0; row<X_n_rows; ++row) for(uword row=0; row<X_n_rows; ++row)
{ {
for(uword col=0; col<X_n_cols; ++col) for(uword col=0; col<X_n_cols; ++col)
{ {
tmp_vec[col].val = std::abs(X.at(row,col)); tmp_vec[col].val = std::abs(X.at(row,col));
tmp_vec[col].index = col; tmp_vec[col].index = col;
} }
uword index1; uword index1 = 0;
uword index2; uword index2 = 0;
op_median::direct_cx_median_index(index1, index2, tmp_vec); op_median::direct_cx_median_index(index1, index2, tmp_vec);
out[row] = op_mean::robust_mean( X.at(row,index1), X.at(row,index2) ); out[row] = op_mean::robust_mean( X.at(row,index1), X.at(row,index2) );
} }
} }
} }
} }
template<typename T1> template<typename T1>
inline inline
skipping to change at line 228 skipping to change at line 185
( (
const T1& X, const T1& X,
const typename arma_not_cx<typename T1::elem_type>::result* junk const typename arma_not_cx<typename T1::elem_type>::result* junk
) )
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename Proxy<T1>::stored_type P_stored_type; const quasi_unwrap<T1> U(X);
const Proxy<T1> P(X); const uword n_elem = U.M.n_elem;
const uword n_elem = P.get_n_elem();
if(n_elem == 0) if(n_elem == 0)
{ {
arma_debug_check(true, "median(): object has no elements"); arma_debug_check(true, "median(): object has no elements");
return Datum<eT>::nan; return Datum<eT>::nan;
} }
std::vector<eT> tmp_vec(n_elem); arma_debug_check( U.M.has_nan(), "median(): detected NaN" );
if(is_Mat<P_stored_type>::value)
{
const unwrap<P_stored_type> tmp(P.Q);
const typename unwrap<P_stored_type>::stored_type& Y = tmp.M;
arrayops::copy( &(tmp_vec[0]), Y.memptr(), n_elem );
}
else
{
if(Proxy<T1>::use_at == false)
{
typedef typename Proxy<T1>::ea_type ea_type;
ea_type A = P.get_ea();
for(uword i=0; i<n_elem; ++i) { tmp_vec[i] = A[i]; } std::vector<eT> tmp_vec(n_elem);
}
else
{
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
if(n_cols == 1) arrayops::copy( &(tmp_vec[0]), U.M.memptr(), n_elem );
{
for(uword row=0; row < n_rows; ++row) { tmp_vec[row] = P.at(row,0); }
}
else
if(n_rows == 1)
{
for(uword col=0; col < n_cols; ++col) { tmp_vec[col] = P.at(0,col); }
}
else
{
arma_stop_logic_error("op_median::median_vec(): expected a vector" );
}
}
}
return op_median::direct_median(tmp_vec); return op_median::direct_median(tmp_vec);
} }
template<typename T1> template<typename T1>
inline inline
typename T1::elem_type typename T1::elem_type
op_median::median_vec op_median::median_vec
( (
const T1& X, const T1& X,
const typename arma_cx_only<typename T1::elem_type>::result* junk const typename arma_cx_only<typename T1::elem_type>::result* junk
) )
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
arma_ignore(junk); arma_ignore(junk);
typedef typename T1::elem_type eT; typedef typename T1::elem_type eT;
typedef typename T1::pod_type T; typedef typename T1::pod_type T;
const Proxy<T1> P(X); const quasi_unwrap<T1> U(X);
const uword n_elem = P.get_n_elem(); const uword n_elem = U.M.n_elem;
if(n_elem == 0) if(n_elem == 0)
{ {
arma_debug_check(true, "median(): object has no elements"); arma_debug_check(true, "median(): object has no elements");
return Datum<eT>::nan; return Datum<eT>::nan;
} }
std::vector< arma_cx_median_packet<T> > tmp_vec(n_elem); arma_debug_check( U.M.has_nan(), "median(): detected NaN" );
if(Proxy<T1>::use_at == false) std::vector< arma_cx_median_packet<T> > tmp_vec(n_elem);
{
typedef typename Proxy<T1>::ea_type ea_type;
ea_type A = P.get_ea();
for(uword i=0; i<n_elem; ++i)
{
tmp_vec[i].val = std::abs( A[i] );
tmp_vec[i].index = i;
}
uword index1; const eT* A = U.M.memptr();
uword index2;
op_median::direct_cx_median_index(index1, index2, tmp_vec);
return op_mean::robust_mean( A[index1], A[index2] ); for(uword i=0; i<n_elem; ++i)
}
else
{ {
const uword n_rows = P.get_n_rows(); tmp_vec[i].val = std::abs( A[i] );
const uword n_cols = P.get_n_cols(); tmp_vec[i].index = i;
}
if(n_cols == 1)
{
for(uword row=0; row < n_rows; ++row)
{
tmp_vec[row].val = std::abs( P.at(row,0) );
tmp_vec[row].index = row;
}
uword index1;
uword index2;
op_median::direct_cx_median_index(index1, index2, tmp_vec);
return op_mean::robust_mean( P.at(index1,0), P.at(index2,0) );
}
else
if(n_rows == 1)
{
for(uword col=0; col < n_cols; ++col)
{
tmp_vec[col].val = std::abs( P.at(0,col) );
tmp_vec[col].index = col;
}
uword index1;
uword index2;
op_median::direct_cx_median_index(index1, index2, tmp_vec);
return op_mean::robust_mean( P.at(0,index1), P.at(0,index2) ); uword index1 = 0;
} uword index2 = 0;
else op_median::direct_cx_median_index(index1, index2, tmp_vec);
{
arma_stop_logic_error("op_median::median_vec(): expected a vector" );
return eT(0); return op_mean::robust_mean( A[index1], A[index2] );
}
}
} }
//! find the median value of a std::vector (contents is modified)
template<typename eT> template<typename eT>
inline inline
eT eT
op_median::direct_median(std::vector<eT>& X) op_median::direct_median(std::vector<eT>& X)
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
// TODO: if NaN is detected, return NaN
const uword n_elem = uword(X.size()); const uword n_elem = uword(X.size());
const uword half = n_elem/2; const uword half = n_elem/2;
typename std::vector<eT>::iterator first = X.begin(); typename std::vector<eT>::iterator first = X.begin();
typename std::vector<eT>::iterator nth = first + half; typename std::vector<eT>::iterator nth = first + half;
typename std::vector<eT>::iterator pastlast = X.end(); typename std::vector<eT>::iterator pastlast = X.end();
std::nth_element(first, nth, pastlast); std::nth_element(first, nth, pastlast);
if((n_elem % 2) == 0) // even number of elements if((n_elem % 2) == 0) // even number of elements
skipping to change at line 423 skipping to change at line 296
( (
uword& out_index1, uword& out_index1,
uword& out_index2, uword& out_index2,
std::vector< arma_cx_median_packet<T> >& X std::vector< arma_cx_median_packet<T> >& X
) )
{ {
arma_extra_debug_sigprint(); arma_extra_debug_sigprint();
typedef arma_cx_median_packet<T> eT; typedef arma_cx_median_packet<T> eT;
// TODO: if NaN is detected, return bool set to false, indicating presence of
NaN
const uword n_elem = uword(X.size()); const uword n_elem = uword(X.size());
const uword half = n_elem/2; const uword half = n_elem/2;
typename std::vector<eT>::iterator first = X.begin(); typename std::vector<eT>::iterator first = X.begin();
typename std::vector<eT>::iterator nth = first + half; typename std::vector<eT>::iterator nth = first + half;
typename std::vector<eT>::iterator pastlast = X.end(); typename std::vector<eT>::iterator pastlast = X.end();
std::nth_element(first, nth, pastlast); std::nth_element(first, nth, pastlast);
out_index1 = (*nth).index; out_index1 = (*nth).index;
 End of changes. 52 change blocks. 
202 lines changed or deleted 69 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)