github.com/matrixorigin/matrixone@v1.2.0/pkg/vectorize/moarray/external_test.go (about)

     1  // Copyright 2023 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package moarray
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/common/assertx"
    19  	"reflect"
    20  	"testing"
    21  )
    22  
    23  func TestAdd(t *testing.T) {
    24  	type args struct {
    25  		leftArgF32  []float32
    26  		rightArgF32 []float32
    27  
    28  		leftArgF64  []float64
    29  		rightArgF64 []float64
    30  	}
    31  	type testCase struct {
    32  		name    string
    33  		args    args
    34  		wantF32 []float32
    35  		wantF64 []float64
    36  	}
    37  	tests := []testCase{
    38  		{
    39  			name:    "Test1 - float32",
    40  			args:    args{leftArgF32: []float32{1, 2, 3}, rightArgF32: []float32{2, 3, 4}},
    41  			wantF32: []float32{3, 5, 7},
    42  		},
    43  		{
    44  			name:    "Test2 - float64",
    45  			args:    args{leftArgF64: []float64{1, 2, 3}, rightArgF64: []float64{2, 3, 4}},
    46  			wantF64: []float64{3, 5, 7},
    47  		},
    48  	}
    49  	for _, tt := range tests {
    50  		t.Run(tt.name, func(t *testing.T) {
    51  
    52  			if tt.args.rightArgF32 != nil {
    53  				if gotRes, err := Add[float32](tt.args.leftArgF32, tt.args.rightArgF32); err != nil || !reflect.DeepEqual(gotRes, tt.wantF32) {
    54  					t.Errorf("Add() = %v, want %v", gotRes, tt.wantF32)
    55  				}
    56  			}
    57  			if tt.args.rightArgF64 != nil {
    58  				if gotRes, err := Add[float64](tt.args.leftArgF64, tt.args.rightArgF64); err != nil || !assertx.InEpsilonF64Slice(gotRes, tt.wantF64) {
    59  					t.Errorf("Add() = %v, want %v", gotRes, tt.wantF64)
    60  				}
    61  			}
    62  		})
    63  	}
    64  }
    65  
    66  func TestSubtract(t *testing.T) {
    67  	type args struct {
    68  		leftArgF32  []float32
    69  		rightArgF32 []float32
    70  
    71  		leftArgF64  []float64
    72  		rightArgF64 []float64
    73  	}
    74  	type testCase struct {
    75  		name    string
    76  		args    args
    77  		wantF32 []float32
    78  		wantF64 []float64
    79  	}
    80  	tests := []testCase{
    81  		{
    82  			name:    "Test1 - float32",
    83  			args:    args{leftArgF32: []float32{1, 2, 3}, rightArgF32: []float32{2, 3, 4}},
    84  			wantF32: []float32{-1, -1, -1},
    85  		},
    86  		{
    87  			name:    "Test2 - float64",
    88  			args:    args{leftArgF64: []float64{1, 4, 3}, rightArgF64: []float64{1, 3, 4}},
    89  			wantF64: []float64{0, 1, -1},
    90  		},
    91  	}
    92  	for _, tt := range tests {
    93  		t.Run(tt.name, func(t *testing.T) {
    94  
    95  			if tt.args.rightArgF32 != nil {
    96  				if gotRes, err := Subtract[float32](tt.args.leftArgF32, tt.args.rightArgF32); err != nil || !reflect.DeepEqual(gotRes, tt.wantF32) {
    97  					t.Errorf("Subtract() = %v, want %v", gotRes, tt.wantF32)
    98  				}
    99  			}
   100  			if tt.args.rightArgF64 != nil {
   101  				if gotRes, err := Subtract[float64](tt.args.leftArgF64, tt.args.rightArgF64); err != nil || !assertx.InEpsilonF64Slice(tt.wantF64, gotRes) {
   102  					t.Errorf("Subtract() = %v, want %v", gotRes, tt.wantF64)
   103  				}
   104  			}
   105  		})
   106  	}
   107  }
   108  
   109  func TestMultiply(t *testing.T) {
   110  	type args struct {
   111  		leftArgF32  []float32
   112  		rightArgF32 []float32
   113  
   114  		leftArgF64  []float64
   115  		rightArgF64 []float64
   116  	}
   117  	type testCase struct {
   118  		name    string
   119  		args    args
   120  		wantF32 []float32
   121  		wantF64 []float64
   122  	}
   123  	tests := []testCase{
   124  		{
   125  			name:    "Test1 - float32",
   126  			args:    args{leftArgF32: []float32{1, 2, 3}, rightArgF32: []float32{2, 3, 4}},
   127  			wantF32: []float32{2, 6, 12},
   128  		},
   129  		{
   130  			name:    "Test2 - float64",
   131  			args:    args{leftArgF64: []float64{1, 4, 3}, rightArgF64: []float64{1, 3, 4}},
   132  			wantF64: []float64{1, 12, 12},
   133  		},
   134  		{
   135  			name:    "Test3 - float64",
   136  			args:    args{leftArgF64: []float64{0.66616553}, rightArgF64: []float64{0.66616553}},
   137  			wantF64: []float64{0.4437765133601809},
   138  		},
   139  	}
   140  	for _, tt := range tests {
   141  		t.Run(tt.name, func(t *testing.T) {
   142  
   143  			if tt.args.rightArgF32 != nil {
   144  				if gotRes, err := Multiply[float32](tt.args.leftArgF32, tt.args.rightArgF32); err != nil || !reflect.DeepEqual(tt.wantF32, gotRes) {
   145  					t.Errorf("Multiply() = %v, want %v", gotRes, tt.wantF32)
   146  				}
   147  			}
   148  			if tt.args.rightArgF64 != nil {
   149  				if gotRes, err := Multiply[float64](tt.args.leftArgF64, tt.args.rightArgF64); err != nil || !assertx.InEpsilonF64Slice(tt.wantF64, gotRes) {
   150  					t.Errorf("Multiply() = %v, want %v", gotRes, tt.wantF64)
   151  				}
   152  			}
   153  		})
   154  	}
   155  }
   156  
   157  func TestDivide(t *testing.T) {
   158  	type args struct {
   159  		leftArgF32  []float32
   160  		rightArgF32 []float32
   161  
   162  		leftArgF64  []float64
   163  		rightArgF64 []float64
   164  	}
   165  	type testCase struct {
   166  		name    string
   167  		args    args
   168  		wantF32 []float32
   169  		wantF64 []float64
   170  		wantErr bool
   171  	}
   172  	tests := []testCase{
   173  		{
   174  			name:    "Test1 - float32",
   175  			args:    args{leftArgF32: []float32{1, 2, 3}, rightArgF32: []float32{2, 3, 4}},
   176  			wantF32: []float32{0.5, 0.6666667, 0.75},
   177  		},
   178  		{
   179  			name:    "Test2 - float32 - div by zero",
   180  			args:    args{leftArgF32: []float32{1, 4, 3}, rightArgF32: []float32{1, 0, 4}},
   181  			wantErr: true,
   182  		},
   183  		{
   184  			name:    "Test3 - float64",
   185  			args:    args{leftArgF64: []float64{1, 4, 3}, rightArgF64: []float64{1, 3, 4}},
   186  			wantF64: []float64{1, 1.3333333333333333, 0.75},
   187  		},
   188  		{
   189  			name:    "Test4 - float64 - div by zero",
   190  			args:    args{leftArgF64: []float64{1, 4, 3}, rightArgF64: []float64{1, 0, 4}},
   191  			wantErr: true,
   192  		},
   193  		{
   194  			name:    "Test5 - float64 - dimension mismatch",
   195  			args:    args{leftArgF64: []float64{1, 4}, rightArgF64: []float64{1, 1, 4}},
   196  			wantErr: true,
   197  		},
   198  	}
   199  	for _, tt := range tests {
   200  		t.Run(tt.name, func(t *testing.T) {
   201  
   202  			if tt.args.rightArgF32 != nil {
   203  				if tt.wantErr {
   204  					if _, gotErr := Divide[float32](tt.args.leftArgF32, tt.args.rightArgF32); gotErr == nil {
   205  						t.Errorf("Divide() should throw error")
   206  					}
   207  				} else if gotRes, err := Divide[float32](tt.args.leftArgF32, tt.args.rightArgF32); err != nil || !reflect.DeepEqual(gotRes, tt.wantF32) {
   208  					t.Errorf("Divide() = %v, want %v", gotRes, tt.wantF32)
   209  				}
   210  			}
   211  			if tt.args.rightArgF64 != nil {
   212  				if tt.wantErr {
   213  					if _, gotErr := Divide[float64](tt.args.leftArgF64, tt.args.rightArgF64); gotErr == nil {
   214  						t.Errorf("Divide() should throw error")
   215  					}
   216  				} else if gotRes, err := Divide[float64](tt.args.leftArgF64, tt.args.rightArgF64); err != nil || !assertx.InEpsilonF64Slice(tt.wantF64, gotRes) {
   217  					t.Errorf("Divide() = %v, want %v", gotRes, tt.wantF64)
   218  				}
   219  			}
   220  		})
   221  	}
   222  }
   223  
   224  func TestCompare(t *testing.T) {
   225  	type args struct {
   226  		leftArgF32  []float32
   227  		rightArgF32 []float32
   228  
   229  		leftArgF64  []float64
   230  		rightArgF64 []float64
   231  	}
   232  	type testCase struct {
   233  		name string
   234  		args args
   235  		want int
   236  	}
   237  	tests := []testCase{
   238  		{
   239  			name: "Test1 - float32-less",
   240  			args: args{leftArgF32: []float32{1, 2, 3}, rightArgF32: []float32{2, 3, 4}},
   241  			want: -1,
   242  		},
   243  		{
   244  			name: "Test2 - float32-large",
   245  			args: args{leftArgF32: []float32{3, 2, 3}, rightArgF32: []float32{2, 3, 4}},
   246  			want: 1,
   247  		},
   248  		{
   249  			name: "Test3 - float32-equal",
   250  			args: args{leftArgF32: []float32{3, 2, 3}, rightArgF32: []float32{3, 2, 3}},
   251  			want: 0,
   252  		},
   253  		{
   254  			name: "Test4 - float64-less",
   255  			args: args{leftArgF64: []float64{1, 2, 3}, rightArgF64: []float64{2, 3, 4}},
   256  			want: -1,
   257  		},
   258  		{
   259  			name: "Test5 - float64-large",
   260  			args: args{leftArgF64: []float64{3, 2, 3}, rightArgF64: []float64{2, 3, 4}},
   261  			want: 1,
   262  		},
   263  		{
   264  			name: "Test6 - float64-equal",
   265  			args: args{leftArgF64: []float64{3, 2, 3}, rightArgF64: []float64{3, 2, 3}},
   266  			want: 0,
   267  		},
   268  		{
   269  			name: "Test7 - float64 difference dims",
   270  			args: args{leftArgF64: []float64{3, 2}, rightArgF64: []float64{3, 2, 3}},
   271  			want: -1,
   272  		},
   273  		{
   274  			name: "Test7 - float64 difference dims",
   275  			args: args{leftArgF64: []float64{3, 2, 3}, rightArgF64: []float64{3, 2}},
   276  			want: 1,
   277  		},
   278  	}
   279  	for _, tt := range tests {
   280  		t.Run(tt.name, func(t *testing.T) {
   281  
   282  			if tt.args.rightArgF32 != nil {
   283  				if gotRes := Compare[float32](tt.args.leftArgF32, tt.args.rightArgF32); !reflect.DeepEqual(gotRes, tt.want) {
   284  					t.Errorf("CompareArray() = %v, want %v", gotRes, tt.want)
   285  				}
   286  			}
   287  			if tt.args.rightArgF64 != nil {
   288  				if gotRes := Compare[float64](tt.args.leftArgF64, tt.args.rightArgF64); !reflect.DeepEqual(gotRes, tt.want) {
   289  					t.Errorf("CompareArray() = %v, want %v", gotRes, tt.want)
   290  				}
   291  			}
   292  
   293  		})
   294  	}
   295  }
   296  
   297  func TestCast(t *testing.T) {
   298  	type args struct {
   299  		argF32 []float32
   300  		argF64 []float64
   301  	}
   302  	type testCase struct {
   303  		name    string
   304  		args    args
   305  		wantF32 []float32
   306  		wantF64 []float64
   307  	}
   308  	tests := []testCase{
   309  		{
   310  			name:    "Test1 - float32 to float64",
   311  			args:    args{argF32: []float32{1, 2, 3}},
   312  			wantF64: []float64{1, 2, 3},
   313  		},
   314  		{
   315  			name:    "Test2 - float64 to float32",
   316  			args:    args{argF64: []float64{1, 4, 3}},
   317  			wantF32: []float32{1, 4, 3},
   318  		},
   319  	}
   320  	for _, tt := range tests {
   321  		t.Run(tt.name, func(t *testing.T) {
   322  
   323  			if tt.args.argF32 != nil && tt.wantF64 != nil {
   324  				if gotResF64, err := Cast[float32, float64](tt.args.argF32); err != nil || !assertx.InEpsilonF64Slice(gotResF64, tt.wantF64) {
   325  					t.Errorf("Cast() = %v, want %v", gotResF64, tt.wantF64)
   326  				}
   327  			}
   328  			if tt.args.argF64 != nil && tt.wantF32 != nil {
   329  				if gotResF32, err := Cast[float64, float32](tt.args.argF64); err != nil || !reflect.DeepEqual(gotResF32, tt.wantF32) {
   330  					t.Errorf("Cast() = %v, want %v", gotResF32, tt.wantF32)
   331  				}
   332  			}
   333  		})
   334  	}
   335  }
   336  
   337  func TestAbs(t *testing.T) {
   338  	type args struct {
   339  		argF32 []float32
   340  		argF64 []float64
   341  	}
   342  	type testCase struct {
   343  		name string
   344  		args args
   345  
   346  		wantF32 []float32
   347  		wantF64 []float64
   348  	}
   349  	tests := []testCase{
   350  		{
   351  			name:    "Test1 - float32",
   352  			args:    args{argF32: []float32{-1, 0, -3.4e+38}},
   353  			wantF32: []float32{1, 0, 3.4e+38},
   354  		},
   355  		{
   356  			name:    "Test2 - float64",
   357  			args:    args{argF64: []float64{-1, 0, 3}},
   358  			wantF64: []float64{1, 0, 3},
   359  		},
   360  	}
   361  	for _, tt := range tests {
   362  		t.Run(tt.name, func(t *testing.T) {
   363  
   364  			if tt.args.argF32 != nil {
   365  				if gotRes, err := Abs[float32](tt.args.argF32); err != nil || !reflect.DeepEqual(gotRes, tt.wantF32) {
   366  					t.Errorf("Abs() = %v, want %v", gotRes, tt.wantF32)
   367  				}
   368  			}
   369  			if tt.args.argF64 != nil {
   370  				if gotRes, err := Abs[float64](tt.args.argF64); err != nil || !assertx.InEpsilonF64Slice(tt.wantF64, gotRes) {
   371  					t.Errorf("Abs() = %v, want %v", gotRes, tt.wantF64)
   372  				}
   373  			}
   374  		})
   375  	}
   376  }
   377  
   378  func TestNormalizeL2(t *testing.T) {
   379  	type args struct {
   380  		argF32 []float32
   381  		argF64 []float64
   382  	}
   383  	type testCase struct {
   384  		name string
   385  		args args
   386  
   387  		wantF32 []float32
   388  		wantF64 []float64
   389  		wantErr bool
   390  	}
   391  	tests := []testCase{
   392  		{
   393  			name:    "Test1 - float32 - zero vector",
   394  			args:    args{argF32: []float32{0, 0, 0}},
   395  			wantF32: []float32{0, 0, 0},
   396  		},
   397  		{
   398  			name:    "Test1.b - float32",
   399  			args:    args{argF32: []float32{1, 2, 3}},
   400  			wantF32: []float32{0.26726124, 0.5345225, 0.80178374},
   401  		},
   402  		{
   403  			name:    "Test1.c - float32",
   404  			args:    args{argF32: []float32{10, 3.333333333333333, 4, 5}},
   405  			wantF32: []float32{0.8108108, 0.27027026, 0.32432434, 0.4054054},
   406  		},
   407  		{
   408  			name:    "Test2 - float64 - zero vector",
   409  			args:    args{argF64: []float64{0, 0, 0}},
   410  			wantF64: []float64{0, 0, 0},
   411  		},
   412  		{
   413  			name:    "Test3 - float64",
   414  			args:    args{argF64: []float64{1, 2, 3}},
   415  			wantF64: []float64{0.2672612419124244, 0.5345224838248488, 0.8017837257372732},
   416  		},
   417  		{
   418  			name:    "Test4 - float64",
   419  			args:    args{argF64: []float64{-1, 2, 3}},
   420  			wantF64: []float64{-0.2672612419124244, 0.5345224838248488, 0.8017837257372732},
   421  		},
   422  		{
   423  			name:    "Test5 - float64",
   424  			args:    args{argF64: []float64{10, 3.333333333333333, 4, 5}},
   425  			wantF64: []float64{0.8108108108108107, 0.27027027027027023, 0.3243243243243243, 0.4054054054054054},
   426  		},
   427  		{
   428  			name:    "Test6 - float64",
   429  			args:    args{argF64: []float64{1, 2, 3.6666666666666665, 4.666666666666666}},
   430  			wantF64: []float64{0.15767649936829103, 0.31535299873658207, 0.5781471643504004, 0.7358236637186913},
   431  		},
   432  	}
   433  	for _, tt := range tests {
   434  		t.Run(tt.name, func(t *testing.T) {
   435  
   436  			if tt.args.argF32 != nil {
   437  				if tt.wantErr {
   438  					if _, err := NormalizeL2[float32](tt.args.argF32); err == nil {
   439  						t.Errorf("NormalizeL2() should throw error")
   440  					}
   441  				} else if gotRes, err := NormalizeL2[float32](tt.args.argF32); err != nil || !reflect.DeepEqual(tt.wantF32, gotRes) {
   442  					t.Errorf("NormalizeL2() = %v, want %v", gotRes, tt.wantF32)
   443  				}
   444  			}
   445  			if tt.args.argF64 != nil {
   446  				if tt.wantErr {
   447  					if _, err := NormalizeL2[float64](tt.args.argF64); err == nil {
   448  						t.Errorf("NormalizeL2() should throw error")
   449  					}
   450  				} else if gotRes, err := NormalizeL2[float64](tt.args.argF64); err != nil || !assertx.InEpsilonF64Slice(tt.wantF64, gotRes) {
   451  					t.Errorf("NormalizeL2() = %v, want %v", gotRes, tt.wantF64)
   452  				}
   453  			}
   454  		})
   455  	}
   456  }
   457  
   458  func TestSqrt(t *testing.T) {
   459  	type args struct {
   460  		argF32 []float32
   461  		argF64 []float64
   462  	}
   463  	type testCase struct {
   464  		name string
   465  		args args
   466  
   467  		wantF32 []float64 // ie result for argF32 is []float32
   468  		wantF64 []float64 // ie result for argF64 is []float64
   469  		wantErr bool
   470  	}
   471  	tests := []testCase{
   472  		{
   473  			name:    "Test1 - float32",
   474  			args:    args{argF32: []float32{1, 0, 4}},
   475  			wantF32: []float64{1, 0, 2},
   476  		},
   477  		{
   478  			name:    "Test2 - float32 error case",
   479  			args:    args{argF32: []float32{-1, 0, 4}},
   480  			wantErr: true,
   481  		},
   482  		{
   483  			name:    "Test3 - float64",
   484  			args:    args{argF64: []float64{1, 0, 4}},
   485  			wantF64: []float64{1, 0, 2},
   486  		},
   487  		{
   488  			name:    "Test4 - float64 error case",
   489  			args:    args{argF64: []float64{-1, 0, 4}},
   490  			wantErr: true,
   491  		},
   492  	}
   493  	for _, tt := range tests {
   494  		t.Run(tt.name, func(t *testing.T) {
   495  
   496  			if tt.args.argF32 != nil {
   497  				if tt.wantErr {
   498  					if _, err := Sqrt[float32](tt.args.argF32); err == nil {
   499  						t.Errorf("Sqrt() should throw error")
   500  					}
   501  				} else if gotRes, err := Sqrt[float32](tt.args.argF32); err != nil || !reflect.DeepEqual(gotRes, tt.wantF32) {
   502  					t.Errorf("Sqrt() = %v, want %v", err, tt.wantErr)
   503  					t.Errorf("Sqrt() = %v, want %v", gotRes, tt.wantF32)
   504  				}
   505  			}
   506  			if tt.args.argF64 != nil {
   507  				if tt.wantErr {
   508  					if _, err := Sqrt[float64](tt.args.argF64); err == nil {
   509  						t.Errorf("Sqrt() should throw error")
   510  					}
   511  				} else if gotRes, err := Sqrt[float64](tt.args.argF64); err != nil || !assertx.InEpsilonF64Slice(tt.wantF64, gotRes) {
   512  					t.Errorf("Sqrt() = %v, want %v", gotRes, tt.wantF64)
   513  				}
   514  			}
   515  
   516  		})
   517  	}
   518  }
   519  
   520  func TestSummation(t *testing.T) {
   521  	type args struct {
   522  		argF32 []float32
   523  		argF64 []float64
   524  	}
   525  	type testCase struct {
   526  		name string
   527  		args args
   528  		want float64
   529  	}
   530  	tests := []testCase{
   531  		{
   532  			name: "Test1 - float32",
   533  			args: args{argF32: []float32{1, 2, 3}},
   534  			want: 6,
   535  		},
   536  		{
   537  			name: "Test2 - float64",
   538  			args: args{argF64: []float64{1, 2, 3}},
   539  			want: 6,
   540  		},
   541  	}
   542  	for _, tt := range tests {
   543  		t.Run(tt.name, func(t *testing.T) {
   544  
   545  			if tt.args.argF32 != nil {
   546  				if gotRes, err := Summation[float32](tt.args.argF32); err != nil || !assertx.InEpsilonF64(tt.want, gotRes) {
   547  					t.Errorf("Summation() = %v, want %v", gotRes, tt.want)
   548  				}
   549  			}
   550  			if tt.args.argF64 != nil {
   551  				if gotRes, err := Summation[float64](tt.args.argF64); err != nil || !assertx.InEpsilonF64(tt.want, gotRes) {
   552  					t.Errorf("Summation() = %v, want %v", gotRes, tt.want)
   553  				}
   554  			}
   555  
   556  		})
   557  	}
   558  }
   559  
   560  func TestInnerProduct(t *testing.T) {
   561  	type args struct {
   562  		argLeftF32  []float32
   563  		argRightF32 []float32
   564  
   565  		argLeftF64  []float64
   566  		argRightF64 []float64
   567  	}
   568  	type testCase struct {
   569  		name string
   570  		args args
   571  		want float64
   572  	}
   573  	tests := []testCase{
   574  		{
   575  			name: "Test1 - float32",
   576  			args: args{argLeftF32: []float32{1, 2, 3}, argRightF32: []float32{1, 2, 3}},
   577  			want: 14,
   578  		},
   579  		{
   580  			name: "Test2 - float64",
   581  			args: args{argLeftF64: []float64{1, 2, 3}, argRightF64: []float64{1, 2, 3}},
   582  			want: 14,
   583  		},
   584  	}
   585  	for _, tt := range tests {
   586  		t.Run(tt.name, func(t *testing.T) {
   587  
   588  			if tt.args.argLeftF32 != nil {
   589  				if gotRes, _ := InnerProduct[float32](tt.args.argLeftF32, tt.args.argRightF32); !assertx.InEpsilonF64(tt.want, gotRes) {
   590  					t.Errorf("InnerProduct() = %v, want %v", gotRes, tt.want)
   591  				}
   592  			}
   593  			if tt.args.argLeftF64 != nil {
   594  				if gotRes, _ := InnerProduct[float64](tt.args.argLeftF64, tt.args.argRightF64); !assertx.InEpsilonF64(tt.want, gotRes) {
   595  					t.Errorf("InnerProduct() = %v, want %v", gotRes, tt.want)
   596  				}
   597  			}
   598  
   599  		})
   600  	}
   601  }
   602  
   603  func TestL1Norm(t *testing.T) {
   604  	type args struct {
   605  		argF32 []float32
   606  		argF64 []float64
   607  	}
   608  	type testCase struct {
   609  		name string
   610  		args args
   611  		want float64
   612  	}
   613  	tests := []testCase{
   614  		{
   615  			name: "Test1 - float32",
   616  			args: args{argF32: []float32{1, 2, 3}},
   617  			want: 6,
   618  		},
   619  		{
   620  			name: "Test2 - float64",
   621  			args: args{argF64: []float64{1, 2, 3}},
   622  			want: 6,
   623  		},
   624  	}
   625  	for _, tt := range tests {
   626  		t.Run(tt.name, func(t *testing.T) {
   627  
   628  			if tt.args.argF32 != nil {
   629  				if gotRes, _ := L1Norm[float32](tt.args.argF32); !assertx.InEpsilonF64(tt.want, gotRes) {
   630  					t.Errorf("L1Norm() = %v, want %v", gotRes, tt.want)
   631  				}
   632  			}
   633  			if tt.args.argF64 != nil {
   634  				if gotRes, _ := L1Norm[float64](tt.args.argF64); !assertx.InEpsilonF64(tt.want, gotRes) {
   635  					t.Errorf("L1Norm() = %v, want %v", gotRes, tt.want)
   636  				}
   637  			}
   638  
   639  		})
   640  	}
   641  }
   642  
   643  func TestL2Norm(t *testing.T) {
   644  	type args struct {
   645  		argF32 []float32
   646  		argF64 []float64
   647  	}
   648  	type testCase struct {
   649  		name string
   650  		args args
   651  		want float64
   652  	}
   653  	tests := []testCase{
   654  		{
   655  			name: "Test1 - float32",
   656  			args: args{argF32: []float32{1, 2, 3}},
   657  			want: 3.741657386773941,
   658  		},
   659  		{
   660  			name: "Test2 - float64",
   661  			args: args{argF64: []float64{1, 2, 3}},
   662  			want: 3.741657386773941,
   663  		},
   664  	}
   665  	for _, tt := range tests {
   666  		t.Run(tt.name, func(t *testing.T) {
   667  
   668  			if tt.args.argF32 != nil {
   669  				if gotRes, _ := L2Norm[float32](tt.args.argF32); !assertx.InEpsilonF64(tt.want, gotRes) {
   670  					t.Errorf("L2Norm() = %v, want %v", gotRes, tt.want)
   671  				}
   672  			}
   673  			if tt.args.argF64 != nil {
   674  				if gotRes, _ := L2Norm[float64](tt.args.argF64); !assertx.InEpsilonF64(tt.want, gotRes) {
   675  					t.Errorf("L2Norm() = %v, want %v", gotRes, tt.want)
   676  				}
   677  			}
   678  
   679  		})
   680  	}
   681  }
   682  
   683  func TestCosineSimilarity(t *testing.T) {
   684  	type args struct {
   685  		argLeftF32  []float32
   686  		argRightF32 []float32
   687  
   688  		argLeftF64  []float64
   689  		argRightF64 []float64
   690  	}
   691  	type testCase struct {
   692  		name string
   693  		args args
   694  		want float64
   695  	}
   696  	tests := []testCase{
   697  		{
   698  			name: "Test1.a - float32",
   699  			args: args{argLeftF32: []float32{1, 2, 3}, argRightF32: []float32{1, 2, 3}},
   700  			want: 1,
   701  		},
   702  		{
   703  			name: "Test1.b - float32",
   704  			args: args{argLeftF32: []float32{0.46323407, 23.498016, 563.923, 56.076736, 8732.958}, argRightF32: []float32{0.46323407, 23.498016, 563.923, 56.076736, 8732.958}},
   705  			want: 1,
   706  		},
   707  		{
   708  			name: "Test2.a - float64",
   709  			args: args{argLeftF64: []float64{1, 2, 3}, argRightF64: []float64{1, 2, 3}},
   710  			want: 1,
   711  		},
   712  		{
   713  			name: "Test2.b - float64",
   714  			args: args{argLeftF64: []float64{0.46323407, 23.498016, 563.923, 56.076736, 8732.958}, argRightF64: []float64{0.46323407, 23.498016, 563.923, 56.076736, 8732.958}},
   715  			want: 1,
   716  		},
   717  		{
   718  			name: "Test2.c - float64",
   719  			args: args{argLeftF64: []float64{0.8166459, 0.66616553, 0.4886152}, argRightF64: []float64{0.8166459, 0.66616553, 0.4886152}},
   720  			want: 1,
   721  		},
   722  		{
   723  			name: "Test2.d - float64",
   724  			args: args{argLeftF64: []float64{8.5606893, 6.7903588, 821.977768}, argRightF64: []float64{8.5606893, 6.7903588, 821.977768}},
   725  			want: 1,
   726  		},
   727  		{
   728  			name: "Test2.e - float64",
   729  			args: args{argLeftF64: []float64{0.9260021, 0.26637346, 0.06567037}, argRightF64: []float64{0.9260021, 0.26637346, 0.06567037}},
   730  			want: 1,
   731  		},
   732  		{
   733  			name: "Test2.f - float64",
   734  			args: args{argLeftF64: []float64{0.45756745, 65.2996871, 321.623636, 3.60082066, 87.58445764}, argRightF64: []float64{0.45756745, 65.2996871, 321.623636, 3.60082066, 87.58445764}},
   735  			want: 1,
   736  		},
   737  		{
   738  			name: "Test2.g - float64",
   739  			args: args{argLeftF64: []float64{0.46323407, 23.49801546, 563.9229458, 56.07673508, 8732.9583881}, argRightF64: []float64{0.46323407, 23.49801546, 563.9229458, 56.07673508, 8732.9583881}},
   740  			want: 1,
   741  		},
   742  	}
   743  	for _, tt := range tests {
   744  		t.Run(tt.name, func(t *testing.T) {
   745  
   746  			if tt.args.argLeftF32 != nil {
   747  				if gotRes, _ := CosineSimilarity[float32](tt.args.argLeftF32, tt.args.argRightF32); !reflect.DeepEqual(tt.want, gotRes) {
   748  					t.Errorf("CosineSimilarity() = %v, want %v", gotRes, tt.want)
   749  				}
   750  			}
   751  			if tt.args.argLeftF64 != nil {
   752  				if gotRes, _ := CosineSimilarity[float64](tt.args.argLeftF64, tt.args.argRightF64); !reflect.DeepEqual(tt.want, gotRes) {
   753  					t.Errorf("CosineSimilarity() = %v, want %v", gotRes, tt.want)
   754  				}
   755  			}
   756  
   757  		})
   758  	}
   759  }
   760  
   761  func TestL2Distance(t *testing.T) {
   762  	type args struct {
   763  		argLeftF32  []float32
   764  		argRightF32 []float32
   765  
   766  		argLeftF64  []float64
   767  		argRightF64 []float64
   768  	}
   769  	type testCase struct {
   770  		name string
   771  		args args
   772  		want float64
   773  	}
   774  	tests := []testCase{
   775  		{
   776  			name: "Test1 - float32",
   777  			args: args{argLeftF32: []float32{1, 2, 3}, argRightF32: []float32{10, 20, 30}},
   778  			want: 33.67491648096547,
   779  		},
   780  		{
   781  			name: "Test2 - float64",
   782  			args: args{argLeftF64: []float64{1, 2, 3}, argRightF64: []float64{10, 20, 30}},
   783  			want: 33.67491648096547,
   784  		},
   785  	}
   786  	for _, tt := range tests {
   787  		t.Run(tt.name, func(t *testing.T) {
   788  
   789  			if tt.args.argLeftF32 != nil {
   790  				if gotRes, _ := L2Distance[float32](tt.args.argLeftF32, tt.args.argRightF32); !assertx.InEpsilonF64(tt.want, gotRes) {
   791  					t.Errorf("L2Distance() = %v, want %v", gotRes, tt.want)
   792  				}
   793  			}
   794  			if tt.args.argLeftF64 != nil {
   795  				if gotRes, _ := L2Distance[float64](tt.args.argLeftF64, tt.args.argRightF64); !assertx.InEpsilonF64(tt.want, gotRes) {
   796  					t.Errorf("L2Distance() = %v, want %v", gotRes, tt.want)
   797  				}
   798  			}
   799  
   800  		})
   801  	}
   802  }
   803  
   804  func TestCosineDistance(t *testing.T) {
   805  	type args struct {
   806  		argLeftF32  []float32
   807  		argRightF32 []float32
   808  
   809  		argLeftF64  []float64
   810  		argRightF64 []float64
   811  	}
   812  	type testCase struct {
   813  		name string
   814  		args args
   815  		want float64
   816  	}
   817  	tests := []testCase{
   818  		{
   819  			name: "Test1 - float32",
   820  			args: args{argLeftF32: []float32{1, 2, 3}, argRightF32: []float32{-1, -2, -3}},
   821  			want: 2,
   822  		},
   823  		{
   824  			name: "Test2 - float64",
   825  			args: args{argLeftF64: []float64{1, 2, 3}, argRightF64: []float64{1, 2, 3}},
   826  			want: 0,
   827  		},
   828  	}
   829  	for _, tt := range tests {
   830  		t.Run(tt.name, func(t *testing.T) {
   831  
   832  			if tt.args.argLeftF32 != nil {
   833  				if gotRes, _ := CosineDistance[float32](tt.args.argLeftF32, tt.args.argRightF32); !assertx.InEpsilonF64(tt.want, gotRes) {
   834  					t.Errorf("CosineDistance() = %v, want %v", gotRes, tt.want)
   835  				}
   836  			}
   837  			if tt.args.argLeftF64 != nil {
   838  				if gotRes, _ := CosineDistance[float64](tt.args.argLeftF64, tt.args.argRightF64); !assertx.InEpsilonF64(tt.want, gotRes) {
   839  					t.Errorf("CosineDistance() = %v, want %v", gotRes, tt.want)
   840  				}
   841  			}
   842  
   843  		})
   844  	}
   845  }
   846  
   847  func TestScalarOp(t *testing.T) {
   848  	type args struct {
   849  		argVecF32 []float32
   850  		argVecF64 []float64
   851  		argOp     string
   852  		argSca    float64
   853  	}
   854  	type testCase struct {
   855  		name       string
   856  		args       args
   857  		wantVecF32 []float32
   858  		wantVecF64 []float64
   859  	}
   860  	tests := []testCase{
   861  		{
   862  			name:       "Test1 - float32",
   863  			args:       args{argVecF32: []float32{1, 2, 3}, argOp: "+", argSca: 2},
   864  			wantVecF32: []float32{3, 4, 5},
   865  		},
   866  		{
   867  			name:       "Test2 - float32",
   868  			args:       args{argVecF32: []float32{1, 2, 3}, argOp: "-", argSca: 2},
   869  			wantVecF32: []float32{-1, 0, 1},
   870  		},
   871  		{
   872  			name:       "Test3 - float32",
   873  			args:       args{argVecF32: []float32{1, 2, 3}, argOp: "*", argSca: 2},
   874  			wantVecF32: []float32{2, 4, 6},
   875  		},
   876  		{
   877  			name:       "Test4 - float32",
   878  			args:       args{argVecF32: []float32{1, 2, 3}, argOp: "/", argSca: 2},
   879  			wantVecF32: []float32{0.5, 1, 1.5},
   880  		},
   881  
   882  		{
   883  			name:       "Test5 - float64",
   884  			args:       args{argVecF64: []float64{1, 2, 3}, argOp: "+", argSca: 2},
   885  			wantVecF64: []float64{3, 4, 5},
   886  		},
   887  		{
   888  			name:       "Test6 - float64",
   889  			args:       args{argVecF64: []float64{1, 2, 3}, argOp: "-", argSca: 2},
   890  			wantVecF64: []float64{-1, 0, 1},
   891  		},
   892  		{
   893  			name:       "Test7 - float64",
   894  			args:       args{argVecF64: []float64{1, 2, 3}, argOp: "*", argSca: 2},
   895  			wantVecF64: []float64{2, 4, 6},
   896  		},
   897  		{
   898  			name:       "Test8 - float64",
   899  			args:       args{argVecF64: []float64{1, 2, 3}, argOp: "/", argSca: 2},
   900  			wantVecF64: []float64{0.5, 1, 1.5},
   901  		},
   902  	}
   903  	for _, tt := range tests {
   904  		t.Run(tt.name, func(t *testing.T) {
   905  
   906  			if tt.args.argVecF32 != nil {
   907  				if gotRes, _ := ScalarOp[float32](tt.args.argVecF32, tt.args.argOp, tt.args.argSca); !reflect.DeepEqual(gotRes, tt.wantVecF32) {
   908  					t.Errorf("ScalarOp() = %v, want %v", gotRes, tt.wantVecF32)
   909  				}
   910  			} else if tt.args.argVecF64 != nil {
   911  				if gotRes, _ := ScalarOp[float64](tt.args.argVecF64, tt.args.argOp, tt.args.argSca); !reflect.DeepEqual(gotRes, tt.wantVecF64) {
   912  					t.Errorf("ScalarOp() = %v, want %v", gotRes, tt.wantVecF64)
   913  				}
   914  			}
   915  
   916  		})
   917  	}
   918  }