Programmazione con maple, goemetria
Ho il seguente esercizio:
Si scriva una procedura maple che accetti in input due coppie di punti (P1,P2) e (Q1,Q2) del piano Euclideo ℝ2 e dia in output, se possibile, un'isometria f(x)=Ax+v, tale che f(Pi)=Qi, i=1,2.
Io ho fatto in questo modo:
restart:with(geometry):with(linalg):
isometria:=proc(P,Q,R,S)
local X, Y, A, v, a, b, F, G;
F:=randvector(2); G:=randvector(2);
if norm(P-Q,2)<>norm(R-S,2) and norm(P-F,2)<>norm(R-G,2) then
ERROR(nonesisteun'isometriachemandaP∈R,Q∈SeF∈G);
end if;
X:=[evalm(P-Q),evalm(P-F)];
Y:=[evalm(R-S),evalm(R-G)];
A:=evalm(transpose(matrix(Y))&*inverse(transpose(matrix(X))));
v:=evalm(R-A&*P);
print(F); print(G);
print([simplify(A),simplify(v)]);
end proc;
Il problema è il seguente, il mio professore mi ha detto che i punti F e G, non devono essere qualsiasi, ma li deve determinare opportunamente la procedura, qualcuno saprebbe dirmi come modificare la procedura per fare in modo che ciò avvenga?
Grazie a presto
Si scriva una procedura maple che accetti in input due coppie di punti (P1,P2) e (Q1,Q2) del piano Euclideo ℝ2 e dia in output, se possibile, un'isometria f(x)=Ax+v, tale che f(Pi)=Qi, i=1,2.
Io ho fatto in questo modo:
restart:with(geometry):with(linalg):
isometria:=proc(P,Q,R,S)
local X, Y, A, v, a, b, F, G;
F:=randvector(2); G:=randvector(2);
if norm(P-Q,2)<>norm(R-S,2) and norm(P-F,2)<>norm(R-G,2) then
ERROR(nonesisteun'isometriachemandaP∈R,Q∈SeF∈G);
end if;
X:=[evalm(P-Q),evalm(P-F)];
Y:=[evalm(R-S),evalm(R-G)];
A:=evalm(transpose(matrix(Y))&*inverse(transpose(matrix(X))));
v:=evalm(R-A&*P);
print(F); print(G);
print([simplify(A),simplify(v)]);
end proc;
Il problema è il seguente, il mio professore mi ha detto che i punti F e G, non devono essere qualsiasi, ma li deve determinare opportunamente la procedura, qualcuno saprebbe dirmi come modificare la procedura per fare in modo che ciò avvenga?
Grazie a presto
Risposte
1) Questa roba starebbe meglio nel forum di Informatica, magari usando opportunamente il tag "[code]" (ti consiglio di usare il pulsante "Modifica");
2) F, G sono due vettori che fai generare alla procedura in modo casuale. Perché?
3) Per caso studi qui a Bari?
2) F, G sono due vettori che fai generare alla procedura in modo casuale. Perché?
3) Per caso studi qui a Bari?
"dissonance":
1) Questa roba starebbe meglio nel forum di Informatica, magari usando opportunamente il tag "[code]" (ti consiglio di usare il pulsante "Modifica");
2) F, G sono due vettori che fai generare alla procedura in modo casuale. Perché?
3) Per caso studi qui a Bari?
1) all'inizio infatti l'avevo messo nella sezione di informatica, ma poi pensandoci l'ho messa nells sezione geometria e algebra lineare perchè mi sembrava più adatta, comunque se pensi che sia meglio spostare il messaggio nella sezione di informatica, fa pure

