1 #Region "Microsoft.VisualBasic::89b92c1ad139283aee322604f715bad3, Microsoft.VisualBasic.Core\Extensions\Collection\Matrix.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     Module MatrixExtensions
35     
36     '     Function: DATA, MAT, (+2 Overloads) Matrix, RowIterator, ToFloatMatrix
37     '               ToMatrix, ToVectorList
38     
39     ' /********************************************************************************/
40
41 #End Region
42
43 Imports System.Runtime.CompilerServices
44 Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
45 Imports Microsoft.VisualBasic.Language
46 Imports Microsoft.VisualBasic.Linq
47
48 Public Module MatrixExtensions
49
50     ''' <summary>
51     ''' 将数据集之中的虽有属性值取出来构建一个矩阵
52     ''' </summary>
53     ''' <param name="data"></param>
54     ''' <returns></returns>
55     Public Iterator Function Matrix(Of T, DataSet As DynamicPropertyBase(Of T))(data As IEnumerable(Of DataSet)) As IEnumerable(Of T())
56         With data.ToArray
57             Dim allFields = .Select(Function(x) x.Properties.Keys) _
58                             .IteratesALL _
59                             .Distinct _
60                             .ToArray
61
62             For Each x As DataSet In .ByRef
63                 ' 利用属性名列表做subset,得到每一个数据对象的属性向量
64                 Yield x.ItemValue(allFields)
65             Next
66         End With
67     End Function
68
69     <MethodImpl(MethodImplOptions.AggressiveInlining)>
70     <Extension>
71     Public Function Matrix(Of DataSet As DynamicPropertyBase(Of Double))(data As IEnumerable(Of DataSet)) As IEnumerable(Of Double())
72         Return Matrix(Of Double, DataSet)(data)
73     End Function
74
75     '<MethodImpl(MethodImplOptions.AggressiveInlining)>
76     '<Extension>
77     'Public Function Matrix(Of DataSet As DynamicPropertyBase(Of String))(data As IEnumerable(Of DataSet)) As IEnumerable(Of String())
78     '    Return Matrix(Of String, DataSet)(data)
79     'End Function
80
81     ''' <summary>
82     ''' Converts a <see cref="DataTable"/> to a 2-dimensional array
83     ''' </summary>
84     ''' <param name="table">A System.Data.DataTable containing data to cluster</param>
85     ''' <returns>A 2-dimensional array containing data to cluster</returns>
86     <Extension> Public Function ToFloatMatrix(table As DataTable) As Double(,)
87         Dim rowCount As Integer = table.Rows.Count
88         Dim fieldCount As Integer = table.Columns.Count
89         Dim dataPoints As Double(,)
90         Dim fieldValue As Double = 0.0
91         Dim row As DataRow
92
93         dataPoints = New Double(rowCount - 1, fieldCount - 1) {}
94
95         For rowPosition As Integer = 0 To rowCount - 1
96             row = table.Rows(rowPosition)
97
98             For fieldPosition As Integer = 0 To fieldCount - 1
99                 Try
100                     fieldValue = Double.Parse(row(fieldPosition).ToString())
101                 Catch ex As Exception
102                     Dim msg$ = $"Invalid row at {rowPosition.ToString()} and field {fieldPosition.ToString()}"
103                     ex = New InvalidCastException(msg, ex)
104                     ex.PrintException
105
106                     Throw ex
107                 End Try
108
109                 dataPoints(rowPosition, fieldPosition) = fieldValue
110             Next
111         Next
112
113         Return dataPoints
114     End Function
115
116     ''' <summary>
117     ''' Gets property field data from a generic data frame
118     ''' </summary>
119     ''' <typeparam name="T"></typeparam>
120     ''' <param name="dataframe"></param>
121     ''' <param name="property$"></param>
122     ''' <returns></returns>
123     ''' 
124     <MethodImpl(MethodImplOptions.AggressiveInlining)>
125     <Extension>
126     Public Function DATA(Of T)(dataframe As IEnumerable(Of DynamicPropertyBase(Of T)), property$) As T()
127         Return dataframe.Select(Function(d) d([property])).ToArray
128     End Function
129
130     ''' <summary>
131     ''' 生成一个有m行n列的矩阵,但是是使用数组来表示的
132     ''' </summary>
133     ''' <typeparam name="T"></typeparam>
134     ''' <param name="m"></param>
135     ''' <param name="n"></param>
136     ''' <returns></returns>
137     Public Function MAT(Of T)(m%, n%) As T()()
138         Dim newMAT As T()() = New T(m - 1)() {}
139
140         For i As Integer = 0 To m - 1
141             newMAT(i) = New T(n - 1) {}
142         Next
143
144         Return newMAT
145     End Function
146
147     ''' <summary>
148     ''' Convert the data collection into a matrix value.
149     ''' </summary>
150     ''' <typeparam name="T"></typeparam>
151     ''' <param name="source">The elements number in each collection should be agreed!(要求集合之中的每一列之中的数据的元素数目都相等)</param>
152     ''' <returns></returns>
153     ''' <remarks></remarks>
154     <Extension> Public Function ToMatrix(Of T)(source As IEnumerable(Of IEnumerable(Of T))) As T(,)
155         Dim array As IEnumerable(Of T)() = source.ToArray
156         Dim width As Integer = array(Scan0).Count
157         Dim height As Integer = array.Length
158         Dim M As T(,) = New T(height - 1, width - 1) {}
159
160         For i As Integer = 0 To height - 1
161             Dim V As T() = array(i).ToArray
162
163             For j As Integer = 0 To width - 1
164                 M(i, j) = V(j)
165             Next
166         Next
167
168         Return M
169     End Function
170
171     ''' <summary>
172     ''' Convert the matrix data into a collection of collection data type.(将矩阵对象转换为集合的集合的类型)
173     ''' </summary>
174     ''' <typeparam name="T"></typeparam>
175     ''' <param name="MAT"></param>
176     ''' <returns></returns>
177     ''' <remarks></remarks>
178     ''' 
179     <MethodImpl(MethodImplOptions.AggressiveInlining)>
180     <Extension> Public Function ToVectorList(Of T)(MAT As T(,)) As List(Of T())
181         Return MAT.RowIterator.AsList
182     End Function
183
184     ''' <summary>
185     ''' Iterates each row data in a matrix type array.
186     ''' </summary>
187     ''' <typeparam name="T"></typeparam>
188     ''' <param name="MAT"></param>
189     ''' <returns></returns>
190     <Extension>
191     Public Iterator Function RowIterator(Of T)(MAT As T(,)) As IEnumerable(Of T())
192         Dim width As Integer = MAT.GetLength(1)
193         Dim height As Integer = MAT.GetLength(0)
194         Dim Temp As T()
195
196         For i As Integer = 0 To height - 1
197             Temp = New T(width - 1) {}
198
199             For j As Integer = 0 To width - 1
200                 Temp(j) = MAT(i, j)
201             Next
202
203             Yield Temp
204         Next
205     End Function
206 End Module