1 #Region "Microsoft.VisualBasic::5460c30408e9b56911770355f1ae9d85, Microsoft.VisualBasic.Core\ComponentModel\Algorithm\base\SlideWindow\Extensions.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 SlideWindowExtensions
35     
36     '         Function: (+5 Overloads) [Select], __extendTails, CreateSlideWindows, SlideWindows
37     
38     
39     ' /********************************************************************************/
40
41 #End Region
42
43 Imports System.Runtime.CompilerServices
44 Imports Microsoft.VisualBasic.Language
45 Imports Microsoft.VisualBasic.Linq
46
47 Namespace ComponentModel.Algorithm.base
48
49     ''' <summary>
50     ''' Create a collection of slide Windows data for the target collection object.
51     ''' </summary>
52     Public Module SlideWindowExtensions
53
54         ''' <summary>
55         ''' Create a collection of slide Windows data for the target collection object.(创建一个滑窗集合)
56         ''' </summary>
57         ''' <typeparam name="T"></typeparam>
58         ''' <param name="data"></param>
59         ''' <param name="winSize">The windows size of the created slide window.(窗口的大小)</param>
60         ''' <param name="offset">在序列之上移动的步长</param>
61         ''' <returns></returns>
62         ''' <param name="extTails">引用类型不建议打开这个参数</param>
63         ''' <remarks></remarks>
64         <Extension> Public Function CreateSlideWindows(Of T)(data As IEnumerable(Of T), winSize%,
65                            Optional offset% = 1,
66                            Optional extTails As Boolean = FalseAs SlideWindow(Of T)()
67             Return data.SlideWindows(winSize, offset, extTails).ToArray
68         End Function
69
70         ''' <summary>
71         ''' Create a collection of slide Windows data for the target collection object.(创建一个滑窗集合)
72         ''' </summary>
73         ''' <typeparam name="T"></typeparam>
74         ''' <param name="data"></param>
75         ''' <param name="winSize">The windows size of the created slide window.(窗口的大小)</param>
76         ''' <param name="offset">在序列之上移动的步长</param>
77         ''' <returns></returns>
78         ''' <param name="extTails">引用类型不建议打开这个参数</param>
79         ''' <remarks></remarks>
80         <Extension> Public Iterator Function SlideWindows(Of T)(data As IEnumerable(Of T), winSize%, Optional offset% = 1, Optional extTails As Boolean = FalseAs IEnumerable(Of SlideWindow(Of T))
81             Dim tmp As New List(Of T)(data)
82             Dim n% = tmp.Count
83
84             If n = 0 Then
85                 ' 没有任何数据,则返回一个空集合
86                 Return
87             ElseIf winSize >= n Then
88                 Yield New SlideWindow(Of T)() With {
89                     .Left = 0,
90                     .Items = tmp.ToArray
91                 }
92                 ' 这里要return,否则会出现重复的数据
93                 Return
94             End If
95
96             If offset < 1 Then
97                 Call VBDebugger.Warning($"The offset parameter '{offset}' is not correct, set its value to 1 as default!")
98                 offset = 1
99             End If
100
101             Dim p As int = 0
102
103             n = n - winSize - 1
104
105             For i As Integer = 0 To n Step offset
106                 Dim buf As T() = tmp.Take(winSize).ToArray
107
108                 Yield New SlideWindow(Of T)() With {
109                     .Items = buf,
110                     .Left = i,
111                     .Index = ++p
112                 }
113
114                 tmp.RemoveRange(0, offset)
115             Next
116
117             If Not tmp.IsNullOrEmpty Then
118                 Dim left = n + 1
119
120                 If extTails Then
121                     ' 在这里需要使用CInt拷贝一下指针p的值,否则会以引用的方式
122                     ' 传递进入下一层函数之中造成当前的函数调用栈被修改
123                     For Each x In __extendTails(tmp, winSize, left, CInt(p))
124                         Yield x
125                     Next
126                 Else
127                     Yield New SlideWindow(Of T)() With {
128                         .Left = left,
129                         .Items = tmp.ToArray,
130                         .Index = p
131                     }
132                 End If
133             End If
134         End Function
135
136         Private Iterator Function __extendTails(Of T)(tempList As List(Of T), winSize%, left%, p As int) As IEnumerable(Of SlideWindow(Of T))
137             Dim array As T() = tempList.ToArray
138
139             For i As Integer = 0 To winSize - 1
140                 Yield New SlideWindow(Of T) With {
141                     .Left = left,
142                     .Index = ++p,
143                     .Items = array
144                 }
145
146                 left += 1
147             Next
148         End Function
149
150         <MethodImpl(MethodImplOptions.AggressiveInlining)>
151         <Extension>
152         Public Function [Select](Of T, TOut)(windows As IEnumerable(Of SlideWindow(Of T)), projection As Func(Of T, T, TOut)) As IEnumerable(Of TOut)
153             Return windows.Select(selector:=Function(win) projection(win(0), win(1)))
154         End Function
155
156         <MethodImpl(MethodImplOptions.AggressiveInlining)>
157         <Extension>
158         Public Function [Select](Of T, TOut)(windows As IEnumerable(Of SlideWindow(Of T)), projection As Func(Of T, T, T, TOut)) As IEnumerable(Of TOut)
159             Return windows.Select(selector:=Function(win) projection(win(0), win(1), win(2)))
160         End Function
161
162         <MethodImpl(MethodImplOptions.AggressiveInlining)>
163         <Extension>
164         Public Function [Select](Of T, TOut)(windows As IEnumerable(Of SlideWindow(Of T)), projection As Func(Of T, T, T, T, TOut)) As IEnumerable(Of TOut)
165             Return windows.Select(selector:=Function(win) projection(win(0), win(1), win(2), win(3)))
166         End Function
167
168         <MethodImpl(MethodImplOptions.AggressiveInlining)>
169         <Extension>
170         Public Function [Select](Of T, TOut)(windows As IEnumerable(Of SlideWindow(Of T)), projection As Func(Of T, T, T, T, T, TOut)) As IEnumerable(Of TOut)
171             Return windows.Select(selector:=Function(win) projection(win(0), win(1), win(2), win(3), win(4)))
172         End Function
173
174         <MethodImpl(MethodImplOptions.AggressiveInlining)>
175         <Extension>
176         Public Function [Select](Of T, TOut)(windows As IEnumerable(Of SlideWindow(Of T)), projection As Func(Of T, T, T, T, T, T, TOut)) As IEnumerable(Of TOut)
177             Return windows.Select(selector:=Function(win)
178                                                 Dim i As int = Scan0
179                                                 Return projection(win(++i), win(++i), win(++i), win(++i), win(++i), win(++i))
180                                             End Function)
181         End Function
182     End Module
183 End Namespace