Commit c397ec0a authored by Tandri Gauksson's avatar Tandri Gauksson

sync MatrixReduce with CodeExpert

parent 7a0a4b47
#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
// 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 */
/* SAM_LISTING_END_0 */
// END
// Question: is there a reduction method that returns the average of A directly?
/* SAM_LISTING_BEGIN_1 */
double percent_zero(const 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.
// The benefit of using an Array here is that we can do entry-wise boolean
// comparison, which is not available for matrices.
ArrayXXd Arr = A.array();
double ratio;
// TO DO: Calculate the ratio of zero entries in A.
// START
// END
return ratio * 100;
}
/* SAM_LISTING_END_1 */
/* SAM_LISTING_BEGIN_2 */
bool has_zero_column(const MatrixXd &A) {
/*
* Returns 1 if A has a column that is exactly equal to zero.
* Returns 0 otherwise.
*/
bool 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 array to perform entry-wise comparison.
// START
// END
return result;
}
/* SAM_LISTING_END_2 */
/* SAM_LISTING_BEGIN_3 */
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
// END
return B;
}
/* SAM_LISTING_END_3 */
#endif
# Code Expert Generic Project Configuration.
#
# In case this file is omitted, the execution is done with the default values.
# You can either define a cmd or a script file to be executed.
# Default to script file setting a cmd overrides it.
cmd:
# compile: echo "COMPILE"
# run: echo "RUN"
# test: echo "TEST"
# submit: echo "SUBMIT"
# All scripts are set by default to "/scripts/${ACTION}.sh"
script:
compile: /scripts/compile.sh
run: /scripts/run.sh
test: /scripts/test.sh
submit: /scripts/submit.sh
\ No newline at end of file
descriptions:
default:
name: Default
default: true
# Optionally add mulitple versions here.
# Use the file name without the .md extension as key and add a `name:` to it.
\ No newline at end of file
# Tutorial: part 3/3
## Matrix reductions
> Eigen matrices have a range of methods that reduce them to a single number. Suppose A is an Eigen::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.
> The [Eigen::Array class](https://eigen.tuxfamily.org/dox/group__TutorialArrayClass.html) is also featured in this exercise to perform coefficient-wise comparison.
> Open "MatrixReduce.hpp" and fill in the missing code in between the delimiters `// START` and `// END` according to the instructions preceded by `// TO DO:`.
> Read each function of the program carefully. The code will not compile until after the first two tasks are finished, which is to include headers, set the namespace, and write the average() function.
\ No newline at end of file
# Tests of MatrixReduction.hpp
> There are four functions in MatrixReduction.hpp and main.cpp has one test for each function.
***
> `average( MatrixXd A )`: This function should calculate the average of the entries in A.
The test prints `average(Matrix3d::Identity())`, and the correct result is:
```
0.333333
```
***
> `percent_zero( MatrixXd A )`: This function calculates the percentage of entries in A that are exactly equal to zero.
The test prints `percent_zero(Matrix3d::Identity())`, and the correct result is:
```
66.6667
```
***
> `has_zero_column( MatrixXd A )`: This function checks if any one of the columns in A is equal to zero.
The test prints
`has_zero_column(B)` followed by `has_zero_column(B.transpose())` where `B=MatrixXd::Identity(4,5)`, and the correct result is:
```
1 0
```
***
> `columns_sum_to_zero( MatrixXd A )`: This functions returns a copy of A, except that the diagonal entries have been changed in a way such that the columns of the new matrix sum to zero.
The test prints `columns_sum_to_zero(C)` where `C=Matrix3d::Random()+Matrix3d::Constant(1)` (the random seed is fixed), and the correct result is:
```
-0.721194 0.160061 0.561133
0.0929355 -0.989846 0.896911
1.98551 0.159289 -2.1448
```
#include "MatrixReduce.hpp"
#include <iostream>
int main(){
std::cout<< "\nTest of average():\n";
Matrix3d A = Matrix3d::Identity();
std::cout<< average( A ) << "\n\n";
std::cout<< "Test of percent_zero():\n";
std::cout<< percent_zero( A ) << "\n\n";
std::cout<< "Test of has_zero_column():\n";
MatrixXd B = MatrixXd::Identity(4,5);
std::cout<< has_zero_column( B ) << " " << has_zero_column( B.transpose() ) << "\n\n";
std::cout<< "Test of columns_sum_to_zero():\n";
std::srand(5); // So that random behaviour is predictable.
Matrix3d C = Matrix3d::Random() + Matrix3d::Constant(1);
std::cout<< columns_sum_to_zero( C ) << "\n\n";
return 0;
}
#!/bin/bash
echo "Compiling ..."
# compile c code
# find . -iname '*.cpp' | sort | xargs g++ -fdiagnostics-color=always --pedantic -Wextra -Wall -std=c++14 -I/usr/include/python3.7m -llibpython -o bin/a.out || exit 1
# Compiling for 'matplotlibcpp.h'
mkdir -p bin
find . -iname '*.cpp' | sort | xargs \
g++ -fdiagnostics-color=always -std=c++11 \
-I/usr/local/include/python3.7m \
-I/usr/local/lib/python3.7/site-packages/numpy/core/include \
-I/usr/include/eigen3/ \
-lpython3.7m \
-lpthread -lutil -ldl \
-Xlinker -export-dynamic \
-o bin/a.out
echo "Compilation successful"
\ No newline at end of file
#!/bin/bash
export PYTHONIOENCODING="UTF-8"
# compile (call compile script)
bash "${WORKDIR}/scripts/compile.sh"
# run
bin/a.out
\ No newline at end of file
#!/bin/bash
echo "Not implemented"
\ No newline at end of file
#!/bin/bash
# run (call run script)
bash "${WORKDIR}/scripts/run.sh"
\ No newline at end of file
// "testname", "input", "expected output", "points", "execution time limit (ms)"
"average", "(any input)", "0.333333", "1", "5000",
"percent_zero", "(any input)", "66.6667", "1", "5000",
"has_zero_column", "(any input)", "1 0", "1", "5000",
"columns_sum_to_zero", "(any input)", "-0.721194 0.160061 0.561133\n0.0929355 -0.989846 0.896911\n 1.98551 0.159289 -2.1448", "1", "5000",
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment