cg-Cad

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