MatrixBase<T>& Matrix<T>::operator+=(const MatrixBase<T>& rhs) { int rows = getNumRows(); int cols = getNumCols(); if( rows != rhs.getNumRows() ) throw SizeError(rows, "operator+= row"); if( cols != rhs.getNumCols() ) throw SizeError(cols, "operator+= col"); for(int i=0; i < rows; i++) { for(int j=0; j < cols; j++) { operator()(i,j) = operator()(i,j) + rhs(i,j); } } return *this; }
void Matrix<T>::setSize(int rows, int cols) { if(numRows != rows || numCols != cols) { if(rows < 0) throw SizeError(rows, "setSize: row"); if(cols < 0) throw SizeError(cols, "setSize: col"); delete [] head; numRows = rows; numCols = cols; head = new Vector<T>[numRows]; for(int i=0; i<numRows; i++) { head[i].setSize(numCols); } } }
MatrixBase<T>& Matrix<T>::operator=(const MatrixBase<T>& rhs) { if(&rhs != this) { const int row = rhs.getNumRows(); const int col = rhs.getNumCols(); if(row != getNumRows()) throw SizeError(row,"operator= row"); if(col != getNumCols()) throw SizeError(col,"operator= col"); for(int i=0; i < row; i++) { for(int j=0; j < col; j++) { this->operator()(i,j) = rhs(i,j); } } } return *this; }
Vector<T> Matrix<T>::operator*(const Vector<T>& rhs) const { if( getNumRows() != rhs.getSize() ) throw SizeError(rhs.getSize(), "operator*= vector"); Vector<T> retVal(getNumRows()); for(int i=0; i < getNumRows(); i++) { retVal[i] = getRow(i) * rhs; } return retVal; }
// a and b should be of equal sizes double dotProduct(const std::vector< double > a, const std::vector< double > b) { if (a.size() != b.size()) { std::cout << "Vector a and b must be of equal sizes:\n" << "A: " << a.size() << ", " << "B: " << b.size() << std::endl; throw SizeError(); } double sum = 0.0; for(int i = 0; i < a.size(); ++i) { sum += a[i] * b[i]; } return sum; }
MatrixBase<T>& Matrix<T>::operator*=(const MatrixBase<T>& rhs) { if( getNumCols() != rhs.getNumRows() ) throw SizeError(getNumCols(), "operator*= matrix"); MatrixBase<T>* retVal = new Matrix<T>(getNumRows(), rhs.getNumCols()); for(int i=0; i < getNumRows(); i++) { for(int j=0; j < rhs.getNumCols(); j++) { retVal->operator()(i,j) = getRow(i) * rhs.getColumn(j); } } *this = *retVal; delete retVal; return *this; }
void Matrix<T>::addColumn(const Vector<T>& newCol) { if(newCol.getSize() != numRows) throw SizeError(newCol.getSize()); Vector<T> temp(numCols + 1); for(int i=0; i < numRows; i++) { for(int j=0; j < numCols; j++) { temp[j] = head[i][j]; } temp[numCols] = newCol[i]; head[i].setSize(numCols + 1); head[i] = temp; } numCols++; }
/*! * Function to seed the generalized Halton sequencer, this function calls * reset then set the configuration according to the inScrambling argument. * \param inScrambling A randomized sequence of integers representing the * generalized Halton scrambling, if not provided, srand is initialized with * time(NULL). */ void GeneralizedHalton::seed(PyObject* inScrambling /*= NULL*/){ reset(); if(inScrambling){ PyObject* lNumber = NULL; PyObject* lDSeq = NULL; mPermutations = std::vector<std::vector<unsigned long> >(0); for(unsigned long i = 0; i < mDim; ++i){ mPermutations.push_back(std::vector<unsigned long>(PRIMES[i])); lDSeq = PySequence_GetItem(inScrambling, i); if(PySequence_Size(lDSeq) != PRIMES[i]){ std::ostringstream lMessage; lMessage << "Wrong scrambling size, for dimension " << i+1 << " the scrambling size must be "; lMessage << PRIMES[i] << ". "; lMessage << "Current size is " << PySequence_Size(lDSeq) << "."; throw(SizeError(lMessage.str())); } for(unsigned long j = 0; j < PRIMES[i]; ++j){ lNumber = PySequence_GetItem(lDSeq, j); #ifdef PY3K mPermutations[i][j] = PyLong_AsLong(lNumber); #else mPermutations[i][j] = PyInt_AsLong(lNumber); #endif Py_DECREF(lNumber); lNumber = NULL; } Py_DECREF(lDSeq); lDSeq = NULL; } }else{ srand(time(NULL)); mPermutations = std::vector<std::vector<unsigned long> >(mDim); for(unsigned long i = 0; i < mDim; ++i){ mPermutations.push_back(std::vector<unsigned long>()); for(unsigned long j = 0; j < PRIMES[i]; ++j){ mPermutations[i].push_back(j); } std::random_shuffle(mPermutations[i].begin() + 1, mPermutations[i].end()); } } }
Matrix Matrix::operator*(const Matrix& x) const { if(columns != x.rows) throw SizeError(); Matrix result(rows,x.columns); for(int i = 0; i < rows; i++) { for(int j = 0; j < x.columns; j++) { float a = 0; for(int k = 0; k < columns; k++) { a += items[i][k] * x.items[k][j]; } result[i][j] = a; } } return result; }
void Matrix::gaussian_elimination(Vector& answers) { if(rows != columns) throw SizeError(); int sz = rows; int i = 0, j = 0; while(i < sz && j < sz) { int maxi = i; for(int k = i+1; k < sz; k++) { if(abs(items[k][j]) > abs(items[maxi][j])) maxi = k; } if(items[maxi][j] != 0) { Vector tmp = items[maxi]; items[maxi] = items[i]; items[i] = tmp; float atmp = answers[maxi]; answers[maxi] = answers[i]; answers[i] = atmp; for(int k = 0; k < sz; k++) { items[i][k] /= items[i][j]; } answers[i] /= items[i][j]; for(int u = i+1; u < sz; u++) { for(int k = 0; k < sz; k++) { items[u][k] -= items[u][i] * items[i][k]; } answers[u] -= items[u][i] * answers[i]; } i++; } j++; } }
void Vector::check_size_equals(const Vector& other) const { if(sz != other.sz) throw SizeError(); }
void Matrix::check_size_equals(const Matrix& other) const { if(rows != other.rows || columns != other.columns) throw SizeError(); }