gonum.org/v1/gonum@v0.14.0/internal/asm/c128/stubs_test.go (about)

     1  // Copyright ©2016 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 c128_test
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  
    11  	"gonum.org/v1/gonum/cmplxs/cscalar"
    12  	. "gonum.org/v1/gonum/internal/asm/c128"
    13  )
    14  
    15  func TestAdd(t *testing.T) {
    16  	var src_gd, dst_gd complex128 = 1, 0
    17  	for j, v := range []struct {
    18  		dst, src, expect []complex128
    19  	}{
    20  		{
    21  			dst:    []complex128{1 + 1i},
    22  			src:    []complex128{0},
    23  			expect: []complex128{1 + 1i},
    24  		},
    25  		{
    26  			dst:    []complex128{1, 2, 3},
    27  			src:    []complex128{1 + 1i},
    28  			expect: []complex128{2 + 1i, 2, 3},
    29  		},
    30  		{
    31  			dst:    []complex128{},
    32  			src:    []complex128{},
    33  			expect: []complex128{},
    34  		},
    35  		{
    36  			dst:    []complex128{1},
    37  			src:    []complex128{cnan},
    38  			expect: []complex128{cnan},
    39  		},
    40  		{
    41  			dst:    []complex128{8, 8, 8, 8, 8},
    42  			src:    []complex128{2 + 1i, 4 - 1i, cnan, 8 + 1i, 9 - 1i},
    43  			expect: []complex128{10 + 1i, 12 - 1i, cnan, 16 + 1i, 17 - 1i},
    44  		},
    45  		{
    46  			dst:    []complex128{0, 1 + 1i, 2, 3 - 1i, 4},
    47  			src:    []complex128{cinf, 4, cnan, 8 + 1i, 9 - 1i},
    48  			expect: []complex128{cinf, 5 + 1i, cnan, 11, 13 - 1i},
    49  		},
    50  		{
    51  			dst:    make([]complex128, 50)[1:49],
    52  			src:    make([]complex128, 50)[1:49],
    53  			expect: make([]complex128, 50)[1:49],
    54  		},
    55  	} {
    56  		sg_ln, dg_ln := 4+j%2, 4+j%3
    57  		v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln)
    58  		src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
    59  		Add(dst, src)
    60  		for i := range v.expect {
    61  			if !cscalar.Same(dst[i], v.expect[i]) {
    62  				t.Errorf("Test %d Add error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i])
    63  			}
    64  		}
    65  		if !isValidGuard(v.src, src_gd, sg_ln) {
    66  			t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:])
    67  		}
    68  		if !isValidGuard(v.dst, dst_gd, dg_ln) {
    69  			t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:])
    70  		}
    71  	}
    72  }
    73  
    74  func TestAddConst(t *testing.T) {
    75  	var src_gd complex128 = 0
    76  	for j, v := range []struct {
    77  		alpha       complex128
    78  		src, expect []complex128
    79  	}{
    80  		{
    81  			alpha:  1 + 1i,
    82  			src:    []complex128{0},
    83  			expect: []complex128{1 + 1i},
    84  		},
    85  		{
    86  			alpha:  5,
    87  			src:    []complex128{},
    88  			expect: []complex128{},
    89  		},
    90  		{
    91  			alpha:  1,
    92  			src:    []complex128{cnan},
    93  			expect: []complex128{cnan},
    94  		},
    95  		{
    96  			alpha:  8 + 1i,
    97  			src:    []complex128{2, 4, cnan, 8, 9},
    98  			expect: []complex128{10 + 1i, 12 + 1i, cnan, 16 + 1i, 17 + 1i},
    99  		},
   100  		{
   101  			alpha:  cinf,
   102  			src:    []complex128{cinf, 4, cnan, 8, 9},
   103  			expect: []complex128{cinf, cinf, cnan, cinf, cinf},
   104  		},
   105  	} {
   106  		g_ln := 4 + j%2
   107  		v.src = guardVector(v.src, src_gd, g_ln)
   108  		src := v.src[g_ln : len(v.src)-g_ln]
   109  		AddConst(v.alpha, src)
   110  		for i := range v.expect {
   111  			if !cscalar.Same(src[i], v.expect[i]) {
   112  				t.Errorf("Test %d AddConst error at %d Got: %v Expected: %v", j, i, src[i], v.expect[i])
   113  			}
   114  		}
   115  		if !isValidGuard(v.src, src_gd, g_ln) {
   116  			t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:g_ln], v.src[len(v.src)-g_ln:])
   117  		}
   118  	}
   119  }
   120  
   121  var axpyTests = []struct {
   122  	incX, incY, incDst int
   123  	ix, iy, idst       uintptr
   124  	a                  complex128
   125  	dst, x, y          []complex128
   126  	ex                 []complex128
   127  }{
   128  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   129  		a:   1 + 1i,
   130  		dst: []complex128{5},
   131  		x:   []complex128{1},
   132  		y:   []complex128{1i},
   133  		ex:  []complex128{1 + 2i}},
   134  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   135  		a:   1 + 2i,
   136  		dst: []complex128{0, 0, 0},
   137  		x:   []complex128{0, 0, 0},
   138  		y:   []complex128{1, 1, 1},
   139  		ex:  []complex128{1, 1, 1}},
   140  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   141  		a:   1 + 2i,
   142  		dst: []complex128{0, 0, 0},
   143  		x:   []complex128{0, 0},
   144  		y:   []complex128{1, 1, 1},
   145  		ex:  []complex128{1, 1}},
   146  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   147  		a:   1 + 2i,
   148  		dst: []complex128{1i, 1i, 1i},
   149  		x:   []complex128{1i, 1i, 1i},
   150  		y:   []complex128{1, 2, 1},
   151  		ex:  []complex128{-1 + 1i, 1i, -1 + 1i}},
   152  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   153  		a:   -1i,
   154  		dst: []complex128{1i, 1i, 1i},
   155  		x:   []complex128{1i, 1i, 1i},
   156  		y:   []complex128{1, 2, 1},
   157  		ex:  []complex128{2, 3, 2}},
   158  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   159  		a:   -1i,
   160  		dst: []complex128{1i, 1i, 1i},
   161  		x:   []complex128{1i, 1i, 1i, 1i, 1i}[1:4],
   162  		y:   []complex128{1, 1, 2, 1, 1}[1:4],
   163  		ex:  []complex128{2, 3, 2}},
   164  	{incX: 2, incY: 4, incDst: 3, ix: 0, iy: 0, idst: 0,
   165  		a:   -2,
   166  		dst: []complex128{1i, 1i, 1i, 1i, 1i},
   167  		x:   []complex128{2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i},
   168  		y:   []complex128{1, 1, 2, 1, 1},
   169  		ex:  []complex128{-3 - 2i, -3 - 2i, -2 - 2i, -3 - 2i, -3 - 2i}},
   170  	// Run big test twice, once aligned once unaligned.
   171  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   172  		a:   1 - 1i,
   173  		dst: make([]complex128, 10),
   174  		x:   []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i},
   175  		y:   []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1},
   176  		ex:  []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}},
   177  	{incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0,
   178  		a:   1 - 1i,
   179  		dst: make([]complex128, 10),
   180  		x:   []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i},
   181  		y:   []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1},
   182  		ex:  []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}},
   183  	{incX: -2, incY: -2, incDst: -3, ix: 18, iy: 18, idst: 27,
   184  		a:   1 - 1i,
   185  		dst: make([]complex128, 10),
   186  		x:   []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i},
   187  		y:   []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1},
   188  		ex:  []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}},
   189  	{incX: -2, incY: 2, incDst: -3, ix: 18, iy: 0, idst: 27,
   190  		a:   1 - 1i,
   191  		dst: make([]complex128, 10),
   192  		x:   []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i},
   193  		y:   []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1},
   194  		ex:  []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}},
   195  }
   196  
   197  func TestAxpyUnitary(t *testing.T) {
   198  	const xGdVal, yGdVal = 1, 1
   199  	for cas, test := range axpyTests {
   200  		xgLn, ygLn := 4+cas%2, 4+cas%3
   201  		test.x, test.y = guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn)
   202  		x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn]
   203  		AxpyUnitary(test.a, x, y)
   204  		for i := range test.ex {
   205  			if y[i] != test.ex[i] {
   206  				t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i], test.ex[i])
   207  			}
   208  		}
   209  		if !isValidGuard(test.x, xGdVal, xgLn) {
   210  			t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xgLn], test.x[len(test.x)-xgLn:])
   211  		}
   212  		if !isValidGuard(test.y, yGdVal, ygLn) {
   213  			t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:ygLn], test.y[len(test.y)-ygLn:])
   214  		}
   215  	}
   216  }
   217  
   218  func TestAxpyUnitaryTo(t *testing.T) {
   219  	const xGdVal, yGdVal, dstGdVal = 1, 1, 0
   220  	for cas, test := range axpyTests {
   221  		xgLn, ygLn := 4+cas%2, 4+cas%3
   222  		test.x, test.y = guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn)
   223  		test.dst = guardVector(test.dst, dstGdVal, xgLn)
   224  		x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn]
   225  		dst := test.dst[xgLn : len(test.dst)-xgLn]
   226  		AxpyUnitaryTo(dst, test.a, x, y)
   227  		for i := range test.ex {
   228  			if dst[i] != test.ex[i] {
   229  				t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i], test.ex[i])
   230  			}
   231  		}
   232  		if !isValidGuard(test.x, xGdVal, xgLn) {
   233  			t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xgLn], test.x[len(test.x)-xgLn:])
   234  		}
   235  		if !isValidGuard(test.y, yGdVal, ygLn) {
   236  			t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:ygLn], test.y[len(test.y)-ygLn:])
   237  		}
   238  		if !isValidGuard(test.dst, dstGdVal, xgLn) {
   239  			t.Errorf("Test %d Guard violated in dst vector %v %v", cas, test.dst[:xgLn], test.dst[len(test.dst)-xgLn:])
   240  		}
   241  
   242  	}
   243  }
   244  
   245  func TestAxpyInc(t *testing.T) {
   246  	const xGdVal, yGdVal = 1, 1
   247  	for cas, test := range axpyTests {
   248  		xgLn, ygLn := 4+cas%2, 4+cas%3
   249  		test.x, test.y = guardIncVector(test.x, xGdVal, test.incX, xgLn), guardIncVector(test.y, yGdVal, test.incY, ygLn)
   250  		x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn]
   251  		AxpyInc(test.a, x, y, uintptr(len(test.ex)), uintptr(test.incX), uintptr(test.incY), test.ix, test.iy)
   252  		for i := range test.ex {
   253  			if y[int(test.iy)+i*test.incY] != test.ex[i] {
   254  				t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i*test.incY], test.ex[i])
   255  			}
   256  		}
   257  		checkValidIncGuard(t, test.x, xGdVal, test.incX, xgLn)
   258  		checkValidIncGuard(t, test.y, yGdVal, test.incY, ygLn)
   259  	}
   260  }
   261  
   262  func TestAxpyIncTo(t *testing.T) {
   263  	const xGdVal, yGdVal, dstGdVal = 1, 1, 0
   264  	for cas, test := range axpyTests {
   265  		xgLn, ygLn := 4+cas%2, 4+cas%3
   266  		test.x, test.y = guardIncVector(test.x, xGdVal, test.incX, xgLn), guardIncVector(test.y, yGdVal, test.incY, ygLn)
   267  		test.dst = guardIncVector(test.dst, dstGdVal, test.incDst, xgLn)
   268  		x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn]
   269  		dst := test.dst[xgLn : len(test.dst)-xgLn]
   270  		AxpyIncTo(dst, uintptr(test.incDst), test.idst, test.a, x, y, uintptr(len(test.ex)), uintptr(test.incX), uintptr(test.incY), test.ix, test.iy)
   271  		for i := range test.ex {
   272  			if dst[int(test.idst)+i*test.incDst] != test.ex[i] {
   273  				t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i*test.incDst], test.ex[i])
   274  			}
   275  		}
   276  		checkValidIncGuard(t, test.x, xGdVal, test.incX, xgLn)
   277  		checkValidIncGuard(t, test.y, yGdVal, test.incY, ygLn)
   278  		checkValidIncGuard(t, test.dst, dstGdVal, test.incDst, xgLn)
   279  	}
   280  }
   281  
   282  func TestCumSum(t *testing.T) {
   283  	var src_gd, dst_gd complex128 = -1, 0
   284  	for j, v := range []struct {
   285  		dst, src, expect []complex128
   286  	}{
   287  		{
   288  			dst:    []complex128{},
   289  			src:    []complex128{},
   290  			expect: []complex128{},
   291  		},
   292  		{
   293  			dst:    []complex128{0},
   294  			src:    []complex128{1 + 1i},
   295  			expect: []complex128{1 + 1i},
   296  		},
   297  		{
   298  			dst:    []complex128{cnan},
   299  			src:    []complex128{cnan},
   300  			expect: []complex128{cnan},
   301  		},
   302  		{
   303  			dst:    []complex128{0, 0, 0},
   304  			src:    []complex128{1, 2 + 1i, 3 + 2i},
   305  			expect: []complex128{1, 3 + 1i, 6 + 3i},
   306  		},
   307  		{
   308  			dst:    []complex128{0, 0, 0, 0},
   309  			src:    []complex128{1, 2 + 1i, 3 + 2i},
   310  			expect: []complex128{1, 3 + 1i, 6 + 3i},
   311  		},
   312  		{
   313  			dst:    []complex128{0, 0, 0, 0},
   314  			src:    []complex128{1, 2 + 1i, 3 + 2i, 4 + 3i},
   315  			expect: []complex128{1, 3 + 1i, 6 + 3i, 10 + 6i},
   316  		},
   317  		{
   318  			dst:    []complex128{1, cnan, cnan, 1, 1},
   319  			src:    []complex128{1, 1, cnan, 1, 1},
   320  			expect: []complex128{1, 2, cnan, cnan, cnan},
   321  		},
   322  		{
   323  			dst:    []complex128{cnan, 4, cinf, cinf, 9},
   324  			src:    []complex128{cinf, 4, cnan, cinf, 9},
   325  			expect: []complex128{cinf, cinf, cnan, cnan, cnan},
   326  		},
   327  		{
   328  			dst:    make([]complex128, 16),
   329  			src:    []complex128{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
   330  			expect: []complex128{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
   331  		},
   332  	} {
   333  		g_ln := 4 + j%2
   334  		v.src, v.dst = guardVector(v.src, src_gd, g_ln), guardVector(v.dst, dst_gd, g_ln)
   335  		src, dst := v.src[g_ln:len(v.src)-g_ln], v.dst[g_ln:len(v.dst)-g_ln]
   336  		ret := CumSum(dst, src)
   337  		for i := range v.expect {
   338  			if !cscalar.Same(ret[i], v.expect[i]) {
   339  				t.Errorf("Test %d CumSum error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
   340  			}
   341  			if !cscalar.Same(ret[i], dst[i]) {
   342  				t.Errorf("Test %d CumSum ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i])
   343  			}
   344  		}
   345  		if !isValidGuard(v.src, src_gd, g_ln) {
   346  			t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:g_ln], v.src[len(v.src)-g_ln:])
   347  		}
   348  		if !isValidGuard(v.dst, dst_gd, g_ln) {
   349  			t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:g_ln], v.dst[len(v.dst)-g_ln:])
   350  		}
   351  	}
   352  }
   353  
   354  func TestCumProd(t *testing.T) {
   355  	var src_gd, dst_gd complex128 = -1, 1
   356  	for j, v := range []struct {
   357  		dst, src, expect []complex128
   358  	}{
   359  		{
   360  			dst:    []complex128{},
   361  			src:    []complex128{},
   362  			expect: []complex128{},
   363  		},
   364  		{
   365  			dst:    []complex128{1},
   366  			src:    []complex128{1 + 1i},
   367  			expect: []complex128{1 + 1i},
   368  		},
   369  		{
   370  			dst:    []complex128{cnan},
   371  			src:    []complex128{cnan},
   372  			expect: []complex128{cnan},
   373  		},
   374  		{
   375  			dst:    []complex128{0, 0, 0, 0},
   376  			src:    []complex128{1, 2 + 1i, 3 + 2i, 4 + 3i},
   377  			expect: []complex128{1, 2 + 1i, 4 + 7i, -5 + 40i},
   378  		},
   379  		{
   380  			dst:    []complex128{0, 0, 0},
   381  			src:    []complex128{1, 2 + 1i, 3 + 2i},
   382  			expect: []complex128{1, 2 + 1i, 4 + 7i},
   383  		},
   384  		{
   385  			dst:    []complex128{0, 0, 0, 0},
   386  			src:    []complex128{1, 2 + 1i, 3 + 2i},
   387  			expect: []complex128{1, 2 + 1i, 4 + 7i},
   388  		},
   389  		{
   390  			dst:    []complex128{cnan, 1, cnan, 1, 0},
   391  			src:    []complex128{1, 1, cnan, 1, 1},
   392  			expect: []complex128{1, 1, cnan, cnan, cnan},
   393  		},
   394  		{
   395  			dst:    []complex128{cnan, 4, cnan, cinf, 9},
   396  			src:    []complex128{cinf, 4, cnan, cinf, 9},
   397  			expect: []complex128{cinf, cnan, cnan, cnan, cnan},
   398  		},
   399  		{
   400  			dst:    make([]complex128, 18),
   401  			src:    []complex128{2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i, 2i},
   402  			expect: []complex128{2i, -4, -8i, 16, 32i, -64, -128i, 256, 512i, -1024, -2048i, 4096, 8192i, -16384, -32768i, 65536},
   403  		},
   404  	} {
   405  		sg_ln, dg_ln := 4+j%2, 4+j%3
   406  		v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln)
   407  		src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
   408  		ret := CumProd(dst, src)
   409  		for i := range v.expect {
   410  			if !cscalar.Same(ret[i], v.expect[i]) {
   411  				t.Errorf("Test %d CumProd error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
   412  			}
   413  			if !cscalar.Same(ret[i], dst[i]) {
   414  				t.Errorf("Test %d CumProd ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i])
   415  			}
   416  		}
   417  		if !isValidGuard(v.src, src_gd, sg_ln) {
   418  			t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:])
   419  		}
   420  		if !isValidGuard(v.dst, dst_gd, dg_ln) {
   421  			t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:])
   422  		}
   423  	}
   424  }
   425  
   426  func TestDiv(t *testing.T) {
   427  	const tol = 1e-15
   428  
   429  	var src_gd, dst_gd complex128 = -1, 0.5
   430  	for j, v := range []struct {
   431  		dst, src, expect []complex128
   432  	}{
   433  		{
   434  			dst:    []complex128{1 + 1i},
   435  			src:    []complex128{1 + 1i},
   436  			expect: []complex128{1},
   437  		},
   438  		{
   439  			dst:    []complex128{cnan},
   440  			src:    []complex128{cnan},
   441  			expect: []complex128{cnan},
   442  		},
   443  		{
   444  			dst:    []complex128{1 + 1i, 2 + 1i, 3 + 1i, 4 + 1i},
   445  			src:    []complex128{1 + 1i, 2 + 1i, 3 + 1i, 4 + 1i},
   446  			expect: []complex128{1, 1, 1, 1},
   447  		},
   448  		{
   449  			dst:    []complex128{1 + 1i, 2 + 1i, 3 + 1i, 4 + 1i, 2 + 2i, 4 + 2i, 6 + 2i, 8 + 2i},
   450  			src:    []complex128{1 + 1i, 2 + 1i, 3 + 1i, 4 + 1i, 1 + 1i, 2 + 1i, 3 + 1i, 4 + 1i},
   451  			expect: []complex128{1, 1, 1, 1, 2, 2, 2, 2},
   452  		},
   453  		{
   454  			dst:    []complex128{2 + 2i, 4 + 8i, 6 - 12i},
   455  			src:    []complex128{1 + 1i, 2 + 4i, 3 - 6i},
   456  			expect: []complex128{2, 2, 2},
   457  		},
   458  		{
   459  			dst:    []complex128{0, 0, 0, 0},
   460  			src:    []complex128{1 + 1i, 2 + 2i, 3 + 3i},
   461  			expect: []complex128{0, 0, 0},
   462  		},
   463  		{
   464  			dst:    []complex128{cnan, 1, cnan, 1, 0, cnan, 1, cnan, 1, 0},
   465  			src:    []complex128{1, 1, cnan, 1, 1, 1, 1, cnan, 1, 1},
   466  			expect: []complex128{cnan, 1, cnan, 1, 0, cnan, 1, cnan, 1, 0},
   467  		},
   468  		{
   469  			dst:    []complex128{cinf, 4, cnan, cinf, 9, cinf, 4, cnan, cinf, 9},
   470  			src:    []complex128{cinf, 4, cnan, cinf, 3, cinf, 4, cnan, cinf, 3},
   471  			expect: []complex128{cnan, 1, cnan, cnan, 3, cnan, 1, cnan, cnan, 3},
   472  		},
   473  	} {
   474  		sg_ln, dg_ln := 4+j%2, 4+j%3
   475  		v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln)
   476  		src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln]
   477  		Div(dst, src)
   478  		for i := range v.expect {
   479  			if !sameCmplxApprox(dst[i], v.expect[i], tol) {
   480  				t.Errorf("Test %d Div error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i])
   481  			}
   482  		}
   483  		if !isValidGuard(v.src, src_gd, sg_ln) {
   484  			t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:])
   485  		}
   486  		if !isValidGuard(v.dst, dst_gd, dg_ln) {
   487  			t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:])
   488  		}
   489  	}
   490  }
   491  
   492  func TestDivTo(t *testing.T) {
   493  	const tol = 1e-15
   494  
   495  	var dst_gd, x_gd, y_gd complex128 = -1, 0.5, 0.25
   496  	for j, v := range []struct {
   497  		dst, x, y, expect []complex128
   498  	}{
   499  		{
   500  			dst:    []complex128{1 - 1i},
   501  			x:      []complex128{1 + 1i},
   502  			y:      []complex128{1 + 1i},
   503  			expect: []complex128{1},
   504  		},
   505  		{
   506  			dst:    []complex128{1},
   507  			x:      []complex128{cnan},
   508  			y:      []complex128{cnan},
   509  			expect: []complex128{cnan},
   510  		},
   511  		{
   512  			dst:    []complex128{-2, -2, -2},
   513  			x:      []complex128{1 + 1i, 2 + 1i, 3 + 1i},
   514  			y:      []complex128{1 + 1i, 2 + 1i, 3 + 1i},
   515  			expect: []complex128{1, 1, 1},
   516  		},
   517  		{
   518  			dst:    []complex128{0, 0, 0},
   519  			x:      []complex128{2 + 2i, 4 + 4i, 6 + 6i},
   520  			y:      []complex128{1 + 1i, 2 + 2i, 3 + 3i, 4 + 4i},
   521  			expect: []complex128{2, 2, 2},
   522  		},
   523  		{
   524  			dst:    []complex128{-1, -1, -1},
   525  			x:      []complex128{0, 0, 0},
   526  			y:      []complex128{1 + 1i, 2 + 1i, 3 + 1i},
   527  			expect: []complex128{0, 0, 0},
   528  		},
   529  		{
   530  			dst:    []complex128{cinf, cinf, cinf, cinf, cinf, cinf, cinf, cinf, cinf, cinf},
   531  			x:      []complex128{cnan, 1, cnan, 1, 0, cnan, 1, cnan, 1, 0},
   532  			y:      []complex128{1, 1, cnan, 1, 1, 1, 1, cnan, 1, 1},
   533  			expect: []complex128{cnan, 1, cnan, 1, 0, cnan, 1, cnan, 1, 0},
   534  		},
   535  		{
   536  			dst:    []complex128{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   537  			x:      []complex128{cinf, 4, cnan, cinf, 9, cinf, 4, cnan, cinf, 9},
   538  			y:      []complex128{cinf, 4, cnan, cinf, 3, cinf, 4, cnan, cinf, 3},
   539  			expect: []complex128{cnan, 1, cnan, cnan, 3, cnan, 1, cnan, cnan, 3},
   540  		},
   541  	} {
   542  		xg_ln, yg_ln := 4+j%2, 4+j%3
   543  		v.y, v.x = guardVector(v.y, y_gd, yg_ln), guardVector(v.x, x_gd, xg_ln)
   544  		y, x := v.y[yg_ln:len(v.y)-yg_ln], v.x[xg_ln:len(v.x)-xg_ln]
   545  		v.dst = guardVector(v.dst, dst_gd, xg_ln)
   546  		dst := v.dst[xg_ln : len(v.dst)-xg_ln]
   547  		ret := DivTo(dst, x, y)
   548  		for i := range v.expect {
   549  			if !sameCmplxApprox(ret[i], v.expect[i], tol) {
   550  				t.Errorf("Test %d DivTo error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i])
   551  			}
   552  			if !cscalar.Same(ret[i], dst[i]) {
   553  				t.Errorf("Test %d DivTo ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i])
   554  			}
   555  		}
   556  		if !isValidGuard(v.y, y_gd, yg_ln) {
   557  			t.Errorf("Test %d Guard violated in y vector %v %v", j, v.y[:yg_ln], v.y[len(v.y)-yg_ln:])
   558  		}
   559  		if !isValidGuard(v.x, x_gd, xg_ln) {
   560  			t.Errorf("Test %d Guard violated in x vector %v %v", j, v.x[:xg_ln], v.x[len(v.x)-xg_ln:])
   561  		}
   562  		if !isValidGuard(v.dst, dst_gd, xg_ln) {
   563  			t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:xg_ln], v.dst[len(v.dst)-xg_ln:])
   564  		}
   565  	}
   566  }
   567  
   568  var dscalTests = []struct {
   569  	alpha float64
   570  	x     []complex128
   571  	want  []complex128
   572  }{
   573  	{
   574  		alpha: 0,
   575  		x:     []complex128{},
   576  		want:  []complex128{},
   577  	},
   578  	{
   579  		alpha: 1,
   580  		x:     []complex128{1 + 2i},
   581  		want:  []complex128{1 + 2i},
   582  	},
   583  	{
   584  		alpha: 2,
   585  		x:     []complex128{1 + 2i},
   586  		want:  []complex128{2 + 4i},
   587  	},
   588  	{
   589  		alpha: 2,
   590  		x:     []complex128{1 + 2i, 3 + 5i, 6 + 11i, 12 - 23i},
   591  		want:  []complex128{2 + 4i, 6 + 10i, 12 + 22i, 24 - 46i},
   592  	},
   593  	{
   594  		alpha: 3,
   595  		x:     []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i},
   596  		want:  []complex128{3 + 6i, 15 + 12i, 9 + 18i, 24 + 36i, -9 - 6i, -15 + 15i},
   597  	},
   598  	{
   599  		alpha: 5,
   600  		x:     []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i, 1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i},
   601  		want:  []complex128{5 + 10i, 25 + 20i, 15 + 30i, 40 + 60i, -15 - 10i, -25 + 25i, 5 + 10i, 25 + 20i, 15 + 30i, 40 + 60i, -15 - 10i, -25 + 25i},
   602  	},
   603  }
   604  
   605  func TestDscalUnitary(t *testing.T) {
   606  	const xGdVal = -0.5
   607  	for i, test := range dscalTests {
   608  		for _, align := range align1 {
   609  			prefix := fmt.Sprintf("Test %v (x:%v)", i, align)
   610  			xgLn := 4 + align
   611  			xg := guardVector(test.x, xGdVal, xgLn)
   612  			x := xg[xgLn : len(xg)-xgLn]
   613  
   614  			DscalUnitary(test.alpha, x)
   615  
   616  			for i := range test.want {
   617  				if !cscalar.Same(x[i], test.want[i]) {
   618  					t.Errorf(msgVal, prefix, i, x[i], test.want[i])
   619  				}
   620  			}
   621  			if !isValidGuard(xg, xGdVal, xgLn) {
   622  				t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
   623  			}
   624  		}
   625  	}
   626  }
   627  
   628  func TestDscalInc(t *testing.T) {
   629  	const xGdVal = -0.5
   630  	gdLn := 4
   631  	for i, test := range dscalTests {
   632  		n := len(test.x)
   633  		for _, incX := range []int{1, 2, 3, 4, 7, 10} {
   634  			prefix := fmt.Sprintf("Test %v (x:%v)", i, incX)
   635  			xg := guardIncVector(test.x, xGdVal, incX, gdLn)
   636  			x := xg[gdLn : len(xg)-gdLn]
   637  
   638  			DscalInc(test.alpha, x, uintptr(n), uintptr(incX))
   639  
   640  			for i := range test.want {
   641  				if !cscalar.Same(x[i*incX], test.want[i]) {
   642  					t.Errorf(msgVal, prefix, i, x[i*incX], test.want[i])
   643  				}
   644  			}
   645  			checkValidIncGuard(t, xg, xGdVal, incX, gdLn)
   646  		}
   647  	}
   648  }
   649  
   650  var scalTests = []struct {
   651  	alpha complex128
   652  	x     []complex128
   653  	want  []complex128
   654  }{
   655  	{
   656  		alpha: 0,
   657  		x:     []complex128{},
   658  		want:  []complex128{},
   659  	},
   660  	{
   661  		alpha: 1 + 1i,
   662  		x:     []complex128{1 + 2i},
   663  		want:  []complex128{-1 + 3i},
   664  	},
   665  	{
   666  		alpha: 2 + 3i,
   667  		x:     []complex128{1 + 2i},
   668  		want:  []complex128{-4 + 7i},
   669  	},
   670  	{
   671  		alpha: 2 - 4i,
   672  		x:     []complex128{1 + 2i},
   673  		want:  []complex128{10},
   674  	},
   675  	{
   676  		alpha: 2 + 8i,
   677  		x:     []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i},
   678  		want:  []complex128{-14 + 12i, -22 + 48i, -42 + 36i, -80 + 88i, 10 - 28i, -50 - 30i},
   679  	},
   680  	{
   681  		alpha: 5 - 10i,
   682  		x:     []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i, 1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i},
   683  		want:  []complex128{25, 65 - 30i, 75, 160 - 20i, -35 + 20i, 25 + 75i, 25, 65 - 30i, 75, 160 - 20i, -35 + 20i, 25 + 75i},
   684  	},
   685  }
   686  
   687  func TestScalUnitary(t *testing.T) {
   688  	const xGdVal = -0.5
   689  	for i, test := range scalTests {
   690  		for _, align := range align1 {
   691  			prefix := fmt.Sprintf("Test %v (x:%v)", i, align)
   692  			xgLn := 4 + align
   693  			xg := guardVector(test.x, xGdVal, xgLn)
   694  			x := xg[xgLn : len(xg)-xgLn]
   695  
   696  			ScalUnitary(test.alpha, x)
   697  
   698  			for i := range test.want {
   699  				if !cscalar.Same(x[i], test.want[i]) {
   700  					t.Errorf(msgVal, prefix, i, x[i], test.want[i])
   701  				}
   702  			}
   703  			if !isValidGuard(xg, xGdVal, xgLn) {
   704  				t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
   705  			}
   706  		}
   707  	}
   708  }
   709  
   710  func TestScalInc(t *testing.T) {
   711  	const xGdVal = -0.5
   712  	gdLn := 4
   713  	for i, test := range scalTests {
   714  		n := len(test.x)
   715  		for _, inc := range []int{1, 2, 3, 4, 7, 10} {
   716  			prefix := fmt.Sprintf("Test %v (x:%v)", i, inc)
   717  			xg := guardIncVector(test.x, xGdVal, inc, gdLn)
   718  			x := xg[gdLn : len(xg)-gdLn]
   719  
   720  			ScalInc(test.alpha, x, uintptr(n), uintptr(inc))
   721  
   722  			for i := range test.want {
   723  				if !cscalar.Same(x[i*inc], test.want[i]) {
   724  					t.Errorf(msgVal, prefix, i, x[i*inc], test.want[i])
   725  				}
   726  			}
   727  			checkValidIncGuard(t, xg, xGdVal, inc, gdLn)
   728  		}
   729  	}
   730  }
   731  
   732  func TestSum(t *testing.T) {
   733  	var srcGd complex128 = -1
   734  	for j, v := range []struct {
   735  		src    []complex128
   736  		expect complex128
   737  	}{
   738  		{
   739  			src:    []complex128{},
   740  			expect: 0,
   741  		},
   742  		{
   743  			src:    []complex128{1},
   744  			expect: 1,
   745  		},
   746  		{
   747  			src:    []complex128{cnan},
   748  			expect: cnan,
   749  		},
   750  		{
   751  			src:    []complex128{1 + 1i, 2 + 2i, 3 + 3i},
   752  			expect: 6 + 6i,
   753  		},
   754  		{
   755  			src:    []complex128{1 + 1i, -4, 3 - 1i},
   756  			expect: 0,
   757  		},
   758  		{
   759  			src:    []complex128{1 - 1i, 2 + 2i, 3 - 3i, 4 + 4i},
   760  			expect: 10 + 2i,
   761  		},
   762  		{
   763  			src:    []complex128{1, 1, cnan, 1, 1},
   764  			expect: cnan,
   765  		},
   766  		{
   767  			src:    []complex128{cinf, 4, cnan, cinf, 9},
   768  			expect: cnan,
   769  		},
   770  		{
   771  			src:    []complex128{1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 9 + 9i, 1 + 1i, 1 + 1i, 1 + 1i, 2 + 2i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 5 + 5i, 1 + 1i},
   772  			expect: 29 + 29i,
   773  		},
   774  		{
   775  			src:    []complex128{1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 9 + 9i, 1 + 1i, 1 + 1i, 1 + 1i, 2 + 2i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 5 + 5i, 11 + 11i, 1 + 1i, 1 + 1i, 1 + 1i, 9 + 9i, 1 + 1i, 1 + 1i, 1 + 1i, 2 + 2i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 5 + 5i, 1 + 1i},
   776  			expect: 67 + 67i,
   777  		},
   778  	} {
   779  		gdLn := 4 + j%2
   780  		gsrc := guardVector(v.src, srcGd, gdLn)
   781  		src := gsrc[gdLn : len(gsrc)-gdLn]
   782  		ret := Sum(src)
   783  		if !cscalar.Same(ret, v.expect) {
   784  			t.Errorf("Test %d Sum error Got: %v Expected: %v", j, ret, v.expect)
   785  		}
   786  		if !isValidGuard(gsrc, srcGd, gdLn) {
   787  			t.Errorf("Test %d Guard violated in src vector %v %v", j, gsrc[:gdLn], gsrc[len(gsrc)-gdLn:])
   788  		}
   789  	}
   790  }