2) F e G sono due vettori qualsiasi e li faccio generare dalla procedura in modo tale da avere un'espressione esplicita dell'isometria.
3) Si studio qui a Bari
E' ancora Antonio Lotta il professore? Mi pare proprio un esercizio dato da lui. Comunque, il fatto di generare vettori random mi puzza proprio di errore. Tu hai già in input tutti i dati necessari a ottenere esplicitamente le equazioni dell'isometria, che bisogno c'è di generarne altri? Prova ad aggiungere qualche commento nel codice, così com'è è poco leggibile. Cerca di spiegare cosa vuoi fare. E usa il tag "[code]", come ti dicevo nel post precedente.
Sisi dissonance, confermo, è ancora lui!
Stamattina ho parlato con Lotta e mi ha detto che usare randvector non va bene. Comunque mi è venuta un'altra idea, la procedura l'ho impostata in questo modo:
isometria:=proc(P,Q)
local X, Y, A, v, a, b, c, d, F, G, x, y;
fsolve({(a-(P[1][1]+P[2][1])/2)^2+(b-(P[1][2]+P[2][2])/2)^2=1,(a-P[1][1])^2+(b-P[1][2])^2=(a-P[2][1])^2+(b-P[2][2])^2,(c-(Q[1][1]+Q[2][1])/2)^2+(d-(Q[1][2]+Q[2][2])/2)^2=1,(c-Q[1][1])^2+(d-Q[1][2])^2=(c-Q[2][1])^2+(d-Q[2][2])^2},{a, b, c, d});
assign(%);
F:=[a,b]; G:=[c,d];
print(F); print(G);
if norm(P[1]-P[2],2)<>norm(Q[1]-Q[2],2) then ERROR($'
non esiste un'isometria che manda P[1] in Q[1] e P[2] in Q[2]'$);
end if;il
X:=[evalm(P[1]-P[2]),evalm(P[1]-F)];
Y:=[evalm(Q[1]-Q[2]),evalm(Q[1]-G)];
A:=evalm(transpose(matrix(Y))&*inverse(transpose(matrix(X))));
v:=evalm(Q[1]-A&*P[1]);
print([simplify(A),simplify(v)]);
print(evalm(inverse(A)&*vector([x,y])-inverse(A)&*v));
end proc;
Questa procedura, come l'ho impostata funziona però ha il difetto che rappresenta i numeri in notazione decimale.
Questo perchè invece che uare solve ho usato fsolve che esprime le soluzioni del sistema in notazione decimale.
Ho utilizzato fsolve invece che solve perchè il sistema purtroppo non è lineare e quindi se scrivevo solve(...)
avevo una cosa di questo tipo:
{ y = RootOf(_Z2 −_Z −4, label = _L1), x = RootOf(_Z2 −_Z −4, label = _L1)−1 }
e quindi non mi dava le soluzioni cercate, invece il comando fsolve ha il pregio di esprimere numericamente una delle soluzioni del sistema e quindi sceglie una sola soluzione per ogni variabile incognita, ed è proprio quello che fa al caso mio. L'unico difetto di fsolve è appunto il fatto che esprime le soluzioni in notazione decimale.
Percaso sapete come risolvere questo problema?
isometria:=proc(P,Q)
local X, Y, A, v, a, b, c, d, F, G, x, y;
fsolve({(a-(P[1][1]+P[2][1])/2)^2+(b-(P[1][2]+P[2][2])/2)^2=1,(a-P[1][1])^2+(b-P[1][2])^2=(a-P[2][1])^2+(b-P[2][2])^2,(c-(Q[1][1]+Q[2][1])/2)^2+(d-(Q[1][2]+Q[2][2])/2)^2=1,(c-Q[1][1])^2+(d-Q[1][2])^2=(c-Q[2][1])^2+(d-Q[2][2])^2},{a, b, c, d});
assign(%);
F:=[a,b]; G:=[c,d];
print(F); print(G);
if norm(P[1]-P[2],2)<>norm(Q[1]-Q[2],2) then ERROR($'
non esiste un'isometria che manda P[1] in Q[1] e P[2] in Q[2]'$);
end if;il
X:=[evalm(P[1]-P[2]),evalm(P[1]-F)];
Y:=[evalm(Q[1]-Q[2]),evalm(Q[1]-G)];
A:=evalm(transpose(matrix(Y))&*inverse(transpose(matrix(X))));
v:=evalm(Q[1]-A&*P[1]);
print([simplify(A),simplify(v)]);
print(evalm(inverse(A)&*vector([x,y])-inverse(A)&*v));
end proc;
Questa procedura, come l'ho impostata funziona però ha il difetto che rappresenta i numeri in notazione decimale.
Questo perchè invece che uare solve ho usato fsolve che esprime le soluzioni del sistema in notazione decimale.
Ho utilizzato fsolve invece che solve perchè il sistema purtroppo non è lineare e quindi se scrivevo solve(...)
avevo una cosa di questo tipo:
{ y = RootOf(_Z2 −_Z −4, label = _L1), x = RootOf(_Z2 −_Z −4, label = _L1)−1 }
e quindi non mi dava le soluzioni cercate, invece il comando fsolve ha il pregio di esprimere numericamente una delle soluzioni del sistema e quindi sceglie una sola soluzione per ogni variabile incognita, ed è proprio quello che fa al caso mio. L'unico difetto di fsolve è appunto il fatto che esprime le soluzioni in notazione decimale.
Percaso sapete come risolvere questo problema?
"serway2":Scrivendo meglio la matematica dietro la procedura. Questo problema si può risolvere senza fare uso di equazioni non lineari.
Percaso sapete come risolvere questo problema?
[EDIT]Rettifico: qualche equazione non lineare (quadratica) ci vuole, ma sicuramente meno di quante ne abbia usate tu.
lo so, però io così sono riuscito a risolvere l'esercizio, comunque se conosci un altro metodo per risolverlo e ti va di spiegarmelo ben venga, te ne sarei molto grato

