Author Topic: Inverse Matrix using Cayley-Haminton theorem and Boucher formula  (Read 1407 times)

0 Members and 1 Guest are viewing this topic.

mrtile02

  • Mosquito
  • Posts: 1
Hi everybody. Here is my routine which I use it to get an Inverse Matrix. It based on Cayley-Hamilton theorem and Boucher formula.
Routine code as below.
Thanks for your interest.



; Matrix Inverse
; based on Cayley-Hamilton theorem
; and Boucher formula

(princ "\nType mInverse to run ")

(defun c:mInverse ( / ma uma msize mp mplist spn splist fan falist
         falist-1 mplist-1 faz mma rma mm i maStr okStr)

(defun *error* ( msg )
(if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
   (princ (strcat "\nError : " msg))
)
(princ)
) ; end *error*

(vl-load-com)

;; Matrix Transpose  -  Doug Wilson
;; Args: m - nxn matrix
(defun mTrp ( m )
    (apply 'mapcar (cons 'list m))
) ; end mTrp

;; Matrix x Vector  -  Vladimir Nesterovsky
;; Args: m - nxn matrix, v - vector in R^n
(defun MxV ( m v )
    (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
) ; end MxV

;; Matrix x Matrix  -  Vladimir Nesterovsky
;; Args: m1, m2 - nxn matrices
(defun MxM ( m1 m2 )   

   (mapcar (function (lambda (r) (MxV (mTrp m2) r))) m1)

   ;((lambda ( a ) (mapcar '(lambda ( r ) (MxV a r)) m1)) (mTrp m2))
) ; end MxM

;; matrix + matrix
;; Args: m1, m2 - nxn matrices
(defun MpM (m1 m2)
   (mapcar '(lambda (a b) (mapcar '+ a b)) m1 m2)
) ; end MpM

; e.g : (mpm '((1 2) (3 4)) '((5 6) (7 8)))
; ->    ((6 8) (10 12))

;; Make Vector
(defun make-vector (num n / vec)

(setq vec (list))
(repeat n
   (setq vec (append vec (list num)))
)
   vec
) ; end make-vector


; make vector matrix
(defun make-Vmatrix (num n / vma)

(setq vma (list))
(repeat n
   (setq vma (append vma (list (make-vector num n))))
) ; end repeat

  vma

) ; end make-Vmatrix


;; matrix scalar product
(defun Masp (num ma / vnum)
   (setq vnum (make-vector num (length ma)))
   (mapcar '(lambda (x) (mapcar '* vnum x)) ma)
) ; end masp

