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