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

     1  package num
     2  
     3  // Diff 元素的第一个离散差
     4  //
     5  //	n默认是1
     6  func Diff[E Number](S []E, n int) []E {
     7  	return v4Diff[E](S, n)
     8  }
     9  
    10  // v1Diff 元素的第一个离散差
    11  //
    12  //	First discrete difference of element.
    13  //	Calculates the difference of a {klass} element compared with another
    14  //	element in the {klass} (default is element in previous row).
    15  func v1Diff[T Number](s []T, param any) []T {
    16  	blocks := Rolling[T](s, param)
    17  	var d []T
    18  	var front = TypeDefault[T]()
    19  	for _, block := range blocks {
    20  		vs := block
    21  		vl := len(block)
    22  		if vl == 0 {
    23  			d = append(d, TypeDefault[T]())
    24  			continue
    25  		}
    26  		vf := vs[0]
    27  		vc := vs[vl-1]
    28  		if DTypeIsNaN(Any2DType(vc)) || DTypeIsNaN(Any2DType(front)) {
    29  			front = vf
    30  			d = append(d, TypeDefault[T]())
    31  			continue
    32  		}
    33  		diff := vc - front
    34  		d = append(d, diff)
    35  		front = vf
    36  	}
    37  
    38  	return d
    39  }
    40  
    41  // Deprecated: 推荐使用Diff [wangfeng on 2024/2/22 17:51]
    42  func V2Diff[T BaseType](s []T, param any) []T {
    43  	return v2Diff[T](s, param)
    44  }
    45  
    46  func v2Diff[T BaseType](s []T, param any) []T {
    47  	var d any
    48  	switch vs := any(s).(type) {
    49  	case []float32:
    50  		d = v1Diff(vs, param)
    51  	case []float64:
    52  		d = v1Diff(vs, param)
    53  	case []int:
    54  		d = v1Diff(vs, param)
    55  	case []int8:
    56  		d = v1Diff(vs, param)
    57  	case []int16:
    58  		d = v1Diff(vs, param)
    59  	case []int32:
    60  		d = v1Diff(vs, param)
    61  	case []int64:
    62  		d = v1Diff(vs, param)
    63  	//case []uint, []uint8, []uint16, []uint32, []uint64, []uintptr:
    64  	//	d = xv
    65  	default:
    66  		// 其它类型原样返回
    67  		panic(TypeError(vs))
    68  	}
    69  
    70  	return d.([]T)
    71  }
    72  
    73  // 最原始的算法, 只支持向右滑动
    74  func v3Diff[E Number](S []E, n int) []E {
    75  	length := len(S)
    76  	d := make([]E, length)
    77  	offset := AbsInt(n)
    78  	defaultValue := TypeDefault[E]()
    79  	for i, _ := range S[:length-offset] {
    80  		d[i] = S[i+offset] - S[i]
    81  	}
    82  	for i := length - offset; i < length; i++ {
    83  		d[i] = defaultValue
    84  	}
    85  	return d
    86  }
    87  
    88  func v4Diff[E Number](S []E, n int) []E {
    89  	d := v3Shift(S, n)
    90  	SubInplace(d, S)
    91  	return d
    92  }
    93  
    94  // 支持向左向右两个方向滑动
    95  func v5Diff[E Number](S []E, n int) []E {
    96  	d := v3Shift(S, n)
    97  	for i, _ := range S {
    98  		d[i] -= S[i]
    99  	}
   100  	return d
   101  }
   102  
   103  func v6Diff[E Number](S []E, n int) []E {
   104  	arr := ndarray[E](S)
   105  	d := arr.v1Rolling(n, func(index int, v E) E {
   106  		return v - S[index]
   107  	})
   108  	return d
   109  }
   110  
   111  func v7Diff[E Number](S []E, n int) []E {
   112  	arr := ndarray[E](S)
   113  	d := arr.v2Rolling(n, func(index int, v E) E {
   114  		return v - S[index]
   115  	})
   116  	return d
   117  }
   118  
   119  func v8Diff[E Number](S []E, n int) []E {
   120  	length := len(S)
   121  	d := make([]E, length)
   122  	window := Any2Window[DType](n)
   123  	defaultValue := TypeDefault[E]()
   124  	for i := 0; i < length; i++ {
   125  		val := S[i]
   126  		period := window.At(i)
   127  		if DTypeIsNaN(period) {
   128  			val = defaultValue
   129  		} else {
   130  			newIndex := i - int(period)
   131  			if newIndex < 0 || newIndex >= length {
   132  				val = defaultValue
   133  			} else {
   134  				val = S[newIndex] - val
   135  			}
   136  		}
   137  		d[i] = val
   138  	}
   139  	return d
   140  }