[eigen] Re: LU precision tuning |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen <eigen@xxxxxxxxxxxxxxxxxxx>
- Subject: [eigen] Re: LU precision tuning
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Thu, 7 May 2009 16:46:44 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type; bh=G3UFBpv2Rar69OytBRoT2OjlKeCBd4qMg/Po7tVYGcI=; b=LFpVeC7uBPNQawNLJSBr3EAulK2+9B8sgSWsFw1FtNP9elJ3rDyWXHvRzMXrHhGKDI ohYpfjlACZQ1rKfTQCU2zAqb9ncpWngHbR6XuoA9y3JpNdrb4n8Vwsg6EnPFrPqDvpPy NlKMV5Rf3+nOYAZRoYCBzH4PNgxikKslm/UHI=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=M5LUcDaIeu2SkP+45pYBeCJLkV4vWt4zLwZiCXpA+/ujJZwxuLbe9O9G15dQ5kTEPh DylzCnNP9Aj/CWkk+0DsPRO4JYrckWmluMZRV1W+LfTYwbc87HgnP7xZ5c6KkoVX50s7 AyUp3Sho8k6DDIIzcktDWL2evZeqJXr7XCeUg=
oops, a little bug. find attached updated program (runs faster, more
significant output)
2009/5/7 Benoit Jacob <jacob.benoit.1@xxxxxxxxx>:
> Hi,
>
> This is mostly for Hauke but the attached file biscuitlu is worthy of
> being archived here, so here goes...
>
> In decompositions such as LU, we need to make decisions when to
> consider something as zero, and this depends on an arbitrary cutoff
> that can only be tuned by experiment. In LLt, we were lucky to have
> Keir who found a research paper telling us the optimal cutoff, but
> there doesn't seem to be anything like that for LU.
>
> So:
> - attached patch difflu allows LU to override the default precision level
> - attached patch biscuitlu tests the precision of LU::rank() for
> matrix sizes from 100 to 1000, for various precisions.
>
> This should allow us to infer the formula for the maximum precision we
> can use to allow for exact rank determination. Once this range of
> values is known, the next step will be to find the optimal 'precision"
> value to get optimally precise LU::solve(). So if you want to help,
> this 2nd program remains to be written !
>
> Benoit
>
#include <Eigen/LU>
#include <Eigen/Array>
#include <ctime>
using namespace Eigen;
using namespace std;
const int repeat = 10;
template<typename Derived>
void doSomeRankPreservingOperations(Eigen::MatrixBase<Derived>& m)
{
typedef typename Derived::RealScalar RealScalar;
for(int a = 0; a < 3*(m.rows()+m.cols()); a++)
{
RealScalar d = Eigen::ei_random<RealScalar>(-1,1);
int i = Eigen::ei_random<int>(0,m.rows()-1); // i is a random row number
int j;
do {
j = Eigen::ei_random<int>(0,m.rows()-1);
} while (i==j); // j is another one (must be different)
m.row(i) += d * m.row(j);
i = Eigen::ei_random<int>(0,m.cols()-1); // i is a random column number
do {
j = Eigen::ei_random<int>(0,m.cols()-1);
} while (i==j); // j is another one (must be different)
m.col(i) += d * m.col(j);
}
}
template<typename Scalar>
float test_lu_rank_one_size_one_precision(int size, typename NumTraits<Scalar>::Real precision)
{
float result = 0;
for(int i = 0; i < repeat; i++)
{
int rank = ei_random<int>(1, size-1);
typedef Matrix<Scalar,Dynamic,Dynamic> Mat;
Mat m = Mat::Random(size,size);
for(int i = rank; i < size; i++) m.row(i).setZero();
doSomeRankPreservingOperations(m);
LU<Mat> lu(m, precision);
result += float(abs(rank - lu.rank())) / size;
}
return result / repeat;
}
template<typename Scalar>
void test_lu_rank()
{
typedef typename NumTraits<Scalar>::Real RealScalar;
#ifdef __GNUC__
cout << "starting " << __PRETTY_FUNCTION__ << endl;
#else
cout << "starting " << __func__ << endl;
#endif
for(int size = 100; size <= 1000; size += 100)
{
for(RealScalar precision = machine_epsilon<RealScalar>();
precision < sqrt(machine_epsilon<RealScalar>());
precision *= 2)
{
float result = test_lu_rank_one_size_one_precision<Scalar>(size, precision);
cout << "size " << size << ", precision " << precision << ", average relative error in rank: " << result << endl;
}
}
}
int main()
{
srand((unsigned int) time(NULL));
cout << "repeating each test " << repeat << " times" << endl;
test_lu_rank<float>();
test_lu_rank<double>();
test_lu_rank<complex<float> >();
test_lu_rank<complex<double> >();
}