github.com/wzzhu/tensor@v0.9.24/dense_matop_memmove.go (about) 1 package tensor 2 3 import "github.com/pkg/errors" 4 5 // This file contains code pertaining to tensor operations that actually move memory 6 7 // Transpose() actually transposes the data. 8 // This is a generalized version of the inplace matrix transposition algorithm from Wikipedia: 9 // https://en.wikipedia.org/wiki/In-place_matrix_transposition 10 func (t *Dense) Transpose() error { 11 // if there is no oldinfo, that means the current info is the latest, and not the transpose 12 if t.old.IsZero() { 13 return nil 14 } 15 16 if t.IsScalar() { 17 return nil // cannot transpose scalars - no data movement 18 } 19 20 defer func() { 21 t.old.zero() 22 t.transposeWith = nil 23 }() 24 25 expShape := t.Shape() 26 27 // important! because the strides would have changed once the underlying data changed 28 var expStrides []int 29 if t.AP.o.IsColMajor() { 30 expStrides = expShape.CalcStridesColMajor() 31 } else { 32 expStrides = expShape.CalcStrides() 33 } 34 defer ReturnInts(expStrides) 35 defer func() { 36 copy(t.AP.strides, expStrides) // dimensions do not change, so it's actually safe to do this 37 t.sanity() 38 }() 39 40 if t.IsVector() { 41 // no data movement 42 return nil 43 } 44 45 // actually move data 46 var e Engine = t.e 47 48 transposer, ok := e.(Transposer) 49 if !ok { 50 return errors.Errorf("Engine does not support Transpose()") 51 } 52 return transposer.Transpose(t, expStrides) 53 } 54 55 // Repeat is like Numpy's repeat. It repeats the elements of an array. 56 // The repeats param defines how many times each element in the axis is repeated. 57 // Just like NumPy, the repeats param is broadcasted to fit the size of the given axis. 58 func (t *Dense) Repeat(axis int, repeats ...int) (retVal Tensor, err error) { 59 e := t.Engine() 60 61 if rp, ok := e.(Repeater); ok { 62 return rp.Repeat(t, axis, repeats...) 63 } 64 return nil, errors.New("Engine does not support Repeat") 65 } 66 67 // Concat concatenates the other tensors along the given axis. It is like Numpy's concatenate() function. 68 func (t *Dense) Concat(axis int, Ts ...*Dense) (retVal *Dense, err error) { 69 e := t.Engine() 70 71 if c, ok := e.(Concater); ok { 72 var ret Tensor 73 others := densesToTensors(Ts) 74 if ret, err = c.Concat(t, axis, others...); err != nil { 75 return nil, errors.Wrapf(err, opFail, "Concat") 76 } 77 return ret.(*Dense), nil 78 } 79 return nil, errors.New("Engine does not support Concat") 80 } 81 82 // Hstack stacks other tensors columnwise (horizontal stacking) 83 func (t *Dense) Hstack(others ...*Dense) (*Dense, error) { 84 // check that everything is at least 1D 85 if t.Dims() == 0 { 86 return nil, errors.Errorf(atleastDims, 1) 87 } 88 89 for _, d := range others { 90 if d.Dims() < 1 { 91 return nil, errors.Errorf(atleastDims, 1) 92 } 93 } 94 95 if t.Dims() == 1 { 96 return t.Concat(0, others...) 97 } 98 return t.Concat(1, others...) 99 } 100 101 // Vstack stacks other tensors rowwise (vertical stacking). Vertical stacking requires all involved Tensors to have at least 2 dimensions 102 func (t *Dense) Vstack(others ...*Dense) (*Dense, error) { 103 // check that everything is at least 2D 104 if t.Dims() < 2 { 105 return nil, errors.Errorf(atleastDims, 2) 106 } 107 108 for _, d := range others { 109 if d.Dims() < 2 { 110 return nil, errors.Errorf(atleastDims, 2) 111 } 112 } 113 return t.Concat(0, others...) 114 } 115 116 // Stack stacks the other tensors along the axis specified. It is like Numpy's stack function. 117 func (t *Dense) Stack(axis int, others ...*Dense) (retVal *Dense, err error) { 118 var ret DenseTensor 119 var ok bool 120 if ret, err = t.stackDense(axis, densesToDenseTensors(others)...); err != nil { 121 return nil, err 122 } 123 if retVal, ok = ret.(*Dense); !ok { 124 return nil, errors.Errorf("Return not *Dense") 125 } 126 return 127 } 128 129 func (t *Dense) stackDense(axis int, others ...DenseTensor) (retVal DenseTensor, err error) { 130 if ds, ok := t.Engine().(DenseStacker); ok { 131 return ds.StackDense(t, axis, others...) 132 } 133 return nil, errors.Errorf("Engine does not support DenseStacker") 134 }