Zaawansowane CPP/Ćwiczenia 8: Metaprogramowanie: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
m Zastępowanie tekstu – „ \displaystyle ” na „”
m Zastępowanie tekstu – „\displaystyle ” na „”
Linia 3: Linia 3:
Napisz szablon funkcji lub klasy wyliczający  
Napisz szablon funkcji lub klasy wyliczający  
funkcję silnia:
funkcję silnia:
<center><math>\displaystyle
<center><math>
n!=n(n-1)(n-2)\cdots 1
n!=n(n-1)(n-2)\cdots 1
</math></center>
</math></center>
Linia 9: Linia 9:
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
Rozwiązanie jest bezpośrednim zastosowaniem rekurencyjnej definicji funkcji silnia:
Rozwiązanie jest bezpośrednim zastosowaniem rekurencyjnej definicji funkcji silnia:
<center><math>\displaystyle
<center><math>
n!=n*(n-1)!,\quad 0!=1
n!=n*(n-1)!,\quad 0!=1
</math></center>
</math></center>
Linia 26: Linia 26:


Zaimplementuj szablon <code><nowiki>Pow<N,M></nowiki></code> obliczający
Zaimplementuj szablon <code><nowiki>Pow<N,M></nowiki></code> obliczający
<math>\displaystyle N^M</math>. Np.:
<math>N^M</math>. Np.:


  Pow<3,4>::val;
  Pow<3,4>::val;
Linia 34: Linia 34:
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
Implementujemy rekurencyjną definicję potęgi:
Implementujemy rekurencyjną definicję potęgi:
<center><math>\displaystyle
<center><math>
N^M=N*N^{M-1},\quad N^0=1
N^M=N*N^{M-1},\quad N^0=1
</math></center>
</math></center>
Linia 68: Linia 68:
}}
}}
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Podpowiedź</span><div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Podpowiedź</span><div class="mw-collapsible-content" style="display:none">
<center><math>\displaystyle
<center><math>
x^{(2 n)} = (x^2)^n,\quad x^{(2 n+1)} = x (x^2)^n
x^{(2 n)} = (x^2)^n,\quad x^{(2 n+1)} = x (x^2)^n
</math></center>
</math></center>
Linia 75: Linia 75:
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
Do wzoru podanego w podpowiedzi dodajemy warunki brzegowe:
Do wzoru podanego w podpowiedzi dodajemy warunki brzegowe:
<center><math>\displaystyle
<center><math>
x^0=1,\quad x^1=x
x^0=1,\quad x^1=x
</math></center>
</math></center>
Linia 94: Linia 94:
Napisz szablon generujący pierwsze <math>N</math> wyrazów rozwinięcia funkcji
Napisz szablon generujący pierwsze <math>N</math> wyrazów rozwinięcia funkcji
<math>sin(x)</math>:
<math>sin(x)</math>:
<center><math>\displaystyle
<center><math>
sin<</math>N<math>> (x)=x-\frac{x^3}{3!}+\cdots +(-1)^{N+1}\frac{(x)^{2N-1}}{(2N-1)!}
sin<</math>N<math>> (x)=x-\frac{x^3}{3!}+\cdots +(-1)^{N+1}\frac{(x)^{2N-1}}{(2N-1)!}
</math></center>
</math></center>
Linia 101: Linia 101:
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none">
Jak zwykle najpierw piszemy definicję rekurencyjną:
Jak zwykle najpierw piszemy definicję rekurencyjną:
<center><math>\displaystyle
<center><math>
sin<N> (x)=sin<N-1> (x)+(-1)^{N+1}\frac{x^{2N-1}}{(2N-1)!},
sin<N> (x)=sin<N-1> (x)+(-1)^{N+1}\frac{x^{2N-1}}{(2N-1)!},


\displaystyle sin<0> (x)=0
sin<0> (x)=0
</math></center>
</math></center>


Linia 132: Linia 132:


