template<typename MatrixType> void vectorwiseop_matrix(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType; typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealColVectorType; typedef Matrix<RealScalar, 1, MatrixType::ColsAtCompileTime> RealRowVectorType; Index rows = m.rows(); Index cols = m.cols(); Index r = internal::random<Index>(0, rows-1), c = internal::random<Index>(0, cols-1); MatrixType m1 = MatrixType::Random(rows, cols), m2(rows, cols), m3(rows, cols); ColVectorType colvec = ColVectorType::Random(rows); RowVectorType rowvec = RowVectorType::Random(cols); RealColVectorType rcres; RealRowVectorType rrres; // test addition m2 = m1; m2.colwise() += colvec; VERIFY_IS_APPROX(m2, m1.colwise() + colvec); VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec); VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose()); VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose()); m2 = m1; m2.rowwise() += rowvec; VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec); VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec); VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose()); VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose()); // test substraction m2 = m1; m2.colwise() -= colvec; VERIFY_IS_APPROX(m2, m1.colwise() - colvec); VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec); VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose()); VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose()); m2 = m1; m2.rowwise() -= rowvec; VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec); VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec); VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose()); VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose()); // test norm rrres = m1.colwise().norm(); VERIFY_IS_APPROX(rrres(c), m1.col(c).norm()); rcres = m1.rowwise().norm(); VERIFY_IS_APPROX(rcres(r), m1.row(r).norm()); // test normalized m2 = m1.colwise().normalized(); VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized()); m2 = m1.rowwise().normalized(); VERIFY_IS_APPROX(m2.row(r), m1.row(r).normalized()); // test normalize m2 = m1; m2.colwise().normalize(); VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized()); m2 = m1; m2.rowwise().normalize(); VERIFY_IS_APPROX(m2.row(r), m1.row(r).normalized()); }
// returns the # of cols of the matrix *seen* as fortran matrix template <typename MatrixType> int get_n_cols (MatrixType const & A) { return (A.memory_layout_is_fortran() ? second_dim(A) : first_dim(A)); }
__attribute__ ((noinline)) void benchLLT(const MatrixType& m) { int rows = m.rows(); int cols = m.cols(); double cost = 0; for (int j=0; j<rows; ++j) { int r = std::max(rows - j -1,0); cost += 2*(r*j+r+j); } int repeats = (REPEAT*1000)/(rows*rows); typedef typename MatrixType::Scalar Scalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType; MatrixType a = MatrixType::Random(rows,cols); SquareMatrixType covMat = a * a.adjoint(); BenchTimer timerNoSqrt, timerSqrt; Scalar acc = 0; int r = internal::random<int>(0,covMat.rows()-1); int c = internal::random<int>(0,covMat.cols()-1); for (int t=0; t<TRIES; ++t) { timerNoSqrt.start(); for (int k=0; k<repeats; ++k) { LDLT<SquareMatrixType> cholnosqrt(covMat); acc += cholnosqrt.matrixL().coeff(r,c); } timerNoSqrt.stop(); } for (int t=0; t<TRIES; ++t) { timerSqrt.start(); for (int k=0; k<repeats; ++k) { LLT<SquareMatrixType> chol(covMat); acc += chol.matrixL().coeff(r,c); } timerSqrt.stop(); } if (MatrixType::RowsAtCompileTime==Dynamic) std::cout << "dyn "; else std::cout << "fixed "; std::cout << covMat.rows() << " \t" << (timerNoSqrt.best()) / repeats << "s " << "(" << 1e-9 * cost*repeats/timerNoSqrt.best() << " GFLOPS)\t" << (timerSqrt.best()) / repeats << "s " << "(" << 1e-9 * cost*repeats/timerSqrt.best() << " GFLOPS)\n"; #ifdef BENCH_GSL if (MatrixType::RowsAtCompileTime==Dynamic) { timerSqrt.reset(); gsl_matrix* gslCovMat = gsl_matrix_alloc(covMat.rows(),covMat.cols()); gsl_matrix* gslCopy = gsl_matrix_alloc(covMat.rows(),covMat.cols()); eiToGsl(covMat, &gslCovMat); for (int t=0; t<TRIES; ++t) { timerSqrt.start(); for (int k=0; k<repeats; ++k) { gsl_matrix_memcpy(gslCopy,gslCovMat); gsl_linalg_cholesky_decomp(gslCopy); acc += gsl_matrix_get(gslCopy,r,c); } timerSqrt.stop(); } std::cout << " | \t" << timerSqrt.value() * REPEAT / repeats << "s"; gsl_matrix_free(gslCovMat); } #endif std::cout << "\n"; // make sure the compiler does not optimize too much if (acc==123) std::cout << acc; }
/** @brief Constructor for the preconditioner * * @param mat The system matrix * @param tag A row scaling tag holding the desired norm. */ row_scaling(MatrixType const & mat, row_scaling_tag const & tag) : diag_M(viennacl::traits::size1(mat)) { assert(mat.size1() == mat.size2() && bool("Size mismatch")); init(mat, tag); }
template<typename PointT> template <typename MatrixType> void pcl::search::OrganizedNeighbor<PointT>::makeSymmetric (MatrixType& matrix, bool use_upper_triangular) const { if (use_upper_triangular) { matrix.coeffRef (4) = matrix.coeff (1); matrix.coeffRef (8) = matrix.coeff (2); matrix.coeffRef (9) = matrix.coeff (6); matrix.coeffRef (12) = matrix.coeff (3); matrix.coeffRef (13) = matrix.coeff (7); matrix.coeffRef (14) = matrix.coeff (11); } else { matrix.coeffRef (1) = matrix.coeff (4); matrix.coeffRef (2) = matrix.coeff (8); matrix.coeffRef (6) = matrix.coeff (9); matrix.coeffRef (3) = matrix.coeff (12); matrix.coeffRef (7) = matrix.coeff (13); matrix.coeffRef (11) = matrix.coeff (14); } }
template<typename MatrixType> void product_notemporary(const MatrixType& m) { /* This test checks the number of temporaries created * during the evaluation of a complex expression */ typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef Matrix<Scalar, 1, Dynamic> RowVectorType; typedef Matrix<Scalar, Dynamic, 1> ColVectorType; typedef Matrix<Scalar, Dynamic, Dynamic, ColMajor> ColMajorMatrixType; typedef Matrix<Scalar, Dynamic, Dynamic, RowMajor> RowMajorMatrixType; Index rows = m.rows(); Index cols = m.cols(); ColMajorMatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols); RowVectorType rv1 = RowVectorType::Random(rows), rvres(rows); ColVectorType cv1 = ColVectorType::Random(cols), cvres(cols); RowMajorMatrixType rm3(rows, cols); Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>(), s3 = internal::random<Scalar>(); Index c0 = internal::random<Index>(4,cols-8), c1 = internal::random<Index>(8,cols-c0), r0 = internal::random<Index>(4,cols-8), r1 = internal::random<Index>(8,rows-r0); VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()), 1); VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()).transpose(), 1); VERIFY_EVALUATION_COUNT( m3.noalias() = m1 * m2.adjoint(), 0); VERIFY_EVALUATION_COUNT( m3 = s1 * (m1 * m2.transpose()), 1); // VERIFY_EVALUATION_COUNT( m3 = m3 + s1 * (m1 * m2.transpose()), 1); VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * (m1 * m2.transpose()), 0); VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()), 1); VERIFY_EVALUATION_COUNT( m3 = m3 + (m1 * m2.adjoint()).transpose(), 1); VERIFY_EVALUATION_COUNT( m3.noalias() = m3 + m1 * m2.transpose(), 0); VERIFY_EVALUATION_COUNT( m3.noalias() += m3 + m1 * m2.transpose(), 0); VERIFY_EVALUATION_COUNT( m3.noalias() -= m3 + m1 * m2.transpose(), 0); VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * m2.adjoint(), 0); VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * (m1*s3+m2*s2).adjoint(), 1); VERIFY_EVALUATION_COUNT( m3.noalias() = (s1 * m1).adjoint() * s2 * m2, 0); VERIFY_EVALUATION_COUNT( m3.noalias() += s1 * (-m1*s3).adjoint() * (s2 * m2 * s3), 0); VERIFY_EVALUATION_COUNT( m3.noalias() -= s1 * (m1.transpose() * m2), 0); VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() += -m1.block(r0,c0,r1,c1) * (s2*m2.block(r0,c0,r1,c1)).adjoint() ), 0); VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() -= s1 * m1.block(r0,c0,r1,c1) * m2.block(c0,r0,c1,r1) ), 0); // NOTE this is because the Block expression is not handled yet by our expression analyser VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() = s1 * m1.block(r0,c0,r1,c1) * (s1*m2).block(c0,r0,c1,r1) ), 1); VERIFY_EVALUATION_COUNT( m3.noalias() -= (s1 * m1).template triangularView<Lower>() * m2, 0); VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<Upper>() * (m2+m2), 1); VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * m2.adjoint(), 0); VERIFY_EVALUATION_COUNT( m3.template triangularView<Upper>() = (m1 * m2.adjoint()), 0); VERIFY_EVALUATION_COUNT( m3.template triangularView<Upper>() -= (m1 * m2.adjoint()), 0); // NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products VERIFY_EVALUATION_COUNT( rm3.col(c0).noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * (s2*m2.row(c0)).adjoint(), 1); VERIFY_EVALUATION_COUNT( m1.template triangularView<Lower>().solveInPlace(m3), 0); VERIFY_EVALUATION_COUNT( m1.adjoint().template triangularView<Lower>().solveInPlace(m3.transpose()), 0); VERIFY_EVALUATION_COUNT( m3.noalias() -= (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2*s3).adjoint(), 0); VERIFY_EVALUATION_COUNT( m3.noalias() = s2 * m2.adjoint() * (s1 * m1.adjoint()).template selfadjointView<Upper>(), 0); VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template selfadjointView<Lower>() * m2.adjoint(), 0); // NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() = (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2.row(c0)*s3).adjoint(), 1); VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() -= (s1 * m1).adjoint().template selfadjointView<Upper>() * (-m2.row(c0)*s3).adjoint(), 1); VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() += m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * (s1*m2.block(r0,c0,r1,c1)), 0); VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() = m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * m2.block(r0,c0,r1,c1), 0); VERIFY_EVALUATION_COUNT( m3.template selfadjointView<Lower>().rankUpdate(m2.adjoint()), 0); // Here we will get 1 temporary for each resize operation of the lhs operator; resize(r1,c1) would lead to zero temporaries m3.resize(1,1); VERIFY_EVALUATION_COUNT( m3.noalias() = m1.block(r0,r0,r1,r1).template selfadjointView<Lower>() * m2.block(r0,c0,r1,c1), 1); m3.resize(1,1); VERIFY_EVALUATION_COUNT( m3.noalias() = m1.block(r0,r0,r1,r1).template triangularView<UnitUpper>() * m2.block(r0,c0,r1,c1), 1); // Zero temporaries for lazy products ... VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose().lazyProduct(m3)).diagonal().sum(), 0 ); // ... and even no temporary for even deeply (>=2) nested products VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose() * m3).diagonal().sum(), 0 ); VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose() * m3).diagonal().array().abs().sum(), 0 ); // Zero temporaries for ... CoeffBasedProductMode VERIFY_EVALUATION_COUNT( m3.col(0).template head<5>() * m3.col(0).transpose() + m3.col(0).template head<5>() * m3.col(0).transpose(), 0 ); // Check matrix * vectors VERIFY_EVALUATION_COUNT( cvres.noalias() = m1 * cv1, 0 ); VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * cv1, 0 ); VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * m2.col(0), 0 ); VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * rv1.adjoint(), 0 ); VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * m2.row(0).transpose(), 0 ); VERIFY_EVALUATION_COUNT( cvres.noalias() = (m1+m1) * cv1, 0 ); VERIFY_EVALUATION_COUNT( cvres.noalias() = (rm3+rm3) * cv1, 0 ); VERIFY_EVALUATION_COUNT( cvres.noalias() = (m1+m1) * (m1*cv1), 1 ); VERIFY_EVALUATION_COUNT( cvres.noalias() = (rm3+rm3) * (m1*cv1), 1 ); // Check outer products m3 = cv1 * rv1; VERIFY_EVALUATION_COUNT( m3.noalias() = cv1 * rv1, 0 ); VERIFY_EVALUATION_COUNT( m3.noalias() = (cv1+cv1) * (rv1+rv1), 1 ); VERIFY_EVALUATION_COUNT( m3.noalias() = (m1*cv1) * (rv1), 1 ); VERIFY_EVALUATION_COUNT( m3.noalias() += (m1*cv1) * (rv1), 1 ); VERIFY_EVALUATION_COUNT( rm3.noalias() = (cv1) * (rv1 * m1), 1 ); VERIFY_EVALUATION_COUNT( rm3.noalias() -= (cv1) * (rv1 * m1), 1 ); VERIFY_EVALUATION_COUNT( rm3.noalias() = (m1*cv1) * (rv1 * m1), 2 ); VERIFY_EVALUATION_COUNT( rm3.noalias() += (m1*cv1) * (rv1 * m1), 2 ); }
template<typename MatrixType> void map_class_matrix(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; Index rows = m.rows(), cols = m.cols(), size = rows*cols; Scalar s1 = internal::random<Scalar>(); // array1 and array2 -> aligned heap allocation Scalar* array1 = internal::aligned_new<Scalar>(size); for(int i = 0; i < size; i++) array1[i] = Scalar(1); Scalar* array2 = internal::aligned_new<Scalar>(size); for(int i = 0; i < size; i++) array2[i] = Scalar(1); // array3unaligned -> unaligned pointer to heap Scalar* array3 = new Scalar[size+1]; for(int i = 0; i < size+1; i++) array3[i] = Scalar(1); Scalar* array3unaligned = internal::UIntPtr(array3)%EIGEN_MAX_ALIGN_BYTES == 0 ? array3+1 : array3; Scalar array4[256]; if(size<=256) for(int i = 0; i < size; i++) array4[i] = Scalar(1); Map<MatrixType> map1(array1, rows, cols); Map<MatrixType, AlignedMax> map2(array2, rows, cols); Map<MatrixType> map3(array3unaligned, rows, cols); Map<MatrixType> map4(array4, rows, cols); VERIFY_IS_EQUAL(map1, MatrixType::Ones(rows,cols)); VERIFY_IS_EQUAL(map2, MatrixType::Ones(rows,cols)); VERIFY_IS_EQUAL(map3, MatrixType::Ones(rows,cols)); map1 = MatrixType::Random(rows,cols); map2 = map1; map3 = map1; MatrixType ma1 = map1; MatrixType ma2 = map2; MatrixType ma3 = map3; VERIFY_IS_EQUAL(map1, map2); VERIFY_IS_EQUAL(map1, map3); VERIFY_IS_EQUAL(ma1, ma2); VERIFY_IS_EQUAL(ma1, ma3); VERIFY_IS_EQUAL(ma1, map3); VERIFY_IS_APPROX(s1*map1, s1*map2); VERIFY_IS_APPROX(s1*ma1, s1*ma2); VERIFY_IS_EQUAL(s1*ma1, s1*ma3); VERIFY_IS_APPROX(s1*map1, s1*map3); map2 *= s1; map3 *= s1; VERIFY_IS_APPROX(s1*map1, map2); VERIFY_IS_APPROX(s1*map1, map3); if(size<=256) { VERIFY_IS_EQUAL(map4, MatrixType::Ones(rows,cols)); map4 = map1; MatrixType ma4 = map4; VERIFY_IS_EQUAL(map1, map4); VERIFY_IS_EQUAL(ma1, map4); VERIFY_IS_EQUAL(ma1, ma4); VERIFY_IS_APPROX(s1*map1, s1*map4); map4 *= s1; VERIFY_IS_APPROX(s1*map1, map4); } internal::aligned_delete(array1, size); internal::aligned_delete(array2, size); delete[] array3; }
template<typename MatrixType> void inverse(const MatrixType& m) { using std::abs; typedef typename MatrixType::Index Index; /* this test covers the following files: Inverse.h */ Index rows = m.rows(); Index cols = m.cols(); typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType; MatrixType m1(rows, cols), m2(rows, cols), identity = MatrixType::Identity(rows, rows); createRandomPIMatrixOfRank(rows,rows,rows,m1); m2 = m1.inverse(); VERIFY_IS_APPROX(m1, m2.inverse() ); VERIFY_IS_APPROX((Scalar(2)*m2).inverse(), m2.inverse()*Scalar(0.5)); VERIFY_IS_APPROX(identity, m1.inverse() * m1 ); VERIFY_IS_APPROX(identity, m1 * m1.inverse() ); VERIFY_IS_APPROX(m1, m1.inverse().inverse() ); // since for the general case we implement separately row-major and col-major, test that VERIFY_IS_APPROX(MatrixType(m1.transpose().inverse()), MatrixType(m1.inverse().transpose())); #if !defined(EIGEN_TEST_PART_5) && !defined(EIGEN_TEST_PART_6) //computeInverseAndDetWithCheck tests //First: an invertible matrix bool invertible; RealScalar det; m2.setZero(); m1.computeInverseAndDetWithCheck(m2, det, invertible); VERIFY(invertible); VERIFY_IS_APPROX(identity, m1*m2); VERIFY_IS_APPROX(det, m1.determinant()); m2.setZero(); m1.computeInverseWithCheck(m2, invertible); VERIFY(invertible); VERIFY_IS_APPROX(identity, m1*m2); //Second: a rank one matrix (not invertible, except for 1x1 matrices) VectorType v3 = VectorType::Random(rows); MatrixType m3 = v3*v3.transpose(), m4(rows,cols); m3.computeInverseAndDetWithCheck(m4, det, invertible); VERIFY( rows==1 ? invertible : !invertible ); VERIFY_IS_MUCH_SMALLER_THAN(abs(det-m3.determinant()), RealScalar(1)); m3.computeInverseWithCheck(m4, invertible); VERIFY( rows==1 ? invertible : !invertible ); #endif // check in-place inversion if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4) { // in-place is forbidden VERIFY_RAISES_ASSERT(m1 = m1.inverse()); } else { m2 = m1.inverse(); m1 = m1.inverse(); VERIFY_IS_APPROX(m1,m2); } }
template<typename MatrixType> void adjoint(const MatrixType& m) { /* this test covers the following files: Transpose.h Conjugate.h Dot.h */ typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType; int rows = m.rows(); int cols = m.cols(); RealScalar largerEps = test_precision<RealScalar>(); if (ei_is_same_type<RealScalar,float>::ret) largerEps = RealScalar(1e-3f); MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = SquareMatrixType::Identity(rows, rows), square = SquareMatrixType::Random(rows, rows); VectorType v1 = VectorType::Random(rows), v2 = VectorType::Random(rows), v3 = VectorType::Random(rows), vzero = VectorType::Zero(rows); Scalar s1 = ei_random<Scalar>(), s2 = ei_random<Scalar>(); // check basic compatibility of adjoint, transpose, conjugate VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(), m1); VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(), m1); // check multiplicative behavior VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(), m2.adjoint() * m1); VERIFY_IS_APPROX((s1 * m1).adjoint(), ei_conj(s1) * m1.adjoint()); // check basic properties of dot, norm, norm2 typedef typename NumTraits<Scalar>::Real RealScalar; VERIFY(ei_isApprox((s1 * v1 + s2 * v2).dot(v3), s1 * v1.dot(v3) + s2 * v2.dot(v3), largerEps)); VERIFY(ei_isApprox(v3.dot(s1 * v1 + s2 * v2), ei_conj(s1)*v3.dot(v1)+ei_conj(s2)*v3.dot(v2), largerEps)); VERIFY_IS_APPROX(ei_conj(v1.dot(v2)), v2.dot(v1)); VERIFY_IS_APPROX(ei_abs(v1.dot(v1)), v1.squaredNorm()); if(NumTraits<Scalar>::HasFloatingPoint) VERIFY_IS_APPROX(v1.squaredNorm(), v1.norm() * v1.norm()); VERIFY_IS_MUCH_SMALLER_THAN(ei_abs(vzero.dot(v1)), static_cast<RealScalar>(1)); if(NumTraits<Scalar>::HasFloatingPoint) VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1)); // check compatibility of dot and adjoint VERIFY(ei_isApprox(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), largerEps)); // like in testBasicStuff, test operator() to check const-qualification int r = ei_random<int>(0, rows-1), c = ei_random<int>(0, cols-1); VERIFY_IS_APPROX(m1.conjugate()(r,c), ei_conj(m1(r,c))); VERIFY_IS_APPROX(m1.adjoint()(c,r), ei_conj(m1(r,c))); if(NumTraits<Scalar>::HasFloatingPoint) { // check that Random().normalized() works: tricky as the random xpr must be evaluated by // normalized() in order to produce a consistent result. VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1)); } // check inplace transpose m3 = m1; m3.transposeInPlace(); VERIFY_IS_APPROX(m3,m1.transpose()); m3.transposeInPlace(); VERIFY_IS_APPROX(m3,m1); }
//************************************************************************************ //************************************************************************************ void UpdatedLagrangianFluid3Dinc::CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo) { KRATOS_TRY const double& density = 0.25*(GetGeometry()[0].FastGetSolutionStepValue(DENSITY)+ GetGeometry()[1].FastGetSolutionStepValue(DENSITY) + GetGeometry()[2].FastGetSolutionStepValue(DENSITY)+ GetGeometry()[3].FastGetSolutionStepValue(DENSITY)); double K = 0.25* (GetGeometry()[0].FastGetSolutionStepValue(BULK_MODULUS)+ GetGeometry()[1].FastGetSolutionStepValue(BULK_MODULUS) + GetGeometry()[2].FastGetSolutionStepValue(BULK_MODULUS)+ GetGeometry()[3].FastGetSolutionStepValue(BULK_MODULUS)); K *= density; //unsigned int dim = 3; unsigned int number_of_nodes = 4; if(rLeftHandSideMatrix.size1() != 12) rLeftHandSideMatrix.resize(12,12,false); if(rRightHandSideVector.size() != 12) rRightHandSideVector.resize(12,false); //calculate current area double current_volume; GeometryUtils::CalculateGeometryData(GetGeometry(), msDN_Dx, msN, current_volume); //writing the body force const array_1d<double,3>& body_force = 0.25*(GetGeometry()[0].FastGetSolutionStepValue(BODY_FORCE)+ GetGeometry()[1].FastGetSolutionStepValue(BODY_FORCE) + GetGeometry()[2].FastGetSolutionStepValue(BODY_FORCE) + GetGeometry()[3].FastGetSolutionStepValue(BODY_FORCE)); for(unsigned int i = 0; i<number_of_nodes; i++) { rRightHandSideVector[i*3] = body_force[0]* density * mA0 * 0.25; rRightHandSideVector[i*3+1] = body_force[1] * density * mA0 * 0.25; rRightHandSideVector[i*3+2] = body_force[2] * density * mA0 * 0.25; } /* //VISCOUS CONTRIBUTION TO THE STIFFNESS MATRIX // rLeftHandSideMatrix += Laplacian * nu; //filling matrix B for (unsigned int i=0;i<number_of_nodes;i++) { unsigned int index = dim*i; msB(0,index+0)=msDN_Dx(i,0); msB(0,index+1)= 0.0; msB(1,index+0)=0.0; msB(1,index+1)= msDN_Dx(i,1); msB(2,index+0)= msDN_Dx(i,1); msB(2,index+1)= msDN_Dx(i,0); } //constitutive tensor ms_constitutive_matrix(0,0) = K; ms_constitutive_matrix(0,1) = K ; ms_constitutive_matrix(0,2) = 0.0; ms_constitutive_matrix(1,0) = K; ms_constitutive_matrix(1,1) = K; ms_constitutive_matrix(1,2) = 0.0; ms_constitutive_matrix(2,0) = 0.0; ms_constitutive_matrix(2,1) = 0.0; ms_constitutive_matrix(2,2) = 0.0; //calculating viscous contributions ms_temp = prod( ms_constitutive_matrix , msB); noalias(rLeftHandSideMatrix) = prod( trans(msB) , ms_temp); rLeftHandSideMatrix *= -current_area; */ noalias(rLeftHandSideMatrix) = ZeroMatrix(12,12); //get the nodal pressure double p0 = GetGeometry()[0].FastGetSolutionStepValue(PRESSURE); double p1 = GetGeometry()[1].FastGetSolutionStepValue(PRESSURE); double p2 = GetGeometry()[2].FastGetSolutionStepValue(PRESSURE); double p3 = GetGeometry()[3].FastGetSolutionStepValue(PRESSURE); //adding pressure gradient double pavg = p0 + p1 + p2 + p3; //calculate old pressure over the element pavg *= 0.25 * current_volume; rRightHandSideVector[0] += msDN_Dx(0,0)*pavg; rRightHandSideVector[1] += msDN_Dx(0,1)*pavg; rRightHandSideVector[2] += msDN_Dx(0,2)*pavg; rRightHandSideVector[3] += msDN_Dx(1,0)*pavg; rRightHandSideVector[4] += msDN_Dx(1,1)*pavg; rRightHandSideVector[5] += msDN_Dx(1,2)*pavg; rRightHandSideVector[6] += msDN_Dx(2,0)*pavg; rRightHandSideVector[7] += msDN_Dx(2,1)*pavg; rRightHandSideVector[8] += msDN_Dx(2,2)*pavg; rRightHandSideVector[9] += msDN_Dx(3,0)*pavg; rRightHandSideVector[10] += msDN_Dx(3,1)*pavg; rRightHandSideVector[11] += msDN_Dx(3,2)*pavg; KRATOS_CATCH("") }
void UpdatedLagrangianFluid3Dinc::CalculateDampingMatrix(MatrixType& rDampingMatrix, ProcessInfo& rCurrentProcessInfo) { KRATOS_TRY unsigned int number_of_nodes = GetGeometry().size(); unsigned int dim = GetGeometry().WorkingSpaceDimension(); if(rDampingMatrix.size1() != 12) rDampingMatrix.resize(12,12,false); //getting data for the given geometry double current_volume; GeometryUtils::CalculateGeometryData(GetGeometry(), msDN_Dx, msN, current_volume); //getting properties const double& nu = 0.25*(GetGeometry()[0].FastGetSolutionStepValue(VISCOSITY)+ GetGeometry()[1].FastGetSolutionStepValue(VISCOSITY) + GetGeometry()[2].FastGetSolutionStepValue(VISCOSITY)+ GetGeometry()[3].FastGetSolutionStepValue(VISCOSITY)); //double nu = GetProperties()[VISCOSITY]; //double density = GetProperties()[DENSITY]; const double& density = 0.25*(GetGeometry()[0].FastGetSolutionStepValue(DENSITY)+ GetGeometry()[1].FastGetSolutionStepValue(DENSITY) + GetGeometry()[2].FastGetSolutionStepValue(DENSITY)+ GetGeometry()[3].FastGetSolutionStepValue(DENSITY)); //VISCOUS CONTRIBUTION TO THE STIFFNESS MATRIX // rLeftHandSideMatrix += Laplacian * nu; //filling matrix B for(unsigned int i = 0; i<number_of_nodes; i++) { unsigned int start = dim*i; msB(0,start) = msDN_Dx(i,0); msB(1,start+1)= msDN_Dx(i,1); msB(2,start+2)= msDN_Dx(i,2); msB(3,start) = msDN_Dx(i,1); msB(3,start+1) = msDN_Dx(i,0); msB(4,start) = msDN_Dx(i,2); msB(4,start+2) = msDN_Dx(i,0); msB(5,start+1)= msDN_Dx(i,2); msB(5,start+2) = msDN_Dx(i,1); } const double& a = nu*density; //constitutive tensor ms_constitutive_matrix(0,0) = (4.0/3.0)*a; ms_constitutive_matrix(0,1) = -2.0/3.0*a; ms_constitutive_matrix(0,2) = -2.0/3.0*a; ms_constitutive_matrix(0,3) = 0.0; ms_constitutive_matrix(0,4) = 0.0; ms_constitutive_matrix(0,5) = 0.0; ms_constitutive_matrix(1,0) = -2.0/3.0*a; ms_constitutive_matrix(1,1) = 4.0/3.0*a; ms_constitutive_matrix(1,2) = -2.0/3.0*a; ms_constitutive_matrix(1,3) = 0.0; ms_constitutive_matrix(1,4) = 0.0; ms_constitutive_matrix(1,5) = 0.0; ms_constitutive_matrix(2,0) = -2.0/3.0*a; ms_constitutive_matrix(2,1) = -2.0/3.0*a; ms_constitutive_matrix(2,2) = 4.0/3.0*a; ms_constitutive_matrix(2,3) = 0.0; ms_constitutive_matrix(2,4) = 0.0; ms_constitutive_matrix(2,5) = 0.0; ms_constitutive_matrix(3,0) = 0.0; ms_constitutive_matrix(3,1) = 0.0; ms_constitutive_matrix(3,2) = 0.0; ms_constitutive_matrix(3,3) = a; ms_constitutive_matrix(3,4) = 0.0; ms_constitutive_matrix(3,5) = 0.0; ms_constitutive_matrix(4,0) = 0.0; ms_constitutive_matrix(4,1) = 0.0; ms_constitutive_matrix(4,2) = 0.0; ms_constitutive_matrix(4,3) = 0.0; ms_constitutive_matrix(4,4) = a; ms_constitutive_matrix(4,5) = 0.0; ms_constitutive_matrix(5,0) = 0.0; ms_constitutive_matrix(5,1) = 0.0; ms_constitutive_matrix(5,2) = 0.0; ms_constitutive_matrix(5,3) = 0.0; ms_constitutive_matrix(5,4) = 0.0; ms_constitutive_matrix(5,5) = a; //calculating viscous contributions ms_temp = prod( ms_constitutive_matrix , msB); noalias(rDampingMatrix) = prod( trans(msB) , ms_temp); rDampingMatrix *= current_volume; KRATOS_CATCH("") }
//************************************************************************************ //************************************************************************************ void Monolithic2DNeumann::CalculateLocalSystem(MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, ProcessInfo& rCurrentProcessInfo) { if(rLeftHandSideMatrix.size1() != 4) { rLeftHandSideMatrix.resize(4,4,false); rRightHandSideVector.resize(4,false); } noalias(rLeftHandSideMatrix) = ZeroMatrix(4,4); //calculate normal to element.(normal follows the cross rule) array_1d<double,2> An,edge; edge[0] = GetGeometry()[1].X() - GetGeometry()[0].X(); edge[1] = GetGeometry()[1].Y() - GetGeometry()[0].Y(); double norm = edge[0]*edge[0] + edge[1]*edge[1]; norm = pow(norm,0.5); An[0] = -edge[1]; An[1] = edge[0]; //An /= norm; this is then simplified by length of element in integration so is not divided. double mean_ex_p = 0.0; for(unsigned int i = 0; i<2 ; i++) mean_ex_p += 0.5*GetGeometry()[i].FastGetSolutionStepValue(EXTERNAL_PRESSURE); double p0 = GetGeometry()[0].FastGetSolutionStepValue(EXTERNAL_PRESSURE); rRightHandSideVector[0] = -0.5*An[0]*p0; rRightHandSideVector[1] = -0.5*An[1]*p0; double p1 = GetGeometry()[1].FastGetSolutionStepValue(EXTERNAL_PRESSURE); rRightHandSideVector[2] = -0.5*An[0]*p1; rRightHandSideVector[3] = -0.5*An[1]*p1; // if(mean_ex_p !=GetGeometry()[0].FastGetSolutionStepValue(EXTERNAL_PRESSURE)) // mean_ex_p = 0.0; //KRATOS_WATCH(mean_ex_p); /* for(unsigned int ii = 0; ii< 2; ++ii) { int id = (2 + 1)*(ii); rRightHandSideVector[id] = mean_ex_p * An[0]* 0.5; rRightHandSideVector[id + 1] = mean_ex_p * An[1]* 0.5; rRightHandSideVector[id + 2] = 0.0; //KRATOS_WATCH(An); }*/ // KRATOS_WATCH(An); //KRATOS_WATCH(p0); //KRATOS_WATCH(p1); //KRATOS_WATCH("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"); // KRATOS_WATCH(rRightHandSideVector); }
typename GaussianProcess<TScalarType>::MatrixType GaussianProcess<TScalarType>::InvertKernelMatrix(const typename GaussianProcess<TScalarType>::MatrixType &K, typename GaussianProcess<TScalarType>::InversionMethod inv_method = GaussianProcess<TScalarType>::FullPivotLU, bool stable) const{ // compute core matrix if(debug){ std::cout << "GaussianProcess::InvertKernelMatrix: inverting kernel matrix... "; std::cout.flush(); } typename GaussianProcess<TScalarType>::MatrixType core; switch(inv_method){ // standard method: fast but not that accurate // Uses the LU decomposition with full pivoting for the inversion case FullPivotLU:{ if(debug) std::cout << " (inversion method: FullPivotLU) " << std::flush; try{ if(stable){ core = K.inverse(); } else{ if(debug) std::cout << " (using lapack) " << std::flush; core = lapack::lu_invert<TScalarType>(K); } } catch(lapack::LAPACKException& e){ core = K.inverse(); } } break; // very accurate and very slow method, use it for small problems // Uses the two-sided Jacobi SVD decomposition case JacobiSVD:{ if(debug) std::cout << " (inversion method: JacobiSVD) " << std::flush; Eigen::JacobiSVD<MatrixType> jacobisvd(K, Eigen::ComputeThinU | Eigen::ComputeThinV); if((jacobisvd.singularValues().real().array() < 0).any() && debug){ std::cout << "GaussianProcess::InvertKernelMatrix: warning: there are negative eigenvalues."; std::cout.flush(); } core = jacobisvd.matrixV() * VectorType(1/jacobisvd.singularValues().array()).asDiagonal() * jacobisvd.matrixU().transpose(); } break; // accurate method and faster than Jacobi SVD. // Uses the bidiagonal divide and conquer SVD case BDCSVD:{ if(debug) std::cout << " (inversion method: BDCSVD) " << std::flush; #ifdef EIGEN_BDCSVD_H Eigen::BDCSVD<MatrixType> bdcsvd(K, Eigen::ComputeThinU | Eigen::ComputeThinV); if((bdcsvd.singularValues().real().array() < 0).any() && debug){ std::cout << "GaussianProcess::InvertKernelMatrix: warning: there are negative eigenvalues."; std::cout.flush(); } core = bdcsvd.matrixV() * VectorType(1/bdcsvd.singularValues().array()).asDiagonal() * bdcsvd.matrixU().transpose(); #else // this is checked, since BDCSVD is currently not in the newest release throw std::string("GaussianProcess::InvertKernelMatrix: BDCSVD is not supported by the provided Eigen library."); #endif } break; // faster than the SVD method but less stable // computes the eigenvalues/eigenvectors of selfadjoint matrices case SelfAdjointEigenSolver:{ if(debug) std::cout << " (inversion method: SelfAdjointEigenSolver) " << std::flush; try{ core = lapack::chol_invert<TScalarType>(K); } catch(lapack::LAPACKException& e){ Eigen::SelfAdjointEigenSolver<MatrixType> es; es.compute(K); VectorType eigenValues = es.eigenvalues().reverse(); MatrixType eigenVectors = es.eigenvectors().rowwise().reverse(); if((eigenValues.real().array() < 0).any() && debug){ std::cout << "GaussianProcess::InvertKernelMatrix: warning: there are negative eigenvalues."; std::cout.flush(); } core = eigenVectors * VectorType(1/eigenValues.array()).asDiagonal() * eigenVectors.transpose(); } } break; } if(debug) std::cout << "[done]" << std::endl; return core; }
void GaussianProcess<TScalarType>::Load(std::string prefix){ if(debug){ std::cout << "GaussianProcess::Load: loading gaussian process: " << std::endl; std::cout << "\t " << prefix+"-RegressionVectors.txt" << std::endl; std::cout << "\t " << prefix+"-CoreMatrix.txt" << std::endl; std::cout << "\t " << prefix+"-SampleVectors.txt" << std::endl; std::cout << "\t " << prefix+"-LabelVectors.txt" << std::endl; std::cout << "\t " << prefix+"-ParameterFile.txt" << std::endl; } // load regression vectors std::string rv_filename = prefix+"-RegressionVectors.txt"; fs::path rv_file(rv_filename.c_str()); if(!(fs::exists(rv_file) && !fs::is_directory(rv_file))){ throw std::string("GaussianProcess::Load: "+rv_filename+" does not exist or is a directory."); } m_RegressionVectors = ReadMatrix<MatrixType>(rv_filename); // load core matrix std::string cm_filename = prefix+"-CoreMatrix.txt"; fs::path cm_file(cm_filename.c_str()); if(!(fs::exists(cm_file) && !fs::is_directory(cm_file))){ throw std::string("GaussianProcess::Load: "+cm_filename+" does not exist or is a directory."); } m_CoreMatrix = ReadMatrix<MatrixType>(cm_filename); // load sample vectors std::string sv_filename = prefix+"-SampleVectors.txt"; fs::path sv_file(sv_filename.c_str()); if(!(fs::exists(sv_file) && !fs::is_directory(sv_file))){ throw std::string("GaussianProcess::Load: "+sv_filename+" does not exist or is a directory."); } MatrixType X = ReadMatrix<MatrixType>(sv_filename); m_SampleVectors.clear(); for(unsigned i=0; i<X.cols(); i++){ m_SampleVectors.push_back(X.col(i)); } // load label vectors std::string lv_filename = prefix+"-LabelVectors.txt"; fs::path lv_file(lv_filename.c_str()); if(!(fs::exists(lv_file) && !fs::is_directory(lv_file))){ throw std::string("GaussianProcess::Load: "+lv_filename+" does not exist or is a directory."); } MatrixType Y = ReadMatrix<MatrixType>(lv_filename); m_LabelVectors.clear(); for(unsigned i=0; i<Y.cols(); i++){ m_LabelVectors.push_back(Y.col(i)); } // load parameters std::string pf_filename = prefix+"-ParameterFile.txt"; if(!(fs::exists(pf_filename) && !fs::is_directory(pf_filename))){ throw std::string("GaussianProcess::Load: "+pf_filename+" does not exist or is a directory."); } std::ifstream parameter_infile; parameter_infile.open( pf_filename.c_str() ); // reading parameter file std::string line; bool load = true; if(std::getline(parameter_infile, line)) { std::stringstream line_stream(line); if(!(line_stream >> m_Sigma && line_stream >> m_InputDimension && line_stream >> m_OutputDimension && line_stream >> m_EfficientStorage && line_stream >> debug) || load == false){ throw std::string("GaussianProcess::Load: parameter file is corrupt"); } std::string kernel_string; line_stream >> kernel_string; m_Kernel = KernelFactory<TScalarType>::GetKernel(kernel_string); } parameter_infile.close(); m_Initialized = true; }
//---------------------- //----- PRIVATE ------ //---------------------- //*********************************************************************************** void FaceHeatConvection::CalculateAll( MatrixType& rLeftHandSideMatrix, VectorType& rRightHandSideVector, const ProcessInfo& rCurrentProcessInfo, bool CalculateStiffnessMatrixFlag, bool CalculateResidualVectorFlag ) { KRATOS_TRY const unsigned int number_of_nodes = GetGeometry().size(); unsigned int MatSize = number_of_nodes; //resizing as needed the LHS if ( CalculateStiffnessMatrixFlag == true ) //calculation of the matrix is required { if ( rLeftHandSideMatrix.size1() != MatSize ) rLeftHandSideMatrix.resize( MatSize, MatSize, false ); noalias( rLeftHandSideMatrix ) = ZeroMatrix( MatSize, MatSize ); //resetting LHS } //resizing as needed the RHS if ( CalculateResidualVectorFlag == true ) //calculation of the matrix is required { if ( rRightHandSideVector.size() != MatSize ) rRightHandSideVector.resize( MatSize ); rRightHandSideVector = ZeroVector( MatSize ); //resetting RHS } //reading integration points and local gradients const GeometryType::IntegrationPointsArrayType& integration_points = GetGeometry().IntegrationPoints(); const GeometryType::ShapeFunctionsGradientsType& DN_DeContainer = GetGeometry().ShapeFunctionsLocalGradients(); const Matrix& Ncontainer = GetGeometry().ShapeFunctionsValues(); //calculating actual jacobian GeometryType::JacobiansType J; J = GetGeometry().Jacobian( J ); //auxiliary terms for ( unsigned int PointNumber = 0; PointNumber < integration_points.size(); PointNumber++ ) { double convection_coefficient = 0.0; double T_ambient = 0.0; double T = 0.0; for ( unsigned int n = 0; n < GetGeometry().size(); n++ ) { convection_coefficient += ( GetGeometry()[n] ).GetSolutionStepValue( CONVECTION_COEFFICIENT ) * Ncontainer( PointNumber, n ); T_ambient += ( GetGeometry()[n] ).GetSolutionStepValue( AMBIENT_TEMPERATURE ) * Ncontainer( PointNumber, n ); T += ( GetGeometry()[n] ).GetSolutionStepValue( TEMPERATURE ) * Ncontainer( PointNumber, n ); } // if ( PointNumber == 1 ) // std::cout << "CONDITION ### HeatConvection: h= " << convection_coefficient << ",\t T_ambient= " << T_ambient << ",\t T_surface= " << T << std::endl; double IntegrationWeight = GetGeometry().IntegrationPoints()[PointNumber].Weight(); Vector t1 = ZeroVector( 3 );//first tangential vector Vector t2 = ZeroVector( 3 );//second tangential vector for ( unsigned int n = 0; n < number_of_nodes; n++ ) { t1[0] += GetGeometry().GetPoint( n ).X0() * DN_DeContainer[PointNumber]( n, 0 ); t1[1] += GetGeometry().GetPoint( n ).Y0() * DN_DeContainer[PointNumber]( n, 0 ); t1[2] += GetGeometry().GetPoint( n ).Z0() * DN_DeContainer[PointNumber]( n, 0 ); t2[0] += GetGeometry().GetPoint( n ).X0() * DN_DeContainer[PointNumber]( n, 1 ); t2[1] += GetGeometry().GetPoint( n ).Y0() * DN_DeContainer[PointNumber]( n, 1 ); t2[2] += GetGeometry().GetPoint( n ).Z0() * DN_DeContainer[PointNumber]( n, 1 ); } //calculating normal Vector v3 = ZeroVector( 3 ); v3[0] = t1[1] * t2[2] - t1[2] * t2[1]; v3[1] = t1[2] * t2[0] - t1[0] * t2[2]; v3[2] = t1[0] * t2[1] - t1[1] * t2[0]; double dA = sqrt( v3[0] * v3[0] + v3[1] * v3[1] + v3[2] * v3[2] ); if ( CalculateResidualVectorFlag == true ) //calculation of the matrix is required { for ( unsigned int n = 0; n < number_of_nodes; n++ ) rRightHandSideVector( n ) -= Ncontainer( PointNumber, n ) * convection_coefficient * ( T - T_ambient ) * IntegrationWeight * dA; // W/(m^2*°C) = kg*s^-3*°C°^-1 } if ( CalculateStiffnessMatrixFlag == true ) //calculation of the matrix is required { for ( unsigned int n = 0; n < number_of_nodes; n++ ) rLeftHandSideMatrix( n, n ) += Ncontainer( PointNumber, n ) * convection_coefficient * Ncontainer( PointNumber, n ) * IntegrationWeight * dA; // W/(m^2*°C) = kg*s^-3*°C°^-1 } } KRATOS_CATCH( "" ) }
static void run(MatrixType& result, typename MatrixType::Index size) { result.resize(size, size); result.template triangularView<Upper>() = MatrixType::Random(size, size); }
template<typename MatrixType> void product_extra(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; typedef Matrix<Scalar, 1, Dynamic> RowVectorType; typedef Matrix<Scalar, Dynamic, 1> ColVectorType; typedef Matrix<Scalar, Dynamic, Dynamic, MatrixType::Flags&RowMajorBit> OtherMajorMatrixType; Index rows = m.rows(); Index cols = m.cols(); MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = MatrixType::Identity(rows, rows), square = MatrixType::Random(rows, rows), res = MatrixType::Random(rows, rows), square2 = MatrixType::Random(cols, cols), res2 = MatrixType::Random(cols, cols); RowVectorType v1 = RowVectorType::Random(rows), vrres(rows); ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols); OtherMajorMatrixType tm1 = m1; Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>(), s3 = internal::random<Scalar>(); VERIFY_IS_APPROX(m3.noalias() = m1 * m2.adjoint(), m1 * m2.adjoint().eval()); VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * square.adjoint(), m1.adjoint().eval() * square.adjoint().eval()); VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * m2, m1.adjoint().eval() * m2); VERIFY_IS_APPROX(m3.noalias() = (s1 * m1.adjoint()) * m2, (s1 * m1.adjoint()).eval() * m2); VERIFY_IS_APPROX(m3.noalias() = ((s1 * m1).adjoint()) * m2, (numext::conj(s1) * m1.adjoint()).eval() * m2); VERIFY_IS_APPROX(m3.noalias() = (- m1.adjoint() * s1) * (s3 * m2), (- m1.adjoint() * s1).eval() * (s3 * m2).eval()); VERIFY_IS_APPROX(m3.noalias() = (s2 * m1.adjoint() * s1) * m2, (s2 * m1.adjoint() * s1).eval() * m2); VERIFY_IS_APPROX(m3.noalias() = (-m1*s2) * s1*m2.adjoint(), (-m1*s2).eval() * (s1*m2.adjoint()).eval()); // a very tricky case where a scale factor has to be automatically conjugated: VERIFY_IS_APPROX( m1.adjoint() * (s1*m2).conjugate(), (m1.adjoint()).eval() * ((s1*m2).conjugate()).eval()); // test all possible conjugate combinations for the four matrix-vector product cases: VERIFY_IS_APPROX((-m1.conjugate() * s2) * (s1 * vc2), (-m1.conjugate()*s2).eval() * (s1 * vc2).eval()); VERIFY_IS_APPROX((-m1 * s2) * (s1 * vc2.conjugate()), (-m1*s2).eval() * (s1 * vc2.conjugate()).eval()); VERIFY_IS_APPROX((-m1.conjugate() * s2) * (s1 * vc2.conjugate()), (-m1.conjugate()*s2).eval() * (s1 * vc2.conjugate()).eval()); VERIFY_IS_APPROX((s1 * vc2.transpose()) * (-m1.adjoint() * s2), (s1 * vc2.transpose()).eval() * (-m1.adjoint()*s2).eval()); VERIFY_IS_APPROX((s1 * vc2.adjoint()) * (-m1.transpose() * s2), (s1 * vc2.adjoint()).eval() * (-m1.transpose()*s2).eval()); VERIFY_IS_APPROX((s1 * vc2.adjoint()) * (-m1.adjoint() * s2), (s1 * vc2.adjoint()).eval() * (-m1.adjoint()*s2).eval()); VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.transpose()), (-m1.adjoint()*s2).eval() * (s1 * v1.transpose()).eval()); VERIFY_IS_APPROX((-m1.transpose() * s2) * (s1 * v1.adjoint()), (-m1.transpose()*s2).eval() * (s1 * v1.adjoint()).eval()); VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.adjoint()), (-m1.adjoint()*s2).eval() * (s1 * v1.adjoint()).eval()); VERIFY_IS_APPROX((s1 * v1) * (-m1.conjugate() * s2), (s1 * v1).eval() * (-m1.conjugate()*s2).eval()); VERIFY_IS_APPROX((s1 * v1.conjugate()) * (-m1 * s2), (s1 * v1.conjugate()).eval() * (-m1*s2).eval()); VERIFY_IS_APPROX((s1 * v1.conjugate()) * (-m1.conjugate() * s2), (s1 * v1.conjugate()).eval() * (-m1.conjugate()*s2).eval()); VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.adjoint()), (-m1.adjoint()*s2).eval() * (s1 * v1.adjoint()).eval()); // test the vector-matrix product with non aligned starts Index i = internal::random<Index>(0,m1.rows()-2); Index j = internal::random<Index>(0,m1.cols()-2); Index r = internal::random<Index>(1,m1.rows()-i); Index c = internal::random<Index>(1,m1.cols()-j); Index i2 = internal::random<Index>(0,m1.rows()-1); Index j2 = internal::random<Index>(0,m1.cols()-1); VERIFY_IS_APPROX(m1.col(j2).adjoint() * m1.block(0,j,m1.rows(),c), m1.col(j2).adjoint().eval() * m1.block(0,j,m1.rows(),c).eval()); VERIFY_IS_APPROX(m1.block(i,0,r,m1.cols()) * m1.row(i2).adjoint(), m1.block(i,0,r,m1.cols()).eval() * m1.row(i2).adjoint().eval()); // regression test MatrixType tmp = m1 * m1.adjoint() * s1; VERIFY_IS_APPROX(tmp, m1 * m1.adjoint() * s1); }
template<typename MatrixType> void basicStuff(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType; Index rows = m.rows(); Index cols = m.cols(); // this test relies a lot on Random.h, and there's not much more that we can do // to test it, hence I consider that we will have tested Random.h MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols), square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows); VectorType v1 = VectorType::Random(rows), vzero = VectorType::Zero(rows); SquareMatrixType sm1 = SquareMatrixType::Random(rows,rows), sm2(rows,rows); Scalar x = 0; while(x == Scalar(0)) x = internal::random<Scalar>(); Index r = internal::random<Index>(0, rows-1), c = internal::random<Index>(0, cols-1); m1.coeffRef(r,c) = x; VERIFY_IS_APPROX(x, m1.coeff(r,c)); m1(r,c) = x; VERIFY_IS_APPROX(x, m1(r,c)); v1.coeffRef(r) = x; VERIFY_IS_APPROX(x, v1.coeff(r)); v1(r) = x; VERIFY_IS_APPROX(x, v1(r)); v1[r] = x; VERIFY_IS_APPROX(x, v1[r]); VERIFY_IS_APPROX( v1, v1); VERIFY_IS_NOT_APPROX( v1, 2*v1); VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1); VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1.squaredNorm()); VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1, v1); VERIFY_IS_APPROX( vzero, v1-v1); VERIFY_IS_APPROX( m1, m1); VERIFY_IS_NOT_APPROX( m1, 2*m1); VERIFY_IS_MUCH_SMALLER_THAN( mzero, m1); VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1, m1); VERIFY_IS_APPROX( mzero, m1-m1); // always test operator() on each read-only expression class, // in order to check const-qualifiers. // indeed, if an expression class (here Zero) is meant to be read-only, // hence has no _write() method, the corresponding MatrixBase method (here zero()) // should return a const-qualified object so that it is the const-qualified // operator() that gets called, which in turn calls _read(). VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1)); // now test copying a row-vector into a (column-)vector and conversely. square.col(r) = square.row(r).eval(); Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows); Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows); rv = square.row(r); cv = square.col(r); VERIFY_IS_APPROX(rv, cv.transpose()); if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic) { VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1))); } if(cols!=1 && rows!=1) { VERIFY_RAISES_ASSERT(m1[0]); VERIFY_RAISES_ASSERT((m1+m1)[0]); } VERIFY_IS_APPROX(m3 = m1,m1); MatrixType m4; VERIFY_IS_APPROX(m4 = m1,m1); m3.real() = m1.real(); VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real()); VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real()); // check == / != operators VERIFY(m1==m1); VERIFY(m1!=m2); VERIFY(!(m1==m2)); VERIFY(!(m1!=m1)); m1 = m2; VERIFY(m1==m2); VERIFY(!(m1!=m2)); // check automatic transposition sm2.setZero(); for(typename MatrixType::Index i=0;i<rows;++i) sm2.col(i) = sm1.row(i); VERIFY_IS_APPROX(sm2,sm1.transpose()); sm2.setZero(); for(typename MatrixType::Index i=0;i<rows;++i) sm2.col(i).noalias() = sm1.row(i); VERIFY_IS_APPROX(sm2,sm1.transpose()); sm2.setZero(); for(typename MatrixType::Index i=0;i<rows;++i) sm2.col(i).noalias() += sm1.row(i); VERIFY_IS_APPROX(sm2,sm1.transpose()); sm2.setZero(); for(typename MatrixType::Index i=0;i<rows;++i) sm2.col(i).noalias() -= sm1.row(i); VERIFY_IS_APPROX(sm2,-sm1.transpose()); // check ternary usage { bool b = internal::random<int>(0,10)>5; m3 = b ? m1 : m2; if(b) VERIFY_IS_APPROX(m3,m1); else VERIFY_IS_APPROX(m3,m2); m3 = b ? -m1 : m2; if(b) VERIFY_IS_APPROX(m3,-m1); else VERIFY_IS_APPROX(m3,m2); m3 = b ? m1 : -m2; if(b) VERIFY_IS_APPROX(m3,m1); else VERIFY_IS_APPROX(m3,-m2); } }
// Kernel launch static void apply(const MatrixType matrix) { const size_type nrow = matrix.numRows(); Kokkos::parallel_for( nrow, AddDiagonalValuesAtomicKernel(matrix) ); }
template<typename MatrixType> void vectorwiseop_matrix(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType; typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealColVectorType; typedef Matrix<RealScalar, 1, MatrixType::ColsAtCompileTime> RealRowVectorType; Index rows = m.rows(); Index cols = m.cols(); Index r = internal::random<Index>(0, rows-1), c = internal::random<Index>(0, cols-1); MatrixType m1 = MatrixType::Random(rows, cols), m2(rows, cols), m3(rows, cols); ColVectorType colvec = ColVectorType::Random(rows); RowVectorType rowvec = RowVectorType::Random(cols); RealColVectorType rcres; RealRowVectorType rrres; // test addition m2 = m1; m2.colwise() += colvec; VERIFY_IS_APPROX(m2, m1.colwise() + colvec); VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec); if(rows>1) { VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose()); VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose()); } m2 = m1; m2.rowwise() += rowvec; VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec); VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec); if(cols>1) { VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose()); VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose()); } // test substraction m2 = m1; m2.colwise() -= colvec; VERIFY_IS_APPROX(m2, m1.colwise() - colvec); VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec); if(rows>1) { VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose()); VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose()); } m2 = m1; m2.rowwise() -= rowvec; VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec); VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec); if(cols>1) { VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose()); VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose()); } // test norm rrres = m1.colwise().norm(); VERIFY_IS_APPROX(rrres(c), m1.col(c).norm()); rcres = m1.rowwise().norm(); VERIFY_IS_APPROX(rcres(r), m1.row(r).norm()); VERIFY_IS_APPROX(m1.cwiseAbs().colwise().sum(), m1.colwise().template lpNorm<1>()); VERIFY_IS_APPROX(m1.cwiseAbs().rowwise().sum(), m1.rowwise().template lpNorm<1>()); VERIFY_IS_APPROX(m1.cwiseAbs().colwise().maxCoeff(), m1.colwise().template lpNorm<Infinity>()); VERIFY_IS_APPROX(m1.cwiseAbs().rowwise().maxCoeff(), m1.rowwise().template lpNorm<Infinity>()); // regression for bug 1158 VERIFY_IS_APPROX(m1.cwiseAbs().colwise().sum().x(), m1.col(0).cwiseAbs().sum()); // test normalized m2 = m1.colwise().normalized(); VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized()); m2 = m1.rowwise().normalized(); VERIFY_IS_APPROX(m2.row(r), m1.row(r).normalized()); // test normalize m2 = m1; m2.colwise().normalize(); VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized()); m2 = m1; m2.rowwise().normalize(); VERIFY_IS_APPROX(m2.row(r), m1.row(r).normalized()); // test with partial reduction of products Matrix<Scalar,MatrixType::RowsAtCompileTime,MatrixType::RowsAtCompileTime> m1m1 = m1 * m1.transpose(); VERIFY_IS_APPROX( (m1 * m1.transpose()).colwise().sum(), m1m1.colwise().sum()); Matrix<Scalar,1,MatrixType::RowsAtCompileTime> tmp(rows); VERIFY_EVALUATION_COUNT( tmp = (m1 * m1.transpose()).colwise().sum(), (MatrixType::RowsAtCompileTime==Dynamic ? 1 : 0)); m2 = m1.rowwise() - (m1.colwise().sum()/RealScalar(m1.rows())).eval(); m1 = m1.rowwise() - (m1.colwise().sum()/RealScalar(m1.rows())); VERIFY_IS_APPROX( m1, m2 ); VERIFY_EVALUATION_COUNT( m2 = (m1.rowwise() - m1.colwise().sum()/RealScalar(m1.rows())), (MatrixType::RowsAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime!=1 ? 1 : 0) ); }
/** @brief Constructor for the preconditioner * * @param mat The system matrix * @param tag A row scaling tag holding the desired norm. */ row_scaling(MatrixType const & mat, row_scaling_tag const & tag) : diag_M(mat.size1(), viennacl::traits::context(mat)) { init(mat, tag); }
void bdcsvd(const MatrixType& a = MatrixType(), bool pickrandom = true) { MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a; bdcsvd_test_all_computation_options<MatrixType>(m); } // end template bdcsvd
template<typename MatrixType> void cwiseops(const MatrixType& m) { typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; int rows = m.rows(); int cols = m.cols(); MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), m4(rows, cols), mzero = MatrixType::Zero(rows, cols), mones = MatrixType::Ones(rows, cols), identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> ::Identity(rows, rows); VectorType vzero = VectorType::Zero(rows), vones = VectorType::Ones(rows), v3(rows); int r = ei_random<int>(0, rows-1), c = ei_random<int>(0, cols-1); Scalar s1 = ei_random<Scalar>(); // test Zero, Ones, Constant, and the set* variants m3 = MatrixType::Constant(rows, cols, s1); for (int j=0; j<cols; ++j) for (int i=0; i<rows; ++i) { VERIFY_IS_APPROX(mzero(i,j), Scalar(0)); VERIFY_IS_APPROX(mones(i,j), Scalar(1)); VERIFY_IS_APPROX(m3(i,j), s1); } VERIFY(mzero.isZero()); VERIFY(mones.isOnes()); VERIFY(m3.isConstant(s1)); VERIFY(identity.isIdentity()); VERIFY_IS_APPROX(m4.setConstant(s1), m3); VERIFY_IS_APPROX(m4.setConstant(rows,cols,s1), m3); VERIFY_IS_APPROX(m4.setZero(), mzero); VERIFY_IS_APPROX(m4.setZero(rows,cols), mzero); VERIFY_IS_APPROX(m4.setOnes(), mones); VERIFY_IS_APPROX(m4.setOnes(rows,cols), mones); m4.fill(s1); VERIFY_IS_APPROX(m4, m3); VERIFY_IS_APPROX(v3.setConstant(rows, s1), VectorType::Constant(rows,s1)); VERIFY_IS_APPROX(v3.setZero(rows), vzero); VERIFY_IS_APPROX(v3.setOnes(rows), vones); m2 = m2.template binaryExpr<AddIfNull<Scalar> >(mones); VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().abs2()); VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().square()); VERIFY_IS_APPROX(m1.cwise().pow(3), m1.cwise().cube()); VERIFY_IS_APPROX(m1 + mones, m1.cwise()+Scalar(1)); VERIFY_IS_APPROX(m1 - mones, m1.cwise()-Scalar(1)); m3 = m1; m3.cwise() += 1; VERIFY_IS_APPROX(m1 + mones, m3); m3 = m1; m3.cwise() -= 1; VERIFY_IS_APPROX(m1 - mones, m3); VERIFY_IS_APPROX(m2, m2.cwise() * mones); VERIFY_IS_APPROX(m1.cwise() * m2, m2.cwise() * m1); m3 = m1; m3.cwise() *= m2; VERIFY_IS_APPROX(m3, m1.cwise() * m2); VERIFY_IS_APPROX(mones, m2.cwise()/m2); if(NumTraits<Scalar>::HasFloatingPoint) { VERIFY_IS_APPROX(m1.cwise() / m2, m1.cwise() * (m2.cwise().inverse())); m3 = m1.cwise().abs().cwise().sqrt(); VERIFY_IS_APPROX(m3.cwise().square(), m1.cwise().abs()); VERIFY_IS_APPROX(m1.cwise().square().cwise().sqrt(), m1.cwise().abs()); VERIFY_IS_APPROX(m1.cwise().abs().cwise().log().cwise().exp() , m1.cwise().abs()); VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().square()); m3 = (m1.cwise().abs().cwise()<=RealScalar(0.01)).select(mones,m1); VERIFY_IS_APPROX(m3.cwise().pow(-1), m3.cwise().inverse()); m3 = m1.cwise().abs(); VERIFY_IS_APPROX(m3.cwise().pow(RealScalar(0.5)), m3.cwise().sqrt()); // VERIFY_IS_APPROX(m1.cwise().tan(), m1.cwise().sin().cwise() / m1.cwise().cos()); VERIFY_IS_APPROX(mones, m1.cwise().sin().cwise().square() + m1.cwise().cos().cwise().square()); m3 = m1; m3.cwise() /= m2; VERIFY_IS_APPROX(m3, m1.cwise() / m2); } // check min VERIFY_IS_APPROX( m1.cwise().min(m2), m2.cwise().min(m1) ); VERIFY_IS_APPROX( m1.cwise().min(m1+mones), m1 ); VERIFY_IS_APPROX( m1.cwise().min(m1-mones), m1-mones ); // check max VERIFY_IS_APPROX( m1.cwise().max(m2), m2.cwise().max(m1) ); VERIFY_IS_APPROX( m1.cwise().max(m1-mones), m1 ); VERIFY_IS_APPROX( m1.cwise().max(m1+mones), m1+mones ); VERIFY( (m1.cwise() == m1).all() ); VERIFY( (m1.cwise() != m2).any() ); VERIFY(!(m1.cwise() == (m1+mones)).any() ); if (rows*cols>1) { m3 = m1; m3(r,c) += 1; VERIFY( (m1.cwise() == m3).any() ); VERIFY( !(m1.cwise() == m3).all() ); } VERIFY( (m1.cwise().min(m2).cwise() <= m2).all() ); VERIFY( (m1.cwise().max(m2).cwise() >= m2).all() ); VERIFY( (m1.cwise().min(m2).cwise() < (m1+mones)).all() ); VERIFY( (m1.cwise().max(m2).cwise() > (m1-mones)).all() ); VERIFY( (m1.cwise()<m1.unaryExpr(bind2nd(plus<Scalar>(), Scalar(1)))).all() ); VERIFY( !(m1.cwise()<m1.unaryExpr(bind2nd(minus<Scalar>(), Scalar(1)))).all() ); VERIFY( !(m1.cwise()>m1.unaryExpr(bind2nd(plus<Scalar>(), Scalar(1)))).any() ); }
template<typename MatrixType> void diagonalmatrices(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime }; typedef Matrix<Scalar, Rows, 1> VectorType; typedef Matrix<Scalar, 1, Cols> RowVectorType; typedef Matrix<Scalar, Rows, Rows> SquareMatrixType; typedef DiagonalMatrix<Scalar, Rows> LeftDiagonalMatrix; typedef DiagonalMatrix<Scalar, Cols> RightDiagonalMatrix; typedef Matrix<Scalar, Rows==Dynamic?Dynamic:2*Rows, Cols==Dynamic?Dynamic:2*Cols> BigMatrix; Index rows = m.rows(); Index cols = m.cols(); MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols); VectorType v1 = VectorType::Random(rows), v2 = VectorType::Random(rows); RowVectorType rv1 = RowVectorType::Random(cols), rv2 = RowVectorType::Random(cols); LeftDiagonalMatrix ldm1(v1), ldm2(v2); RightDiagonalMatrix rdm1(rv1), rdm2(rv2); Scalar s1 = internal::random<Scalar>(); SquareMatrixType sq_m1 (v1.asDiagonal()); VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix()); sq_m1 = v1.asDiagonal(); VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix()); SquareMatrixType sq_m2 = v1.asDiagonal(); VERIFY_IS_APPROX(sq_m1, sq_m2); ldm1 = v1.asDiagonal(); LeftDiagonalMatrix ldm3(v1); VERIFY_IS_APPROX(ldm1.diagonal(), ldm3.diagonal()); LeftDiagonalMatrix ldm4 = v1.asDiagonal(); VERIFY_IS_APPROX(ldm1.diagonal(), ldm4.diagonal()); sq_m1.block(0,0,rows,rows) = ldm1; VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix()); sq_m1.transpose() = ldm1; VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix()); Index i = internal::random<Index>(0, rows-1); Index j = internal::random<Index>(0, cols-1); VERIFY_IS_APPROX( ((ldm1 * m1)(i,j)) , ldm1.diagonal()(i) * m1(i,j) ); VERIFY_IS_APPROX( ((ldm1 * (m1+m2))(i,j)) , ldm1.diagonal()(i) * (m1+m2)(i,j) ); VERIFY_IS_APPROX( ((m1 * rdm1)(i,j)) , rdm1.diagonal()(j) * m1(i,j) ); VERIFY_IS_APPROX( ((v1.asDiagonal() * m1)(i,j)) , v1(i) * m1(i,j) ); VERIFY_IS_APPROX( ((m1 * rv1.asDiagonal())(i,j)) , rv1(j) * m1(i,j) ); VERIFY_IS_APPROX( (((v1+v2).asDiagonal() * m1)(i,j)) , (v1+v2)(i) * m1(i,j) ); VERIFY_IS_APPROX( (((v1+v2).asDiagonal() * (m1+m2))(i,j)) , (v1+v2)(i) * (m1+m2)(i,j) ); VERIFY_IS_APPROX( ((m1 * (rv1+rv2).asDiagonal())(i,j)) , (rv1+rv2)(j) * m1(i,j) ); VERIFY_IS_APPROX( (((m1+m2) * (rv1+rv2).asDiagonal())(i,j)) , (rv1+rv2)(j) * (m1+m2)(i,j) ); BigMatrix big; big.setZero(2*rows, 2*cols); big.block(i,j,rows,cols) = m1; big.block(i,j,rows,cols) = v1.asDiagonal() * big.block(i,j,rows,cols); VERIFY_IS_APPROX((big.block(i,j,rows,cols)) , v1.asDiagonal() * m1 ); big.block(i,j,rows,cols) = m1; big.block(i,j,rows,cols) = big.block(i,j,rows,cols) * rv1.asDiagonal(); VERIFY_IS_APPROX((big.block(i,j,rows,cols)) , m1 * rv1.asDiagonal() ); // scalar multiple VERIFY_IS_APPROX(LeftDiagonalMatrix(ldm1*s1).diagonal(), ldm1.diagonal() * s1); VERIFY_IS_APPROX(LeftDiagonalMatrix(s1*ldm1).diagonal(), s1 * ldm1.diagonal()); VERIFY_IS_APPROX(m1 * (rdm1 * s1), (m1 * rdm1) * s1); VERIFY_IS_APPROX(m1 * (s1 * rdm1), (m1 * rdm1) * s1); // Diagonal to dense sq_m1.setRandom(); sq_m2 = sq_m1; VERIFY_IS_APPROX( (sq_m1 += (s1*v1).asDiagonal()), sq_m2 += (s1*v1).asDiagonal().toDenseMatrix() ); VERIFY_IS_APPROX( (sq_m1 -= (s1*v1).asDiagonal()), sq_m2 -= (s1*v1).asDiagonal().toDenseMatrix() ); VERIFY_IS_APPROX( (sq_m1 = (s1*v1).asDiagonal()), (s1*v1).asDiagonal().toDenseMatrix() ); }
template <typename MatrixType> char get_trans(MatrixType const & A, bool transpose) { return (A.memory_layout_is_fortran() ? (transpose ? 'T' : 'N') : (transpose ? 'N' : 'T') ); }
int generate_matrix_structure(const simple_mesh_description<typename MatrixType::GlobalOrdinalType>& mesh, MatrixType& A) { int myproc = 0; #ifdef HAVE_MPI MPI_Comm_rank(MPI_COMM_WORLD, &myproc); #endif int threw_exc = 0; try { typedef typename MatrixType::GlobalOrdinalType GlobalOrdinal; typedef typename MatrixType::LocalOrdinalType LocalOrdinal; const int global_nodes_x = mesh.global_box[0][1]+1; const int global_nodes_y = mesh.global_box[1][1]+1; const int global_nodes_z = mesh.global_box[2][1]+1; Box box; copy_box(mesh.local_box, box); //num-owned-nodes in each dimension is num-elems+1 //only if num-elems > 0 in that dimension *and* //we are at the high end of the global range in that dimension: if (box[0][1] > box[0][0] && box[0][1] == mesh.global_box[0][1]) ++box[0][1]; if (box[1][1] > box[1][0] && box[1][1] == mesh.global_box[1][1]) ++box[1][1]; if (box[2][1] > box[2][0] && box[2][1] == mesh.global_box[2][1]) ++box[2][1]; GlobalOrdinal global_nrows = global_nodes_x; global_nrows *= global_nodes_y*global_nodes_z; GlobalOrdinal nrows = get_num_ids<GlobalOrdinal>(box); try { A.reserve_space(nrows, 27); } catch(std::exception& exc) { std::ostringstream osstr; osstr << "One of A.rows.resize, A.row_offsets.resize, A.packed_cols.reserve or A.packed_coefs.reserve: nrows=" <<nrows<<": "; osstr << exc.what(); std::string str1 = osstr.str(); throw std::runtime_error(str1); } std::vector<GlobalOrdinal> rows(nrows); std::vector<LocalOrdinal> row_offsets(nrows+1); std::vector<LocalOrdinal> row_coords(nrows*3); const MINIFE_GLOBAL_ORDINAL z_width = box[2][1] - box[2][0]; const MINIFE_GLOBAL_ORDINAL y_width = box[1][1] - box[1][0]; const MINIFE_GLOBAL_ORDINAL x_width = box[0][1] - box[0][0]; const MINIFE_GLOBAL_ORDINAL r_n = (box[2][1] - box[2][0]) * (box[1][1] - box[1][0]) * (box[0][1] - box[0][0]); const MINIFE_GLOBAL_ORDINAL xy_width = x_width * y_width; MINIFE_GLOBAL_ORDINAL* const row_ptr = &rows[0]; MINIFE_LOCAL_ORDINAL* const row_offset_ptr = &row_offsets[0]; MINIFE_LOCAL_ORDINAL* const row_coords_ptr = &row_coords[0]; #pragma omp parallel for for(int r = 0; r < r_n; ++r) { int iz = r / (xy_width) + box[2][0]; int iy = (r / x_width) % y_width + box[1][0]; int ix = r % x_width + box[0][0]; GlobalOrdinal row_id = get_id<GlobalOrdinal>(global_nodes_x, global_nodes_y, global_nodes_z, ix, iy, iz); row_ptr[r] = mesh.map_id_to_row(row_id); row_coords_ptr[r*3] = ix; row_coords_ptr[r*3+1] = iy; row_coords_ptr[r*3+2] = iz; MINIFE_LOCAL_ORDINAL nnz = 0; for(int sz=-1; sz<=1; ++sz) { for(int sy=-1; sy<=1; ++sy) { for(int sx=-1; sx<=1; ++sx) { GlobalOrdinal col_id = get_id<GlobalOrdinal>(global_nodes_x, global_nodes_y, global_nodes_z, ix+sx, iy+sy, iz+sz); if (col_id >= 0 && col_id < global_nrows) { ++nnz; } } } } row_offset_ptr[r+1] = nnz; } const MINIFE_GLOBAL_ORDINAL n = row_offsets.size() - 1; for(int i = 0; i < n; ++i) { row_offset_ptr[i+1] += row_offset_ptr[i]; } init_matrix(A, rows, row_offsets, row_coords, global_nodes_x, global_nodes_y, global_nodes_z, global_nrows, mesh); } catch(...) { std::cout << "proc " << myproc << " threw an exception in generate_matrix_structure, probably due to running out of memory." << std::endl; threw_exc = 1; } #ifdef HAVE_MPI int global_throw = 0; MPI_Allreduce(&threw_exc, &global_throw, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); threw_exc = global_throw; #endif if (threw_exc) { return 1; } return 0; }
template <typename MatrixType> int get_ld (MatrixType const & A) { return A.indexmap().strides()[A.memory_layout_is_fortran() ? 1 : 0]; }
//*********************************************************************************** void FaceHeatConvection::DampMatrix( MatrixType& rDampMatrix, ProcessInfo& rCurrentProcessInfo ) { KRATOS_TRY rDampMatrix.resize( 0, 0, false ); KRATOS_CATCH( "" ) }
template<typename MatrixType> void permutationmatrices(const MatrixType& m) { typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime, Options = MatrixType::Options }; typedef PermutationMatrix<Rows> LeftPermutationType; typedef Matrix<int, Rows, 1> LeftPermutationVectorType; typedef Map<LeftPermutationType> MapLeftPerm; typedef PermutationMatrix<Cols> RightPermutationType; typedef Matrix<int, Cols, 1> RightPermutationVectorType; typedef Map<RightPermutationType> MapRightPerm; Index rows = m.rows(); Index cols = m.cols(); MatrixType m_original = MatrixType::Random(rows,cols); LeftPermutationVectorType lv; randomPermutationVector(lv, rows); LeftPermutationType lp(lv); RightPermutationVectorType rv; randomPermutationVector(rv, cols); RightPermutationType rp(rv); MatrixType m_permuted = MatrixType::Random(rows,cols); VERIFY_EVALUATION_COUNT(m_permuted = lp * m_original * rp, 1); // 1 temp for sub expression "lp * m_original" for (int i=0; i<rows; i++) for (int j=0; j<cols; j++) VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j))); Matrix<Scalar,Rows,Rows> lm(lp); Matrix<Scalar,Cols,Cols> rm(rp); VERIFY_IS_APPROX(m_permuted, lm*m_original*rm); m_permuted = m_original; VERIFY_EVALUATION_COUNT(m_permuted = lp * m_permuted * rp, 1); VERIFY_IS_APPROX(m_permuted, lm*m_original*rm); VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original); VERIFY_IS_APPROX(lv.asPermutation().inverse()*m_permuted*rv.asPermutation().inverse(), m_original); VERIFY_IS_APPROX(MapLeftPerm(lv.data(),lv.size()).inverse()*m_permuted*MapRightPerm(rv.data(),rv.size()).inverse(), m_original); VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity()); VERIFY((lv.asPermutation()*lv.asPermutation().inverse()).toDenseMatrix().isIdentity()); VERIFY((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv.data(),lv.size()).inverse()).toDenseMatrix().isIdentity()); LeftPermutationVectorType lv2; randomPermutationVector(lv2, rows); LeftPermutationType lp2(lv2); Matrix<Scalar,Rows,Rows> lm2(lp2); VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2); VERIFY_IS_APPROX((lv.asPermutation()*lv2.asPermutation()).toDenseMatrix().template cast<Scalar>(), lm*lm2); VERIFY_IS_APPROX((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv2.data(),lv2.size())).toDenseMatrix().template cast<Scalar>(), lm*lm2); LeftPermutationType identityp; identityp.setIdentity(rows); VERIFY_IS_APPROX(m_original, identityp*m_original); // check inplace permutations m_permuted = m_original; VERIFY_EVALUATION_COUNT(m_permuted.noalias()= lp.inverse() * m_permuted, 1); // 1 temp to allocate the mask VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original); m_permuted = m_original; VERIFY_EVALUATION_COUNT(m_permuted.noalias() = m_permuted * rp.inverse(), 1); // 1 temp to allocate the mask VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse()); m_permuted = m_original; VERIFY_EVALUATION_COUNT(m_permuted.noalias() = lp * m_permuted, 1); // 1 temp to allocate the mask VERIFY_IS_APPROX(m_permuted, lp*m_original); m_permuted = m_original; VERIFY_EVALUATION_COUNT(m_permuted.noalias() = m_permuted * rp, 1); // 1 temp to allocate the mask VERIFY_IS_APPROX(m_permuted, m_original*rp); if(rows>1 && cols>1) { lp2 = lp; Index i = internal::random<Index>(0, rows-1); Index j; do j = internal::random<Index>(0, rows-1); while(j==i); lp2.applyTranspositionOnTheLeft(i, j); lm = lp; lm.row(i).swap(lm.row(j)); VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>()); RightPermutationType rp2 = rp; i = internal::random<Index>(0, cols-1); do j = internal::random<Index>(0, cols-1); while(j==i); rp2.applyTranspositionOnTheRight(i, j); rm = rp; rm.col(i).swap(rm.col(j)); VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>()); } { // simple compilation check Matrix<Scalar, Cols, Cols> A = rp; Matrix<Scalar, Cols, Cols> B = rp.transpose(); VERIFY_IS_APPROX(A, B.transpose()); } }
void SoItkMatrix::evaluate() { if( mOutput ) { mOutput->unref(); mOutput = 0; SO_ENGINE_OUTPUT( Output, SoItkSFDataMatrix, setValue( 0 ) ); } try { // FIXME : check size switch( ValueType.getValue() ) { case UNSIGNED_SHORT: { switch( MatrixType.getValue() ) { case _2x2: { typedef itk::Matrix< unsigned short, 2, 2 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 2; ++ i ) for( unsigned int j = 0; j < 2; ++ j ) { array->operator() ( i, j ) = Values[ i*2 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_2X2 ); mOutput->ref(); mOutput->setPointer( array ); } break ; case _3x3: { typedef itk::Matrix< unsigned short, 3, 3 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 3; ++ i ) for( unsigned int j = 0; j < 3; ++ j ) { array->operator() ( i, j ) = Values[ i*3 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_3X3 ); mOutput->ref(); mOutput->setPointer( array ); } break ; case _4x4: { typedef itk::Matrix< unsigned short, 4, 4 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 4; ++ i ) for( unsigned int j = 0; j < 4; ++ j ) { array->operator() ( i, j ) = Values[ i*4 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_4X4 ); mOutput->ref(); mOutput->setPointer( array ); } break ; } } break ; case FLOAT: { switch( MatrixType.getValue() ) { case _2x2: { typedef itk::Matrix< float, 2, 2 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 2; ++ i ) for( unsigned int j = 0; j < 2; ++ j ) { array->operator() ( i, j ) = Values[ i*2 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_2X2 ); mOutput->ref(); mOutput->setPointer( array ); } break ; case _3x3: { typedef itk::Matrix< float, 3, 3 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 3; ++ i ) for( unsigned int j = 0; j < 3; ++ j ) { array->operator() ( i, j ) = Values[ i*3 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_3X3 ); mOutput->ref(); mOutput->setPointer( array ); } break ; case _4x4: { typedef itk::Matrix< float, 4, 4 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 4; ++ i ) for( unsigned int j = 0; j < 4; ++ j ) { array->operator() ( i, j ) = Values[ i*4 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_4X4 ); mOutput->ref(); mOutput->setPointer( array ); } break ; } } break ; case DOUBLE: { switch( MatrixType.getValue() ) { case _2x2: { typedef itk::Matrix< double, 2, 2 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 2; ++ i ) for( unsigned int j = 0; j < 2; ++ j ) { array->operator() ( i, j ) = Values[ i*2 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_2X2 ); mOutput->ref(); mOutput->setPointer( array ); } break ; case _3x3: { typedef itk::Matrix< double, 3, 3 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 3; ++ i ) for( unsigned int j = 0; j < 3; ++ j ) { array->operator() ( i, j ) = Values[ i*3 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_3X3 ); mOutput->ref(); mOutput->setPointer( array ); } break ; case _4x4: { typedef itk::Matrix< double, 4, 4 > MatrixType; MatrixType* array = new MatrixType(); for( unsigned int i = 0; i < 4; ++ i ) for( unsigned int j = 0; j < 4; ++ j ) { array->operator() ( i, j ) = Values[ i*4 + j ]; } mOutput = new SoItkDataMatrix( SoItkDataMatrix::UNSIGNED_SHORT, SoItkDataMatrix::MATRIX_4X4 ); mOutput->ref(); mOutput->setPointer( array ); } break ; } } break ; } } catch(...) { SoDebugError::post( __FILE__, "Unknown Exception" ); return ; } SO_ENGINE_OUTPUT( Output, SoItkSFDataMatrix, setValue( mOutput ) ); }