void UniqueLinSolveAtom::retrieve(const Query& query, Answer& answer) throw (PluginError) { Tuple parms = query.getInputTuple(); std::string matrixPred = ""; std::string constantPred = ""; int argc = 2; char* argv[] = {"-linkname", "math -mathlink"}; //check number and type of arguments if (parms.size()!= 2) { throw PluginError("Wrong number of arguments"); } else { if(parms[0].isSymbol() && parms[1].isSymbol()) { matrixPred = parms[0].getString(); //std::cout << "Matrixpraedikat: " << matrixPred << std::endl; constantPred = parms[1].getString(); //std::cout << "Vektorpraedikat: " << vectorPred << std::endl; } else { throw PluginError("Wrong type of arguments"); } } //get complete Interpretation of given predicates in query AtomSet totalInt = query.getInterpretation(); AtomSet matrixInt; AtomSet constantInt; if (totalInt.empty()) { throw PluginError("Could not find any interpretion"); } else { // separate interpretation into facts of first predicate (matrix) totalInt.matchPredicate(matrixPred, matrixInt); // and into facts of second predicate (vector) totalInt.matchPredicate(constantPred, constantInt); } int mRows = 0; int mColumns = 0; int cRows = 0; int cColumns = 0; evaluateMatrix(matrixInt, mRows, mColumns); evaluateVector(constantInt, cRows, cColumns); if(mRows != cRows) throw PluginError("Coefficient matrix and target vector(s) or matrix do not have the same dimensions."); std::vector <std::vector <std::string> > matrix(mRows); for(int i = 0; i < mRows; i++) matrix[i].resize(mColumns); std::vector <std::vector <std::string> > constants(cRows); for (int i = 0; i < cRows; i++) constants[i].resize(cColumns); //write the values of the Atoms in the Interpretation into std::vectors for further processing convertMatrixToVector(matrixInt, mRows, mColumns, matrix); convertMatrixToVector(constantInt, cRows, cColumns, constants); //check if matrix and target vector or matrix are fully defined checkVector(matrix, mRows, mColumns, matrixPred); checkVector(constants, cRows, cColumns, constantPred); //convert matrix to MatrixRank-expression and calculate rank of coefficient matrix A std::string coeffMRankExpr = toMatrixRankExpr(matrix, mRows, mColumns); //std::cout << "MatrixRank expression: " << coeffMRankExpr << std::endl; int coeffMRank = calculateRank(argc, argv, coeffMRankExpr); //convert matrix A and target b to MatrixRank-expression and calculate rank //of extended coefficient matrix [A,b] std::string extendedMRankExpr = toMatrixRankExpr(matrix, mRows, mColumns, constants, cRows, cColumns); //std::cout << "Extended MatrixRank expression: " << extendedMRankExpr << std::endl; int extCoeffMRank = calculateRank(argc, argv, extendedMRankExpr); //compare calculated ranks and number of matrix colums, iff they are equal, //a unique solution for the matrix equation exists if ((coeffMRank == extCoeffMRank) && (coeffMRank == mColumns)) { std::string linSolExpr = toLinearSolveExpr(matrix, mRows, mColumns, constants, cRows, cColumns); std::vector <std::string> result; result = calculateSolution(argc, argv, linSolExpr); if(result.size() != mColumns*cColumns) throw PluginError("Wrong number of arguments in result vector"); Tuple out; int index = 0; //fill the result values with correct indices into Tuple out //and add all Tuples to Answer for (int r = 1; r <= mColumns; r++) { for(int c = 1; c<= cColumns; c++) { out.push_back(Term(r)); out.push_back(Term(c)); out.push_back(Term(result[index],true)); answer.addTuple(out); out.clear(); index++; } } } }
int main() { /* Get Objective Function Z */ int n, m; //Number of variables and number of equations int i, j; // Dummy variables int rank, rank_aug; printf("Enter number of variables in the system:\n"); scanf("%d", &n); printf("Enter number of equations in the system\n"); scanf("%d", &m); assert(n > m); // Number of variables should be more than the constraints int nbasic = n - m; // Number of non-basic variables // Coefficient matrix double **A = (double **)malloc(m * sizeof(double *)); for(i = 0; i < m; i++) A[i] = (double *)malloc(n * sizeof(double)); // Output matrix (Y - values) double **B = (double **)malloc(m * sizeof(double *)); for(i = 0; i < m; i++) B[i] = (double *)malloc(sizeof(double)); printf("Enter coefficients of constraints equations in matrix form:"); getMatrix(A, m, n); // Get A printf("Enter the right side values of the equations:"); getMatrix(B, m, 1); // Get B for(i = 0 ; i < m; i++) { for(j = 0 ; j < n; j++){ copied[i][j] = A[i][j]; } } rank = calculateRank(m, n);; double **C = augmentMatrices(A, B, m, n); // Make (A | b) for(i = 0 ; i < m; i++) { for(j = 0 ; j <= n; j++){ copied[i][j] = C[i][j]; } } rank_aug = calculateRank(m, n + 1); printf("Rank of A is : %d \n", rank); printf("Rank of A | b is : %d \n", rank_aug); if(rank != rank_aug) { printf("No solution!\n"); return 0; } int mo = n - rank; int pw2 = (int)pow(2, n); int cnt1 = 0, v, solInd = 0, ind = 0; for(int i = 1 ; i < pw2 ; i++){ v = i; cnt1 = 0; while(v != 0){ cnt1 = cnt1 + v%2; v = v/2; } if(cnt1 != (n - mo)) continue; for(int k = 0 ; k < rank ; k++) { v = i; ind = 0; for(j = 0 ; j < n ; j++){ if(v%2 == 1){ copied[k][ind++] = C[k][j]; } v = v/2; } copied[k][ind] = C[k][n]; } if(calculateRank(cnt1, cnt1) != cnt1) continue; for(int k = 0 ; k < rank ; k++) { v = i; ind = 0; for(j = 0 ; j < n ; j++){ if(v%2 == 1){ copied[k][ind++] = C[k][j]; } v = v/2; } copied[k][ind] = C[k][n]; } ind = 0; solve(n - mo); v = i; for(j = 0 ; j < n ; j++){ if(v%2 == 1){ ans[solInd][j] = d[ind++]; } else{ ans[solInd][j] = 0; } v = v/2; } solInd++; } // Print Basic Feasible Solutions for(int k = 0 ; k < solInd ; k++){ int check = 1; for(int l = 0 ; l < n ; l++){ if(ans[k][l] < 0){ check = 0; break; } } if(check != 1) continue; printf("One BFS is "); for(int l = 0 ; l < n ; l++){ printf("%6.2f ", ans[k][l]); } printf("\n"); } // Answers in ans[][] printf("Enter coefficients of each variable as in objective function\n"); for(i = 0 ; i < n ; i++) { scanf("%lf",&z[i]); } int bl = 0; printf("Enter 1 for maximum, 2 for minimum, 3 to get both \n"); scanf("%d", &bl); if(bl & (1 << 1)) getMin(solInd, n); if(bl&1) getMax(solInd, n); // Free dynamically allocated memory free(A); free(B); free(C); return 0; }