diff --git a/CMakeLists.txt b/CMakeLists.txt index 720868fb1e5e708a713b4f1788dc1cc9ea6179e9..cfc6ff6bae700c9a7aa96adc574976cd638e2381 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ option(ENABLE_TETGEN_OLD "Use old version of Tetgen" OFF) option(ENABLE_VORO3D "Enable Voro3D" ${DEFAULT}) option(ENABLE_WRAP_JAVA "Build Java wrappers" OFF) option(ENABLE_WRAP_PYTHON "Build Python wrappers" OFF) +option(LIB_ONLY "Build only the library (gmsh executable is not created if OFF)" OFF) set(GMSH_MAJOR_VERSION 2) set(GMSH_MINOR_VERSION 7) @@ -1076,19 +1077,21 @@ if(ENABLE_BUILD_SHARED OR ENABLE_WRAP_PYTHON OR ENABLE_WRAP_JAVA) endif(ENABLE_BUILD_SHARED OR ENABLE_WRAP_PYTHON OR ENABLE_WRAP_JAVA) # binary targets -if(HAVE_FLTK) - add_executable(gmsh WIN32 Fltk/Main.cpp ${GMSH_SRC}) - add_executable(gmsh_dynamic EXCLUDE_FROM_ALL Fltk/Main.cpp) - target_link_libraries(gmsh_dynamic shared) -elseif(HAVE_QT) - qt4_wrap_cpp(GMSH_MOC_SRC ${GMSH_MOC_HDR}) - add_executable(gmsh WIN32 Qt/Main.cpp ${GMSH_SRC} ${GMSH_MOC_SRC}) -else(HAVE_FLTK) - add_executable(gmsh Common/Main.cpp ${GMSH_SRC}) - add_executable(gmsh_dynamic EXCLUDE_FROM_ALL Common/Main.cpp) - target_link_libraries(gmsh_dynamic shared) -endif(HAVE_FLTK) -target_link_libraries(gmsh ${LINK_LIBRARIES}) +if(NOT LIB_ONLY) + if(HAVE_FLTK) + add_executable(gmsh WIN32 Fltk/Main.cpp ${GMSH_SRC}) + add_executable(gmsh_dynamic EXCLUDE_FROM_ALL Fltk/Main.cpp) + target_link_libraries(gmsh_dynamic shared) + elseif(HAVE_QT) + qt4_wrap_cpp(GMSH_MOC_SRC ${GMSH_MOC_HDR}) + add_executable(gmsh WIN32 Qt/Main.cpp ${GMSH_SRC} ${GMSH_MOC_SRC}) + else(HAVE_FLTK) + add_executable(gmsh Common/Main.cpp ${GMSH_SRC}) + add_executable(gmsh_dynamic EXCLUDE_FROM_ALL Common/Main.cpp) + target_link_libraries(gmsh_dynamic shared) + endif(HAVE_FLTK) + target_link_libraries(gmsh ${LINK_LIBRARIES}) +endif(NOT LIB_ONLY) # increase stack to 16Mb on Windows to avoid overflows in recursive # tet classification for large 3D Delaunay grids + force static @@ -1191,7 +1194,9 @@ endif(WIN32 OR CYGWIN) # mark targets as optional so we can install them separately if needed # (e.g. "make lib" or "make shared" followed by "make install/fast") -install(TARGETS gmsh DESTINATION ${GMSH_BIN} OPTIONAL) +if(NOT LIB_ONLY) + install(TARGETS gmsh DESTINATION ${GMSH_BIN} OPTIONAL) +endif(NOT LIB_ONLY) if(ENABLE_BUILD_LIB) install(TARGETS lib DESTINATION lib OPTIONAL) endif(ENABLE_BUILD_LIB) diff --git a/Numeric/fullMatrix.cpp b/Numeric/fullMatrix.cpp index e38d74d480ca5e87601a471d3a71146ea3003a91..3a73dda16c8d0d85e041aeffaa6ee11f638eb20e 100644 --- a/Numeric/fullMatrix.cpp +++ b/Numeric/fullMatrix.cpp @@ -379,4 +379,171 @@ bool fullMatrix<double>::svd(fullMatrix<double> &V, fullVector<double> &S) return false; } +#else + +// Provide a default implementation of the matrix inversion +// Bad algorithms but it allows to use +// the polynomial basis without having lapack +template<> +double fullMatrix<double>::determinant() const{ + + if(_r == 2) + return (*this)(0,0) * (*this)(1,1) - (*this)(0,1) * (*this)(1,0); + else if (_r == 3) + { + double det = ((*this)(0,0)*(*this)(1,1)*(*this)(2,2) + + (*this)(0,1)*(*this)(1,2)*(*this)(2,0) + + (*this)(0,2)*(*this)(1,0)*(*this)(2,1)); + det -= (*this)(0,0)*(*this)(1,2)*(*this)(2,1); + det -= (*this)(0,1)*(*this)(1,0)*(*this)(2,2); + det -= (*this)(0,2)*(*this)(1,1)*(*this)(2,0); + return det; + } + else if (_r == 4) + { + std::vector<fullMatrix<double> > temp(4,fullMatrix<double>(3,3)); + for(int k = 0; k < 4; k++) + { + for(int i = 1; i < 4; i++) + { + int j1 = 0; + for(int j = 0; j < 4; j++) + { + if(k != j) + temp[k](i-1,j1++) = (*this)(i,j); + } + + } + } + return ((*this)(0,0) * temp[0].determinant() - + (*this)(0,1) * temp[1].determinant() + + (*this)(0,2) * temp[2].determinant() - + (*this)(0,3) * temp[3].determinant()); + } + else if (_r == 5) + { + std::vector<fullMatrix<double> > temp(5,fullMatrix<double>(4,4)); + for(int k = 0; k < 5; k++) + { + for(int i = 1; i < 5; i++) + { + int j1 = 0; + for(int j = 0; j < 5; j++) + { + if(k != j) + temp[k](i-1,j1++) = (*this)(i,j); + } + } + } + return ((*this)(0,0) * temp[0].determinant() - + (*this)(0,1) * temp[1].determinant() + + (*this)(0,2) * temp[2].determinant() - + (*this)(0,3) * temp[3].determinant() + + (*this)(0,4) * temp[4].determinant()); + } + else + { + std::vector<fullMatrix<double> > temp(_r,fullMatrix<double>(_r-1,_r-1)); + for(int k = 0; k < _r; k++) + { + for(int i = 1; i < _r; i++) + { + int j1 = 0; + for(int j = 0; j < _r; j++) + { + if(k != j) + temp[k](i-1,j1++) = (*this)(i,j); + } + } + } + double det = 0; + for(int k = 0; k < _r; k+=2) + { + det += (*this)(0,k) * temp[k].determinant(); + } + for(int k = 1; k < _r; k+=2) + { + det -= (*this)(0,k) * temp[k].determinant(); + } + return det; + } + return (*this)(0,0); // 1x1 matrix +} + +template<> +bool fullMatrix<double>::invert(fullMatrix<double> &result) const +{ + if(_r != _c) return false; + + // Copy the matrix + result.resize(_r,_c); + + // to find out Determinant + double det = this->determinant(); + + if(det == 0) + return false; + + // Matrix of cofactor put this in a function? + fullMatrix<double> cofactor(_r,_c); + if(_r == 2) + { + cofactor(0,0) = (*this)(1,1); + cofactor(0,1) = -(*this)(1,0); + cofactor(1,0) = -(*this)(0,1); + cofactor(1,1) = (*this)(0,0); + } + else if(_r >= 3) + { + std::vector<std::vector<fullMatrix<double> > > temp(_r,std::vector<fullMatrix<double> >(_r,fullMatrix<double>(_r-1,_r-1))); + for(int k1 = 0; k1 < _r; k1++) + { + for(int k2 = 0; k2 < _r; k2++) + { + int i1 = 0; + for(int i = 0; i < _r; i++) + { + int j1 = 0; + for(int j = 0; j < _r; j++) + { + if(k1 != i && k2 != j) + temp[k1][k2](i1,j1++) = (*this)(i,j); + } + if(k1 != i) + i1++; + } + } + } + bool flagPositive; + for(int k1 = 0; k1 < _r; k1++) + { + flagPositive = (k1 % 2) == 0 ? true : false; + for(int k2 = 0; k2 < _r; k2++) + { + if(flagPositive) + { + cofactor(k1,k2) = temp[k1][k2].determinant(); + flagPositive = false; + } + else + { + cofactor(k1,k2) = -temp[k1][k2].determinant(); + flagPositive = true; + } + } + } + } + // end cofactor + + // inv = transpose of cofactor / Determinant + for(int i = 0; i < _r; i++) + { + for(int j = 0; j < _c; j++) + { + result(j,i) = cofactor(i,j) / det; + } + } + return true; +} + #endif diff --git a/Numeric/fullMatrix.h b/Numeric/fullMatrix.h index ba86a159a4e64f46e80a173b51cd21d712b1018f..fbd4df35216f926077136343df50eb02a47f660f 100644 --- a/Numeric/fullMatrix.h +++ b/Numeric/fullMatrix.h @@ -488,14 +488,8 @@ class fullMatrix } #endif ; - bool invert(fullMatrix<scalar> &result) const -#if !defined(HAVE_LAPACK) - { - Msg::Error("LU factorization requires LAPACK"); - return false; - } -#endif - ; + bool invert(fullMatrix<scalar> &result) const; + fullMatrix<scalar> cofactor(int i, int j) const { int ni = size1(); @@ -507,14 +501,8 @@ class fullMatrix cof(I < i ? I : I - 1, J < j ? J : J - 1) = (*this)(I, J); return cof; } - scalar determinant() const -#if !defined(HAVE_LAPACK) - { - Msg::Error("Determinant computation requires LAPACK"); - return scalar(0.); - } -#endif - ; + scalar determinant() const; + bool svd(fullMatrix<scalar> &V, fullVector<scalar> &S) #if !defined(HAVE_LAPACK) {