38 numOfCols (_numOfCols)
43 msg <<
"Row::Row **** ERROR **** Invalid Dimension[" << _numOfCols <<
"].";
44 cerr << std::endl << msg << std::endl << std::endl;
53 numOfCols (_row.numOfCols)
70 numOfCols = _numOfCols;
78 if ((idx < 0) || (idx >= numOfCols))
81 <<
"Row::operator[] **** ERROR ****, Index[" 82 << idx <<
"] out of range of [0-" << numOfCols <<
"]." 114 numOfCols (_numOfCols),
115 numOfRows (_numOfRows),
123 msg <<
"Matrix::Matrix **** ERROR ****, Row Dimension[" << _numOfRows <<
"] Invalid.";
124 cerr << std::endl << msg <<std::endl << std::endl;
131 msg <<
"Matrix::Matrix **** ERROR ****, Col Dimension[" << _numOfCols <<
"] Invalid.";
132 cerr << std::endl << msg <<std::endl << std::endl;
145 numOfCols (_matrix.numOfCols),
146 numOfRows (_matrix.numOfRows),
152 memcpy (dataArea, _matrix.dataArea, totNumCells *
sizeof (
double));
166 for (row = 0; row < numOfRows; ++row)
167 dataArea[row] = _v[row];
195 if ((numOfRows < 1) || (numOfCols < 1))
197 cerr << std::endl << std::endl <<
"Matrix::BuildFromArray ***ERROR*** NumOfRows[" << numOfRows <<
"] or NumOfCols[" << numOfCols <<
"] is invalid." << std::endl << std::endl;
203 cerr << std::endl << std::endl <<
"Matrix::BuildFromArray ***ERROR*** No source data (data == NULL)." << std::endl << std::endl;
207 MatrixPtr m =
new Matrix (numOfRows, numOfCols);
209 for (kkint32 row = 0; row < numOfRows; ++row)
211 T* srcRow = data[row];
212 double* destRow = m->data[row];
215 for (kkint32 col = 0; col < numOfCols; ++col)
216 destRow[col] = (
double)(srcRow[col]);
229 numOfRows = _numOfRows;
230 numOfCols = _numOfCols;
237 void Matrix::AllocateStorage ()
239 totNumCells = numOfRows * numOfCols;
240 dataArea =
new double[totNumCells];
241 data =
new double*[numOfRows];
242 rows =
new Row [numOfRows];
246 for (x = 0; x < totNumCells; ++x)
250 double* dataAreaPtr = dataArea;
251 for (x = 0; x < numOfRows; x++)
254 data[x] = dataAreaPtr;
255 dataAreaPtr += numOfCols;
263 delete[] rows; rows = NULL;
264 delete[] data; data = NULL;
265 delete[] dataArea; dataArea = NULL;
272 if ((rowIDX < 0) || (rowIDX >= numOfRows))
275 msg <<
"Matrix::operator[] **** ERROR ****, Row Index[" << rowIDX <<
"] Invalid.";
276 cerr << std::endl << msg << std::endl << std::endl;
280 return (rows[rowIDX]);
288 if (numOfCols != numOfRows)
291 msg <<
"Matrix::Determinant *** ERROR *** Dimensions are not Square[" << numOfRows <<
"," << numOfCols <<
"] Invalid.";
292 cerr << std::endl << msg << std::endl << std::endl;
305 for (x = 0; x < numOfRows; x++)
309 for (x = 0; x < numOfCols; x++)
312 double det = CalcDeterminent (rowMap, colMap, numOfCols);
331 ReSize (right.numOfRows
, right.numOfCols
);
332 memcpy (dataArea, right.dataArea, totNumCells *
sizeof (
double));
339 ReSize ((kkuint32)right.size (), 1);
340 for (kkint32 row = 0; row < numOfRows; row++)
341 dataArea[row] = right[row];
352 for (x = 0; x < totNumCells; ++x)
353 dataArea[x] *= right;
362 for (x = 0; x < totNumCells; ++x)
363 dataArea[x] += right;
371 if ((numOfRows != right.numOfRows) ||
372 (numOfCols != right.numOfCols))
375 msg <<
"Matrix::operator+ **** ERROR ****, Dimensions Don't Match [" << numOfRows <<
"," << numOfCols <<
"] + [" << right.numOfRows <<
"," << right.numOfCols <<
"].";
376 cerr << std::endl << msg << std::endl << std::endl;
382 double* resultDataArea = result.dataArea;
383 double* rightDataArea = right.dataArea;
385 for (
kkint32 x = 0; x < totNumCells; ++x)
386 resultDataArea[x] = dataArea[x] + rightDataArea[x];
398 if ((numOfRows != right.numOfRows) ||
399 (numOfCols != right.numOfCols))
402 msg <<
"Matrix::operator+= **** ERROR ****, Dimensions Don't Match [" << numOfRows <<
"," << numOfCols <<
"] + [" << right.numOfRows <<
"," << right.numOfCols <<
"].";
403 cerr << std::endl << msg << std::endl << std::endl;
407 double* rightDataArea = right.dataArea;
409 for (
kkint32 x = 0; x < totNumCells; ++x)
410 dataArea[x] += rightDataArea[x];
421 if ((numOfRows != right.numOfRows) ||
422 (numOfCols != right.numOfCols))
425 msg <<
"Matrix::operator- **** ERROR ****, Dimensions Don't Match [" << numOfRows <<
"," << numOfCols <<
"] + [" << right.numOfRows <<
"," << right.numOfCols <<
"].";
426 cerr << std::endl << msg << std::endl << std::endl;
432 double* resultDataArea = result.dataArea;
433 double* rightDataArea = right.dataArea;
435 for (
kkint32 x = 0; x < totNumCells; ++x)
436 resultDataArea[x] = dataArea[x] - rightDataArea[x];
446 double* resultDataArea = result.dataArea;
447 for (
kkint32 x = 0; x < totNumCells; ++x)
448 resultDataArea[x] = dataArea[x] - right;
462 kkint32 totNumCells = right.totNumCells;
465 double* resultDataArea = result.dataArea;
466 double* rightDataArea = right.dataArea;
468 for (
kkint32 x = 0; x < totNumCells; ++x)
469 resultDataArea[x] = left - rightDataArea[x];
480 if (numOfCols != right.numOfRows)
483 msg <<
"Matrix::operator* **** ERROR ****, Dimension Mismatch Left[" << numOfRows <<
"," << numOfCols <<
"] Right[" << right.numOfRows <<
"," << right.numOfCols <<
"].";
484 cerr << std::endl << msg << std::endl << std::endl;
492 kkint32 rCols = right.numOfCols;
496 double** resultData = result.data;
497 double** rightData = right.data;
501 for (row = 0; row < rRows; row++)
503 for (col = 0; col < rCols; col++)
507 for (x = 0; x < innerDim; x++)
508 val = val + data[row][x] * rightData[x][col];
509 resultData[row][col] = val;
522 double* resultDataArea = result.dataArea;
523 for (
kkint32 x = 0; x < totNumCells; ++x)
524 resultDataArea[x] = dataArea[x] + right;
533 double* resultDataArea = result.dataArea;
534 for (
kkint32 x = 0; x < totNumCells; ++x)
535 resultDataArea[x] = dataArea[x] * right;
553 double* topCols = data[rowMap[0]];
554 double* botCols = data[rowMap[1]];
555 return topCols[colMap[0]] * botCols[colMap[1]] - topCols[colMap[1]] * botCols[colMap[0]];
558 double* coFactors = data[rowMap[0]];
567 for (row = 1; row < size; row++)
569 newRowMap[row - 1] = rowMap[row];
573 for (cfCol = 0; cfCol < size; cfCol++)
579 for (oldCol = 0; oldCol < size; oldCol++)
583 newColMap[newCol] = colMap[oldCol];
588 det = det + sign * coFactors[colMap [cfCol]] * CalcDeterminent (newRowMap, newColMap, newSize);
608 if (numOfCols != numOfRows)
611 <<
"Matrix::CalcCoFactors **** ERROR ****, Matrix not a Square[" 612 << numOfRows <<
"," << numOfCols <<
"]." 621 kkint32 newSize = numOfCols - 1;
633 for (row = 0; row < numOfRows; row++)
639 for (x = 0; x < numOfRows; x++)
648 for (col = 0; col < numOfCols; col++)
654 for (x = 0; x < numOfCols; x++)
663 if (((row + col) % 2) == 0)
670 for (
kkint32 r = 0; r < newSize; r++)
673 for (
kkint32 c = 0; c < newSize; c++)
674 temp
[r][c] = data[tempR][colMap[c]];
690 if ((data == NULL) || (numOfRows != numOfCols))
693 for (
kkint32 row = 0; row < numOfRows; ++row)
695 for (
kkint32 col = row + 1; col < numOfCols; ++col)
697 if (data[row][col] != data[col][row])
714 double** resultData = result.data;
716 for (row = 0; row < numOfRows; row++)
718 for (col = 0; col < numOfCols; col++)
720 resultData[col][row] = data[row][col];
733 if (numOfCols != numOfRows)
736 msg <<
"Matrix::Inverse *** ERROR *** Dimensions are not Square[" << numOfRows <<
"," << numOfCols <<
"] Invalid.";
738 cerr << std::endl << msg << std::endl << std::endl;
745 cerr << std::endl <<
"Matrix::Inverse *** ERROR *** Determinant of Matrix is Zero." << std::endl << std::endl;
757 result
*= (1.0 / det);
774 if ((data == NULL) || (numOfRows < 1))
776 cerr << std::endl <<
"Matrix::EigenVectors ***ERROR*** 'data' not defined in Matrix." << std::endl << std::endl;
780 if (numOfRows != numOfCols)
782 cerr << std::endl <<
"Matrix::EigenVectors ***ERROR*** Not a square matrix NumOfRows[" << numOfRows <<
"] NumOfCols[" << numOfCols <<
"]." << std::endl << std::endl;
790 double* d =
new double[numOfRows];
791 double* e =
new double[numOfRows];
792 for (
kkint32 x = 0; x < numOfRows; ++x)
797 Tred2 (eigenVectors->data, numOfRows, d, e);
798 kkint32 successful = Tqli (d, e, numOfRows, eigenVectors->data);
801 delete eigenVectors; eigenVectors = NULL;
802 delete[] d; d = NULL;
803 delete[] e; e = NULL;
808 for (kkint32 x = 0; x < numOfRows; ++x)
809 eigenValues->push_back (d[x]);
811 delete[] d; d = NULL;
812 delete[] e; e = NULL;
833 for (
kkint32 row = 0; row < numOfRows; ++row)
835 double* dataRow = data[row];
836 for (
kkint32 col = 0; col < numOfCols; ++col)
838 if (dataRow[col] > maxVal)
840 maxVal = dataRow[col];
853 ostream& operator<< ( ostream& os,
860 os <<
"[" << matrix.NumOfRows () <<
"," << matrix.NumOfCols () <<
"]" << std::endl;
878 os << matrix[row][col];
881 os <<
"]" << std::endl;
884 os <<
"]" << std::endl;
894 for (kkint32 r = 0; r < numOfRows; r++)
895 colResult[r] = data[r][col];
901 #if !defined(DBL_EPSILON) 902 #define DBL_EPSILON 2.2204460492503131e-016
910 double Matrix::DeterminantSwap (
double** mat,
911 unsigned short offset
917 for (ushort i = offset + 1; i < numOfRows; i++)
934 return (mat[offset][offset]);
947 if (numOfCols != numOfRows)
952 double** mat =
new double*[numOfRows];
953 for (r = 0; r < numOfRows; r++)
955 mat[r] =
new double[numOfCols];
956 for (c = 0; c < numOfCols; c++)
958 mat[r][c] = data[r][c];
963 unsigned short i = 0;
965 for (i = 0; i < numOfRows; i++)
967 const double Aii = DeterminantSwap (mat, i);
968 unsigned short j = 0;
979 for (j = i + 1; j < numOfRows; j++)
981 const double pivot = mat[j][i] / Aii;
982 for (
ushort k = i; k < numOfRows; k++)
983 mat[j][k] -= pivot * mat[i][k];
987 for (r = 0; r < numOfRows; r++)
1006 if ((data == NULL) || (numOfRows < 1))
1008 cerr << std::endl <<
"Matrix::Covariance ***ERROR*** 'data' not defined in Matrix." << std::endl << std::endl;
1018 double* totals =
new double[numOfCols];
1019 double* means =
new double[numOfCols];
1020 double** centeredVals =
new double*[numOfCols];
1021 for (col = 0; col < numOfCols; ++col)
1024 centeredVals[col] =
new double[numOfRows];
1027 for (row = 0; row < numOfRows; ++row)
1029 double* rowData = data[row];
1030 for (col = 0; col < numOfCols; ++col)
1031 totals[col] += rowData[col];
1034 for (col = 0; col < numOfCols; ++col)
1035 means[col] = totals[col] / numOfRows;
1037 for (row = 0; row < numOfRows; ++row)
1039 double* rowData = data[row];
1040 for (col = 0; col < numOfCols; ++col)
1041 centeredVals[col][row] = rowData[col] - means[col];
1046 for (
kkint32 varIdxX = 0; varIdxX < numOfCols; ++varIdxX)
1048 double* varXs = centeredVals[varIdxX];
1049 for (
kkint32 varIdxY = varIdxX; varIdxY < numOfCols; ++varIdxY)
1053 double* varYs = centeredVals[varIdxY];
1054 double total = 0.0f;
1055 for (row = 0; row < numOfRows; ++row)
1056 total += varXs[row] * varYs[row];
1062 for (col = 0; col < numOfCols; col++)
1064 delete[] centeredVals[col];
1065 centeredVals[col] = NULL;
1067 delete[] centeredVals; centeredVals = NULL;
1068 delete[] means; means = NULL;
1069 delete[] totals; totals = NULL;
1086 void Matrix::Tred2 (
double** a,
1094 double scale, hh, h, g, f;
1096 for (i = n - 1; i > 0; i--)
1103 for (k = 0; k < l + 1; k++)
1104 scale += fabs (a[i][k]);
1113 for (k = 0; k < l + 1; k++)
1116 h+= a[i][k] * a[i][k];
1120 g = (f > 0 ? -sqrt(h) : sqrt(h));
1126 for (j = 0; j < l + 1; j++)
1128 a[j][i] = a[i][j] / h;
1130 for (k = 0; k < j + 1; k++)
1131 g += a[j][k] * a[i][k];
1133 for (k = j + 1; k < l + 1; k++)
1134 g += a[k][j] * a[i][k];
1138 f += e[j] * a[i][j];
1143 for (j = 0; j < l + 1; j++)
1146 e[j] = g = e[j] - hh * f;
1147 for (k = 0; k < j + 1; k++)
1148 a[j][k] -= (f * e[k] + g * a[i][k]);
1165 for (i = 0; i < n; i++)
1171 for (j = 0; j < l; j++)
1174 for (k = 0; k < l; k++)
1175 g += a[i][k] * a[k][j];
1177 for (k = 0; k < l; k++)
1178 a[k][j] -= g * a[k][i];
1186 for (j = 0; j < l; j++)
1187 a[j][i] = a[i][j] = 0.0;
1218 #define SQR(X) ((X) * (X)) 1221 double Matrix::Pythag (
const double a,
1232 return absa * sqrt (1.0 +
SQR (absb / absa));
1239 return absb * sqrt (1.0 +
SQR (absa / absb));
1268 double s, r, p,g, f, dd, c, b;
1270 for (i = 1; i < n; i++)
1275 for (l = 0; l < n; l++)
1281 for (m = l; m < n - 1; m++)
1285 dd = fabs (d[m]) + fabs (d[m + 1]);
1286 if (fabs (e[m]) + dd == dd)
1294 cerr << std::endl << std::endl
1295 <<
"Matrix::tqli **** ERROR **** To many iterations in tqli" << std::endl
1303 g = (d[l + 1] - d[l]) / (2.0 * e[l]);
1304 r = Pythag (g, 1.0);
1305 g = d[m] - d[l] + e[l] / (g + SIGN (r, g));
1309 for (i = m - 1; i >= l; i--)
1313 e[i + 1] = (r = Pythag (f, g));
1324 r = (d[i] - g) * s + 2.0 * c * b;
1325 d[i + 1] = g + (p = s * r);
1330 for (k = 0; k < n; k++)
1333 z[k][i + 1] = s * z[k][i] + c * f;
1334 z[k][i] = c * z[k][i] - s * f;
1339 if ((r == 0.0) && (i >= l))
Row & operator[](kkint32 rowIDX) const
KKStr(kkint32 size)
Creates a KKStr object that pre-allocates space for 'size' characters.
kkint32 NumOfRows() const
Matrix & operator=(const Matrix &right)
VectorDouble GetCol(kkint32 col) const
Matrix operator-(double right)
Matrix operator+(double right)
Matrix(kkint32 _numOfRows, kkint32 _numOfCols)
Supports two dimensional matrices.
static MatrixPtr BuildFromArray(kkint32 numOfRows, kkint32 numOfCols, T **data)
Will create a new matrix using the 2dArray "data" for source.
Matrix(const Matrix &_matrix)
Matrix & operator=(const VectorDouble &right)
MatrixPtr Covariance() const
Returns a Covariance matrix.
kkint32 NumOfCols() const
double & operator[](kkint32 idx)
Matrix operator*(const Matrix &right)
double DeterminantSlow()
Recursive Implementation.
void EigenVectors(MatrixPtr &eigenVectors, VectorDouble *&eigenValues) const
Will derive the Eigen vectors and values of the matrix.
Matrix(const VectorDouble &_v)
void FindMaxValue(double &maxVal, kkint32 &row, kkint32 &col)
Locates the maximum value in a matrix along with the row and column that is located.
Matrix operator+(const Matrix &right)
Matrix & operator+=(const Matrix &right)
Row(kkint32 _numOfCols, double *_cells)
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of 'std::string' strings.
unsigned short ushort
Unsigned short.
Matrix & operator*=(double right)
std::ostream &__cdecl operator<<(std::ostream &os, const KKStr &str)
const T SIGN(const T &a, const T &b)
Matrix operator-(const Matrix &right)
void ReSize(kkint32 _numOfRows, kkint32 _numOfCols)
Matrix operator-(double left, const Matrix &right)
MatrixPtr CalcCoFactorMatrix()
KKException(const KKStr &_exceptionStr)
void Define(kkint32 _numOfCols, double *_cells)
Matrix & operator+=(double right)
Matrix operator*(double right)
std::vector< double > VectorDouble
Vector of doubles.