gitee.com/quant1x/num@v0.3.2/shift.go (about)

     1  package num
     2  
     3  import (
     4  	"slices"
     5  )
     6  
     7  // Shift 使用可选的时间频率按所需的周期数移动索引
     8  //
     9  //	N 支持前后移动, N>0 向右, N<0 向左
    10  func Shift[E BaseType](S []E, N any) []E {
    11  	return v3Shift[E](S, N)
    12  }
    13  
    14  // N为常量常量, 未加速处理, 且做了一次对齐操作
    15  func v1Shift[T BaseType](S []T, N any) []T {
    16  	length := len(S)
    17  	var _n []DType
    18  	switch v := N.(type) {
    19  	case DTypeArray:
    20  		_n = v.DTypes()
    21  	case int:
    22  		if v == 0 {
    23  			return S
    24  		}
    25  		_n = Repeat[DType](DType(v), length)
    26  	case DType:
    27  		if v == 0 || DTypeIsNaN(v) {
    28  			return S
    29  		}
    30  		_n = Repeat[DType](DType(v), length)
    31  	case []int:
    32  		_n = Slice2DType(v)
    33  		_n = Align(_n, NaN(), length)
    34  	case []DType:
    35  		_n = Align(v, NaN(), length)
    36  	default:
    37  		panic(ErrInvalidWindow)
    38  	}
    39  	var d []T
    40  	d = slices.Clone(S)
    41  	values := d
    42  	for i, _ := range S {
    43  		x := _n[i]
    44  		pos := int(x)
    45  		if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 {
    46  			values[i] = TypeDefault[T]()
    47  			continue
    48  		}
    49  		values[i] = S[i-pos]
    50  	}
    51  
    52  	return d
    53  }
    54  
    55  // N为常量常量, 未加速处理
    56  func v2Shift[E BaseType](S []E, N any) []E {
    57  	length := len(S)
    58  	w := Any2Window[DType](N)
    59  	d := slices.Clone(S)
    60  	for i, _ := range S {
    61  		x := w.At(i)
    62  		pos := int(x)
    63  		if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 {
    64  			d[i] = TypeDefault[E]()
    65  			continue
    66  		}
    67  		d[i] = S[i-pos]
    68  	}
    69  	return d
    70  }
    71  
    72  // N为常量常量, copy处理
    73  func v3Shift[E BaseType](S []E, N any) []E {
    74  	length := len(S)
    75  	w := Any2Window[DType](N)
    76  	defaultValue := TypeDefault[E]()
    77  	d := make([]E, length)
    78  	if w.IsConst() {
    79  		// 如果参数是常量
    80  		n := int(w.C)
    81  		m := AbsInt(n)
    82  		if m >= length {
    83  			// 如果n大于S长度, 则返回空
    84  			RepeatInto(d, defaultValue, length)
    85  			return d
    86  		}
    87  		// 分两段操作
    88  		if n > 0 {
    89  			// 左边留空
    90  			// 1. copy从n开始的全部数据到目标切片的n
    91  			copy(d[m:length], S[:length-m])
    92  			// 2. 前部0~n赋予默认值
    93  			RepeatInto[E](d[0:m], defaultValue, m)
    94  		} else if n < 0 {
    95  			// 右边留空
    96  			// 1. copy从0开始的全部数据到目标切片的length-m
    97  			copy(d[0:length-m], S[m:length])
    98  			// 2. 前部length-m~length赋予默认值
    99  			RepeatInto[E](d[length-m:length], defaultValue, m)
   100  		}
   101  		return d
   102  	}
   103  	for i, _ := range S {
   104  		x := w.At(i)
   105  		pos := int(x)
   106  		if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 {
   107  			d[i] = defaultValue
   108  			continue
   109  		}
   110  		d[i] = S[i-pos]
   111  	}
   112  	return d
   113  }
   114  
   115  // N为常量常量, copy处理, v3的简化版, 可读性不高
   116  func v4Shift[E BaseType](S []E, N any) []E {
   117  	length := len(S)
   118  	w := Any2Window[DType](N)
   119  	defaultValue := TypeDefault[E]()
   120  	d := make([]E, length)
   121  	if w.IsConst() {
   122  		// 如果参数是常量
   123  		n := int(w.C)
   124  		m := AbsInt(n)
   125  		if m >= length {
   126  			// 如果n大于S长度, 则返回空
   127  			RepeatInto(d, defaultValue, length)
   128  			return d
   129  		}
   130  		pos := 0
   131  		fixed := 0
   132  		if n < 0 {
   133  			pos = m
   134  			fixed = length - m
   135  		}
   136  		// 分两段操作
   137  		// 1. copy源切片到目标切片
   138  		copy(d[m-pos:length-pos], S[pos:pos+length-m])
   139  		// 2. 空余位置填充默认值
   140  		RepeatInto[E](d[fixed:fixed+m], defaultValue, m)
   141  		return d
   142  	}
   143  	for i, _ := range S {
   144  		x := w.At(i)
   145  		pos := int(x)
   146  		if DTypeIsNaN(x) || i-pos >= length || i-pos < 0 {
   147  			d[i] = defaultValue
   148  			continue
   149  		}
   150  		d[i] = S[i-pos]
   151  	}
   152  	return d
   153  }
   154  
   155  //// ShiftN series切片, 使用可选的时间频率按所需的周期数移动索引
   156  //// Deprecated: 不推荐使用
   157  //func ShiftN[T BaseType](S []T, periods int) []T {
   158  //	d := slices.Clone(S)
   159  //	if periods == 0 {
   160  //		return d
   161  //	}
   162  //
   163  //	values := d
   164  //	var (
   165  //		naVals []T
   166  //		dst    []T
   167  //		src    []T
   168  //	)
   169  //
   170  //	if shlen := int(math.Abs(float64(periods))); shlen < len(values) {
   171  //		if periods > 0 {
   172  //			naVals = values[:shlen]
   173  //			dst = values[shlen:]
   174  //			src = values
   175  //		} else {
   176  //			naVals = values[len(values)-shlen:]
   177  //			dst = values[:len(values)-shlen]
   178  //			src = values[shlen:]
   179  //		}
   180  //		copy(dst, src)
   181  //	} else {
   182  //		naVals = values
   183  //	}
   184  //	for i := range naVals {
   185  //		naVals[i] = TypeDefault[T]()
   186  //	}
   187  //	_ = naVals
   188  //	return d
   189  //}