Partiel Informatique de Base / MM009 Master Mathématiques UPMC

Transcription

Partiel Informatique de Base / MM009 Master Mathématiques UPMC
Partiel Informatique de Base / MM009
Master Mathématiques UPMC
Les documents sont autorisés
F. Hecht, D. Bernardi et N. Seguin
26 Octobre 2010
Rappel: Il faut répondre aux questions (pas plus) et respecter les notations du SUJET.
Le but de ce partiel est d’améliorer la classe poly expliquée et créée par D. Bernardi dans le fichier
polys1.cpp.
Le programme de D. Bernardi a été découpé en trois parties :
Le fichier Poly.hpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
typedef double Reel;
class Poly {
static const int chunk = 10;
int n;
int nmax;
Reel *v;
public:
Poly () : n(0), nmax(chunk), v(new Reel [chunk]) {};
Poly& operator= (const Poly&);
Reel& operator[] (int i);
Poly& operator+= (const Poly&);
friend Poly operator* (const Poly&, const Poly&);
friend std::ostream& operator<< (std::ostream& s, const Poly& p);
˜Poly () {delete [] v;}
}
Poly operator+ (const Poly& p, const Poly &q);
Poly operator* (const Poly& p, const Poly& q);
std::ostream& operator<< (std::ostream& s, const Poly & p);
Le fichier Poly.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
#include <cstdlib>
#include <iostream>
using namespace std;
#include "Poly.hpp"
Poly& Poly::operator= (const Poly& t)
{
if (v != t.v)
{
delete [] v;
n = t.n;
nmax = t.nmax;
v = new Reel[nmax];
for (int i = 0; i < n; i++)
v[i] = t.v[i];
}
return *this;
}
Reel& Poly::operator[] (int j)
1
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
{
while (j >= nmax)
{
nmax += 2;
Reel *w = new Reel [nmax];
for (int i = 0; i < n; i++)
w[i] = v[i];
delete[] v;
v = w;
}
while (n <= j)
v[n++] = 0;
return v[j];
}
Poly& Poly::operator+= (const Poly& p)
{
for (int i = 0; i<p.n; i++)
(*this)[i] += p.v[i];
return *this;
}
Poly operator+ (const Poly& p, const Poly &q)
{
Poly r(p);
return r += q;
}
Poly operator* (const Poly& p, const Poly& q)
{
Poly r;
for (int i = 0; i < p.n; i++)
for (int j = 0; j < q.n; j++)
r[i+j] += p.v[i] * q.v[j];
return r;
}
ostream& operator<< (ostream& s, const Poly & p)
{
s << ’[’;
for (int i = 0; i < p.n; i++)
{
if (i) s << ", ";
s << p.v[i];
}
return s << ’]’;
}
le fichier testPoly.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
#include <cstdlib>
#include <iostream>
#include <time.h>
#include "Poly.hpp"
int main (int argc, char *argv[])
{
int n = argc > 1 ? atoi( argv[1] ): 0;
Poly p;
long t0=clock(),t1;
for (int i = 0; i < n; i++)
p[i] = i;
cout << " construction " << (t1=clock())-t0 << " " <<"s/" << CLOCKS_PER_SEC<< endl;
Poly q=p;
if (n <= 100)
{
cout << p << endl;
2
18
19
20
21
22
23
24
:
cout << p + p << endl;
:
cout << p*p << endl;
:
}
:
else
:
cout << (p*p)[n] << endl;
:
cout << " p*p
" << (clock())-t1 << " " <<"s/" << CLOCKS_PER_SEC<< endl;
: return 0;}
Q1) Lors de la retranscription de la classe, des erreurs ce sont glissées. Corriger les erreurs de syntaxe, de
frappe et les oublis.
Voilà les résultats de la compilation:
picasso:2011-3 hecht$ make -k
g++ -Wall
-c -o testPoly.o testPoly.cpp
In file included from testPoly.cpp:5:
Poly.hpp:17: error: expected initializer before ’operator’
testPoly.cpp: In function ’int main(int, char**)’:
testPoly.cpp:13: error: ’cout’ was not declared in this scope
testPoly.cpp:13: error: ’endl’ was not declared in this scope
testPoly.cpp:18: error: no match for ’operator+’ in ’p + p’
make: *** [testPoly.o] Error 1
g++ -Wall
-c -o Poly.o Poly.cpp
In file included from Poly.cpp:5:
Poly.hpp:17: error: expected initializer before ’operator’
make: *** [Poly.o] Error 1
make: Target ‘all’ not remade because of errors.
picasso:2011-3 hecht$
Q2) Apres la première vague de correction, la recompilation avec d’autres drapeaux de compilation et
l’exécution donnent sur mon ordinateur:
picasso:2011-2 hecht$ make
g++ -Wall -Weffc++
polys1.cpp
-o polys1
g++ -Wall -Weffc++
-c -o testPoly.o testPoly.cpp
In file included from testPoly.cpp:5:
Poly.hpp:2: warning: ’class Poly’ has pointer data members
Poly.hpp:2: warning:
but does not override ’Poly(const Poly&)’
g++ -Wall -Weffc++
-c -o Poly.o Poly.cpp
In file included from Poly.cpp:5:
Poly.hpp:2: warning: ’class Poly’ has pointer data members
Poly.hpp:2: warning:
but does not override ’Poly(const Poly&)’
g++ -o testPoly testPoly.o Poly.o
picasso:2011-2 hecht$ ./testPoly 1000
construction 1206 s/1000000
1.66666e+08
p*p
17077 s/1000000
testPoly(3574) malloc: *** error for object 0x7fbbbb803e00: pointer being freed was not
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
picasso:2011-2 hecht$
Expliquer les problèmes.
Q3) Écrire le code C++ manquant afin de corriger le problème lié à la question précédente.
Après correction on a
P
Q4) La construction du polynôme ni=0 ixi de D. Bernardi dans le programme polys1 est en O(n log n)
mais notre modification est en O(n2 ) comme le montrent les sorties
3
picasso:2011-1 hecht$
# ./polys1 2048
construction 90 s/1000000
1.43166e+09
p*p
58548 s/1000000
# ./polys1 4096
construction 132 s/1000000
1.14532e+10
p*p
223084 s/1000000
# ./polys1 8192
construction 220 s/1000000
9.1626e+10
p*p
884504 s/1000000
# ./polys1 16384
construction 467 s/1000000
7.33008e+11
p*p
3508245 s/1000000
picasso:2011-1 hecht$
# ./testPoly 2048
construction 4574 s/1000000
1.43166e+09
p*p
82044 s/1000000
# ./testPoly 4096
construction 18940 s/1000000
1.14532e+10
p*p
329566 s/1000000
# ./testPoly 8192
construction 80628 s/1000000
9.1626e+10
p*p
1324566 s/1000000
# ./testPoly 16384
construction 325451 s/1000000
7.33008e+11
p*p
5031036 s/1000000
picasso:2011-1 hecht$
Expliquez pourquoi on obtient cette complexité.
Q5) Corrigez la faute de frappe associée à la question précédente.
Q6) Ajoutez à la classe Poly les deux opérateurs - et un évaluateur de la fonction polymône.
Q7) Ajoutez l’opérateur ˆ qui élève à un puissance entière un Poly.
Q8) Quelle est la complexité de votre opérateur ˆ ?
Q9) Ajoutez à la classe Poly un constructeur de polynôme constant à partir d’une constante double.
Q10) Que faut-il ajouter à Poly.hpp et Poly.cpp pour pouvoir écrire dans la fonction main
Poly q= (xˆ2)*3.+x*2.+1.;
Q11) Écrire un Makefile pour compiler votre programme.
Q12)* Comment optimiser la classe Poly pour que l’opérateur ˆ soit en O(1) pour les monômes.
4

Documents pareils