2019-08-11 12:22:38 +08:00
|
|
|
|
#Region "Microsoft.VisualBasic::d6f151fca4df58bc36151064ea48392f, Microsoft.VisualBasic.Core\Language\Linq\Vectorization\Vector.vb"
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2020-02-14 18:42:41 +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:
|
|
|
|
|
|
|
|
|
|
|
|
' Class Vector
|
|
|
|
|
|
'
|
|
|
|
|
|
' Properties: Array, First, IsSingle, Last, Length
|
|
|
|
|
|
'
|
|
|
|
|
|
' Constructor: (+3 Overloads) Sub New
|
|
|
|
|
|
' Function: GetEnumerator, IEnumerable_GetEnumerator, Subset, ToString, Which
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' /********************************************************************************/
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
|
|
|
|
Imports System.Dynamic
|
|
|
|
|
|
Imports System.Runtime.CompilerServices
|
|
|
|
|
|
Imports Microsoft.VisualBasic.ComponentModel
|
|
|
|
|
|
Imports Microsoft.VisualBasic.ComponentModel.Ranges.Model
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Linq
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Scripting.Expressions
|
|
|
|
|
|
Imports CollectionSet = Microsoft.VisualBasic.ComponentModel.DataStructures.Set
|
|
|
|
|
|
|
|
|
|
|
|
Namespace Language.Vectorization
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' VB.NET object collection
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <typeparam name="T"></typeparam>
|
|
|
|
|
|
Public Class Vector(Of T) : Inherits DynamicObject
|
|
|
|
|
|
Implements IEnumerable(Of T)
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Array that hold the .NET object in this collection
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
Protected buffer As T()
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Gets the element counts in this vector collection
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
2019-08-10 01:31:53 +08:00
|
|
|
|
Public Overridable ReadOnly Property Length As Integer
|
2018-08-02 20:14:48 +08:00
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return buffer.Length
|
|
|
|
|
|
End Get
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
Public ReadOnly Property IsSingle As Boolean
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return Length = 1
|
|
|
|
|
|
End Get
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 请注意,这个属性是直接返回内部数组的引用,所以对这个属性的数组内的元素的修改将会直接修改这个向量的值
|
|
|
|
|
|
''' 如果不希望将内部引用进行修改,请使用迭代器或者<see cref="Enumerable.ToArray"/> Linq拓展
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public ReadOnly Property Array As T()
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return buffer
|
|
|
|
|
|
End Get
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
#Region ""
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' The last elements in the collection <see cref="List(Of T)"/>
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Property Last As T
|
|
|
|
|
|
Get
|
|
|
|
|
|
If Length = 0 Then
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return buffer(Length - 1)
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As T)
|
|
|
|
|
|
If Length = 0 Then
|
|
|
|
|
|
Throw New IndexOutOfRangeException
|
|
|
|
|
|
Else
|
|
|
|
|
|
buffer(Length - 1) = value
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' The first elements in the collection <see cref="List(Of T)"/>
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Property First As T
|
|
|
|
|
|
Get
|
|
|
|
|
|
If Length = 0 Then
|
|
|
|
|
|
Return Nothing
|
|
|
|
|
|
Else
|
|
|
|
|
|
Return buffer(0)
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As T)
|
|
|
|
|
|
If Length = 0 Then
|
|
|
|
|
|
Throw New IndexOutOfRangeException
|
|
|
|
|
|
Else
|
|
|
|
|
|
buffer(Scan0) = value
|
|
|
|
|
|
End If
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="args">同时支持boolean和integer</param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overloads Property Item(args As Object) As List(Of T)
|
|
|
|
|
|
Get
|
|
|
|
|
|
Dim index = Indexer.Indexing(args)
|
|
|
|
|
|
Return Me(index)
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set
|
|
|
|
|
|
Dim index = Indexer.Indexing(args)
|
|
|
|
|
|
Me(index) = Value
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' This indexer property is using for the ODEs-system computing.
|
|
|
|
|
|
''' (这个是为了ODEs计算模块所准备的一个数据接口)
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="address"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overloads Property Item(address As IAddress(Of Integer)) As T
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return buffer(address.Address)
|
|
|
|
|
|
End Get
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Set(value As T)
|
|
|
|
|
|
buffer(address.Address) = value
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
#Region "2017-7-22 -1索引好像对向量的意义不大,而且会降低代码性能,所以在这里去除了这个索引属性"
|
|
|
|
|
|
|
|
|
|
|
|
'''' <summary>
|
|
|
|
|
|
'''' Can accept negative number as the index value, negative value means ``<see cref="Count"/> - n``,
|
|
|
|
|
|
'''' example as ``list(-1)``: means the last element in this list: ``list(list.Count -1)``
|
|
|
|
|
|
'''' </summary>
|
|
|
|
|
|
'''' <param name="index%"></param>
|
|
|
|
|
|
'''' <returns></returns>
|
|
|
|
|
|
'Default Public Overloads Property Item(index%) As T
|
|
|
|
|
|
' Get
|
|
|
|
|
|
' If index < 0 Then
|
|
|
|
|
|
' index = Count + index ' -1 -> count -1
|
|
|
|
|
|
' End If
|
|
|
|
|
|
' Return buffer(index)
|
|
|
|
|
|
' End Get
|
|
|
|
|
|
' Set(value As T)
|
|
|
|
|
|
' If index < 0 Then
|
|
|
|
|
|
' index = Count + index ' -1 -> count -1
|
|
|
|
|
|
' End If
|
|
|
|
|
|
|
|
|
|
|
|
' buffer(index) = value
|
|
|
|
|
|
' End Set
|
|
|
|
|
|
'End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Direct get the element in the array by its index.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="index%"></param>
|
|
|
|
|
|
''' <returns></returns>
|
2019-08-10 01:31:53 +08:00
|
|
|
|
Default Public Overridable Overloads Property Item(index%) As T
|
2018-08-02 20:14:48 +08:00
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
2020-02-14 18:42:41 +08:00
|
|
|
|
<DebuggerStepThrough>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Get
|
|
|
|
|
|
Return buffer(index)
|
|
|
|
|
|
End Get
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
2020-02-14 18:42:41 +08:00
|
|
|
|
<DebuggerStepThrough>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Set(value As T)
|
|
|
|
|
|
buffer(index) = value
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Using a index vector expression to select/update many elements from this list collection.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="exp$">
|
|
|
|
|
|
''' + ``1``, index=1
|
|
|
|
|
|
''' + ``1:8``, index=1, count=8
|
|
|
|
|
|
''' + ``1->8``, index from 1 to 8
|
|
|
|
|
|
''' + ``8->1``, index from 8 to 1
|
|
|
|
|
|
''' + ``1,2,3,4``, index=1 or 2 or 3 or 4
|
|
|
|
|
|
''' </param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overloads Property Item(exp$) As List(Of T)
|
|
|
|
|
|
Get
|
|
|
|
|
|
Dim list As New List(Of T)
|
|
|
|
|
|
|
|
|
|
|
|
For Each i% In exp.TranslateIndex
|
|
|
|
|
|
list += buffer(i)
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return list
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As List(Of T))
|
|
|
|
|
|
Dim index%() = exp.TranslateIndex
|
|
|
|
|
|
|
|
|
|
|
|
For Each i As SeqValue(Of Integer) In index.SeqIterator
|
|
|
|
|
|
buffer(i.value) = value(i.i)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Get subset of the collection by using a continues index
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="range"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overloads Property Item(range As IntRange) As List(Of T)
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return New List(Of T)(Me.Skip(range.Min).Take(range.Length))
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As List(Of T))
|
|
|
|
|
|
Dim indices As Integer() = range.ToArray
|
|
|
|
|
|
|
|
|
|
|
|
For i As Integer = 0 To indices.Length - 1
|
|
|
|
|
|
buffer(indices(i)) = value(i)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Gets subset of the collection by using a discontinues index
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="indices"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overloads Property Item(indices As IEnumerable(Of Integer)) As List(Of T)
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return New List(Of T)(indices.Select(Function(i) buffer(i)))
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As List(Of T))
|
|
|
|
|
|
For Each i As SeqValue(Of Integer) In indices.SeqIterator
|
|
|
|
|
|
buffer(+i) = value(i.i)
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
2018-11-17 17:52:38 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 从当前的向量序列之中进行向量子集的截取
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="booleans"></param>
|
|
|
|
|
|
''' <returns></returns>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Public Iterator Function Subset(booleans As IEnumerable(Of Boolean)) As IEnumerable(Of T)
|
|
|
|
|
|
For Each index In booleans.SeqIterator
|
|
|
|
|
|
If index.value = True Then
|
|
|
|
|
|
Yield buffer(index.i)
|
|
|
|
|
|
End If
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Select all of the elements from this list collection is any of them match the condition expression: <paramref name="where"/>
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="[where]"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overloads ReadOnly Property Item([where] As Predicate(Of T)) As T()
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return buffer.Where(Function(o) where(o)).ToArray
|
|
|
|
|
|
End Get
|
|
|
|
|
|
End Property
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Select elements by logical condiction result.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="booleans"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Default Public Overridable Overloads Property Item(booleans As IEnumerable(Of Boolean)) As Vector(Of T)
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Get
|
|
|
|
|
|
Return New Vector(Of T)(Me(indices:=Linq.Which.IsTrue(booleans)))
|
|
|
|
|
|
End Get
|
|
|
|
|
|
Set(value As Vector(Of T))
|
|
|
|
|
|
For Each i In booleans.SeqIterator
|
|
|
|
|
|
If i.value Then
|
|
|
|
|
|
buffer(i) = value(i)
|
|
|
|
|
|
End If
|
|
|
|
|
|
Next
|
|
|
|
|
|
End Set
|
|
|
|
|
|
End Property
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
|
|
|
|
#Region "Constructor"
|
2020-01-04 14:34:29 +08:00
|
|
|
|
|
|
|
|
|
|
<DebuggerStepThrough>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Public Sub New()
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
2020-01-04 14:34:29 +08:00
|
|
|
|
<DebuggerStepThrough>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Sub New(capacity%)
|
|
|
|
|
|
buffer = New T(capacity - 1) {}
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 构建一个新的向量对象,这个向量对象只提供基本的数据存储和访问模型,并没有提供高级的动态处理和模式解析的操作
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="data"></param>
|
2020-01-04 14:34:29 +08:00
|
|
|
|
'''
|
|
|
|
|
|
<DebuggerStepThrough>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Sub New(data As IEnumerable(Of T))
|
|
|
|
|
|
buffer = data.ToArray
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
2020-01-04 14:34:29 +08:00
|
|
|
|
<DebuggerStepThrough>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Public Overrides Function ToString() As String
|
|
|
|
|
|
Return $"{buffer.Length} @ {GetType(T).FullName}"
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2020-01-04 14:34:29 +08:00
|
|
|
|
<DebuggerStepThrough>
|
2019-08-10 01:31:53 +08:00
|
|
|
|
Public Overridable Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
|
|
|
|
|
|
For Each element As T In buffer
|
|
|
|
|
|
Yield element
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Next
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
|
|
|
|
|
|
Yield GetEnumerator()
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Public Function Which(assert As Func(Of T, Boolean)) As Integer()
|
|
|
|
|
|
Return Linq.Which.IsTrue(Me.Select(assert))
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 没用???
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="v"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
Public Overloads Shared Narrowing Operator CType(v As Vector(Of T)) As T()
|
|
|
|
|
|
Return v.buffer.ToArray
|
|
|
|
|
|
End Operator
|
|
|
|
|
|
|
|
|
|
|
|
Public Overloads Shared Narrowing Operator CType(v As Vector(Of T)) As List(Of T)
|
|
|
|
|
|
Return v.buffer.AsList
|
|
|
|
|
|
End Operator
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Append the elements in vector <paramref name="a"/> with all of the elements in vector <paramref name="b"/> directly.
|
|
|
|
|
|
''' Union two collection directly without <see cref="Enumerable.Distinct"/> operation.
|
|
|
|
|
|
''' (请注意,使用<see cref="CollectionSet"/>集合对象的Union功能会去除重复,而这个操作符则是直接进行合并取``并集``而不去重)
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="a"></param>
|
|
|
|
|
|
''' <param name="b"></param>
|
|
|
|
|
|
''' <returns></returns>
|
|
|
|
|
|
'''
|
|
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
|
|
|
|
Public Overloads Shared Operator &(a As Vector(Of T), b As Vector(Of T)) As Vector(Of T)
|
|
|
|
|
|
Return New Vector(Of T)(a.buffer.AsList + b.buffer)
|
|
|
|
|
|
End Operator
|
|
|
|
|
|
End Class
|
|
|
|
|
|
End Namespace
|