////////////////////////////////////////////////////////////////////// // solve for the eigensystem of the matrix ////////////////////////////////////////////////////////////////////// void MATRIX::eigensystem(VECTOR& eigenvalues, MATRIX& eigenvectors) { // basic error checking if (_rows != _cols) { cout << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " : " << endl; cout << " Matrix must be square to get eigenvalues! " << endl; return; } // resize result space eigenvalues.resizeAndWipe(_rows); eigenvectors.resizeAndWipe(_rows, _rows); // OSX specific - clapack stuff __CLPK_integer rowsize = _rows; __CLPK_integer worksize = 5 * _rows; double* work = new double[worksize]; double* valuesReal = new double[2 * _rows]; double* valuesImag = valuesReal + _rows; double* vectors = new double[_rows * _rows]; double* matrix = new double[_rows * _cols]; for (int x = 0; x < _rows * _cols; x++) matrix[x] = _matrix[x]; // the actual LAPACK call __CLPK_integer error; char V = 'V'; char N = 'N'; dgeev_(&V,&N, &rowsize, matrix, &rowsize, valuesReal, valuesImag, vectors, &rowsize, NULL, &rowsize, work, &worksize, &error); if (error != 0) { cout << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " : " << endl; cout << " eigenvalue solver bombed!" << endl; } cout << " Error value: " << error << endl; // copy the results into sortable form vector<EIGENPAIR> pairs; for (int x = 0; x < _rows; x++) { EIGENPAIR pair; pair.value = valuesReal[x]; VECTOR singleVector(_rows); for (int y = 0; y < _rows; y++) singleVector[y] = vectors[y + x * _cols]; pair.eigenvector = singleVector; pairs.push_back(pair); } // sort it sort(pairs.begin(), pairs.end()); // copy out results eigenvalues.resizeAndWipe(_rows); for (int x = 0; x < _rows; x++) eigenvalues(x) = pairs[x].value; eigenvectors.resizeAndWipe(_rows, _rows); for (int x = 0; x < _rows; x++) for (int y = 0; y < _rows; y++) eigenvectors(x,y) = pairs[y].eigenvector[x]; // cleanup delete[] work; delete[] valuesReal; delete[] vectors; delete[] matrix; }