gonum.org/v1/gonum@v0.14.0/internal/asm/f64/axpy_test.go (about)

     1  // Copyright ©2015 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package f64_test
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  
    11  	"gonum.org/v1/gonum/floats/scalar"
    12  	. "gonum.org/v1/gonum/internal/asm/f64"
    13  )
    14  
    15  var axpyTests = []struct {
    16  	alpha   float64
    17  	x       []float64
    18  	y       []float64
    19  	want    []float64
    20  	wantRev []float64 // Result when x is traversed in reverse direction.
    21  }{
    22  	{
    23  		alpha:   0,
    24  		x:       []float64{},
    25  		y:       []float64{},
    26  		want:    []float64{},
    27  		wantRev: []float64{},
    28  	},
    29  	{
    30  		alpha:   0,
    31  		x:       []float64{2},
    32  		y:       []float64{-3},
    33  		want:    []float64{-3},
    34  		wantRev: []float64{-3},
    35  	},
    36  	{
    37  		alpha:   1,
    38  		x:       []float64{2},
    39  		y:       []float64{-3},
    40  		want:    []float64{-1},
    41  		wantRev: []float64{-1},
    42  	},
    43  	{
    44  		alpha:   3,
    45  		x:       []float64{2},
    46  		y:       []float64{-3},
    47  		want:    []float64{3},
    48  		wantRev: []float64{3},
    49  	},
    50  	{
    51  		alpha:   -3,
    52  		x:       []float64{2},
    53  		y:       []float64{-3},
    54  		want:    []float64{-9},
    55  		wantRev: []float64{-9},
    56  	},
    57  	{
    58  		alpha:   1,
    59  		x:       []float64{1, 5},
    60  		y:       []float64{2, -3},
    61  		want:    []float64{3, 2},
    62  		wantRev: []float64{7, -2},
    63  	},
    64  	{
    65  		alpha:   1,
    66  		x:       []float64{2, 3, 4},
    67  		y:       []float64{-3, -2, -1},
    68  		want:    []float64{-1, 1, 3},
    69  		wantRev: []float64{1, 1, 1},
    70  	},
    71  	{
    72  		alpha:   0,
    73  		x:       []float64{0, 0, 1, 1, 2, -3, -4},
    74  		y:       []float64{0, 1, 0, 3, -4, 5, -6},
    75  		want:    []float64{0, 1, 0, 3, -4, 5, -6},
    76  		wantRev: []float64{0, 1, 0, 3, -4, 5, -6},
    77  	},
    78  	{
    79  		alpha:   1,
    80  		x:       []float64{0, 0, 1, 1, 2, -3, -4},
    81  		y:       []float64{0, 1, 0, 3, -4, 5, -6},
    82  		want:    []float64{0, 1, 1, 4, -2, 2, -10},
    83  		wantRev: []float64{-4, -2, 2, 4, -3, 5, -6},
    84  	},
    85  	{
    86  		alpha:   3,
    87  		x:       []float64{0, 0, 1, 1, 2, -3, -4},
    88  		y:       []float64{0, 1, 0, 3, -4, 5, -6},
    89  		want:    []float64{0, 1, 3, 6, 2, -4, -18},
    90  		wantRev: []float64{-12, -8, 6, 6, -1, 5, -6},
    91  	},
    92  	{
    93  		alpha:   -3,
    94  		x:       []float64{0, 0, 1, 1, 2, -3, -4, 0, 0, 1, 1, 2, -3, -4},
    95  		y:       []float64{0, 1, 0, 3, -4, 5, -6, 0, 1, 0, 3, -4, 5, -6},
    96  		want:    []float64{0, 1, -3, 0, -10, 14, 6, 0, 1, -3, 0, -10, 14, 6},
    97  		wantRev: []float64{12, 10, -6, 0, -7, 5, -6, 12, 10, -6, 0, -7, 5, -6},
    98  	},
    99  	{
   100  		alpha:   -5,
   101  		x:       []float64{0, 0, 1, 1, 2, -3, -4, 5, 1, 2, -3, -4, 5},
   102  		y:       []float64{0, 1, 0, 3, -4, 5, -6, 7, 3, -4, 5, -6, 7},
   103  		want:    []float64{0, 1, -5, -2, -14, 20, 14, -18, -2, -14, 20, 14, -18},
   104  		wantRev: []float64{-25, 21, 15, -7, -9, -20, 14, 22, -7, -9, 0, -6, 7},
   105  	},
   106  }
   107  
   108  func TestAxpyUnitary(t *testing.T) {
   109  	const xGdVal, yGdVal = -1, 0.5
   110  	for i, test := range axpyTests {
   111  		for _, align := range align2 {
   112  			prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y)
   113  			xgLn, ygLn := 4+align.x, 4+align.y
   114  			xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn)
   115  			x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn]
   116  			AxpyUnitary(test.alpha, x, y)
   117  			for i := range test.want {
   118  				if !scalar.Same(y[i], test.want[i]) {
   119  					t.Errorf(msgVal, prefix, i, y[i], test.want[i])
   120  				}
   121  			}
   122  			if !isValidGuard(xg, xGdVal, xgLn) {
   123  				t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
   124  			}
   125  			if !isValidGuard(yg, yGdVal, ygLn) {
   126  				t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:])
   127  			}
   128  			if !equalStrided(test.x, x, 1) {
   129  				t.Errorf("%v: modified read-only x argument", prefix)
   130  			}
   131  		}
   132  	}
   133  }
   134  
   135  func TestAxpyUnitaryTo(t *testing.T) {
   136  	const dstGdVal, xGdVal, yGdVal = 1, -1, 0.5
   137  	for i, test := range axpyTests {
   138  		for _, align := range align3 {
   139  			prefix := fmt.Sprintf("Test %v (x:%v y:%v dst:%v)", i, align.x, align.y, align.dst)
   140  
   141  			dgLn, xgLn, ygLn := 4+align.dst, 4+align.x, 4+align.y
   142  			dstOrig := make([]float64, len(test.x))
   143  			xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn)
   144  			dstg := guardVector(dstOrig, dstGdVal, dgLn)
   145  			x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn]
   146  			dst := dstg[dgLn : len(dstg)-dgLn]
   147  
   148  			AxpyUnitaryTo(dst, test.alpha, x, y)
   149  			for i := range test.want {
   150  				if !scalar.Same(dst[i], test.want[i]) {
   151  					t.Errorf(msgVal, prefix, i, dst[i], test.want[i])
   152  				}
   153  			}
   154  			if !isValidGuard(xg, xGdVal, xgLn) {
   155  				t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
   156  			}
   157  			if !isValidGuard(yg, yGdVal, ygLn) {
   158  				t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:])
   159  			}
   160  			if !isValidGuard(dstg, dstGdVal, dgLn) {
   161  				t.Errorf(msgGuard, prefix, "dst", dstg[:dgLn], dstg[len(dstg)-dgLn:])
   162  			}
   163  			if !equalStrided(test.x, x, 1) {
   164  				t.Errorf("%v: modified read-only x argument", prefix)
   165  			}
   166  			if !equalStrided(test.y, y, 1) {
   167  				t.Errorf("%v: modified read-only y argument", prefix)
   168  			}
   169  		}
   170  	}
   171  }
   172  
   173  func TestAxpyInc(t *testing.T) {
   174  	const xGdVal, yGdVal = -1, 0.5
   175  	gdLn := 4
   176  	for i, test := range axpyTests {
   177  		n := len(test.x)
   178  		for _, inc := range newIncSet(-7, -4, -3, -2, -1, 1, 2, 3, 4, 7) {
   179  			var ix, iy int
   180  			if inc.x < 0 {
   181  				ix = (-n + 1) * inc.x
   182  			}
   183  			if inc.y < 0 {
   184  				iy = (-n + 1) * inc.y
   185  			}
   186  			prefix := fmt.Sprintf("test %v, inc.x = %v, inc.y = %v", i, inc.x, inc.y)
   187  			xg := guardIncVector(test.x, xGdVal, inc.x, gdLn)
   188  			yg := guardIncVector(test.y, yGdVal, inc.y, gdLn)
   189  			x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn]
   190  
   191  			AxpyInc(test.alpha, x, y, uintptr(n),
   192  				uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy))
   193  
   194  			want := test.want
   195  			if inc.x*inc.y < 0 {
   196  				want = test.wantRev
   197  			}
   198  			if inc.y < 0 {
   199  				inc.y = -inc.y
   200  			}
   201  			for i := range want {
   202  				if !scalar.Same(y[i*inc.y], want[i]) {
   203  					t.Errorf(msgVal, prefix, i, y[iy+i*inc.y], want[i])
   204  				}
   205  			}
   206  			if !equalStrided(test.x, x, inc.x) {
   207  				t.Errorf("%v: modified read-only x argument", prefix)
   208  			}
   209  			checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn)
   210  			checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn)
   211  		}
   212  	}
   213  }
   214  
   215  func TestAxpyIncTo(t *testing.T) {
   216  	const dstGdVal, xGdVal, yGdVal = 1, -1, 0.5
   217  	var want []float64
   218  	gdLn := 4
   219  	for i, test := range axpyTests {
   220  		n := len(test.x)
   221  		for _, inc := range newIncToSet(-7, -4, -3, -2, -1, 1, 2, 3, 4, 7) {
   222  			var ix, iy, idst uintptr
   223  			if inc.x < 0 {
   224  				ix = uintptr((-n + 1) * inc.x)
   225  			}
   226  			if inc.y < 0 {
   227  				iy = uintptr((-n + 1) * inc.y)
   228  			}
   229  			if inc.dst < 0 {
   230  				idst = uintptr((-n + 1) * inc.dst)
   231  			}
   232  
   233  			prefix := fmt.Sprintf("Test %v: (x: %v, y: %v, dst:%v)", i, inc.x, inc.y, inc.dst)
   234  			dstOrig := make([]float64, len(test.want))
   235  			xg := guardIncVector(test.x, xGdVal, inc.x, gdLn)
   236  			yg := guardIncVector(test.y, yGdVal, inc.y, gdLn)
   237  			dstg := guardIncVector(dstOrig, dstGdVal, inc.dst, gdLn)
   238  			x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn]
   239  			dst := dstg[gdLn : len(dstg)-gdLn]
   240  
   241  			AxpyIncTo(dst, uintptr(inc.dst), idst,
   242  				test.alpha, x, y, uintptr(n),
   243  				uintptr(inc.x), uintptr(inc.y), ix, iy)
   244  			want = test.want
   245  			if inc.x*inc.y < 0 {
   246  				want = test.wantRev
   247  			}
   248  			iW, incW := 0, 1
   249  			if inc.y*inc.dst < 0 {
   250  				iW, incW = len(want)-1, -1
   251  			}
   252  			if inc.dst < 0 {
   253  				inc.dst = -inc.dst
   254  			}
   255  			for i := range want {
   256  				if !scalar.Same(dst[i*inc.dst], want[iW+i*incW]) {
   257  					t.Errorf(msgVal, prefix, i, dst[i*inc.dst], want[iW+i*incW])
   258  				}
   259  			}
   260  
   261  			checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn)
   262  			checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn)
   263  			checkValidIncGuard(t, dstg, dstGdVal, inc.dst, gdLn)
   264  			if !equalStrided(test.x, x, inc.x) {
   265  				t.Errorf("%v: modified read-only x argument", prefix)
   266  			}
   267  			if !equalStrided(test.y, y, inc.y) {
   268  				t.Errorf("%v: modified read-only y argument", prefix)
   269  			}
   270  		}
   271  	}
   272  }