/**************************************************************************** * JMeshExt * * * * Consiglio Nazionale delle Ricerche * * Istituto di Matematica Applicata e Tecnologie Informatiche * * Sezione di Genova * * IMATI-GE / CNR * * * * Authors: Marco Attene * * * * Copyright(C) 2006: IMATI-GE / CNR * * * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #ifndef SPARSELSYSTEM_H #define SPARSELSYSTEM_H #include "matrix.h" ////////////////////////////////////////////////////////////////////////// // // Sparse linear system // ////////////////////////////////////////////////////////////////////////// //! Sparse linear system Ax = B //! Matrix A is a square matrix of size 'system_size'. //! A is initially 0. Non-zero coefficients can be summed through //! the method 'sumCoefficient(coeff_value, row, column)'. //! Matrix B is a generic matrix having 'system_size' rows and 'kterm_size' columns. //! B is initially 0. B[i][j] can be set by summing //! values through sumKnownTerm(value, row, column). //! A solution of the system can be obtained using one column of B trhough //! solve(result, which_column_of_B_to_use). //! In most geometric algorithms 'kterm_size' is 3, and the searched solution //! is the position of some points. In this case, the value of the coordinates //! may be retrieved by solving the system three times, once to retrieve the 'x' //! coordinates, once for the 'y's and once for the 'z's, using the first, the //! second and the third column of B respectively. class sparseSystem { protected: class coeffIndexPair { public: int index; double coeff; coeffIndexPair(int a, double b) {index=a; coeff=b;} }; class sparseSystemRow { public: List cips; sparseSystemRow() {} ~sparseSystemRow() {cips.freeNodes();} void addCoefficient(int, double); void print(FILE *, int); static int rowcompare(const void *, const void *); }; protected: int num_equations; //!< Number of equations (rows) int num_variables; //!< Number of variables (columns) int kterm_size; //!< Nr. of columns of the known term sparseSystemRow *rows; //!< Rows of the system double **known_term; //!< Actual coefficients of the known term public: sparseSystem(int s, int k, int n = 0); //!< Constructs an s x n system having a k column-wide known term ~sparseSystem(); //!< Destructor void sumCoefficient(double v, int i, int j) {rows[i].addCoefficient(j, v);} //!< Sums 'v' to A[i][j] void setKnownTerm(double v, int i, int j) {known_term[j][i] =v;} //!< Sets j'th component of B[i] to 'v' (B[i][j]=v) void sumKnownTerm(double v, int i, int j) {known_term[j][i]+=v;} //!< Sums j'th component of B[i] to 'v' (B[i][j]=v) bool solve(double *solution, int j); //!< Solves the system for j'th component of B (j starts from 0). False if fails. void print(FILE * =stdout); }; // Sparse linear system with size-3 veriables class sparse3System : public sparseSystem { bool *locks; public: sparse3System(int s) : sparseSystem(s, 3) {locks = new bool[num_variables]; for (int i=0; i