Parametrem szablonu ma być dlugość mnożonych wektorów.  
Parametrem szablonu ma być dlugość mnożonych wektorów.  
<center><math>\displaystyle
<center><math>
\operatorname{inner} </math> <N> <math>\displaystyle  (x,y)=x_1 y_1+\cdots y_N x_N
\operatorname{inner} </math> <N> <math> (x,y)=x_1 y_1+\cdots y_N x_N
</math></center>
</math></center>
}}
}}
Linia 177: Linia 177:
  <nowiki> void matrix_v<N>(double *A,double *v,double *u)</nowiki>
  <nowiki> void matrix_v<N>(double *A,double *v,double *u)</nowiki>


<center><math>\displaystyle \begin{align} u_0&= A_{0,0} v_0+A_{0,1} v_1+\cdots+A_{0,M-1} v_{M-1}\\
<center><math>\begin{align} u_0&= A_{0,0} v_0+A_{0,1} v_1+\cdots+A_{0,M-1} v_{M-1}\\
u_1&= A_{1,0} v_0+A_{1,1} v_1+\cdots+A_{1,M-1} v_{M-1}\\
u_1&= A_{1,0} v_0+A_{1,1} v_1+\cdots+A_{1,M-1} v_{M-1}\\
&\vdots&\\
&\vdots&\\
Linia 183: Linia 183:
\end{align}</math></center>
\end{align}</math></center>


Tablica <math>\displaystyle A</math> jest reprezentowana w pamięci zgodnie z konwencją <math>C</math>, tzn. wiersz po wierszu:
Tablica <math>A</math> jest reprezentowana w pamięci zgodnie z konwencją <math>C</math>, tzn. wiersz po wierszu:
elementowi <math>\displaystyle A_{i,j}</math> odpowiada <math>A[M*i+j]</math>.
elementowi <math>A_{i,j}</math> odpowiada <math>A[M*i+j]</math>.
}}
}}



Wersja z 08:57, 28 sie 2023

Ćwiczenie 1

Napisz szablon funkcji lub klasy wyliczający funkcję silnia:

n!=n(n1)(n2)1
Rozwiązanie

Ćwiczenie 2

Zaimplementuj szablon Pow<N,M> obliczający NM. Np.:

Pow<3,4>::val;

powinno mieć wartość 81.

Rozwiązanie

Ćwiczenie 3

Wymyśl i zaimplementuj jako metaprogram szybszy algorytm funkcji pow(x).

Podpowiedź
Rozwiązanie

Ćwiczenie 4

Napisz szablon generujący pierwsze N wyrazów rozwinięcia funkcji sin(x):

sin<N>(x)=xx33!++(1)N+1(x)2N1(2N1)!

Możesz skorzystać z rozwiązań wcześniejszych zadań.

Rozwiązanie

Ćwiczenie 5

Napisz szablon generujący funkcję implementującą iloczyn skalarny dwu wektorów:

template<size_t N> double inner(double *x, double *y);

Parametrem szablonu ma być dlugość mnożonych wektorów.

inner <N> (x,y)=x1y1+yNxN

Ćwiczenie 6

Rozszerz powyższy szablon tak, aby również typ elementów wektora był parametrem szablonu:

template<size_t N, typename T> T dot(T *x, T *y);
Podpowiedź
Rozwiązanie

Ćwiczenie 7

Napisz szablon generujący funkcję implementującą iloczyn macierzy NxM i wektora o M elementach:

 void matrix_v<N>(double *A,double *v,double *u)
u0=A0,0v0+A0,1v1++A0,M1vM1u1=A1,0v0+A1,1v1++A1,M1vM1uN1=AN1,0v0+AN1,1v1++AN1,M1vM1

Tablica A jest reprezentowana w pamięci zgodnie z konwencją C, tzn. wiersz po wierszu: elementowi Ai,j odpowiada A[M*i+j].

Rozwiązanie