### Remove exercises from index

parent f14eeae2
 #include #include #include #include #include #include using T = double; static const int N = 100; /// Calculate sum_{k=0}^N x[k] using Kahan summation algorithm T kahan(std::vector const& x) { // your implementation here return sum; } /// Calculate sum_{k=0}^N x[k] using standard summation T simple(std::vector const& x) { // your implementation here return sum; } int main() { std::vector x(N); // fill the vector using element access x[i] }
 #include // Return the square-root of a calculated recursively with break condition x0 and recursion depth N /** * Recursion defined by * x_n := x_{n-1} - f(x_{n-1})/f'(x_{n-1}) * with x_0 = x0 * for f(x) = x*x - a and f'(x) = df(x)/dx * * Return the value x_N. **/ double sqrt_recu(double a, double x0, int N) { // your implementation here } // Return the square-root of a calculated iteratively, starting from initial value x0 with N iterations /** * Iteration defined by * x_{n+1} := x_{n} - f(x_{n})/f'(x_{n}) * with x_0 = x0 * for f(x) = x*x - a and f'(x) = df(x)/dx * * Return the value x_N. **/ double sqrt_iter(double a, double x0, int N) { // your implementation here } int main() { // test for a=10, x0=3, and N={5,10,100} // compare against std::sqrt } \ No newline at end of file
 int bicgstab_ell(const LinearOperator &A, Vector &x, const Vector &b, const LeftPreconditioner &L, RightPreconditioner const& R, Iteration& iter, size_t l) { using mtl::size; using mtl::irange; using mtl::imax; using mtl::mat::strict_upper; typedef typename mtl::Collection::value_type Scalar; typedef typename mtl::Collection::size_type Size; if (size(b) == 0) throw mtl::logic_error("empty rhs vector"); const Scalar zero= math::zero(Scalar()), one= math::one(Scalar()); Vector x0(resource(x)), y(resource(x)); mtl::dense_vector r_hat(l+1,Vector(resource(x))), u_hat(l+1,Vector(resource(x))); // shift problem x0= zero; r_hat= b; if(two_norm(x)!=zero){r_hat-= A * x;x0= x;x= zero;} Vector r0_tilde(r_hat/two_norm(r_hat)); y= solve(L, r_hat); r_hat= y; u_hat= zero; Scalar rho_0(one), rho_1(zero), alpha(zero), Gamma(zero), beta(zero), omega(one); mtl::mat::dense2D tau(l+1, l+1); mtl::dense_vector sigma(l+1), gamma(l+1), gamma_a(l+1), gamma_aa(l+1); while (! iter.finished(r_hat)) { ++iter; rho_0= -omega * rho_0; for (Size j= 0; j < l; ++j) { rho_1= dot(r0_tilde, r_hat[j]); beta= alpha * rho_1/rho_0; rho_0= rho_1; for(Size i= 0; i <= j; ++i) u_hat[i]= r_hat[i] - beta * u_hat[i]; y= A * Vector(solve(R, u_hat[j])); u_hat[j+1]= solve(L, y); Gamma= dot(r0_tilde, u_hat[j+1]);alpha= rho_0 / Gamma; for (Size i= 0; i <= j; ++i) r_hat[i]-= alpha * u_hat[i+1]; if (iter.finished(r_hat[j])) {x= solve(R, x);x+= x0;return iter;} r_hat[j+1]= solve(R, r_hat[j]); y= A * r_hat[j+1]; r_hat[j+1]= solve(L, y); x+= alpha * u_hat; } // mod GS (MR part) irange i1m(1, imax); mtl::dense_vector r_hat_tail(r_hat[i1m]); tau[i1m][i1m]= orthogonalize_factors(r_hat_tail); for (Size j= 1; j <= l; ++j) gamma_a[j]= dot(r_hat[j], r_hat) / tau[j][j]; gamma[l]= gamma_a[l]; omega= gamma[l]; if (omega == zero) return iter.fail(3, "bicg breakdown #2"); // is this something like a tri-solve? for (Size j= l-1; j > 0; --j) { Scalar sum= zero; for (Size i=j+1;i<=l;++i) sum += tau[j][i] * gamma[i]; gamma[j] = gamma_a[j] - sum;} gamma_aa[irange(1, l)]= strict_upper(tau[irange(1,l)][irange(1,l)])*gamma[irange(2,l+1)]+gamma[irange(2,l+1)]; x+= gamma * r_hat; r_hat-= gamma_a[l]*r_hat[l]; u_hat-= gamma[l]*u_hat[l]; for(Size j=1;j
 #include #include // function template returning the identity element of type T template T identity(); // function template returning a random element of type T template T random(); // a + b can be assigned to a type T template bool test_closure(T const& a, T const& b) { T c{ a + b }; // construction from a + b c = a + b; // assignment to T return true; } // for all a,b,c the associativity law holds template bool test_associativity(T const& a, T const& b, T const& c) { return (a + b) + c == a + (b + c); } // the order of the operands can be interchanged template bool test_commutativity(T const& a, T const& b) { return a + b == b + a; } // there exists an identity element template bool test_identity(T const& a) { T e{ identity() }; return (e + a == a) && (a + e == a); } // for all elements a there exists an inverse element -a template bool test_inverse(T const& a) { T inv_a{ -a }; T e{ identity() }; return (a + inv_a == e) && (inv_a + a == e); } template bool test() { bool has_closure = true; bool has_associativity = true; bool has_commutativity = true; bool has_identity = true; bool has_inverse = true; // run a test with random data 100 times for (int i = 0; i < 100; ++i) { T a{ random() }; T b{ random() }; T c{ random() }; has_closure = has_closure && test_closure(a,b); has_associativity = has_associativity && test_associativity(a,b,c); has_commutativity = has_commutativity && test_commutativity(a,b); has_identity = has_identity && test_identity(a); has_inverse = has_inverse && test_inverse(a); } std::cout << "The type T=" << typeid(T).name() << " has the following properties:" << std::endl; std::cout << " closure: " << has_closure << std::endl; std::cout << " associativity: " << has_associativity << std::endl; std::cout << " commutativity: " << has_commutativity << std::endl; std::cout << " identity: " << has_identity << std::endl; std::cout << " inverse: " << has_inverse << std::endl; return has_associativity && has_closure && has_inverse && has_identity && has_commutativity; }
 ... ... @@ -86,8 +86,8 @@ and "Todos" tabs, and the "Wiki" tab. If and how you use these features is up to - [Git reference](https://www.git-scm.com/docs) - [cheat sheet](https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf) ## Exercise 2 (Compiling code) ## Exercise 2 (Compiling code) In the directory [material/sheet1/](/exercises/material/sheet1) you can find an initial C++ example in the files linear_algebra.cc, linear_algebra.h, and exercise2.cc. Download the files and compile the code: ... ...
 # Exercise sheet 2 ## Exercise 1 (Floating-point numbers) 1. What is the difference between float and double? 2. Assume the following program needs 1 second to run: c++ int main() { double x = 1.0e8; while (x > 0) { --x; } }  How long would it run if you replace double by float? Why? 3. Look at the following code example: c++ #include int main() { using T = float; // a type-alias T a = 0.15 + 0.15; T b = 0.1 + 0.2; assert(a == b); assert(a >= b); }  where assert is a macro resulting in an error if the argument evaluates to false. What is the effect of the program? What happens if we change float to double? Why? ### Resources - https://en.wikipedia.org/wiki/Floating-point_arithmetic - https://en.wikipedia.org/wiki/IEEE_754 ## Exercise 3 (Control structures) Get familiar with control structures in C++, i.e. if, else, for, do, while, switch, case. 1. Rewrite the following while-loop by a for-loop: c++ int log10 = 0; double num = 12345.0; while (num >= 10.0) { num /= 10.0; ++log10; }  2. What is the error in the following statements? i. c++ for (int j = 0, j < 10, ++j) std::cout << j;  ii. c++ int n, sum = 0; do { std::cin >> n; sum += n; } while (n > 0)  iii. c++ int n = 2, m; while (n < 10) m *= n, ++n;  iv. c++ unsigned long n = 0; int cnt = 1; do n += cnt; cnt++; while (n < 100);  3. Write a C++-program that calculates and prints the sum of the first $n$ positive integers, i.e. math 1^2 + 2^2 + 3^2 + 4^2 + ... + n^2  while a positive integer is read from the keyboard. Use the standard stream operator std::cin >> ... and std::cout << ... from  for reading and writing. ### Resources - [if-then-else](https://en.cppreference.com/w/cpp/language/if), [switch-case](https://en.cppreference.com/w/cpp/language/switch), [for-loop](https://en.cppreference.com/w/cpp/language/for), [while-loop](https://en.cppreference.com/w/cpp/language/while), [do-while-loop](https://en.cppreference.com/w/cpp/language/do) - [std::cout](https://en.cppreference.com/w/cpp/io/cout), [std::cin](https://en.cppreference.com/w/cpp/io/cin) ## Exercise 4 (Kahan Summation Formula) Calculate the sum $\sum_{j=0}^{N-1} x_j$ for a given set of values $\{x_j\}$ using the following algorithm:  S = x_0 C = 0 for j = 1,..., N-1 do Y = x_j - C T = S + Y C = (T - S) - Y S = T  What is the difference to a classical summation algorithm? 1. Create a std::vector with 100 float/double values: $x_k := \bar{x}^k/(k!)$ with $\bar{x} = 7$. 2. Sum up these values using the Kahan-algorithm and a simple summation, with internal value format float/double. 3. Compare the result of the summation of floats to doubles and compare to the function std::exp from . 4. Compile your program with - g++ -std=c++11 SOURCE.cc - g++ -std=c++11 -O3 -ffast-math SOURCE.cc - clang++ -std=c++11 SOURCE.cc - clang++ -std=c++11 -O3 -ffast-math SOURCE.cc What is the difference, if any? Why is there a difference in the output? 5. Try again, but reverse the order of the entries of the vector, i.e. c++ #include ... std::reverse(x.begin(), x.end());  6. Try again, but first randomly shuffle the entries of the vector, i.e. c++ #include #include ... std::srand(12345); // fixed initial seed std::random_shuffle(x.begin(), x.end(), [](int n) { return std::rand() % n; });  ### Note For a comparison of the computations, print the value with maximal precision to std::cout, i.e. c++ #include #include ... std::cout << std::setprecision(std::numeric_limits::max_digits10) << SUM << std::endl;  where T is a placeholder for the type that is used, and SUM for the value calculated. ### Material - [material/sheet2/exercise4.cc](/exercises/material/sheet2/exercise4.cc) ### Resources - [Kahan Summation](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) - [std::vector](https://en.cppreference.com/w/cpp/container/vector), [std::exp](http://en.cppreference.com/w/cpp/numeric/math/exp) - [Optimization options](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html), [fast-math](http://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually-do) ## Exercise 5 (GotW-86: Slight typos) See [GotW #86](http://www.gotw.ca/gotw/086.htm). Answer the following question without using a compiler. What is the output of the following program on a standards-conforming C++ compiler? c++ #include #include int main() { int x = 1; for( int i = 0; i < 100; ++i ); // What will the next line do? Increment???????????/ ++x; std::cout << x << std::endl; }  \ No newline at end of file
 # Exercise sheet 3 ## Exercise 1 (Literals) What is the type of the following literals c++ (a) 2L (d) 1.23456f (g) 0302 (b) '\101' (e) 100UL (h) .1e-5 (c) 0x10 (f) 1.2345678 (i) 0xFL  ### Hints To check the type, you can use decltype and static_assert: c++ #include // ... static_assert(std::is_same::value, "Wrong type");  (You have to compile this code with -std=c++11 flag) ### Resources - [cppreference:literals](https://en.cppreference.com/w/cpp/language/expressions#Literals) ## Exercise 2 (Variable declaration) What is the error in the following variable definitions? c++ (a) int n, int i; (c) double side length; (e) Short min(0); (b) int m; double result{.5} (d) char c['a']; (f) double slow_down = "1.E-4";  ## Exercise 3 (Operators) What is the meaning of the following arithmetic expressions? To illustrate which sub-expression is evaluated first, add brackets! c++ (a) x / y * z (g) z-y-x?x+y+z:x-y-z (b) x * y++ / -z (h) z<>y (c) x^2 + y^2 (i) z>>x< 0$you can use the Newton-method, by getting the root (zero-point) of the function$f(x)$, defined by: math f(x) := x^2 - a,  i.e.,$f(x) = 0 \Leftrightarrow |x|=\sqrt{a}$. The Newton-method introduces an iteration$x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}$starting from some initial value$x_0$. This calculation rule can be interpreted as a recursion in the sense: math T: x\mapsto x - f(x)/f'(x),\quad T(x_n) = T(T(x_{n-1})),\; x_0 = \text{\texttt{x0}}  or it can be interpreted as in iteration starting from$x_0$and iteratively calculating the next value. Implement the functions c++ double sqrt_recu(double a, double x0, int N); // returns x_N double sqrt_iter(double a, double x0, int N); // returns x_N  by realizing this code _recursively_ and _iteratively_. Use x0 as recursion break condition or initial value$x_0$and return the value x_N as your approximation of the square-root of a. Try your code with a recursion depth of$N=5, 10, 100$for$a=10$and initial value$x_0=3$. How to check the error you have made? How to choose the initial value x0 and the iteration count N? How would you design your implementation double sqrt(double a) of a square-root function and which version of the implementation above would you choose? ### Notes and additional questions: - You can use the std::sqrt function from  as a comparison. - (optional) Measure the time of your implementation and compare it against the time of the std::sqrt implementation. Therefore, either use the Timer in the lecture material folder, or user the Google micro benchmarking suite: https://github.com/google/benchmark - (optional) What happens if your change your type from double to float. Do you see any difference in accuracy and performance? ### Material - [material/sheet3/exercise4.cc](/exercises/material/sheet3/exercise4.cc) ### Resources - [std::sin](https://en.cppreference.com/w/cpp/numeric/math/sin) ## Exercise 5 (GotW-78: Operators, Operators Everywhere) See [GotW #78](http://www.gotw.ca/gotw/078.htm). 1. What is the greatest number of plus signs (+) that can appear consecutively, without whitespace, in a valid C++-program? *Note:* Of course, plus signs in comments, preprocessor directives and macros, and literals don't count. That would be too easy. 2. **Guru Question**: Similarly, what is the greatest number of each the following characters that can appear consecutively, without whitespace, outside comments in a valid C++-program? - &, - <, - |. For example, the code if( a && b ) trivially demonstrates two consecutive & characters in a valid C++-program.  # Exercise sheet 4 ## Exercise 1 (Work with references and constants) *References* are aliases to existing objects or functions. In contrast to pointers, references are not just addresses, but refer to the data behind that addresses. They can be used like regular variables and are declared with the symbol &: c++ TYPE & VARNAME = OBJECT;  So, the reference variable VARNAME now binds to the aliased object OBJECT. References must be initialized directly and are always bound to one object. A data-type with the qualifier const is called a *constant* and is immutable. It can be declared as c++ TYPE const VARNAME = VALUE;  Constants can not be modified and thus must be initialized directly. 1. Write a function foo(...) that gets one argument, either - double value - double const value - double reference, - double const reference, Change the value of the referenced data inside the function. Is it always possible? 2. Define functions f(char), g(char&), and h(char const&). Call them with the arguments 'a', 49, 3300, c, uc, and sc, where c is a char, uc is an unsigned char, and sc is a signed char variable. Which calls are legal? Which calls cause the compiler to introduce a *temporary variable*? ### Resources - [cppreference:reference](https://en.cppreference.com/w/cpp/language/reference), [cppreference:const](https://en.cppreference.com/w/cpp/language/cv) - [Guidelines](https://www.modernescpp.com/index.php/c-core-guidelines-how-to-pass-function-parameters) - [const-correctness](https://isocpp.org/wiki/faq/const-correctness) ## Exercise 2 (Structs) A struct in C++ is one type of class encapsulating data and methods that act on this data. The most simple structs are those just containing data. In this sense a struct is a compound data-type. Each data-type has a size in memory. This can be evaluated with sizeof(TYPE) or sizeof(EXPRESSION). The actual total size of the data-type might depend on its members and the order of its members. 1. Define a struct with a member of each of the types bool, char, int, long, double, and long double. Order the members so as to get the largest size of the struct and the smallest size of the struct. 2. What is the size of an empty struct without any member variables? Why? ### Note - While you might get different sizes of the struct type when reordering the members, this saving seems to be small, but when you allocate a vector of that many of these types, you might end up with large memory savings. - But be aware of the fact, that the order of members does not only affect the memory size, but also the read and write performance when accessing the members. See the blog post of Jonas Devlieghere from below. ### Resources - [cppreference:class](https://en.cppreference.com/w/cpp/language/class) - https://jonasdevlieghere.com/order-your-members/ ## Exercise 3 (Code formatting) It is recommended to follow some code style guidelines. Be consistent with naming, indentation, brackets, etc. This is not for the compiler. A program can read any valid source code. But it is for you now, for your coworkers or for you in the future when you reopen some old code. Style your code consistently from the first line. A minimal guideline is given in the README. But there is more. And there are different common styles. Sometimes you get code from someone else and need to read/understand it. A good starting point is to transform the code to your code style. This can be automated. In material/sheet4/exercise3.cc you can find a horribly complicated unreadable code. Reformat it, using some tools: - [clang-format](https://clang.llvm.org/docs/ClangFormat.html) - [astyle](http://astyle.sourceforge.net/) - [uncrustify](http://uncrustify.sourceforge.net/) ### Resources - [Google code style](https://google.github.io/styleguide/cppguide.html), - [Indentation styles](https://en.wikipedia.org/wiki/Indentation_style) - [Cpp Core guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md) ## Exercise 4 (Rational numbers) Write a class for rational numbers. The number should always be represented as *fully reduced fraction* of the form math \frac{\text{numerator}}{\text{denominator}}  with$\text{denominator} > 0\$. 1. What is an appropriate data structure for rational numbers? 2. Start by writing a function int gcd(int,int) (greatest common devisor), you will need it to reduce fractions