00001 #ifndef Impala_Core_Matrix_MatNorm2Dist_h
00002 #define Impala_Core_Matrix_MatNorm2Dist_h
00003 
00004 #include "Core/Matrix/MatFunc.h"
00005 #include "Core/Matrix/MatSum.h"
00006 #include "Core/Matrix/MatMul.h"
00007 #include "Core/Matrix/MatReplicateMatrix.h"
00008 #include "Core/Array/Abs.h"
00009 #include "Core/Array/Add.h"
00010 #include "Core/Array/Mul.h"
00011 #include "Core/Array/MulVal.h"
00012 #include "Core/Array/Sqrt.h"
00013 #include "Basis/Timer.h"
00014 #ifdef CUDA
00015 #include "Link/Cuda/Cuda.h"
00016 #include "Link/Cuda/MatNorm2Dist.h"
00017 #endif
00018 
00019 
00020 namespace Impala
00021 {
00022 namespace Core
00023 {
00024 namespace Matrix
00025 {
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 template<class ArrayT>
00080 inline ArrayT*
00081 MatNorm2DistInternal(ArrayT* aT, ArrayT* b)
00082 {
00083     ILOG_VAR(Core.Matrix.MatNorm2Dist);
00084     if (MatNrCol(aT) != MatNrRow(b)) {
00085         ILOG_ERROR("MatNorm2DistInternal operands: dimensionality problem");
00086     }
00087 
00088     Timer timer;
00089     
00090     
00091     ArrayT* tempAT = 0;
00092     Mul(tempAT, aT, aT);         
00093     ArrayT* aaT = MatSumAxis1(tempAT);
00094     delete tempAT;
00095 
00096     ILOG_DEBUG("aaT: " << timer.SplitTimeStr());
00097 
00098     
00099     ArrayT* tempB = 0;
00100     Mul(tempB, b, b);         
00101     ArrayT* bb = MatSumAxis0(tempB);
00102     delete tempB;
00103 
00104     ILOG_DEBUG("bb: " << timer.SplitTimeStr());
00105 
00106     
00107     
00108     
00109 
00110     ILOG_DEBUG("aT " << MatNrRow(aT) << " " << MatNrCol(aT));
00111     ILOG_DEBUG("b  " << MatNrRow(b) << " " << MatNrCol(b));
00112 
00113     ArrayT* ab = MatMul(aT, b);
00114 
00115     ILOG_DEBUG("matmul: " << timer.SplitTimeStr());
00116 
00117     MulVal(ab, ab, -2.0);                   
00118 
00119     ILOG_DEBUG("ab: " << timer.SplitTimeStr());
00120 
00121     
00122     
00123     
00124     
00125 
00126     ArrayT* repAAT = MatReplicateMatrix(aaT, 1, MatNrCol(bb));
00127     ILOG_DEBUG("repmatAAT: " << timer.SplitTimeStr());
00128     ArrayT* repBB = MatReplicateMatrix(bb, MatNrRow(aaT), 1);
00129     ILOG_DEBUG("repmatBB: " << timer.SplitTimeStr());
00130     delete bb;
00131     delete aaT;
00132 
00133     ILOG_DEBUG("delete: " << timer.SplitTimeStr());
00134 
00135     Add(repAAT, repAAT, repBB);
00136     delete repBB;
00137     Add(repAAT, repAAT, ab);
00138     ILOG_DEBUG("add: " << timer.SplitTimeStr());
00139 
00140     delete ab;
00141     Abs(repAAT, repAAT);
00142     ILOG_DEBUG("abs: " << timer.SplitTimeStr());
00143 
00144     Sqrt(repAAT, repAAT);
00145 
00146     ILOG_DEBUG("sqrt: " << timer.SplitTimeStr());
00147 
00148 
00149 
00150     
00151     ILOG_DEBUG(timer.SplitTime() << " (cpu-matnorm2dist-total)");
00152     return repAAT;
00153 }
00154 
00155 
00156 template<class ArrayT>
00157 inline ArrayT*
00158 MatNorm2Dist(ArrayT* a, ArrayT* b)
00159 {
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171     ILOG_VAR(Core.Matrix.MatNorm2Dist);
00172     if (MatNrRow(a) != MatNrRow(b)) {
00173         ILOG_ERROR("MatNorm2Dist operands: A and B should be of same dimensionality");
00174     }
00175     Mat* aT = MatTranspose(a);
00176     ArrayT* result = MatNorm2DistInternal(aT, b);
00177     delete aT;
00178     return result;
00179 }
00180 
00181 
00182 template<class ArrayT>
00183 inline ArrayT*
00184 MatNorm2DistTransposed(ArrayT* aT, ArrayT* bT)
00185 {
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197     ILOG_VAR(Core.Matrix.MatNorm2DistTransposed);
00198     if (MatNrCol(aT) != MatNrCol(bT)) {
00199         ILOG_ERROR("MatNorm2DistTransposed operands: A and B should be of same dimensionality");
00200     }
00201 #ifdef CUDA
00202     if(Link::Cuda::CudaUsed())
00203     {
00204         return Link::Cuda::MatNorm2DistTransposed(aT, bT);
00205     }
00206 #endif
00207     Mat* b = MatTranspose(bT);
00208     Mat* result = MatNorm2DistInternal(aT, b);
00209     delete b;
00210     return result;
00211 }
00212 
00213 } 
00214 } 
00215 } 
00216 
00217 #endif