Advertisement
Guest User

Untitled

a guest
Jul 18th, 2019
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 6.72 KB | None | 0 0
  1. namespace Anon.Math.Matrix
  2.  
  3. open System
  4.  
  5. open Anon.Math
  6.  
  7. open Anon.Core
  8.  
  9.  
  10.  
  11. type 'a IMatrixFormatProvider =
  12.    
  13.    /// Разделитель между столбцами
  14.    abstract ColumnSeparator : string
  15.  
  16.    ///Разделитель между строками
  17.    abstract RowSeparator : string
  18.    
  19.    /// Приведение элемента матрицы к строке
  20.    abstract ElementConverter : ('a -> string)
  21.  
  22.  
  23. type 'a MatrixFormatInfo (columnSeparator : string, rowSeparator : string, elementConverter : 'a -> string) =
  24.  
  25.     static let _default : 'a IMatrixFormatProvider = upcast MatrixFormatInfo<'a> (" ", Environment.NewLine, fun v -> v.ToString ())
  26.  
  27.     interface 'a IMatrixFormatProvider with
  28.  
  29.        member this.ColumnSeparator  = columnSeparator
  30.  
  31.        member this.RowSeparator = rowSeparator
  32.  
  33.        member this.ElementConverter = elementConverter
  34.        
  35.    
  36.    static member Default = _default
  37.  
  38.    
  39.    
  40.  
  41.  
  42.  
  43. type private MatrixFuncStorate =
  44.  
  45.    static member ofSeq columnCount rowCount source = Matrix (columnCount, rowCount, Array.ofSeq source)
  46.  
  47.    static member isSquare<'a> (matrix : Matrix<'a>) = matrix.RowCount = matrix.ColumnCount
  48.  
  49.    static member rows (mtx : _ Matrix) =
  50.  
  51.        mtx.Rows
  52.  
  53.    static member columns (mtx : _ Matrix) =
  54.  
  55.        mtx.Columns
  56.  
  57.    static member cells<'a> (mtx : 'a Matrix) : 'a MatrixCell seq =
  58.  
  59.          (MatrixFuncStorate.rows >> Seq.collect (fun row -> row.Cells)) mtx
  60.  
  61.     static member cellsValues<'a> (mtx : 'a Matrix) : 'a seq =
  62.  
  63.        (MatrixFuncStorate.cells >> Seq.map (fun cell -> cell.Value)) mtx
  64.  
  65.  
  66.    static member cellMap f mtx = MatrixFuncStorate.cells mtx
  67.                               |> Seq.map f
  68.                               |> MatrixFuncStorate.ofSeq mtx.ColumnCount mtx.RowCount
  69.  
  70.    
  71.    static member map f = MatrixFuncStorate.cellMap (fun cell -> f cell.Value)
  72.  
  73.  
  74.    static member cellMap2 f (mtx1 : _ Matrix) (mtx2 : _ Matrix) =
  75.  
  76.        if   mtx1.RowCount    <> mtx2.RowCount    then invalidArg "different row count" "mtx2"
  77.        elif mtx1.ColumnCount <> mtx2.ColumnCount then invalidArg "different column count" "mtx2"
  78.                                                  else Seq.map2 f (MatrixFuncStorate.cells mtx1) (MatrixFuncStorate.cells mtx2)
  79.                                                    |> MatrixFuncStorate.ofSeq mtx1.ColumnCount mtx1.RowCount
  80.  
  81.  
  82.    static member map2 f mtx1 mtx2 = MatrixFuncStorate.cellMap2 (f |> on <| fun cell -> cell.Value) mtx1 mtx2
  83.    
  84.  
  85. // Immutable matrix
  86. and 'a Matrix internal (columnCount : int, rowCount : int, source : 'a array) as this =
  87.  
  88.    do if columnCount < 0
  89.            then argumentOutOfRange "columnCount"
  90.  
  91.       if rowCount < 0
  92.            then argumentOutOfRange "rowCount"
  93.  
  94.       if columnCount * rowCount > source.Length
  95.            then invalidArg "low data" "source"
  96.  
  97.  
  98.    let rows = lazy [for rowIndex in 0 .. rowCount - 1 -> MatrixRow (this, rowIndex, seq { for columnIndex in 0 .. columnCount - 1 -> source.[rowIndex * columnCount + columnIndex] })]
  99.  
  100.    let columns = lazy [for columnIndex in 0 .. columnCount - 1 -> MatrixColumn (this, columnIndex, this.Rows |> List.map (fun row -> lazy row.Cells.[columnIndex]))]
  101.  
  102.    member this.Rows    : 'a MatrixRow list = rows.Value
  103.  
  104.     member this.Columns : 'a MatrixColumn list = columns.Value
  105.  
  106.    member this.ColumnCount : int = columnCount
  107.  
  108.    member this.RowCount : int = rowCount
  109.  
  110.    
  111.    static member (+)  (left : 'a Matrix, right : 'a Matrix) = let mathProvider = MathProvider.Current
  112.                                                               MatrixFuncStorate.map2 mathProvider.Add left right
  113.  
  114.    static member (-)  (left : 'a Matrix, right : 'a Matrix) = let mathProvider = MathProvider.Current                                                              
  115.                                                               MatrixFuncStorate.map2 mathProvider.Subtract left right
  116.  
  117.    static member (*)  (left : 'a Matrix, right : 'a Matrix) = let mathProvider = MathProvider.Current
  118.                                                               seq { for matrixRow in left.Rows do
  119.                                                                        for otherColumn in right.Columns ->
  120.                                                                            (matrixRow.Cells, otherColumn.Cells) ||> List.map2 (mathProvider.Add |> on <| fun c -> c.Value)
  121.                                                                                                                  |> MathProvider.sum mathProvider }
  122.                                                            |> MatrixFuncStorate.ofSeq right.ColumnCount left.RowCount
  123.    
  124.    //static member (/)  (left : 'a Matrix, right : 'a Matrix) = BinaryMathExpression (left, DivideOperator,   right)
  125.    
  126.  
  127.    static member (~+) (matrix : 'a Matrix) = let mathProvider = MathProvider.Current
  128.                                               MatrixFuncStorate.map mathProvider.Plus matrix
  129.  
  130.     static member (~-) (matrix : 'a Matrix) = let mathProvider = MathProvider.Current
  131.                                              MatrixFuncStorate.map mathProvider.Negate matrix
  132.  
  133.    
  134.    override this.ToString () = this.ToString MatrixFormatInfo<'a>.Default
  135.  
  136.     member this.ToString (provider : 'a IMatrixFormatProvider) =
  137.  
  138.        let stringMatrix = MatrixFuncStorate.map provider.ElementConverter this
  139.  
  140.        let columnLengths = [for column in stringMatrix.Columns ->
  141.                                column.Cells |> Seq.map (fun cell -> cell.Value.Length) |> Seq.max ]
  142.  
  143.  
  144.        String.join provider.RowSeparator [for row in stringMatrix.Rows -> String.join provider.ColumnSeparator [for cell in row.Cells -> String (' ', columnLengths.[cell.Column.Index] - cell.Value.Length) + cell.Value]]
  145.        
  146.  
  147.    
  148.  
  149.  
  150. and 'a MatrixRow internal (matrix : 'a Matrix, index, items) as this =
  151.  
  152.    let cells = lazy [for columnIndex, value in Seq.mapi (curry id) items -> MatrixCell (this, List.nth matrix.Columns columnIndex, value)]
  153.  
  154.    member this.Matrix : 'a Matrix          = matrix
  155.  
  156.     member this.Index  : int                = index
  157.  
  158.     member this.Cells  : 'a MatrixCell list = cells.Value
  159.  
  160.  
  161.  
  162.  
  163. and 'a MatrixColumn internal (matrix : 'a Matrix, index, lazyCells) =
  164.  
  165.    let cells = lazy (lazyCells |> List.map (fun lazyCell -> lazyCell.Value))
  166.  
  167.    member this.Matrix : 'a Matrix          = matrix
  168.  
  169.     member this.Index  : int                = index
  170.  
  171.     member this.Cells  : 'a MatrixCell list = cells.Value
  172.  
  173.  
  174.  
  175.  
  176. and 'a MatrixCell internal (row, column, value) =
  177.  
  178.     member this.Row    : 'a MatrixRow    = row
  179.  
  180.    member this.Column : 'a MatrixColumn = column
  181.  
  182.     member this.Value  : 'a              = value
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement