1 #Region "Microsoft.VisualBasic::2321c4bfd9b582b8e1392039335ce8aa, Microsoft.VisualBasic.Core\Language\Linq\Vectorization\Vector.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     '     Class Vector
35     
36     '         Properties: Array, First, IsSingle, Last, Length
37     
38     '         Constructor: (+3 OverloadsSub New
39     '         FunctionGetEnumerator, IEnumerable_GetEnumerator, Subset, ToString, Which
40     
41     
42     ' /********************************************************************************/
43
44 #End Region
45
46 Imports System.Dynamic
47 Imports System.Runtime.CompilerServices
48 Imports Microsoft.VisualBasic.ComponentModel
49 Imports Microsoft.VisualBasic.ComponentModel.Ranges.Model
50 Imports Microsoft.VisualBasic.Linq
51 Imports Microsoft.VisualBasic.Scripting.Expressions
52 Imports CollectionSet = Microsoft.VisualBasic.ComponentModel.DataStructures.Set
53
54 Namespace Language.Vectorization
55
56     ''' <summary>
57     ''' VB.NET object collection
58     ''' </summary>
59     ''' <typeparam name="T"></typeparam>
60     Public Class Vector(Of T) : Inherits DynamicObject
61         Implements IEnumerable(Of T)
62
63         ''' <summary>
64         ''' Array that hold the .NET object in this collection
65         ''' </summary>
66         Protected buffer As T()
67
68         ''' <summary>
69         ''' Gets the element counts in this vector collection
70         ''' </summary>
71         ''' <returns></returns>
72         Public ReadOnly Property Length As Integer
73             <MethodImpl(MethodImplOptions.AggressiveInlining)>
74             Get
75                 Return buffer.Length
76             End Get
77         End Property
78
79         Public ReadOnly Property IsSingle As Boolean
80             Get
81                 Return Length = 1
82             End Get
83         End Property
84
85         ''' <summary>
86         ''' 请注意,这个属性是直接返回内部数组的引用,所以对这个属性的数组内的元素的修改将会直接修改这个向量的值
87         ''' 如果不希望将内部引用进行修改,请使用迭代器或者<see cref="Enumerable.ToArray"/> Linq拓展
88         ''' </summary>
89         ''' <returns></returns>
90         Public ReadOnly Property Array As T()
91             <MethodImpl(MethodImplOptions.AggressiveInlining)>
92             Get
93                 Return buffer
94             End Get
95         End Property
96
97 #Region ""
98         ''' <summary>
99         ''' The last elements in the collection <see cref="List(Of T)"/>
100         ''' </summary>
101         ''' <returns></returns>
102         Public Property Last As T
103             Get
104                 If Length = 0 Then
105                     Return Nothing
106                 Else
107                     Return buffer(Length - 1)
108                 End If
109             End Get
110             Set(value As T)
111                 If Length = 0 Then
112                     Throw New IndexOutOfRangeException
113                 Else
114                     buffer(Length - 1) = value
115                 End If
116             End Set
117         End Property
118
119         ''' <summary>
120         ''' The first elements in the collection <see cref="List(Of T)"/>
121         ''' </summary>
122         ''' <returns></returns>
123         Public Property First As T
124             Get
125                 If Length = 0 Then
126                     Return Nothing
127                 Else
128                     Return buffer(0)
129                 End If
130             End Get
131             Set(value As T)
132                 If Length = 0 Then
133                     Throw New IndexOutOfRangeException
134                 Else
135                     buffer(Scan0) = value
136                 End If
137             End Set
138         End Property
139
140         ''' <summary>
141         ''' 
142         ''' </summary>
143         ''' <param name="args">同时支持boolean和integer</param>
144         ''' <returns></returns>
145         Default Public Overloads Property Item(args As ObjectAs List(Of T)
146             Get
147                 Dim index = Indexer.Indexing(args)
148                 Return Me(index)
149             End Get
150             Set
151                 Dim index = Indexer.Indexing(args)
152                 Me(index) = Value
153             End Set
154         End Property
155
156         ''' <summary>
157         ''' This indexer property is using for the ODEs-system computing.
158         ''' (这个是为了ODEs计算模块所准备的一个数据接口)
159         ''' </summary>
160         ''' <param name="address"></param>
161         ''' <returns></returns>
162         Default Public Overloads Property Item(address As IAddress(Of Integer)) As T
163             <MethodImpl(MethodImplOptions.AggressiveInlining)>
164             Get
165                 Return buffer(address.Address)
166             End Get
167             <MethodImpl(MethodImplOptions.AggressiveInlining)>
168             Set(value As T)
169                 buffer(address.Address) = value
170             End Set
171         End Property
172
173 #Region "2017-7-22 -1索引好像对向量的意义不大,而且会降低代码性能,所以在这里去除了这个索引属性"
174
175         '''' <summary>
176         '''' Can accept negative number as the index value, negative value means ``<see cref="Count"/> - n``, 
177         '''' example as ``list(-1)``: means the last element in this list: ``list(list.Count -1)``
178         '''' </summary>
179         '''' <param name="index%"></param>
180         '''' <returns></returns>
181         'Default Public Overloads Property Item(index%) As T
182         '    Get
183         '        If index < 0 Then
184         '            index = Count + index  ' -1 -> count -1
185         '        End If
186         '        Return buffer(index)
187         '    End Get
188         '    Set(value As T)
189         '        If index < 0 Then
190         '            index = Count + index  ' -1 -> count -1
191         '        End If
192
193         '        buffer(index) = value
194         '    End Set
195         'End Property
196
197         ''' <summary>
198         ''' Direct get the element in the array by its index.
199         ''' </summary>
200         ''' <param name="index%"></param>
201         ''' <returns></returns>
202         Default Public Overloads Property Item(index%) As T
203             <MethodImpl(MethodImplOptions.AggressiveInlining)>
204             Get
205                 Return buffer(index)
206             End Get
207             <MethodImpl(MethodImplOptions.AggressiveInlining)>
208             Set(value As T)
209                 buffer(index) = value
210             End Set
211         End Property
212 #End Region
213
214         ''' <summary>
215         ''' Using a index vector expression to select/update many elements from this list collection.
216         ''' </summary>
217         ''' <param name="exp$">
218         ''' + ``1``, index=1
219         ''' + ``1:8``, index=1, count=8
220         ''' + ``1->8``, index from 1 to 8
221         ''' + ``8->1``, index from 8 to 1
222         ''' + ``1,2,3,4``, index=1 or  2 or 3 or 4
223         ''' </param>
224         ''' <returns></returns>
225         Default Public Overloads Property Item(exp$) As List(Of T)
226             Get
227                 Dim list As New List(Of T)
228
229                 For Each i% In exp.TranslateIndex
230                     list += buffer(i)
231                 Next
232
233                 Return list
234             End Get
235             Set(value As List(Of T))
236                 Dim index%() = exp.TranslateIndex
237
238                 For Each i As SeqValue(Of IntegerIn index.SeqIterator
239                     buffer(i.value) = value(i.i)
240                 Next
241             End Set
242         End Property
243
244         ''' <summary>
245         ''' Get subset of the collection by using a continues index
246         ''' </summary>
247         ''' <param name="range"></param>
248         ''' <returns></returns>
249         Default Public Overloads Property Item(range As IntRange) As List(Of T)
250             <MethodImpl(MethodImplOptions.AggressiveInlining)>
251             Get
252                 Return New List(Of T)(Me.Skip(range.Min).Take(range.Length))
253             End Get
254             Set(value As List(Of T))
255                 Dim indices As Integer() = range.ToArray
256
257                 For i As Integer = 0 To indices.Length - 1
258                     buffer(indices(i)) = value(i)
259                 Next
260             End Set
261         End Property
262
263         ''' <summary>
264         ''' Gets subset of the collection by using a discontinues index
265         ''' </summary>
266         ''' <param name="indices"></param>
267         ''' <returns></returns>
268         Default Public Overloads Property Item(indices As IEnumerable(Of Integer)) As List(Of T)
269             <MethodImpl(MethodImplOptions.AggressiveInlining)>
270             Get
271                 Return New List(Of T)(indices.Select(Function(i) buffer(i)))
272             End Get
273             Set(value As List(Of T))
274                 For Each i As SeqValue(Of IntegerIn indices.SeqIterator
275                     buffer(+i) = value(i.i)
276                 Next
277             End Set
278         End Property
279
280         ''' <summary>
281         ''' 从当前的向量序列之中进行向量子集的截取
282         ''' </summary>
283         ''' <param name="booleans"></param>
284         ''' <returns></returns>
285         Public Iterator Function Subset(booleans As IEnumerable(Of Boolean)) As IEnumerable(Of T)
286             For Each index In booleans.SeqIterator
287                 If index.value = True Then
288                     Yield buffer(index.i)
289                 End If
290             Next
291         End Function
292
293         ''' <summary>
294         ''' Select all of the elements from this list collection is any of them match the condition expression: <paramref name="where"/>
295         ''' </summary>
296         ''' <param name="[where]"></param>
297         ''' <returns></returns>
298         Default Public Overloads ReadOnly Property Item([where] As Predicate(Of T)) As T()
299             <MethodImpl(MethodImplOptions.AggressiveInlining)>
300             Get
301                 Return buffer.Where(Function(o) where(o)).ToArray
302             End Get
303         End Property
304
305         ''' <summary>
306         ''' Select elements by logical condiction result.
307         ''' </summary>
308         ''' <param name="booleans"></param>
309         ''' <returns></returns>
310         Default Public Overridable Overloads Property Item(booleans As IEnumerable(Of Boolean)) As Vector(Of T)
311             <MethodImpl(MethodImplOptions.AggressiveInlining)>
312             Get
313                 Return New Vector(Of T)(Me(indices:=Linq.Which.IsTrue(booleans)))
314             End Get
315             Set(value As Vector(Of T))
316                 For Each i In booleans.SeqIterator
317                     If i.value Then
318                         buffer(i) = value(i)
319                     End If
320                 Next
321             End Set
322         End Property
323 #End Region
324
325 #Region "Constructor"
326         Public Sub New()
327         End Sub
328
329         Sub New(capacity%)
330             buffer = New T(capacity - 1) {}
331         End Sub
332
333         ''' <summary>
334         ''' 构建一个新的向量对象,这个向量对象只提供基本的数据存储和访问模型,并没有提供高级的动态处理和模式解析的操作
335         ''' </summary>
336         ''' <param name="data"></param>
337         Sub New(data As IEnumerable(Of T))
338             buffer = data.ToArray
339         End Sub
340 #End Region
341
342         Public Overrides Function ToString() As String
343             Return $"{buffer.Length} @ {GetType(T).FullName}"
344         End Function
345
346         Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
347             For Each x In buffer
348                 Yield x
349             Next
350         End Function
351
352         Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
353             Yield GetEnumerator()
354         End Function
355
356         <MethodImpl(MethodImplOptions.AggressiveInlining)>
357         Public Function Which(assert As Func(Of T, Boolean)) As Integer()
358             Return Linq.Which.IsTrue(Me.Select(assert))
359         End Function
360
361         ''' <summary>
362         ''' 没用???
363         ''' </summary>
364         ''' <param name="v"></param>
365         ''' <returns></returns>
366         Public Overloads Shared Narrowing Operator CType(v As Vector(Of T)) As T()
367             Return v.buffer.ToArray
368         End Operator
369
370         Public Overloads Shared Narrowing Operator CType(v As Vector(Of T)) As List(Of T)
371             Return v.buffer.AsList
372         End Operator
373
374         ''' <summary>
375         ''' Append the elements in vector <paramref name="a"/> with all of the elements in vector <paramref name="b"/> directly.
376         ''' Union two collection directly without <see cref="Enumerable.Distinct"/> operation.
377         ''' (请注意,使用<see cref="CollectionSet"/>集合对象的Union功能会去除重复,而这个操作符则是直接进行合并取``并集``而不去重)
378         ''' </summary>
379         ''' <param name="a"></param>
380         ''' <param name="b"></param>
381         ''' <returns></returns>
382         ''' 
383         <MethodImpl(MethodImplOptions.AggressiveInlining)>
384         Public Overloads Shared Operator &(a As Vector(Of T), b As Vector(Of T)) As Vector(Of T)
385             Return New Vector(Of T)(a.buffer.AsList + b.buffer)
386         End Operator
387     End Class
388 End Namespace