Für Vorlesungen, bitte die Webseite verwenden. https://flavigny.de/lecture
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

332 lines
9.6KB

  1. \documentclass[uebung]{../../../lecture}
  2. \title{IPI: Übungsblatt 11}
  3. \author{Samuel Weidemaier, Christian Merten}
  4. \begin{document}
  5. \begin{tabular}{|c|m{1cm}|m{1cm}|m{1cm}|m{1cm}|@{}m{0cm}@{}}
  6. \hline
  7. Aufgabe & \centering A1 & \centering A2 & \centering A3 & \centering $\sum$ & \\[5mm] \hline
  8. Punkte & & & & & \\[5mm] \hline
  9. \end{tabular}
  10. \begin{aufgabe}
  11. Polynomschablone. Die vorgegebene Implementation der \lstinline{SimpleArray} Klasse
  12. ist in \textit{simplearray.cc} zu finden. In \textit{polynomial.cc} befindet
  13. sich die Implementation der verallgemeinerten \lstinline{Polynomial} Klasse.
  14. \begin{lstlisting}[language=C++, captionpos=b, title=polynomial.cc]
  15. #include <iostream>
  16. #include <stdio.h>
  17. #include "simplearray.cc"
  18. template <class T>
  19. class Polynomial: public SimpleArray<T> {
  20. public:
  21. // konstruiere Polynom vom Grad n
  22. Polynomial<T> (int n);
  23. // Default-Destruktor ist ok
  24. // Default-Copy-Konstruktor ist ok
  25. // Default-Zuweisung ist ok
  26. // Grad des Polynoms
  27. int degree();
  28. // Auswertung
  29. T eval (T x);
  30. // Addition von Polynomen
  31. Polynomial<T> operator+ (Polynomial<T> q);
  32. // Multiplikation von Polynomen
  33. Polynomial<T> operator* (Polynomial<T> q);
  34. // Gleichheit
  35. bool operator== (Polynomial q);
  36. // drucke Polynom
  37. void print ();
  38. };
  39. // Constructor
  40. template <class T>
  41. Polynomial<T>::Polynomial(int n)
  42. : SimpleArray<T>::SimpleArray(n+1,0.0) {}
  43. // Grad auswerten
  44. template <class T>
  45. int Polynomial<T>::degree ()
  46. {
  47. return SimpleArray<T>::maxIndex();
  48. }
  49. // Addition von Polynomen
  50. template <class T>
  51. Polynomial<T> Polynomial<T>::operator+ (Polynomial<T> q) {
  52. int nr=degree(); // mein grad
  53. if (q.degree()>nr) nr=q.degree();
  54. Polynomial r(nr); // Ergebnispolynom
  55. for (int i=0; i<=nr; i=i+1)
  56. {
  57. if (i<=degree())
  58. r[i] = r[i]+(*this)[i]; // add me to r
  59. if (i<=q.degree())
  60. r[i] = r[i]+q[i]; // add q to r
  61. }
  62. return r;
  63. }
  64. // Multiplikation von Polynomen
  65. template <class T>
  66. Polynomial<T> Polynomial<T>::operator* (Polynomial<T> q)
  67. {
  68. Polynomial r(degree()+q.degree()); // Ergebnispolynom
  69. for (int i=0; i<=degree(); i=i+1)
  70. for (int j=0; j<=q.degree(); j=j+1)
  71. r[i+j] = r[i+j] + (*this)[i]*q[j];
  72. return r;
  73. }
  74. // Drucken
  75. template <class T>
  76. void Polynomial<T>::print ()
  77. {
  78. if (degree()<0)
  79. std::cout << 0;
  80. else
  81. std::cout << (*this)[0];
  82. for (int i=1; i<=SimpleArray<T>::maxIndex(); i=i+1)
  83. std::cout << " + " << (*this)[i] << "*x^" << i;
  84. std::cout << std::endl;
  85. }
  86. int main() {
  87. Polynomial<float> p(2);
  88. p[0] = 1.0;
  89. p[1] = 1.0;
  90. p.print();
  91. p = p*p;
  92. p.print();
  93. Polynomial<double> q(3);
  94. q[0] = 2.0;
  95. q[1] = -1.0;
  96. q[3] = 4.0;
  97. q.print();
  98. }\end{lstlisting}
  99. \end{aufgabe}
  100. \begin{aufgabe}
  101. Vektorimplementation
  102. \begin{lstlisting}[language=C++, captionpos=b, title=vectors.cc]
  103. #include <iostream>
  104. #include <vector>
  105. #include <algorithm>
  106. #include <numeric>
  107. // a class implementing a mathematical vector
  108. template <class K, size_t N>
  109. class Vector {
  110. public:
  111. // constructor, initializes vector with zeroes of length N
  112. Vector() : _vector(N, 0) {}
  113. // initialize by passing vector vec to initialize the vector object with
  114. Vector(std::vector<K> vec) { _vector = vec; }
  115. // copy constructor, assignment, destructor not needed
  116. // all handled by std::vector
  117. // reference [] operator, used for assignments
  118. K& operator[](int i) {
  119. return _vector[i];
  120. }
  121. // const ref [] operator
  122. K operator[](int i) const {
  123. return _vector[i];
  124. }
  125. // return an iterator pointing to the first element of the underlying std::vector
  126. typename std::vector<K>::const_iterator begin() const {
  127. return _vector.begin();
  128. }
  129. // return an iterator pointing to the last element of the underlying std::vector
  130. typename std::vector<K>::const_iterator end() const {
  131. return _vector.end();
  132. }
  133. // dot product of two vectors of the same length
  134. template <class K2>
  135. K operator*(const Vector<K2,N>& y) {
  136. std::vector<K> result(N); // new empty std::vector of correct size
  137. // now multiply one element of the first with one of the second vector
  138. std::transform(_vector.begin(), _vector.end(), y.begin(), result.begin(), std::multiplies<K>());
  139. // and sum up the products
  140. return std::accumulate(result.begin(), result.end(), 0);
  141. }
  142. // vector addition
  143. template <class K2>
  144. Vector<K, N> operator+(const Vector<K2, N>& y) {
  145. std::vector<K> result(N); // new empty std::vector of correct size
  146. // add elements by adding one element of the first to one of the second vector
  147. std::transform(_vector.begin(), _vector.end(), y.begin(), result.begin(), std::plus<K>());
  148. return Vector(result);
  149. }
  150. // return the maximum value in the vector
  151. K max() {
  152. return *std::max_element(_vector.begin(), _vector.end());
  153. }
  154. // return the minimum value in the vector
  155. K min() {
  156. return *std::min_element(_vector.begin(), _vector.end());
  157. }
  158. // return the average value of the vector
  159. K average() {
  160. // sum up all elements
  161. K sum = std::accumulate(_vector.begin(), _vector.end(), 0);
  162. return sum / N; // and divide by length
  163. }
  164. // run the specified function on each vector element
  165. template <class F>
  166. Vector<K,N> map(F op) const {
  167. std::vector<K> result(N); // initialize new std::vector of correct size
  168. // run op on each element
  169. std::transform(_vector.begin(), _vector.end(), result.begin(), op);
  170. return Vector(result);
  171. }
  172. private:
  173. std::vector<K> _vector; // the private std::vector container
  174. };
  175. // print vector
  176. template <class K, size_t N>
  177. std::ostream& operator<<(std::ostream& os, const Vector<K,N>& v) {
  178. os << "["; // opening brackets
  179. for (size_t i = 0; i < N; i++) {
  180. os << v[i]; // print element
  181. if(i < N-1) {
  182. os << ", "; // if not the last one, add comma
  183. }
  184. }
  185. os << "]"; // closing brackets
  186. return os;
  187. }
  188. // scalar multiplication for vector * scalar
  189. template <class K, size_t N, class K2>
  190. Vector<K, N> operator*(const Vector<K,N>& v, const K2 k) {
  191. // multiply a scalar value using the generic map function
  192. return v.map(std::bind1st(std::multiplies<K>(), k));
  193. }
  194. // scalar multiplication for scalar * vector
  195. template <class K, size_t N, class K2>
  196. Vector<K, N> operator*(const K2 k, const Vector<K,N>& v) {
  197. return v * k;
  198. }
  199. // example function
  200. double foo(double val) {
  201. return val*2+3;
  202. }
  203. // testing out functionalities
  204. int main() {
  205. Vector<double, 3> a;
  206. Vector<float, 3> b;
  207. a[0] = 0;
  208. a[1] = 0;
  209. a[2] = 4;
  210. b[0] = 42;
  211. b[1] = -20;
  212. b[2] = 3;
  213. std::cout << "Vektor a: " << a << ", Vektor b: " << b << std::endl;
  214. std::cout << "a+b: " << a+b << std::endl;
  215. std::cout << "a*b: " << a*b << std::endl;
  216. std::cout << "42*b: " << 42*b << std::endl;
  217. std::cout << "b*42: " << b*42 << std::endl;
  218. std::cout << "max(a): " << a.max() << std::endl;
  219. std::cout << "min(a): " << a.min() << std::endl;
  220. std::cout << "mean(a): " << a.average() << std::endl;
  221. std::cout << "foo angewendet auf b: " << b.map(foo) << std::endl;
  222. }\end{lstlisting}
  223. \end{aufgabe}
  224. \begin{aufgabe}[Funktoren und statischer Polymorphismus]
  225. \begin{enumerate}[(a)]
  226. \item Integration mittels Trapezregel
  227. für $n = 10$, $n = 100$ und $n = 1000$ beispielsweise ausgerechnet.
  228. \begin{lstlisting}[language=C++, captionpos=b, title=integration.cc]
  229. #include <iostream>
  230. #include <cmath>
  231. // Implementiert die Trapezregel mit der Intervallanzahl n
  232. // der unteren Integrationsgrenze a, der oberen Integrationsgrenze b
  233. // und ueber die Funktion f
  234. template <class Function>
  235. double trapezregel(int n, double a, double b, Function f) {
  236. double h = (b-a)/n; // berechne intervalllaenge
  237. double accum = 0;
  238. for (int i = 1; i < n; i++) {
  239. accum += f(a + i*h); // fuehre die summe aus
  240. }
  241. return h/2 * (f(a) + 2*accum + f(b)); // wende formel an
  242. }
  243. // beispiel fuer funktor
  244. class Wurzel {
  245. public:
  246. double operator()(double x) {
  247. return std::sqrt(x);
  248. }
  249. };
  250. int main() {
  251. Wurzel f;
  252. // fuehre integration fuer verschiedene Intervallanzahlen n aus
  253. double integ10 = trapezregel(10, 0, 1.5, f);
  254. double integ100 = trapezregel(100, 0, 1.5, f);
  255. double integ1000 = trapezregel(1000, 0, 1.5, f);
  256. std::cout << "Integral ueber sqrt(x) von 0 bis 1.5" << std::endl;
  257. std::cout << "n = 10: " << integ10 << std::endl;
  258. std::cout << "n = 100: " << integ100 << std::endl;
  259. std::cout << "n = 1000: " << integ1000 << std::endl;
  260. }\end{lstlisting}
  261. \item Vorteile der Verwendung von statischem Polymorphismus gegenüber dynamischem Polymorphismus:
  262. \begin{itemize}
  263. \item Auswertung zum Zeitpunkt des Kompilierens führt zu besserer Optimierung und
  264. Fehlererkennung durch den Compiler.
  265. \item Weniger Overhead durch VTABLE's, etc.
  266. \item Deshalb effizienter und schneller
  267. \end{itemize}
  268. Nachteile:
  269. \begin{itemize}
  270. \item Potentiell unübersichtlicher
  271. \item Größe der Programme als kompilierte Binärdatei ist größer
  272. \end{itemize}
  273. \end{enumerate}
  274. \end{aufgabe}
  275. \end{document}