; e.g : (masp 2 '((1 2) (3 4)))
; ->    ((2 4) (6 8))

;; make unit matrix
(defun Make-Umatrix (num n / i j nlst zlst zmatrix zrow irow Umatrix itm mastr)

(setq i 0)
(setq nlst (list))
(repeat n
   (setq nlst (append nlst (list i)))
   (setq i (1+ i))
)

(setq zmatrix (list))
(repeat n
   (setq zlst (list))
   (setq zlst (make-vector 0 n))
   (setq zmatrix (append zmatrix (list zlst)))
)

(setq i 0)
(setq Umatrix (list))
(while (< i n)

   (setq zrow (nth i zmatrix))
   (setq j 0)
   (setq irow (list))
   (while (< j n)
      (setq itm (nth j zrow))
      (if (= j i)
         (setq itm NUM)
      )
      (setq irow (append irow (list itm)))
      (setq j (1+ j))
   ) ; end while
   (setq Umatrix (append Umatrix (list irow)))

(setq i (1+ i))
) ; end while

  Umatrix

) ; end make-Umatrix

; e.g : (make-Umatrix 1 3)
; -> ((1 0 0) (0 1 0) (0 0 1))

; sum of numbers on main cross of matrix
(defun Sum-MaCross (ma / i j n mrow numlst sum)

(setq n (length ma))

(setq numlst (list))

(setq i 0)
(while (< i n)

   (setq mrow (nth i ma))
   (setq j 0)
   
   (while (< j n)
      (setq itm (nth j mrow))
      (if (= j i)         
         (setq numlst (append numlst (list itm)))
      )
      (setq j (1+ j))
   ) ; end while   

(setq i (1+ i))
) ; end while

(apply '+ numlst)

) ; end Sum-MaCross

; e.g: (Sum-MaCross '((1 0 0) (0 1 0) (0 0 1)))
; ->   3

;; string to list [Lee-Mac]
(defun String-to-list ( str del / len lst pos )
    (setq len (1+ (strlen del)))
    (while (setq pos (vl-string-search del str))
        (setq lst (cons (substr str 1 pos) lst)
              str (substr str (+ pos len))
        )
    )
    (reverse (cons str lst))

)    ; end String-to-list

(defun Check-Input-String (str / lst msize i itm row ma)

(setq lst (mapcar 'atof (String-to-list str ",")))
(setq msize (fix (sqrt (length lst))))
(if (/= (expt msize 2) (length lst))
(progn
   (alert (strcat "Invalid Input" "\nExit"))
   (exit)
)
)

(setq ma (list) row (list) i 0)
(while lst
   (setq itm (car lst))            
   (setq row (append row (list itm)))   
   (setq lst (cdr lst))   
   (setq i (1+ i))
   (if (= (rem i msize) 0)
   (progn
    (setq Ma (append Ma (list Row)))
    (setq row (list))
   )
   )
) ; end while
   Ma
) ; end Check-Input-String

; e.g : (Check-Input-String "1,2,3,4")
;    ->((1.0 2.0) (3.0 4.0))

;; + + + + + + + +
;; Main program
;; + + + + + + + +

(if (null maStr0)
   (setq maStr0 "1,2,3,4")
)

(setq maStr (getstring (strcat "\nInput define matrix String or [eXit] <" maStr0 "> : ")))

(cond
( (= (strcase maStr) "X")
   (exit)
)
( (= maStr "")
   (setq maStr maStr0)
)
(T
   (setq okStr maStr)
)
) ; end cond

; supplied matrix
(setq ma (Check-Input-String maStr))

; convert to floating number
(setq ma (mapcar '(lambda(x) (mapcar 'float x)) ma))

; matrix size
(setq msize (length ma))

; unit matrix 1.0
(setq uma (make-Umatrix 1.0 msize))

; a factor list
(setq falist (list))    

; matrix power list
(setq mplist (list))

; specialize polynomical list
(setq splist (list))

(setq i 1)
(repeat msize
   (if (null mp)       ; matrix power   
   (setq mp ma)
   (setq mp (MxM ma mp))
   )
   (setq mplist (append (list mp) mplist))

   (setq spn (Sum-MaCross mp))   
   
   ; follow Boucher formula
   (if (null splist)
   (setq fan (/ spn (* i -1.0)))
   (setq fan (/ (+ spn (apply '+ (mapcar '* (reverse splist) falist))) (* i -1.0)))
   )
   (setq falist (append falist (list fan)))
   (setq splist (append splist (list spn)))

(setq i (1+ i))
) ; end repeat

;; !!!
;; the end factor
;; this must be Non-Zero
(setq faz (last falist))

(if (= faz 0)
(progn
   (alert (strcat "Cannot calculate"
         "\nInverse Matrix"
         "\n*Exit*"
      )
   )
   (exit)
)
)

; when faz satisfied non-zero
(setq maStr0 okStr)
         
; add 1.0 to remain factor list
(setq falist-1 (cons 1.0 (reverse (cdr (reverse falist)))))    

; add unit matrix to matrix power list
(setq mplist-1 (append (cdr mplist) (list uma)))    

; multiply matrix
(setq mma (mapcar '(lambda(n m) (Masp n m))
         falist-1 mplist-1
      )
)

; result matrix
; unit matrix 0.0
(setq Rma (make-Vmatrix 0.0 msize))

; follow Cayley-Haminton theorem
(foreach mm mma
   (setq Rma (MpM mm Rma))   
) ; end foreach

(setq rma (Masp (/ -1.0 faz) rma))

(princ "[")
(mapcar 'print rma)
(princ "\n]")   
         
(*error* nil)
(princ)
) ; end c:mInverse

; result
; inverse matrix of
; [(1.0 2.0) (3.0 4.0)] is :
; [(-2.0 1.0) (1.5 -0.5)]

« Last Edit: August 20, 2021, 04:55:14 AM by mrtile02 »

JohnK

  • Administrator
  • Seagull
  • Posts: 10637
Re: Inverse Matrix using Haminton-Cayley theorem and Bocher formular
« Reply #1 on: August 19, 2021, 02:39:06 PM »
Thank you. Welcome to TheSwamp.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

d2010

  • Bull Frog
  • Posts: 326
Re: Inverse Matrix using Cayley-Haminton theorem and Boucher formula
« Reply #2 on: August 20, 2021, 03:48:59 PM »
Hi everybody. Here is my routine which I use it to get an Inverse Matrix. It based on Cayley-Hamilton theorem and Boucher formula.
Routine code as below.
You need build the future of your Cayley-Hamilton.Lsp,
You can develope the programe Cayley-Hamilton.Lsp, as 100% VLISP-Syntax, but your LISP are very incompatibility your with C++ or Java., in the future 2022Year, Cayley-Hamilton.Lsp have no future upgrade.
 :smitten:
So, I recomand you develope MatrixInverse with C+LISP and you translate
Main goal, == the Cayley-Hamilton.Lsp must be compatibility with C++