1 #Region "Microsoft.VisualBasic::00dde34ef075f4a0fbfe133e6cf0db56, 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, 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         Public Iterator Function Subset(booleans As IEnumerable(Of Boolean)) As IEnumerable(Of T)
281             For Each index In booleans.SeqIterator
282                 If index.value = True Then
283                     Yield buffer(index.i)
284                 End If
285             Next
286         End Function
287
288         ''' <summary>
289         ''' Select all of the elements from this list collection is any of them match the condition expression: <paramref name="where"/>
290         ''' </summary>
291         ''' <param name="[where]"></param>
292         ''' <returns></returns>
293         Default Public Overloads ReadOnly Property Item([where] As Predicate(Of T)) As T()
294             <MethodImpl(MethodImplOptions.AggressiveInlining)>
295             Get
296                 Return buffer.Where(Function(o) where(o)).ToArray
297             End Get
298         End Property
299
300         ''' <summary>
301         ''' Select elements by logical condiction result.
302         ''' </summary>
303         ''' <param name="booleans"></param>
304         ''' <returns></returns>
305         Default Public Overridable Overloads Property Item(booleans As IEnumerable(Of Boolean)) As Vector(Of T)
306             <MethodImpl(MethodImplOptions.AggressiveInlining)>
307             Get
308                 Return New Vector(Of T)(Me(indices:=Linq.Which.IsTrue(booleans)))
309             End Get
310             Set(value As Vector(Of T))
311                 For Each i In booleans.SeqIterator
312                     If i.value Then
313                         buffer(i) = value(i)
314                     End If
315                 Next
316             End Set
317         End Property
318 #End Region
319
320 #Region "Constructor"
321         Public Sub New()
322         End Sub
323
324         Sub New(capacity%)
325             buffer = New T(capacity - 1) {}
326         End Sub
327
328         ''' <summary>
329         ''' 构建一个新的向量对象,这个向量对象只提供基本的数据存储和访问模型,并没有提供高级的动态处理和模式解析的操作
330         ''' </summary>
331         ''' <param name="data"></param>
332         Sub New(data As IEnumerable(Of T))
333             buffer = data.ToArray
334         End Sub
335 #End Region
336
337         Public Overrides Function ToString() As String
338             Return $"{buffer.Length} @ {GetType(T).FullName}"
339         End Function
340
341         Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
342             For Each x In buffer
343                 Yield x
344             Next
345         End Function
346
347         Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
348             Yield GetEnumerator()
349         End Function
350
351         <MethodImpl(MethodImplOptions.AggressiveInlining)>
352         Public Function Which(assert As Func(Of T, Boolean)) As Integer()
353             Return Linq.Which.IsTrue(Me.Select(assert))
354         End Function
355
356         ''' <summary>
357         ''' 没用???
358         ''' </summary>
359         ''' <param name="v"></param>
360         ''' <returns></returns>
361         Public Overloads Shared Narrowing Operator CType(v As Vector(Of T)) As T()
362             Return v.buffer.ToArray
363         End Operator
364
365         Public Overloads Shared Narrowing Operator CType(v As Vector(Of T)) As List(Of T)
366             Return v.buffer.AsList
367         End Operator
368
369         ''' <summary>
370         ''' Append the elements in vector <paramref name="a"/> with all of the elements in vector <paramref name="b"/> directly.
371         ''' Union two collection directly without <see cref="Enumerable.Distinct"/> operation.
372         ''' (请注意,使用<see cref="CollectionSet"/>集合对象的Union功能会去除重复,而这个操作符则是直接进行合并取``并集``而不去重)
373         ''' </summary>
374         ''' <param name="a"></param>
375         ''' <param name="b"></param>
376         ''' <returns></returns>
377         ''' 
378         <MethodImpl(MethodImplOptions.AggressiveInlining)>
379         Public Overloads Shared Operator &(a As Vector(Of T), b As Vector(Of T)) As Vector(Of T)
380             Return New Vector(Of T)(a.buffer.AsList + b.buffer)
381         End Operator
382     End Class
383 End Namespace