Commit 4f73cd58 by ralfh

### New homework problem MatrixReduce

parent c9c70c89
 ... ... @@ -15,8 +15,9 @@ using namespace Eigen; // END M/* SAM_LISTING_BEGIN_0 */ atrixXd zero_row_col(MatrixXd A, int p, int q) { M /* SAM_LISTING_BEGIN_0 */ atrixXd zero_row_col(MatrixXd A, int p, int q) { /* * This function takes a matrix A, and returns a matrix that is exactly the * same, except that row p and column q are set to zero. ... ... @@ -85,6 +86,7 @@ MatrixXd swap_left_right_blocks(MatrixXd A, int p) { } /* SAM_LISTING_END_1 */ /* SAM_LISTING_BEGIN_3 */ MatrixXd tridiagonal(int n, double a, double b, double c) { /* * This function creates an n by n tridiagonal matrix with the values ... ... @@ -110,8 +112,8 @@ MatrixXd tridiagonal(int n, double a, double b, double c) { A.diagonal() = VectorXd::Constant(n, b); A.diagonal(1) = VectorXd::Constant(n - 1, c); // END return A; } /* SAM_LISTING_END_3 */ #endif
 #ifndef MATRIXREDUCE_HPP #define MATRIXREDUCE_HPP // The purpose of this exercise is introduce reduction operations. // TO DO: Include the appropriate header files and namespaces // START #include #include using namespace Eigen; // END // Eigen matrices have a range of methods that reduce them to a single number. // Suppose A is a MatrixXd object, then a few useful methods are: // A.size(): the number of entries in A, // A.sum(): the sum of all entries in A, // A.prod(): the product of all entries in A, // A.minCoeff(): the minimum value amongst the entries of A, // A.maxCoeff(): the maximum value amongst the entries of A, and // A.norm(): The (Frobenius) norm of the matrix A. // TO DO: Write a function "average" that takes as argument a "MatrixXd" object // and returns a "double". m = average(A) should calculate the average of the // entries of A. START /* SAM_LISTING_BEGIN_0 */ double average(MatrixXd A) { /* * Calculates the average of the entries of A */ double m; m = A.sum() / A.size(); return m; } // END /* SAM_LISTING_END_0 */ // Question: is there a reduction method that returns the average of A directly? /* SAM_LISTING_BEGIN_2 */ double percent_zero(MatrixXd A) { /* * Calculates how many entries of A are exactly equal to zero, * as a percentage of the total number of entries. */ // Eigen provides an Array class, that is similar to Matrix, // but has operations that are entry-wise rather than linear algebra // operations. For example, multiplying two Arrays is entry-wise // multiplication, and not matrix multiplication. ArrayXXd Arr(A); // START // The benefit of using an Array here is that we can do entry-wise boolean // comparison, which is not available for matrices. int zeros = (Arr == 0).count(); double ratio; // TO DO: Calculate the ratio of zero entries. ratio = ((double)zeros) / A.size(); // END return ratio * 100; } /* SAM_LISTING_END_2 */ /* SAM_LISTING_BEGIN_3 */ bool has_zero_column(MatrixXd A) { /* * Returns 1 if A has a column that is exactly equal to zero. * Returns 0 otherwise. */ int result; // A vector is the zero vector if and only if it has norm 0. // The following vector contains the squared norms of the columns of A. VectorXd norms = A.colwise().squaredNorm(); // The norm is 0 if and only if the norm squared is zero. // We use squaredNorm() instead of norm(), because norm() = // sqrt(squaredNorm()) calculates a square root that is not necessary for our // purposes. // TO DO: Check if any one of the norms is equal to zero. // Hint: Use an ArrayXd and entry-wise comparison. // START ArrayXd Arr(norms); result = (Arr == 0).any(); // END return result; } /* SAM_LISTING_END_3 */ /* SAM_LISTING_BEGIN_4 */ MatrixXd columns_sum_to_zero(const MatrixXd &A) { /* * Returns a matrix that is like A, but the entries on the diagonal * have been changed so that the sum of the columns is equal to 0. */ MatrixXd B(A); // TO DO: Replace the diagonal of B with values such that the columns of B sum // up to zero. Hint: Use diagonal(), rowwise(), and sum(). START int p = std::min(B.rows(), B.cols()); B.diagonal() = VectorXd::Zero(p); B.diagonal() = -B.rowwise().sum(); // END return B; } /* SAM_LISTING_END_4 */ #endif
 #ifndef MATRIXREDUCE_HPP #define MATRIXREDUCE_HPP // The purpose of this exercise is introduce reduction operations. // TO DO: Include the appropriate header files and namespaces // START #include #include using namespace Eigen; // END // Eigen matrices have a range of methods that reduce them to a single number. // Suppose A is a MatrixXd object, then a few useful methods are: // A.size(): the number of entries in A, // A.sum(): the sum of all entries in A, // A.prod(): the product of all entries in A, // A.minCoeff(): the minimum value amongst the entries of A, // A.maxCoeff(): the maximum value amongst the entries of A, and // A.norm(): The (Frobenius) norm of the matrix A. // TO DO: Write a function "average" that takes as argument a "MatrixXd" object and returns a "double". // m = average(A) should calculate the average of the entries of A. // START double average( MatrixXd A ){ /* * Calculates the average of the entries of A */ double m; m = A.sum()/A.size(); return m; } // END // Question: is there a reduction method that returns the average of A directly? double percent_zero( MatrixXd A ){ /* * Calculates how many entries of A are exactly equal to zero, * as a percentage of the total number of entries. */ // Eigen provides an Array class, that is similar to Matrix, // but has operations that are entry-wise rather than linear algebra operations. // For example, multiplying two Arrays is entry-wise multiplication, and not matrix multiplication. ArrayXXd Arr(A); // The benefit of using an Array here is that we can do entry-wise boolean comparison, // which is not available for matrices. int zeros = (Arr == 0).count(); double ratio; // TO DO: Calculate the ratio of zero entries. // START ratio = ((double) zeros)/A.size(); // END return ratio*100; } int has_zero_column( MatrixXd A ){ /* * Returns 1 if A has a column that is exactly equal to zero. * Returns 0 otherwise. */ int result; // A vector is the zero vector if and only if it has norm 0. // The following vector contains the squared norms of the columns of A. VectorXd norms = A.colwise().squaredNorm(); // The norm is 0 if and only if the norm squared is zero. // We use squaredNorm() instead of norm(), because norm() = sqrt(squaredNorm()) // calculates a square root that is not necessary for our purposes. // TO DO: Check if any one of the norms is equal to zero. // Hint: Use an ArrayXd and entry-wise comparison. // START ArrayXd Arr(norms); result = (Arr == 0).any(); // END return result; } MatrixXd columns_sum_to_zero( MatrixXd A ){ /* * Returns a matrix that is like A, but the entries on the diagonal * have been changed so that the sum of the columns is equal to 0. */ MatrixXd B(A); // TO DO: Replace the diagonal of B with values such that the columns of B sum up to zero. // Hint: Use diagonal(), rowwise(), and sum(). // START int p = std::min(B.rows(),B.cols()); B.diagonal() = VectorXd::Zero(p); B.diagonal() = -B.rowwise().sum(); // END return B; } #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!