/* * Calculate the determinant of the matrix * */ double calcDet(double a[][N], int n) { double ans = 0; double temp[N][N]={{0.0}}; double t; int i,j,k; if (n == 1) { return a[0][0]; } for (i = 0; i < n; i++) { for(j = 0; j < n-1; j++) { for(k = 0; k < n-1; k++) { temp[j][k] = a[j+1][(k>=i)?k+1:k]; } } t = calcDet(temp, n-1); if (i%2 == 0) { // + - + - ... ans += a[0][i]*t; } else { ans -= a[0][i]*t; } } return ans; }
void calcB(Eigen::MatrixXd &points, int n, int k) { Eigen::VectorXd B(n); double sum; //calc first k entries for (int i = 0; i < k; i++) { sum = 0; for (int j = 0; j < n; j++) { sum += points(j, i + 1)*points(j, i + 1) - points(j, i)*points(j, i); } B(i) = sum; } //calc last n-k entries for (int i = k; i < n; i++) { sum = 0; for (int j = 0; j < n; j++) { if (j < n - k) sum += calcDet(points, k, j, i - k) * (points(j, 1) + points(j, 2)); else if (j == i) sum += -calcDet0(points, k) * (points(j, 1) + points(j, 2)); } B(i) = sum; } B = 0.5 * B; }
// n entspricht der dimension der punkte, k = anzahl der punkte - 1 void calcA(Eigen::MatrixXd &points, int n, int k) { Eigen::MatrixXd A(n, n); //calc first k rows for (int i = 0; i < k; i++) { for (int j = 0; j < n; j++) { A(i, j) = points(j, i + 1) - points(j, i); } } //calc last n-k rows for (int i = k; i < n; i++) { for (int j = 0; j < n; j++) { if (j < n-k) A(i, j) = calcDet(points, k, j, i - k); else if (j == i) A(i, j) = -calcDet0(points, k); else A(i, j) = 0; } } }
void MainWindow::onLoad() { ui->detEdit->clear(); ui->detEdit->clear(); ui->LLEdit->clear(); ui->normaEdit->clear(); ui->inputEdit->clear(); ui->solEdit->clear(); if(A != 0) { for(int i = 0; i < n; i++) { free(A[i]); } free(A); A = 0; } if(d != 0) { free(d); d = 0; } if(b != 0) { free(b); b = 0; } QFile file(ui->fileNameEdit->text()); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } n = file.readLine().split('\n').at(0).toInt(0, 10); m = file.readLine().split('\n').at(0).toInt(0, 10); A = (double**) malloc (n * sizeof(double*)); d = (double*) malloc (n * (sizeof (double))); b = (double*) malloc (n * (sizeof (double))); x = (double*) malloc (n * sizeof(double)); for(int i = 0; i < n; i++) { A[i] = (double*) malloc (n * (sizeof (double))); QList<QByteArray> numbers = file.readLine().split(' '); for(int j = 0; j < n; j++) { A[i][j] = numbers.at(j).split('\n').at(0).toDouble(); } d[i] = A[i][i]; } QList<QByteArray> numbers = file.readLine().split(' '); for(int j = 0; j < n; j++) { b[j] = numbers.at(j).split('\n').at(0).toDouble(); } printInput(); calcDesc(); calcDet(); calcSol(); calcNorma(); }
/* * Calculate the inverse of the matrix * */ bool calcInv(double src[][N], int n, double des[][N]) { double det = calcDet(src,n); double t[N][N]={{0.0}}; int i, j; if(det == 0) { return false; // The matrix is singular, haven't multiplicative inverse. } else { calcAdj(src,n,t); for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { des[i][j]=t[i][j]/det; } } } return true; }
/* * Calculate the adjoint of the matrix * */ void calcAdj(double ori[][N], int n, double ans[][N]) { int i,j,k,t; double temp[N][N]={{0.0}}; if (n == 1) { ans[0][0] = 1; return; } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { for (k = 0; k < n-1; k++) { for (t = 0; t < n-1; t++) { temp[k][t] = ori[k>=i?k+1:k][t>=j?t+1:t]; } } ans[j][i] = calcDet(temp,n-1); if ((i+j)%2 == 1) { ans[j][i] = - ans[j][i]; } } } }
void calcBall(ball *ball, Eigen::MatrixXd &points, int n, int k) { //calc A Eigen::MatrixXd A(n, n); //calc first k rows for (int i = 0; i < k; i++) { for (int j = 0; j < n; j++) { A(i, j) = points(j, i + 1) - points(j, i); } } //calc last n-k rows for (int i = k; i < n; i++) { for (int j = 0; j < n; j++) { if (j < n - k) A(i, j) = calcDet(points, k, j, i - k); else if (j == i) A(i, j) = -calcDet0(points, k); else A(i, j) = 0; } } //calc B Eigen::VectorXd B(n); double sum; //calc first k entries for (int i = 0; i < k; i++) { sum = 0; for (int j = 0; j < n; j++) { sum += points(j, i + 1)*points(j, i + 1) - points(j, i)*points(j, i); } B(i) = sum; } //calc last n-k entries for (int i = k; i < n; i++) { sum = 0; for (int j = 0; j < n; j++) { if (j < n - k) sum += calcDet(points, k, j, i - k) * (points(j, 1) + points(j, 2)); else if (j == i) sum += -calcDet0(points, k) * (points(j, 1) + points(j, 2)); } B(i) = sum; } B = 0.5 * B; //calculate center of sphere ball->c = A.inverse() * B; //calculate radius of sphere ball->r = (ball->c - points.col(0)).norm(); }