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