0 people like it.

matrix-inv.fsx

calcula la matriz inversa

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
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: 
open System
type matrix(m:float list list) =
    ///Numero de filas de la matriz
    member this.rows = m.Length
    ///Numero de columnas de la matriz
    member this.cols = m.Head.Length
    //Elementos de la matriz
    member this.items = m        
    //Obtiene el valor de un elemento de la matriz
    member this.item i j = m.[i].[j]
    //Convierte a string la matriz        
    override this.ToString() = "\
" + (this.items |> List.fold (fun r s -> r + "[ " + (s |> List.fold (fun x y -> x + (sprintf "%*.01f "4 y)) "") + "]\
") "")

    (******Metodos para poder realizar operaciones de suma, resta y productos de matrices******)
    ///Operador para suma de matrices donde x y son del mismo tamaño 
    static member (+) (x:matrix, y:matrix) =
        matrix (List.map2 (fun x y-> List.map2(fun x y-> x + y) x y) x.items y.items)
    ///Operador para resta de matrices donde x y son del mismo tamaño
    static member (-) (x:matrix, y:matrix) =
        matrix (List.map2 (fun x y -> List.map2(fun x y-> x - y) x y) x.items y.items)
    ///Operador para multiplicacion de una matriz por un numero n
    static member (*) (n:_, x:matrix) = 
        matrix ( x.items |> List.map (fun x-> x |> List.map(fun x -> x * (float)n)))
    ///Operador para multiplicacion de matrices
    static member (*) (x:matrix, y:matrix) = 
        matrix([for k in 0..x.rows - 1 do 
                yield [for i in 0..y.cols - 1 do
                       yield List.sum [for j in 0..x.cols - 1 do
                                       yield (x.item k j) * (y.item j i)]]])

    ///Obtiene la inversa de una matriz cuadrada
    member this.inv() =
        //Generamos la matriz identidad
        let id = matrix [for i = 0 to this.rows - 1 do
                            yield [for j = 0 to this.cols - 1 do
                                    yield if j = i then 1.0 else 0.0]]  
        //Agregamos la matriz identidad a la derecha de nuestra matriz                              
        let mi = ref (matrix (List.map2 (fun x y -> List.append x y) this.items id.items))
        //Hacemos los calculos necesarios para pasar la matriz identidad a la izquierda
        for i = 0 to mi.Value.rows - 1 do
            //Se hace 1 los elementos que estan en diagonal
            mi := matrix (mi.Value.items |> List.mapi (fun ix x -> x |> List.map (fun y -> if ix = i then y / mi.Value.item i i else y)))            
            //Hacer 0 las columna i de los otros renglones
            mi := matrix (mi.Value.items |> List.mapi (fun ix x -> x |> List.mapi (fun j y -> if ix <> i then (mi.Value.item i j * - mi.Value.item ix i) + y  else y )))                    
        matrix [for i = 0 to this.rows - 1 do
                    yield [for j = this.rows  to mi.Value.cols - 1 do
                            yield mi.Value.item i j]]


        
//Ejemplo 
//Generamos una matriz
let a = matrix [[ 7.0; 1.0; 0.0]
                [ 6.0; 4.0; 2.0]
                [ 1.0; 1.0; 5.0]]

//Obtenemos la inversa de la matriz
let i = a.inv()

//Validamos que la matriz inversa sea correcta
//  Multiplicamos la matriz inversa por la matriz original y el resultado 
//  debe ser la matriz identidad                                 
let x = a * i
namespace System
Multiple items
type matrix =
  new : m:float list list -> matrix
  override ToString : unit -> string
  member cols : int
  member items : float list list
  member rows : int
  member inv : unit -> matrix
  member item : i:int -> j:int -> float
  static member ( + ) : x:matrix * y:matrix -> matrix
  static member ( * ) : n:int * x:matrix -> matrix
  static member ( * ) : x:matrix * y:matrix -> matrix
  ...

Full name: Script.matrix

--------------------
new : m:float list list -> matrix
val m : float list list
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val this : matrix
member matrix.rows : int

Full name: Script.matrix.rows


Numero de filas de la matriz
property List.Length: int
member matrix.cols : int

Full name: Script.matrix.cols


Numero de columnas de la matriz
property List.Head: float list
member matrix.items : float list list

Full name: Script.matrix.items
member matrix.item : i:int -> j:int -> float

Full name: Script.matrix.item
val i : int
val j : int
override matrix.ToString : unit -> string

Full name: Script.matrix.ToString
property matrix.items: float list list
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val fold : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State

Full name: Microsoft.FSharp.Collections.List.fold
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val x : matrix
val y : matrix
val map2 : mapping:('T1 -> 'T2 -> 'U) -> list1:'T1 list -> list2:'T2 list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map2
val x : float list
val y : float list
val x : float
val y : float
val n : int
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val k : int
property matrix.rows: int


Numero de filas de la matriz
property matrix.cols: int


Numero de columnas de la matriz
val sum : list:'T list -> 'T (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sum
member matrix.item : i:int -> j:int -> float
member matrix.inv : unit -> matrix

Full name: Script.matrix.inv


Obtiene la inversa de una matriz cuadrada
val id : matrix
val mi : matrix ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
val append : list1:'T list -> list2:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.append
property Ref.Value: matrix
val mapi : mapping:(int -> 'T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.mapi
val ix : int
val a : matrix

Full name: Script.a
val i : matrix

Full name: Script.i
member matrix.inv : unit -> matrix


Obtiene la inversa de una matriz cuadrada
val x : matrix

Full name: Script.x
Raw view Test code New version

More information

Link:http://fssnip.net/lF
Posted:10 years ago
Author:ivpadim
Tags: matrix , tryfsharp