00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __RVL_ADJTEST
00034 #define __RVL_ADJTEST
00035
00036 #include "op.hh"
00037
00038 namespace RVL {
00039
00045 template<typename Scalar>
00046 bool AdjointTest(LinearOp<Scalar> const & op,
00047 FunctionObject & randomize,
00048 ostream & str,
00049 int tol=100) {
00050
00051 typedef typename ScalarFieldTraits<Scalar>::AbsType atype;
00052
00053 try {
00054
00055 Vector<Scalar> xin(op.getDomain());
00056 Vector<Scalar> yin(op.getRange());
00057 Vector<Scalar> xout(op.getDomain());
00058 Vector<Scalar> yout(op.getRange());
00059
00060 xin.eval(randomize);
00061 yin.eval(randomize);
00062
00063 xout.zero();
00064 yout.zero();
00065
00066 op.applyOp(xin,yout);
00067 op.applyAdjOp(yin,xout);
00068 Scalar ipdom=xin.inner(xout);
00069 Scalar iprng=yout.inner(yin);
00070 atype denom=yout.norm()*yin.norm();
00071 atype eps = tol*numeric_limits<atype>::epsilon();
00072
00073
00074 int nd;
00075 if (numeric_precision<atype>()==1) nd = 8;
00076 if (numeric_precision<atype>()==2) nd = 16;
00077 str<<setprecision(nd)<<setiosflags(ios_base::scientific);
00078
00079 atype aip=abs(ipdom-iprng);
00080 if (aip<eps*denom) {
00081 str<<"AdjointTest"<<endl<<endl;
00082 str<<"adjoint relation holds:";
00083 atype rat;
00084 if (ProtectedDivision<atype>(aip,denom,rat)) {
00085 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"<Ax,y> = "<<iprng<<endl;
00086 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"<x,A'y> = "<<ipdom<<endl;
00087 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"|Ax||y| = "<<denom<<endl;
00088 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"|<Ax,y>-<x,A'y>| = "<<aip<<endl;
00089 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"< 100*macheps*|Ax||y| = "<<eps*denom<<endl;
00090 }
00091 else {
00092 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"|<Ax,y>-<x,A'y>|/|Ax||y| = "<<rat<<endl;
00093 str<<setprecision(nd)<<setiosflags(ios::scientific)<<"< 100*macheps = "<<eps<<endl;
00094 str<<"<Ax,y> = "<<setprecision(nd)<<setiosflags(ios::scientific)<<iprng<<endl;
00095 str<<setprecision(nd)<<setiosflags(ios::scientific)<<"<x,A'y> = "<<ipdom<<endl;
00096 str<<setprecision(nd)<<setiosflags(ios::scientific)<<"|Ax||y| = "<<denom<<endl;
00097 }
00098 return true;
00099 }
00100 else {
00101 str<<"AdjointTest"<<endl;
00102 str<<"adjoint relation fails: ";
00103
00104 atype rat;
00105 if (ProtectedDivision<atype>(aip,denom,rat)) {
00106 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"<Ax,y> = "<<iprng<<endl;
00107 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"<x,A'y> = "<<ipdom<<endl;
00108 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"|Ax||y| = "<<denom<<endl;
00109 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"|<Ax,y>-<x,A'y>| = "<<aip<<endl;
00110 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<">= 100*macheps*|Ax||y| = "<<eps*denom<<endl;
00111 }
00112 else {
00113 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"|<Ax,y>-<x,A'y>|/|Ax||y| = "<<rat<<endl;
00114 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<">= 100*macheps = "<<eps<<endl;
00115 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"<Ax,y> = "<<iprng<<endl;
00116 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"<x,A'y> = "<<ipdom<<endl;
00117 str<<setprecision(nd)<<setiosflags(ios_base::scientific)<<"|Ax||y| = "<<denom<<endl;
00118 }
00119 }
00120 return false;
00121 }
00122 catch (RVLException & e) {
00123 e<<"\ncalled from AdjointTest\n";
00124 throw e;
00125 }
00126 }
00127 }
00128
00129 #endif