|
Lisp »Tips 'n Tricks
»Lisp & Array
»1
»2
»3
»4
»5
»6
»7
»8
»9
»10
La Matrice Identica I è una matrice quadrata di ordine n i cui elementi sono uguali a 1 se gli indici sono uguali (i=j) e a 0 se i/=j.
Vale la relazione A*I=I*A=A
MATI
;|
MATI.LSP
Copyright (C) 2005 Claudio Piccini.
All rights reserved
www.cg-cad.com
Generatore di Matrici Identiche I
|;
(defun ArrayID ( n / i j L X )
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(if (= i j)
(setq L (append L (list 1)))
(setq L (append L (list 0)))
)
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(setq X X)
)
(defun c:mati ( / n A str i j e )
; eco OFF
(setvar "cmdecho" 0)
(initget (+ 2 4))
(setq n (getint "\nNumero righe della matrice [3]: "))
(if (= n nil)(setq n 3))
; inizializza la lista 'array' A
(setq A (ArrayID n))
; legge l'array A
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq e (nth j (nth i A)))
(setq str (strcat " A[" (itoa i) "],[" (itoa j) "]=" (itoa e)))
(princ str)
(setq j (1+ j))
)
(princ "\n")
(setq i (1+ i))
)
; eco ON
(setvar "cmdecho" 1)
(princ)
)
;;;eof
|
Test del Lisp
Command: mati
Numero righe della matrice [3]: 4
A[0],[0]=1 A[0],[1]=0 A[0],[2]=0 A[0],[3]=0
A[1],[0]=0 A[1],[1]=1 A[1],[2]=0 A[1],[3]=0
A[2],[0]=0 A[2],[1]=0 A[2],[2]=1 A[2],[3]=0
A[3],[0]=0 A[3],[1]=0 A[3],[2]=0 A[3],[3]=1
MATT
La Matrice Trasposta AT della matrice A di ordine m,n è una matrice di ordine n,m le cui righe sono ottenute con le colonne di A e le colonne con le righe di A.
;|
MATT.LSP
Copyright (C) 2005 Claudio Piccini.
All rights reserved
www.cg-cad.com
Generatore di Matrici Trasposte AT
|;
(defun lstArray ( NR NC nome / i j L X e str )
(setq i 0)
(while (< i NR)
(setq j 0)
(while (< j NC)
(setq str (strcat "\n Inserire elemento " nome "[" (itoa i) "],[" (itoa j) "]: "))
(initget 1)
(setq e (getreal str))
(setq L (append L (list e)))
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(princ "\n")
(setq X X)
)
(defun scriveArray ( NR NC nome lista / i j e str )
(setq i 0)
(while (< i NR)
(setq j 0)
(while (< j NC)
(setq e (nth j (nth i lista)))
(setq str (strcat nome "[" (itoa i) "],[" (itoa j) "]=" (rtos e 2 2)))
(princ str)
(setq j (1+ j))
)
(princ "\n")
(setq i (1+ i))
)
(princ "\n")
)
(defun trasp ( NR NC lista / i j e L X )
(setq i 0)
(while (< i NR)
(setq j 0)
(while (< j NC)
(setq e (nth i (nth j lista)))
(setq L (append L (list e)))
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(setq X X)
)
(defun c:matt ( / NR NC ; righe e colonne di A
NRT NCT ; righe e colonne di B=Trasposta di A
A B
)
; eco OFF
(setvar "cmdecho" 0)
;|
input A
numero righe = NR
numero colonne = NC
|;
(princ "\nMatrice A:")
(initget (+ 2 4))
(setq NR (getint "\nNumero righe [3]: "))
(if (= NR nil)(setq NR 3))
(setq NC (getint "\nNumero colonne [3]: "))
(if (= NC nil)(setq NC 3))
(setq NRT NC)
(setq NCT NR)
; inizializza la lista 'array' A
(princ "\nInizializzazione matrice A")
(setq A (lstArray NR NC " A"))
; genera la matrice trasposta B
(setq B (trasp NRT NCT A))
; mostra il contenuto dell'array B
(princ "\nTrasposta di A:\n")
(scriveArray NRT NCT " B" B)
; eco ON
(setvar "cmdecho" 1)
(princ)
)
;;;eof
|
Test del Lisp
Command: matt
Matrice A:
Numero righe [3]: Invio
Numero colonne [3]: Invio
Inizializzazione matrice A
Inserire elemento A[0],[0]: 0
Inserire elemento A[0],[1]: 1
Inserire elemento A[0],[2]: 2
Inserire elemento A[1],[0]: 3
Inserire elemento A[1],[1]: 4
Inserire elemento A[1],[2]: 5
Inserire elemento A[2],[0]: 6
Inserire elemento A[2],[1]: 7
Inserire elemento A[2],[2]: 8
Trasposta di A:
B[0],[0]=0 B[0],[1]=3 B[0],[2]=6
B[1],[0]=1 B[1],[1]=4 B[1],[2]=7
B[2],[0]=2 B[2],[1]=5 B[2],[2]=8
Command: matt
Matrice A:
Numero righe [3]: Invio
Numero colonne [3]: 4
Inizializzazione matrice A
Inserire elemento A[0],[0]: 0
Inserire elemento A[0],[1]: 1
Inserire elemento A[0],[2]: 2
Inserire elemento A[0],[3]: 3
Inserire elemento A[1],[0]: 4
Inserire elemento A[1],[1]: 5
Inserire elemento A[1],[2]: 6
Inserire elemento A[1],[3]: 7
Inserire elemento A[2],[0]: 8
Inserire elemento A[2],[1]: 9
Inserire elemento A[2],[2]: 10
Inserire elemento A[2],[3]: 11
Trasposta di A:
B[0],[0]=0 B[0],[1]=4 B[0],[2]=8
B[1],[0]=1 B[1],[1]=5 B[1],[2]=9
B[2],[0]=2 B[2],[1]=6 B[2],[2]=10
B[3],[0]=3 B[3],[1]=7 B[3],[2]=11
Command: matt
Matrice A:
Numero righe [3]: 4
Numero colonne [3]: Invio
Inizializzazione matrice A
Inserire elemento A[0],[0]: 0
Inserire elemento A[0],[1]: 1
Inserire elemento A[0],[2]: 2
Inserire elemento A[1],[0]: 3
Inserire elemento A[1],[1]: 4
Inserire elemento A[1],[2]: 5
Inserire elemento A[2],[0]: 6
Inserire elemento A[2],[1]: 7
Inserire elemento A[2],[2]: 8
Inserire elemento A[3],[0]: 9
Inserire elemento A[3],[1]: 10
Inserire elemento A[3],[2]: 11
Trasposta di A:
B[0],[0]=0 B[0],[1]=3 B[0],[2]=6 B[0],[3]=9
B[1],[0]=1 B[1],[1]=4 B[1],[2]=7 B[1],[3]=10
B[2],[0]=2 B[2],[1]=5 B[2],[2]=8 B[2],[3]=11
MAT_1
Data una matrice quadrata A e una matrice quadrata B se vale A*B=B*A=I, allora B è detta inversa di A e si scrive A-1.
MAT_1 calcola in modo approssimato A-1 tramite un metodo iterativo.
Vincolo del lisp: La somma dei valori assoluti di A deve essere minore di 1.
Legge dal file MATRICE.TXT gli elementi dell'array A (vedi tutorial n.58).
Il Lisp usa funzioni già viste all'interno di questo tutorial (nel caso generale di numero colonne/=numero righe).
Data una matrice IN (con la somma in valore assoluto degli elementi < 1) vale la relazione:
(ID-IN)-1=ID+IN+IN2+IN3+... equivalente a 1/(1-x)=1+x+x2+x3+... con |x|<1
quindi si approssima (ID-IN)-1 con ID+IN+IN2+...+INk, si inizializza AP (matrice d'appoggio) con i valori di ID (matrice identica) e si calcolano k iterazioni della formula AP <- AP*IN+ID, infine OU <- AP.
Il test OU*(ID-IN)=ID prova che OU è una approssimazione di (ID-IN)-1 *.
;|
MAT_1.LSP (9/07/2005)
Copyright (C) 2005 Claudio Piccini.
All rights reserved
www.cg-cad.com
Calcola in modo approssimato la Matrice Inversa di IN
La somma dei valori assoluti di IN deve essere minore di 1.
INPUT (elementi matrice IN):
1. tastiera
2. file MATRICE.TXT
Struttura di MATRICE.TXT:
'(
(n n n)
(n n n)
(n n n)
)
Vincoli:
1. Ogni lista deve avere lo stesso numero di elementi.
2. Numero Colonne=Numero Righe.
3. Il file deve chiamarsi MATRICE.TXT
OUTPUT (OU matrice inversa approssimata di IN):
riga di comando di AutoCAD.
Basato su matricip.c
'C e Java laboratorio di programmazione' AA.VV. McGraw-Hill
|;
;|
inizializza la lista IN
|;
(defun lstArray ( n / i j L X e str )
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq str (strcat "\nInserire elemento A[" (itoa i) "][" (itoa j) "]: "))
(setq e (getreal str))
(setq L (append L (list e)))
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(princ "\n")
(setq X X)
)
;|
legge il file MATRICE.TXT
se e' presente nella cartella aperta
|;
(defun LeggeFile ( / NR NC
nDir nf
i j e
Lst rigo X
)
(setq nDir (getvar "dwgprefix"))
(setq nf (strcat nDir "matrice.txt"))
(setq Lst (load nf))
(setq NR (length Lst))
(setq NC (length (car Lst)))
(if (/= NR NC)
(progn
(princ "\nERRORE: righe/=colonne")
(setq X nil)
)
(progn
(setq n NR)
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq e (nth j (nth i Lst)))
(setq rigo (append rigo (list e)))
(setq j (1+ j))
)
(setq X (append X (list rigo)))
(setq rigo nil)
(setq i (1+ i))
)
)
)
(setq X X)
)
;|
somma i valori assoluti
degli elementi di IN
|;
(defun sommaArray ( n lista / i j e s str )
(setq s 0.0)
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq e (nth j (nth i lista)))
(setq s (+ s e))
(setq j (1+ j))
)
(setq i (1+ i))
)
(if (< (abs s) 1)
(setq ok T)
(progn
(princ "\nERRORE: la somma di |a(i,j)|>1\n")
(setq ok nil)
)
)
)
;|
genera la Matrice Identica ID
|;
(defun ArrayID ( n / i j L X )
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(if (= i j)
(setq L (append L (list 1)))
(setq L (append L (list 0)))
)
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(setq X X)
)
;|
prodotto di 2 matrici NxN
|;
(defun p2Ar ( n A B / i j k e1 e2 e3 L X )
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq e3 0)
(setq k 0)
(while (< k N)
(setq e1 (nth k (nth i A)))
(setq e2 (nth j (nth k B)))
(setq e3 (+ e3 (* e1 e2)))
(setq k (1+ k))
)
(setq L (append L (list e3)))
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(setq X X)
)
;|
somma gli elementi dell'array A
con gli elementi dell'array B
|;
(defun s2Ar ( n A B / i j e1 e2 L X )
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq e1 (nth j (nth i A)))
(setq e2 (nth j (nth i B)))
(setq L (append L (list (+ e1 e2))))
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(setq X X)
)
;|
stampa il contenuto della lista
'matrice' nome
|;
(defun scriveArray ( n nome lista / i j e str )
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq e (nth j (nth i lista)))
(setq str (strcat nome "[" (itoa i) "][" (itoa j) "]=" (rtos e 2 6)))
(princ str)
(setq j (1+ j))
)
(princ "\n")
(setq i (1+ i))
)
(princ "\n")
)
;|
A-B
|;
(defun d2Ar ( n A B / i j e1 e2 L X )
(setq i 0)
(while (< i n)
(setq j 0)
(while (< j n)
(setq e1 (nth j (nth i A)))
(setq e2 (nth j (nth i B)))
(setq L (append L (list (+ e1 (* -1 e2)))))
(setq j (1+ j))
)
(setq X (append X (list L)))
(setq L nil)
(setq i (1+ i))
)
(setq X X)
)
(defun c:mat_1 ( / n i k
rsp ok
IN ; matrice INput
OU ; matrice OUtput (Inversa appross. di IN)
ID ; matrice IDentica
AP ; matrice d'APpoggio
)
; eco OFF
(setvar "cmdecho" 0)
(initget "t T f F")
(setq rsp (getkword "\nInput valori tastiera o file ? <t,f> [f]: "))
(cond
((or (= rsp "t")(= rsp "T"))
(initget (+ 2 4))
(setq n (getint "\n Numero righe di IN [3]: "))
(if (= n nil)(setq n 3))
; inizializza la lista 'array' IN
(setq IN (lstArray n))
(setq ok T)
)
((or (= rsp "f")(= rsp "F")(= rsp nil))
(setq IN (LeggeFile))
(if (/= IN nil)(setq ok T))
)
)
(if ok
(progn
; somma gli elementi di IN
(if (sommaArray n IN)
(progn
; stampa IN
(scriveArray n " IN" IN)
; inizializza la Matrice Identica ID
(setq ID (ArrayID n))
;|
inizializza la matrice d'appoggio
con i valori di ID
|;
(setq AP ID)
;|
calcola la Matrice Inversa OU
in modo approssimato
|;
(initget (+ 2 4))
(setq k (getint "\nSteps di approssimazione [5]: "))
(if (= k nil)(setq k 5))
(setq i 0)
(while (< i k)
(setq AP (p2Ar n AP IN)) ; AP <- AP*IN
(setq AP (s2Ar n AP ID)) ; AP <- AP+ID
(setq i (1+ i))
)
(setq OU AP)
; stampa la matrice inversa approssimata di IN
(princ "\nMatrice inversa approssimata di IN:\n")
(scriveArray n " OU" OU)
; Test
(setq ID (p2Ar n OU (d2Ar n ID IN))) ; ID <- OU*(ID-IN)
(princ "\nTEST: Matrice Inversa*(I-Matrice Input)=I\n")
(scriveArray n " ID" ID)
)
)
)
)
; eco ON
(setvar "cmdecho" 1)
(princ)
)
;;;eof
|
Test del Lisp
Test con MATRICE.TXT:
'(
(0.0 0.1 0.025 0.0111)
(0.1 0 0.1 0.025)
(0.025 0.1 0 0.1)
(0.0111 0.025 0.1 0)
)
Command: mat_1
Input valori tastiera o file ? <t,f> [f]: Invio
IN[0][0]=0 IN[0][1]=0.1 IN[0][2]=0.025 IN[0][3]=0.0111
IN[1][0]=0.1 IN[1][1]=0 IN[1][2]=0.1 IN[1][3]=0.025
IN[2][0]=0.025 IN[2][1]=0.1 IN[2][2]=0 IN[2][3]=0.1
IN[3][0]=0.0111 IN[3][1]=0.025 IN[3][2]=0.1 IN[3][3]=0
Steps di approssimazione [5]: Invio
Matrice inversa approssimata di IN:
OU[0][0]=1.011662 OU[0][1]=0.105356 OU[0][2]=0.037576 OU[0][3]=0.017615
OU[1][0]=0.105356 OU[1][1]=1.022318 OU[1][2]=0.108612 OU[1][3]=0.037576
OU[2][0]=0.037576 OU[2][1]=0.108612 OU[2][2]=1.022318 OU[2][3]=0.105356
OU[3][0]=0.017615 OU[3][1]=0.037576 OU[3][2]=0.105356 OU[3][3]=1.011662
TEST: Matrice Inversa*(I-Matrice Input)=I
ID[0][0]= 0.999992 ID[0][1]=-0.000009 ID[0][2]=-0.000012 ID[0][3]=-0.000006
ID[1][0]=-0.000009 ID[1][1]= 0.999982 ID[1][2]=-0.000012 ID[1][3]=-0.000012
ID[2][0]=-0.000012 ID[2][1]=-0.000012 ID[2][2]= 0.999982 ID[2][3]=-0.000009
ID[3][0]=-0.000006 ID[3][1]=-0.000012 ID[3][2]=-0.000009 ID[3][3]= 0.999992
Command: mat_1
[...]
Steps di approssimazione [5]: 7
Matrice inversa approssimata di IN:
OU[0][0]=1.011672 OU[0][1]=0.105366 OU[0][2]=0.03759 OU[0][3]=0.017623
OU[1][0]=0.105366 OU[1][1]=1.022338 OU[1][2]=0.108627 OU[1][3]=0.03759
OU[2][0]=0.03759 OU[2][1]=0.108627 OU[2][2]=1.022338 OU[2][3]=0.105366
OU[3][0]=0.017623 OU[3][1]=0.03759 OU[3][2]=0.105366 OU[3][3]=1.011672
TEST: Matrice Inversa*(I-Matrice Input)=I
ID[0][0]=1 ID[0][1]=0 ID[0][2]=0 ID[0][3]=0
ID[1][0]=0 ID[1][1]=0.999999 ID[1][2]=0 ID[1][3]=0
ID[2][0]=0 ID[2][1]=0 ID[2][2]=0.999999 ID[2][3]=0
ID[3][0]=0 ID[3][1]=0 ID[3][2]=0 ID[3][3]=1
Command: mat_1
[...]
Steps di approssimazione [5]: 8
Matrice inversa approssimata di IN:
OU[0][0]=1.011672 OU[0][1]=0.105367 OU[0][2]=0.037591 OU[0][3]=0.017623
OU[1][0]=0.105367 OU[1][1]=1.022339 OU[1][2]=0.108627 OU[1][3]=0.037591
OU[2][0]=0.037591 OU[2][1]=0.108627 OU[2][2]=1.022339 OU[2][3]=0.105367
OU[3][0]=0.017623 OU[3][1]=0.037591 OU[3][2]=0.105367 OU[3][3]=1.011672
TEST: Matrice Inversa*(I-Matrice Input)=I
ID[0][0]=1 ID[0][1]=0 ID[0][2]=0 ID[0][3]=0
ID[1][0]=0 ID[1][1]=1 ID[1][2]=0 ID[1][3]=0
ID[2][0]=0 ID[2][1]=0 ID[2][2]=1 ID[2][3]=0
ID[3][0]=0 ID[3][1]=0 ID[3][2]=0 ID[3][3]=1
|
(*) AA.VV., C e Java laboratorio di programmazione - 1997, McGraw-Hill
Lisp »Tips 'n Tricks
Ultimo Aggiornamento_Last Update: 9 Luglio 2005
|
|