Senti, io farei le cose in maniera diretta. Cerchiamo una matrice $A$ e un vettore $v$ tali che, date in input due coppie di vettori $x_1, x_2$ e $y_1, y_2$, risulti ${(Ax_1+v=y_1), (Ax_2+v=y_2):}$ e inoltre l'applicazione $x \mapsto Ax+v$ sia una isometria. Allora, per prima cosa diciamo alla nostra procedura di controllare se questo è possibile, e tu lo hai fatto con:
I due sistemi lineari ${(Ax_1+v=y_1), (Ax_2+v=y_2):}$ forniscono già quattro equazioni. Ne mancano due: una, quadratica, la ottieni imponendo che $A$ sia una matrice ortogonale (così l'applicazione è una isometria), e l'altra, pure quadratica, imponendo che il determinante di $A$ sia uguale a $+1$ (così imponi che sia una isometria diretta). Dai tutto in pasto a solve e vedi che succede.
Non è il massimo, eh, probabilmente si può fare di meglio. Purtroppo adesso non ho molto tempo...
Un'ultima cosa: se il programma non funziona parlane con il professore; anche io due anni fa ho fatto lo stesso esame con lui, e anche a me capitò una procedura che coinvolgeva equazioni non lineari (dovevo mettere una matrice data in input in forma triangolare superiore). C'erano problemi a livello computazionale e il programma non girava bene, ma il professore me lo dette buono lo stesso. Però non usare algoritmi numerici (quindi niente fsolve) perché non te li accetterà.
if norm(P[1]-P[2],2)<>norm(Q[1]-Q[2],2) then ERROR [...]Se le coppie di punti passano questo test, c'è soluzione al problema. In realtà io direi che di soluzioni ce ne sono due, ma spero di non sbagliarmi: una isometria diretta ($detA>0$) ed una isometria inversa ($detA<0$). Il problema è risolto una volta determinate le entrate di $A$, che sono quattro, e quelle di $v$, che sono due: ci servono quindi sei equazioni.
I due sistemi lineari ${(Ax_1+v=y_1), (Ax_2+v=y_2):}$ forniscono già quattro equazioni. Ne mancano due: una, quadratica, la ottieni imponendo che $A$ sia una matrice ortogonale (così l'applicazione è una isometria), e l'altra, pure quadratica, imponendo che il determinante di $A$ sia uguale a $+1$ (così imponi che sia una isometria diretta). Dai tutto in pasto a solve e vedi che succede.
Non è il massimo, eh, probabilmente si può fare di meglio. Purtroppo adesso non ho molto tempo...

Un'ultima cosa: se il programma non funziona parlane con il professore; anche io due anni fa ho fatto lo stesso esame con lui, e anche a me capitò una procedura che coinvolgeva equazioni non lineari (dovevo mettere una matrice data in input in forma triangolare superiore). C'erano problemi a livello computazionale e il programma non girava bene, ma il professore me lo dette buono lo stesso. Però non usare algoritmi numerici (quindi niente fsolve) perché non te li accetterà.
quando hai del tempo potresti almeno iniziare ad impostarmi l'esercizio con maple? Basta che mi fai vedere come iniziare. Però guarda è vero che i numeri sono rappresentati in notazione decimale però la procedura come l'ho fatta io è corretta, i risultati che ottengo sono corretti
non ci posso credere, lo sai che facendo come mi hai detto tu, la procedura mi esce? Oltretutto in questo modo è pure più semplice la procedura, non ho avuto neanche bisogno di inserire il terzo punto e per giunta non viene neanche numerico il risultato. Ti ringrazio davvero tanto, ti faccio vedere come ho costruito la procedura:
isometria:=proc(P,Q)
local a,b,u,v,A,V,x,y;
if norm(P[1]-P[2],2)<>norm(Q[1]-Q[2],2) then ERROR($`non esiste un'isometria che manda P[1] in Q[1] e P[2] in Q[2]`$);
end if;
solve({Q[1][1]=a*P[1][1]+b*P[1][2]+u,Q[1][2]=-b*P[1][1]+a*P[1][2]+v,Q[2][1]=a*P[2][1]+b*P[2][2]+u,Q[2][2]=-b*P[2][1]+a*P[2][2]+v},{a, b, u, v});
assign(%);
A:=array(1..2,1..2,[[a,b],[-b,a]]);
V:=[u,v];
print([simplify(A),simplify(V)]);
end proc;
Tu dici che questa procedura l'accetta Lotta?
isometria:=proc(P,Q)
local a,b,u,v,A,V,x,y;
if norm(P[1]-P[2],2)<>norm(Q[1]-Q[2],2) then ERROR($`non esiste un'isometria che manda P[1] in Q[1] e P[2] in Q[2]`$);
end if;
solve({Q[1][1]=a*P[1][1]+b*P[1][2]+u,Q[1][2]=-b*P[1][1]+a*P[1][2]+v,Q[2][1]=a*P[2][1]+b*P[2][2]+u,Q[2][2]=-b*P[2][1]+a*P[2][2]+v},{a, b, u, v});
assign(%);
A:=array(1..2,1..2,[[a,b],[-b,a]]);
V:=[u,v];
print([simplify(A),simplify(V)]);
end proc;
Tu dici che questa procedura l'accetta Lotta?
Questo problema non richiede metodi non lineari... Si considerino i due vettori $z_1 = (P_2 - P_1)$ e $z_2 = J(P_2 - P_1)$ dove $J$ è la matrice $((0, -1), (1, 0))$. Questi due vettori sono perpendicolari e ${z_1, z_2}$ è una base positivamente orientata. Inoltre se $A$ è una isometria, $J$ commuta con $A$. Quindi la base ${z_1, z_2}$ viene mappata nella base ${w_1, w_2}$ dove $w_1 = (Q_2 - Q_1)$ e $w_2 = J(Q_2 - Q_1)$. La matrice $A$ è di conseguenza ben definita. A questo punto non resta che calcolare il vettore $v$, ma per farlo è sufficiente calcolare $v = Q_1 - AP_1$.
Non ho detto che la tua procedura sia sbagliata; dico solo che secondo me fai troppo ricorso ad equazioni non lineari. Chiedi comunque il parere di Lotta, può essere che lui la pensi diversamente e allora ovviamente dai retta a lui, non a me.
In ogni caso la procedura a cui penso io è molto semplice. Fino al controllo
[EDIT]Mentre scrivevo è successo di tutto! Il mio messaggio è riferito al post di serway
In ogni caso la procedura a cui penso io è molto semplice. Fino al controllo
if norm(P[1]-P[2],2)<>norm(Q[1]-Q[2],2) then ERROR [...]è uguale alla prima che hai postato tu. Poi definisce una matrice vuota $A$ 2x2 e un vettore vuoto $v$ 2x1 mediante i comandi matrix e array. Quindi costruisce un insieme (set; sai cos'è un set in Maple?) di sei equazioni, quelle che dicevo sopra, e lo chiama, per esempio, eqn. Infine chiama un solve(eqn, {A[1], A[2], A[3], A[4], v[1], v[2]}). L'output di solve sono le quattro entrate della matrice e le due entrate del vettore.
[EDIT]Mentre scrivevo è successo di tutto! Il mio messaggio è riferito al post di serway
"serway2":
quando hai del tempo potresti almeno iniziare ad impostarmi l'esercizio con maple? Basta che mi fai vedere come iniziare. Però guarda è vero che i numeri sono rappresentati in notazione decimale però la procedura come l'ho fatta io è corretta, i risultati che ottengo sono corretti
che ne pensi di questa nuova procedura che ho scritto? Sicuramente è corretta, tu dici che Lotta me la darà per buona?
@serway: Questa procedura, a occhio, va bene! Non avevo proprio pensato al fatto che i gradi di libertà non fossero 6 ma 4...
In ultima analisi mi sa che, sostanzialmente, questo è anche il metodo che indica apatriarca. Facci sapere che ne pensa Lotta.

certo che ve lo farò sapere, mi sembra il minimo, ho appuntamento con Lotta mercoledì pomeriggio.
Comunque stai tranquillo, sono io che ho ridotto il numero di equazioni a 4, ho semplicemente saltato un passaggio banale, cioè ho saltato le equazioni che imponevano che il determinante di A vale 1 e che l'inversa di A è uguale alla trasposta A, volendo avrei potuto far scrivere tutto a maple, ma in questo caso mi sembrava eccessivo visto che queste due condizioni le ho scritte in due secondi a mano, ho subito dato per scontato che c=-b e d=a.
Comunque stai tranquillo, sono io che ho ridotto il numero di equazioni a 4, ho semplicemente saltato un passaggio banale, cioè ho saltato le equazioni che imponevano che il determinante di A vale 1 e che l'inversa di A è uguale alla trasposta A, volendo avrei potuto far scrivere tutto a maple, ma in questo caso mi sembrava eccessivo visto che queste due condizioni le ho scritte in due secondi a mano, ho subito dato per scontato che c=-b e d=a.
In effetti il metodo è sostanzialmente lo stesso (il mio si ottiene facendo qualche passaggio nella risoluzione del sistema). La differenza sostanziale a livello di codice è il fatto che il mio metodo, una volta implementato, non farebbe ricorso a solve e sarebbe quindi possibile utilizzare un linguaggio di programmazione che non sia in grado di fare calcolo simbolico. Non conoscendo il tuo prof non sono in grado di ipotizzare quale metodo preferisca vedere.
visto che siamo in tema, ti andrebbe di far vedere come funziona praticamente il tuo metodo, apatriarca?

Siano
$z = (P_2 - P_1) = ((z_x), (z_y))$
$Jz = ((-z_y), (z_x))$
$w = (Q_2 - Q_1) = ((w_x), (w_y))$
$Jw = ((-w_y), (w_x))$
Dall'equazione
$A(z, Jz) = (w, Jw)$
si ottiene
$A = ((1)/(||z||^2))(w, Jw)((z),(Jz)) = ((1)/(||z||^2))((z*w, Jz*w), (- Jz*w, z*w)).$
A questo punto si ottiene $v$ da
$v = Q_1 - AP_1.$
$z = (P_2 - P_1) = ((z_x), (z_y))$
$Jz = ((-z_y), (z_x))$
$w = (Q_2 - Q_1) = ((w_x), (w_y))$
$Jw = ((-w_y), (w_x))$
Dall'equazione
$A(z, Jz) = (w, Jw)$
si ottiene
$A = ((1)/(||z||^2))(w, Jw)((z),(Jz)) = ((1)/(||z||^2))((z*w, Jz*w), (- Jz*w, z*w)).$
A questo punto si ottiene $v$ da
$v = Q_1 - AP_1.$
non mi è molto chiaro il ragionamento che usi, non ho capito perchè poni Jz e Jw in quel modo e ovviamente anche tutto il resto,
cmq questo è il ragionamento in generale, lo sapresti implementare con maple?
Grazie dell'aiuto cmq
cmq questo è il ragionamento in generale, lo sapresti implementare con maple?
Grazie dell'aiuto cmq
Puoi pensare a $J$ come ad una moltiplicazione per l'unità immaginaria $i$, se interpreti i vettori nel piano come numeri complessi. Se fai i calcoli ti viene esattamente quel risultato. $Jz$ è l'unico vettore che soddisfa le condizioni $z*Jz = 0$, $||z|| = ||Jz||$ e ${z, Jz}$ è positivamente orientata. Lo stesso vale per $w$. Maple non lo uso da tanto tempo e non ricordo la sintassi. Se conosci però altri linguaggi posso scriverti il codice in uno di questi.
Appena torno dalla piscina vedo se riesco a darti una spiegazione migliore e forse anche scrivere un po' di codice.
Appena torno dalla piscina vedo se riesco a darti una spiegazione migliore e forse anche scrivere un po' di codice.