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 }