有没有办法找到特征矩阵系数的中值?
Is there a way to find the median value of coefficients of an Eigen Matrix?
我想知道是否有比手动 for 循环更有效的方法。
编辑:这个答案需要 eigen 的开发分支!我一直在使用那个分支很长时间,以至于我忘记了,例如reshaped
不是稳定分支的一部分...
有办法。中位数计算通常需要排序,所以这也是我在这里所做的。如果你有一个可变的 object/expression,它的值被排序并计算中位数。如果你有一个 const object/expression,一个副本被排序并计算中位数。希望这对您有所帮助!
#include <Eigen/Dense>
#include <iostream>
#include <algorithm>
template<typename Derived>
typename Derived::Scalar median( Eigen::DenseBase<Derived>& d ){
auto r { d.reshaped() };
std::sort( r.begin(), r.end() );
return r.size() % 2 == 0 ?
r.segment( (r.size()-2)/2, 2 ).mean() :
r( r.size()/2 );
}
template<typename Derived>
typename Derived::Scalar median( const Eigen::DenseBase<Derived>& d ){
typename Derived::PlainObject m { d.replicate(1,1) };
return median(m);
}
int main(){
// vector with odd length
Eigen::Vector3f vec1 { 0.1, 2.3, 1.1 };
std::cout << median(vec1) << " (expected: 1.1)\n";
// vector with even length
Eigen::Vector4f vec2 { 1, 3, 0, 2 };
std::cout << median(vec2) << " (expected: 1.5)\n";
Eigen::Matrix3f mat;
mat <<
0, 8, 3,
2, 1, 5,
4, 7, 6;
// const reference (operates on a copy)
const Eigen::Matrix3f& matCRef { mat };
std::cout << median(matCRef) << " (expected: 4)\n";
// block expression (operates on a copy of that expression)
auto& cBlock { matCRef.block(1,1,2,2) };
std::cout << median(cBlock) << " (expected: 5.5)\n";
// matrix itself last, because it's going to be sorted afterwards:
std::cout << median(mat) << " (expected: 4)\n";
return 0;
}
因此,对于奇数个系数,返回中值,对于偶数个系数,返回上下中值之间的平均值。
我想知道是否有比手动 for 循环更有效的方法。
编辑:这个答案需要 eigen 的开发分支!我一直在使用那个分支很长时间,以至于我忘记了,例如reshaped
不是稳定分支的一部分...
有办法。中位数计算通常需要排序,所以这也是我在这里所做的。如果你有一个可变的 object/expression,它的值被排序并计算中位数。如果你有一个 const object/expression,一个副本被排序并计算中位数。希望这对您有所帮助!
#include <Eigen/Dense>
#include <iostream>
#include <algorithm>
template<typename Derived>
typename Derived::Scalar median( Eigen::DenseBase<Derived>& d ){
auto r { d.reshaped() };
std::sort( r.begin(), r.end() );
return r.size() % 2 == 0 ?
r.segment( (r.size()-2)/2, 2 ).mean() :
r( r.size()/2 );
}
template<typename Derived>
typename Derived::Scalar median( const Eigen::DenseBase<Derived>& d ){
typename Derived::PlainObject m { d.replicate(1,1) };
return median(m);
}
int main(){
// vector with odd length
Eigen::Vector3f vec1 { 0.1, 2.3, 1.1 };
std::cout << median(vec1) << " (expected: 1.1)\n";
// vector with even length
Eigen::Vector4f vec2 { 1, 3, 0, 2 };
std::cout << median(vec2) << " (expected: 1.5)\n";
Eigen::Matrix3f mat;
mat <<
0, 8, 3,
2, 1, 5,
4, 7, 6;
// const reference (operates on a copy)
const Eigen::Matrix3f& matCRef { mat };
std::cout << median(matCRef) << " (expected: 4)\n";
// block expression (operates on a copy of that expression)
auto& cBlock { matCRef.block(1,1,2,2) };
std::cout << median(cBlock) << " (expected: 5.5)\n";
// matrix itself last, because it's going to be sorted afterwards:
std::cout << median(mat) << " (expected: 4)\n";
return 0;
}
因此,对于奇数个系数,返回中值,对于偶数个系数,返回上下中值之间的平均值。