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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Mirek (dyskusja | edycje)
Nie podano opisu zmian
Mirek (dyskusja | edycje)
Nie podano opisu zmian
Linia 87: Linia 87:
  template<> double pow<0>(double x) {return 1.0;};
  template<> double pow<0>(double x) {return 1.0;};


Patrz plik [http://osilek.mimuw.edu.pl/images/9/9c/Pown.h powx.h].
Patrz plik [http://osilek.mimuw.edu.pl/images/e/e1/Powx.h powx.h].
</div></div>
</div></div>


Linia 99: Linia 99:
Możesz skorzystać z rozwiązań wcześniejszych zadań.
Możesz skorzystać z rozwiązań wcześniejszych zadań.
}}
}}
<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ą:
<center><math>\displaystyle
\sin</math> <N> <math> \displaystyle  (x)=\sin</math> <N-1> <math> \displaystyle  (x) + x-\frac{x^3}{3!}+\cdots +(-1)^{N+1}\frac{(x)^{2N-1}}{(2N-1)!}
</math></center>
template<size_t N,size_t M> struct pow {
    enum {val=N*pow<N,M-1>::val};
};<br>
template<size_t N> struct pow<N,0> {
    enum {val=1};
};
Dla przyspieszenia dodajemy dwie specjalizacje:
template<size_t M> struct pow<1,M>{
    enum {val=1};
};<br>
template<size_t M> struct pow<0,M>{
    enum {val=0};
};
Powyższa specjalizacja spowoduje, że konkretyzacja <tt>Pow<0,0></tt> będzie niejednoznaczna. Możemy to tak zostawić, bo <math>0^0</math> jest nieokreślone. Jeśli jednak zdecydujemy się na jakąś wartość, np. zero, to należy dodać jeszcze jedną specjalizację:
template<> struct pow<0,0>{
    enum {val=0};
};
Patrz plik [http://osilek.mimuw.edu.pl/images/9/9c/Pown.h pown.h].
</div></div>
{{cwiczenie|5||  
{{cwiczenie|5||  



Wersja z 11:08, 21 wrz 2006

Ć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ź

Ć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)
Parser nie mógł rozpoznać (nieznana funkcja „\aligned”): {\displaystyle \displaystyle \aligned 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}\\ &\vdots&\\ u_{N-1}&= A_{N-1,0} v_0+A_{N-1,1} v_1+\cdots+A_{N-1,M-1} v_{M-1}\\ \endaligned}

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