2019-06-04 20:43:55 +08:00
|
|
|
|
#Region "Microsoft.VisualBasic::44bec93731efa49cd5c9e88b17824d27, Microsoft.VisualBasic.Core\Extensions\Collection\Matrix.vb"
|
2018-12-19 20:25:34 +08:00
|
|
|
|
|
|
|
|
|
|
' Author:
|
|
|
|
|
|
'
|
|
|
|
|
|
' asuka (amethyst.asuka@gcmodeller.org)
|
|
|
|
|
|
' xie (genetics@smrucc.org)
|
|
|
|
|
|
' xieguigang (xie.guigang@live.com)
|
|
|
|
|
|
'
|
|
|
|
|
|
' Copyright (c) 2018 GPL3 Licensed
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' GNU GENERAL PUBLIC LICENSE (GPL3)
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is free software: you can redistribute it and/or modify
|
|
|
|
|
|
' it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
' the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
' (at your option) any later version.
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
' but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
' GNU General Public License for more details.
|
|
|
|
|
|
'
|
|
|
|
|
|
' You should have received a copy of the GNU General Public License
|
|
|
|
|
|
' along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
' Summaries:
|
|
|
|
|
|
|
|
|
|
|
|
' Module MatrixExtensions
|
|
|
|
|
|
'
|
|
|
|
|
|
' Function: DATA, GetCol, GetRow, GetSize, MAT
|
2019-06-04 20:43:55 +08:00
|
|
|
|
' (+2 Overloads) Matrix, Rectangle, RowIterator, SetCol, SetRow
|
|
|
|
|
|
' SizeOf, ToFloatMatrix, ToMatrix, ToVectorList
|
2018-12-19 20:25:34 +08:00
|
|
|
|
'
|
|
|
|
|
|
' /********************************************************************************/
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
2018-12-15 21:22:43 +08:00
|
|
|
|
Imports System.Drawing
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Imports System.Runtime.CompilerServices
|
|
|
|
|
|
Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Language
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Linq
|
|
|
|
|
|
|
|
|
|
|
|
Public Module MatrixExtensions
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 将数据集之中的虽有属性值取出来构建一个矩阵
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="data"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Iterator Function Matrix(Of T, DataSet As DynamicPropertyBase(Of T))(data As IEnumerable(Of DataSet)) As IEnumerable(Of T())
|
|
|
|
|
|
With data.ToArray
|
|
|
|
|
|
Dim allFields = .Select(Function(x) x.Properties.Keys) _
|
|
|
|
|
|
.IteratesALL _
|
|
|
|
|
|
.Distinct _
|
|
|
|
|
|
.ToArray
|
|
|
|
|
|
|
|
|
|
|
|
For Each x As DataSet In .ByRef
|
|
|
|
|
|
' 利用属性名列表做subset,得到每一个数据对象的属性向量
|
|
|
|
|
|
Yield x.ItemValue(allFields)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End With
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function Matrix(Of DataSet As DynamicPropertyBase(Of Double))(data As IEnumerable(Of DataSet)) As IEnumerable(Of Double())
|
|
|
|
|
|
Return Matrix(Of Double, DataSet)(data)
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
'<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
'<Extension>
|
|
|
|
|
|
'Public Function Matrix(Of DataSet As DynamicPropertyBase(Of String))(data As IEnumerable(Of DataSet)) As IEnumerable(Of String())
|
|
|
|
|
|
' Return Matrix(Of String, DataSet)(data)
|
|
|
|
|
|
'End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Converts a <see cref="DataTable"/> to a 2-dimensional array
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="table">A System.Data.DataTable containing data to cluster</param>
|
|
|
|
|
|
''' <returns>A 2-dimensional array containing data to cluster</returns>
|
|
|
|
|
|
<Extension> Public Function ToFloatMatrix(table As DataTable) As Double(,)
|
|
|
|
|
|
Dim rowCount As Integer = table.Rows.Count
|
|
|
|
|
|
Dim fieldCount As Integer = table.Columns.Count
|
|
|
|
|
|
Dim dataPoints As Double(,)
|
|
|
|
|
|
Dim fieldValue As Double = 0.0
|
|
|
|
|
|
Dim row As DataRow
|
|
|
|
|
|
|
|
|
|
|
|
dataPoints = New Double(rowCount - 1, fieldCount - 1) {}
|
|
|
|
|
|
|
|
|
|
|
|
For rowPosition As Integer = 0 To rowCount - 1
|
|
|
|
|
|
row = table.Rows(rowPosition)
|
|
|
|
|
|
|
|
|
|
|
|
For fieldPosition As Integer = 0 To fieldCount - 1
|
|
|
|
|
|
Try
|
|
|
|
|
|
fieldValue = Double.Parse(row(fieldPosition).ToString())
|
|
|
|
|
|
Catch ex As Exception
|
|
|
|
|
|
Dim msg$ = $"Invalid row at {rowPosition.ToString()} and field {fieldPosition.ToString()}"
|
|
|
|
|
|
ex = New InvalidCastException(msg, ex)
|
|
|
|
|
|
ex.PrintException
|
|
|
|
|
|
|
|
|
|
|
|
Throw ex
|
|
|
|
|
|
End Try
|
|
|
|
|
|
|
|
|
|
|
|
dataPoints(rowPosition, fieldPosition) = fieldValue
|
|
|
|
|
|
Next
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return dataPoints
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Gets property field data from a generic data frame
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
''' <param name="dataframe"></param>
|
|
|
|
|
|
''' <param name="property$"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
'''
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function DATA(Of T)(dataframe As IEnumerable(Of DynamicPropertyBase(Of T)), property$) As T()
|
|
|
|
|
|
Return dataframe.Select(Function(d) d([property])).ToArray
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
2018-12-15 21:22:43 +08:00
|
|
|
|
''' Create an empty matrix with m row and n cols.
|
|
|
|
|
|
''' (生成一个有m行n列的矩阵,但是是使用数组来表示的)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
2018-12-15 21:22:43 +08:00
|
|
|
|
''' <param name="m">m Rows</param>
|
|
|
|
|
|
''' <param name="n">n Cols</param>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Function MAT(Of T)(m%, n%) As T()()
|
|
|
|
|
|
Dim newMAT As T()() = New T(m - 1)() {}
|
|
|
|
|
|
|
|
|
|
|
|
For i As Integer = 0 To m - 1
|
|
|
|
|
|
newMAT(i) = New T(n - 1) {}
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return newMAT
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2019-05-26 00:31:30 +08:00
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function Rectangle(type As Type, m%, n%) As Array
|
|
|
|
|
|
Dim newMatrix As Array = Array.CreateInstance(type.MakeArrayType, m)
|
|
|
|
|
|
|
|
|
|
|
|
For i As Integer = 0 To m - 1
|
|
|
|
|
|
Call newMatrix.SetValue(Array.CreateInstance(type, n), i)
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return newMatrix
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2019-05-29 21:17:06 +08:00
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function SizeOf(Of T)(rect As T()()) As Size
|
|
|
|
|
|
Return New Size With {
|
|
|
|
|
|
.Width = rect(Scan0).Length,
|
|
|
|
|
|
.Height = rect.Length
|
|
|
|
|
|
}
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Convert the data collection into a matrix value.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
''' <param name="source">The elements number in each collection should be agreed!(要求集合之中的每一列之中的数据的元素数目都相等)</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
''' <remarks></remarks>
|
|
|
|
|
|
<Extension> Public Function ToMatrix(Of T)(source As IEnumerable(Of IEnumerable(Of T))) As T(,)
|
|
|
|
|
|
Dim array As IEnumerable(Of T)() = source.ToArray
|
|
|
|
|
|
Dim width As Integer = array(Scan0).Count
|
|
|
|
|
|
Dim height As Integer = array.Length
|
|
|
|
|
|
Dim M As T(,) = New T(height - 1, width - 1) {}
|
|
|
|
|
|
|
|
|
|
|
|
For i As Integer = 0 To height - 1
|
|
|
|
|
|
Dim V As T() = array(i).ToArray
|
|
|
|
|
|
|
|
|
|
|
|
For j As Integer = 0 To width - 1
|
|
|
|
|
|
M(i, j) = V(j)
|
|
|
|
|
|
Next
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return M
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Convert the matrix data into a collection of collection data type.(将矩阵对象转换为集合的集合的类型)
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
''' <param name="MAT"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
''' <remarks></remarks>
|
|
|
|
|
|
'''
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
<Extension> Public Function ToVectorList(Of T)(MAT As T(,)) As List(Of T())
|
|
|
|
|
|
Return MAT.RowIterator.AsList
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-12-15 21:22:43 +08:00
|
|
|
|
#Region "Matrix Accessor Helper"
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Get matrix width and height values.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
''' <param name="m"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function GetSize(Of T)(m As T(,)) As Size
|
|
|
|
|
|
Dim w As Integer = m.GetLength(1)
|
|
|
|
|
|
Dim h As Integer = m.GetLength(0)
|
|
|
|
|
|
|
|
|
|
|
|
Return New Size With {
|
|
|
|
|
|
.Width = w,
|
|
|
|
|
|
.Height = h
|
|
|
|
|
|
}
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Iterates each row data in a matrix type array.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
''' <param name="MAT"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Iterator Function RowIterator(Of T)(MAT As T(,)) As IEnumerable(Of T())
|
2018-12-15 21:22:43 +08:00
|
|
|
|
Dim size As Size = MAT.GetSize
|
|
|
|
|
|
Dim temp As T()
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2018-12-15 21:22:43 +08:00
|
|
|
|
For i As Integer = 0 To size.Height - 1
|
|
|
|
|
|
temp = New T(size.Width - 1) {}
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2018-12-15 21:22:43 +08:00
|
|
|
|
For j As Integer = 0 To size.Width - 1
|
|
|
|
|
|
temp(j) = MAT(i, j)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Next
|
|
|
|
|
|
|
2018-12-15 21:22:43 +08:00
|
|
|
|
Yield temp
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Next
|
|
|
|
|
|
End Function
|
2018-12-15 21:22:43 +08:00
|
|
|
|
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Iterator Function GetRow(Of T)(m As T(,), i%) As IEnumerable(Of T)
|
|
|
|
|
|
Dim size As Size = m.GetSize
|
|
|
|
|
|
|
|
|
|
|
|
For j As Integer = 0 To size.Width - 1
|
|
|
|
|
|
Yield m(i, j)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function SetRow(Of T)(m As T(,), i%, data As IEnumerable(Of T)) As T(,)
|
|
|
|
|
|
Dim size As Size = m.GetSize
|
|
|
|
|
|
Dim j% = Scan0
|
|
|
|
|
|
|
|
|
|
|
|
For Each x As T In data
|
|
|
|
|
|
m(i, j) = x
|
|
|
|
|
|
j += 1
|
|
|
|
|
|
|
|
|
|
|
|
If j = size.Width Then
|
|
|
|
|
|
Exit For
|
|
|
|
|
|
End If
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return m
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Iterator Function GetCol(Of T)(m As T(,), j%) As IEnumerable(Of T)
|
|
|
|
|
|
Dim size As Size = m.GetSize
|
|
|
|
|
|
|
|
|
|
|
|
For i As Integer = 0 To size.Height - 1
|
|
|
|
|
|
Yield m(i, j)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<Extension>
|
|
|
|
|
|
Public Function SetCol(Of T)(m As T(,), j%, data As IEnumerable(Of T)) As T(,)
|
|
|
|
|
|
Dim size As Size = m.GetSize
|
|
|
|
|
|
Dim i% = Scan0
|
|
|
|
|
|
|
|
|
|
|
|
For Each x As T In data
|
|
|
|
|
|
m(i, j) = x
|
|
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
|
|
|
|
If i = size.Height Then
|
|
|
|
|
|
Exit For
|
|
|
|
|
|
End If
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return m
|
|
|
|
|
|
End Function
|
|
|
|
|
|
#End Region
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Module
|