@digitaldefiance/node-accelerate 1.0.6 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1277 -166
- package/accelerate.cc +1346 -0
- package/examples/advanced-functions.js +0 -0
- package/examples/data-processing.js +123 -0
- package/examples/machine-learning.js +158 -0
- package/examples/mathematical-functions.js +101 -0
- package/examples/matrix-multiply.js +50 -0
- package/examples/ml-pipeline.js +317 -0
- package/examples/signal-processing-advanced.js +98 -0
- package/examples/signal-processing.js +70 -0
- package/examples/statistical-operations.js +44 -0
- package/examples/trigonometric-functions.js +52 -0
- package/examples/vector-operations.js +73 -0
- package/index.d.ts +720 -0
- package/index.js +636 -0
- package/package.json +13 -3
package/accelerate.cc
CHANGED
|
@@ -610,6 +610,1284 @@ static napi_value VectorRMS(napi_env env, napi_callback_info info) {
|
|
|
610
610
|
return js_result;
|
|
611
611
|
}
|
|
612
612
|
|
|
613
|
+
// ============================================================================
|
|
614
|
+
// ADDITIONAL ACCELERATE FUNCTIONS
|
|
615
|
+
// ============================================================================
|
|
616
|
+
|
|
617
|
+
// Variance
|
|
618
|
+
static napi_value VectorVariance(napi_env env, napi_callback_info info) {
|
|
619
|
+
size_t argc = 1;
|
|
620
|
+
napi_value args[1];
|
|
621
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
622
|
+
|
|
623
|
+
size_t len;
|
|
624
|
+
double* A = GetFloat64ArrayData(env, args[0], &len);
|
|
625
|
+
|
|
626
|
+
if (!A) {
|
|
627
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
double mean_val, variance;
|
|
631
|
+
vDSP_meanvD(A, 1, &mean_val, len);
|
|
632
|
+
|
|
633
|
+
// Compute variance manually
|
|
634
|
+
std::vector<double> diff(len);
|
|
635
|
+
double neg_mean = -mean_val;
|
|
636
|
+
vDSP_vsaddD(A, 1, &neg_mean, diff.data(), 1, len);
|
|
637
|
+
vDSP_vsqD(diff.data(), 1, diff.data(), 1, len);
|
|
638
|
+
vDSP_sveD(diff.data(), 1, &variance, len);
|
|
639
|
+
variance /= len;
|
|
640
|
+
|
|
641
|
+
napi_value js_result;
|
|
642
|
+
napi_create_double(env, variance, &js_result);
|
|
643
|
+
return js_result;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Standard Deviation
|
|
647
|
+
static napi_value VectorStdDev(napi_env env, napi_callback_info info) {
|
|
648
|
+
size_t argc = 1;
|
|
649
|
+
napi_value args[1];
|
|
650
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
651
|
+
|
|
652
|
+
size_t len;
|
|
653
|
+
double* A = GetFloat64ArrayData(env, args[0], &len);
|
|
654
|
+
|
|
655
|
+
if (!A) {
|
|
656
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
double mean_val, variance;
|
|
660
|
+
vDSP_meanvD(A, 1, &mean_val, len);
|
|
661
|
+
|
|
662
|
+
std::vector<double> diff(len);
|
|
663
|
+
double neg_mean = -mean_val;
|
|
664
|
+
vDSP_vsaddD(A, 1, &neg_mean, diff.data(), 1, len);
|
|
665
|
+
vDSP_vsqD(diff.data(), 1, diff.data(), 1, len);
|
|
666
|
+
vDSP_sveD(diff.data(), 1, &variance, len);
|
|
667
|
+
variance /= len;
|
|
668
|
+
|
|
669
|
+
double stddev = sqrt(variance);
|
|
670
|
+
|
|
671
|
+
napi_value js_result;
|
|
672
|
+
napi_create_double(env, stddev, &js_result);
|
|
673
|
+
return js_result;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Min and Max together
|
|
677
|
+
static napi_value VectorMinMax(napi_env env, napi_callback_info info) {
|
|
678
|
+
size_t argc = 1;
|
|
679
|
+
napi_value args[1];
|
|
680
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
681
|
+
|
|
682
|
+
size_t len;
|
|
683
|
+
double* A = GetFloat64ArrayData(env, args[0], &len);
|
|
684
|
+
|
|
685
|
+
if (!A) {
|
|
686
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
double min_val, max_val;
|
|
690
|
+
vDSP_minvD(A, 1, &min_val, len);
|
|
691
|
+
vDSP_maxvD(A, 1, &max_val, len);
|
|
692
|
+
|
|
693
|
+
napi_value result, min_js, max_js;
|
|
694
|
+
napi_create_object(env, &result);
|
|
695
|
+
napi_create_double(env, min_val, &min_js);
|
|
696
|
+
napi_create_double(env, max_val, &max_js);
|
|
697
|
+
napi_set_named_property(env, result, "min", min_js);
|
|
698
|
+
napi_set_named_property(env, result, "max", max_js);
|
|
699
|
+
|
|
700
|
+
return result;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// Trigonometric functions
|
|
704
|
+
static napi_value VectorSin(napi_env env, napi_callback_info info) {
|
|
705
|
+
size_t argc = 2;
|
|
706
|
+
napi_value args[2];
|
|
707
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
708
|
+
|
|
709
|
+
size_t len_a, len_b;
|
|
710
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
711
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
712
|
+
|
|
713
|
+
if (!A || !B) {
|
|
714
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
718
|
+
int n = (int)len;
|
|
719
|
+
vvsin(B, A, &n);
|
|
720
|
+
|
|
721
|
+
return args[1];
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
static napi_value VectorCos(napi_env env, napi_callback_info info) {
|
|
725
|
+
size_t argc = 2;
|
|
726
|
+
napi_value args[2];
|
|
727
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
728
|
+
|
|
729
|
+
size_t len_a, len_b;
|
|
730
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
731
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
732
|
+
|
|
733
|
+
if (!A || !B) {
|
|
734
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
738
|
+
int n = (int)len;
|
|
739
|
+
vvcos(B, A, &n);
|
|
740
|
+
|
|
741
|
+
return args[1];
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
static napi_value VectorTan(napi_env env, napi_callback_info info) {
|
|
745
|
+
size_t argc = 2;
|
|
746
|
+
napi_value args[2];
|
|
747
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
748
|
+
|
|
749
|
+
size_t len_a, len_b;
|
|
750
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
751
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
752
|
+
|
|
753
|
+
if (!A || !B) {
|
|
754
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
758
|
+
int n = (int)len;
|
|
759
|
+
vvtan(B, A, &n);
|
|
760
|
+
|
|
761
|
+
return args[1];
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// Exponential and logarithm
|
|
765
|
+
static napi_value VectorExp(napi_env env, napi_callback_info info) {
|
|
766
|
+
size_t argc = 2;
|
|
767
|
+
napi_value args[2];
|
|
768
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
769
|
+
|
|
770
|
+
size_t len_a, len_b;
|
|
771
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
772
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
773
|
+
|
|
774
|
+
if (!A || !B) {
|
|
775
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
779
|
+
int n = (int)len;
|
|
780
|
+
vvexp(B, A, &n);
|
|
781
|
+
|
|
782
|
+
return args[1];
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
static napi_value VectorLog(napi_env env, napi_callback_info info) {
|
|
786
|
+
size_t argc = 2;
|
|
787
|
+
napi_value args[2];
|
|
788
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
789
|
+
|
|
790
|
+
size_t len_a, len_b;
|
|
791
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
792
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
793
|
+
|
|
794
|
+
if (!A || !B) {
|
|
795
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
799
|
+
int n = (int)len;
|
|
800
|
+
vvlog(B, A, &n);
|
|
801
|
+
|
|
802
|
+
return args[1];
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
static napi_value VectorLog10(napi_env env, napi_callback_info info) {
|
|
806
|
+
size_t argc = 2;
|
|
807
|
+
napi_value args[2];
|
|
808
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
809
|
+
|
|
810
|
+
size_t len_a, len_b;
|
|
811
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
812
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
813
|
+
|
|
814
|
+
if (!A || !B) {
|
|
815
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
819
|
+
int n = (int)len;
|
|
820
|
+
vvlog10(B, A, &n);
|
|
821
|
+
|
|
822
|
+
return args[1];
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// Power functions
|
|
826
|
+
static napi_value VectorPow(napi_env env, napi_callback_info info) {
|
|
827
|
+
size_t argc = 3;
|
|
828
|
+
napi_value args[3];
|
|
829
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
830
|
+
|
|
831
|
+
size_t len_a, len_b, len_c;
|
|
832
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
833
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
834
|
+
double* C = GetFloat64ArrayData(env, args[2], &len_c);
|
|
835
|
+
|
|
836
|
+
if (!A || !B || !C) {
|
|
837
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
841
|
+
len = len < len_c ? len : len_c;
|
|
842
|
+
int n = (int)len;
|
|
843
|
+
vvpow(C, B, A, &n);
|
|
844
|
+
|
|
845
|
+
return args[2];
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Clipping
|
|
849
|
+
static napi_value VectorClip(napi_env env, napi_callback_info info) {
|
|
850
|
+
size_t argc = 4;
|
|
851
|
+
napi_value args[4];
|
|
852
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
853
|
+
|
|
854
|
+
size_t len_a, len_b;
|
|
855
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
856
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
857
|
+
|
|
858
|
+
if (!A || !B) {
|
|
859
|
+
NAPI_THROW(env, "First two arguments must be Float64Arrays");
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
double min_val, max_val;
|
|
863
|
+
NAPI_CHECK(napi_get_value_double(env, args[2], &min_val));
|
|
864
|
+
NAPI_CHECK(napi_get_value_double(env, args[3], &max_val));
|
|
865
|
+
|
|
866
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
867
|
+
vDSP_vclipD(A, 1, &min_val, &max_val, B, 1, len);
|
|
868
|
+
|
|
869
|
+
return args[1];
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// Threshold
|
|
873
|
+
static napi_value VectorThreshold(napi_env env, napi_callback_info info) {
|
|
874
|
+
size_t argc = 3;
|
|
875
|
+
napi_value args[3];
|
|
876
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
877
|
+
|
|
878
|
+
size_t len_a, len_b;
|
|
879
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
880
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
881
|
+
|
|
882
|
+
if (!A || !B) {
|
|
883
|
+
NAPI_THROW(env, "First two arguments must be Float64Arrays");
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
double threshold;
|
|
887
|
+
NAPI_CHECK(napi_get_value_double(env, args[2], &threshold));
|
|
888
|
+
|
|
889
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
890
|
+
vDSP_vthrD(A, 1, &threshold, B, 1, len);
|
|
891
|
+
|
|
892
|
+
return args[1];
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// Convolution
|
|
896
|
+
static napi_value Convolve(napi_env env, napi_callback_info info) {
|
|
897
|
+
size_t argc = 3;
|
|
898
|
+
napi_value args[3];
|
|
899
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
900
|
+
|
|
901
|
+
size_t signal_len, kernel_len, result_len;
|
|
902
|
+
double* signal = GetFloat64ArrayData(env, args[0], &signal_len);
|
|
903
|
+
double* kernel = GetFloat64ArrayData(env, args[1], &kernel_len);
|
|
904
|
+
double* result = GetFloat64ArrayData(env, args[2], &result_len);
|
|
905
|
+
|
|
906
|
+
if (!signal || !kernel || !result) {
|
|
907
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
vDSP_convD(signal, 1, kernel, 1, result, 1, result_len, kernel_len);
|
|
911
|
+
|
|
912
|
+
return args[2];
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// Cross-correlation
|
|
916
|
+
static napi_value CrossCorrelation(napi_env env, napi_callback_info info) {
|
|
917
|
+
size_t argc = 3;
|
|
918
|
+
napi_value args[3];
|
|
919
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
920
|
+
|
|
921
|
+
size_t len_a, len_b, len_c;
|
|
922
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
923
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
924
|
+
double* C = GetFloat64ArrayData(env, args[2], &len_c);
|
|
925
|
+
|
|
926
|
+
if (!A || !B || !C) {
|
|
927
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
size_t result_len = len_a + len_b - 1;
|
|
931
|
+
if (len_c < result_len) {
|
|
932
|
+
NAPI_THROW(env, "Result array too small");
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// Use convolution with reversed kernel for correlation
|
|
936
|
+
std::vector<double> b_reversed(len_b);
|
|
937
|
+
for (size_t i = 0; i < len_b; i++) {
|
|
938
|
+
b_reversed[i] = B[len_b - 1 - i];
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
vDSP_convD(A, 1, b_reversed.data(), 1, C, 1, len_a, len_b);
|
|
942
|
+
|
|
943
|
+
return args[2];
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// Window functions
|
|
947
|
+
static napi_value HammingWindow(napi_env env, napi_callback_info info) {
|
|
948
|
+
size_t argc = 1;
|
|
949
|
+
napi_value args[1];
|
|
950
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
951
|
+
|
|
952
|
+
int32_t length;
|
|
953
|
+
NAPI_CHECK(napi_get_value_int32(env, args[0], &length));
|
|
954
|
+
|
|
955
|
+
napi_value arraybuffer;
|
|
956
|
+
void* data;
|
|
957
|
+
napi_create_arraybuffer(env, length * sizeof(double), &data, &arraybuffer);
|
|
958
|
+
double* window = static_cast<double*>(data);
|
|
959
|
+
|
|
960
|
+
vDSP_hamm_windowD(window, length, 0);
|
|
961
|
+
|
|
962
|
+
napi_value result;
|
|
963
|
+
napi_create_typedarray(env, napi_float64_array, length, arraybuffer, 0, &result);
|
|
964
|
+
|
|
965
|
+
return result;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
static napi_value HanningWindow(napi_env env, napi_callback_info info) {
|
|
969
|
+
size_t argc = 1;
|
|
970
|
+
napi_value args[1];
|
|
971
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
972
|
+
|
|
973
|
+
int32_t length;
|
|
974
|
+
NAPI_CHECK(napi_get_value_int32(env, args[0], &length));
|
|
975
|
+
|
|
976
|
+
napi_value arraybuffer;
|
|
977
|
+
void* data;
|
|
978
|
+
napi_create_arraybuffer(env, length * sizeof(double), &data, &arraybuffer);
|
|
979
|
+
double* window = static_cast<double*>(data);
|
|
980
|
+
|
|
981
|
+
vDSP_hann_windowD(window, length, 0);
|
|
982
|
+
|
|
983
|
+
napi_value result;
|
|
984
|
+
napi_create_typedarray(env, napi_float64_array, length, arraybuffer, 0, &result);
|
|
985
|
+
|
|
986
|
+
return result;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
static napi_value BlackmanWindow(napi_env env, napi_callback_info info) {
|
|
990
|
+
size_t argc = 1;
|
|
991
|
+
napi_value args[1];
|
|
992
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
993
|
+
|
|
994
|
+
int32_t length;
|
|
995
|
+
NAPI_CHECK(napi_get_value_int32(env, args[0], &length));
|
|
996
|
+
|
|
997
|
+
napi_value arraybuffer;
|
|
998
|
+
void* data;
|
|
999
|
+
napi_create_arraybuffer(env, length * sizeof(double), &data, &arraybuffer);
|
|
1000
|
+
double* window = static_cast<double*>(data);
|
|
1001
|
+
|
|
1002
|
+
vDSP_blkman_windowD(window, length, 0);
|
|
1003
|
+
|
|
1004
|
+
napi_value result;
|
|
1005
|
+
napi_create_typedarray(env, napi_float64_array, length, arraybuffer, 0, &result);
|
|
1006
|
+
|
|
1007
|
+
return result;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Matrix transpose
|
|
1011
|
+
static napi_value MatrixTranspose(napi_env env, napi_callback_info info) {
|
|
1012
|
+
size_t argc = 4;
|
|
1013
|
+
napi_value args[4];
|
|
1014
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1015
|
+
|
|
1016
|
+
size_t len_a, len_b;
|
|
1017
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1018
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1019
|
+
|
|
1020
|
+
if (!A || !B) {
|
|
1021
|
+
NAPI_THROW(env, "First two arguments must be Float64Arrays");
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
int32_t rows, cols;
|
|
1025
|
+
NAPI_CHECK(napi_get_value_int32(env, args[2], &rows));
|
|
1026
|
+
NAPI_CHECK(napi_get_value_int32(env, args[3], &cols));
|
|
1027
|
+
|
|
1028
|
+
vDSP_mtransD(A, 1, B, 1, cols, rows);
|
|
1029
|
+
|
|
1030
|
+
return args[1];
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// Inverse FFT
|
|
1034
|
+
static napi_value IFFT(napi_env env, napi_callback_info info) {
|
|
1035
|
+
size_t argc = 2;
|
|
1036
|
+
napi_value args[2];
|
|
1037
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1038
|
+
|
|
1039
|
+
size_t real_len, imag_len;
|
|
1040
|
+
double* real_in = GetFloat64ArrayData(env, args[0], &real_len);
|
|
1041
|
+
double* imag_in = GetFloat64ArrayData(env, args[1], &imag_len);
|
|
1042
|
+
|
|
1043
|
+
if (!real_in || !imag_in) {
|
|
1044
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
if (real_len != imag_len) {
|
|
1048
|
+
NAPI_THROW(env, "Real and imaginary arrays must have same length");
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
size_t half = real_len;
|
|
1052
|
+
size_t len = half * 2;
|
|
1053
|
+
|
|
1054
|
+
vDSP_Length log2n = 0;
|
|
1055
|
+
vDSP_Length n = len;
|
|
1056
|
+
while (n > 1) {
|
|
1057
|
+
n >>= 1;
|
|
1058
|
+
log2n++;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
if ((1UL << log2n) != len) {
|
|
1062
|
+
NAPI_THROW(env, "Length must be power of 2");
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
FFTSetupD setup = vDSP_create_fftsetupD(log2n, FFT_RADIX2);
|
|
1066
|
+
if (!setup) {
|
|
1067
|
+
NAPI_THROW(env, "Failed to create FFT setup");
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
std::vector<double> real(half);
|
|
1071
|
+
std::vector<double> imag(half);
|
|
1072
|
+
memcpy(real.data(), real_in, half * sizeof(double));
|
|
1073
|
+
memcpy(imag.data(), imag_in, half * sizeof(double));
|
|
1074
|
+
|
|
1075
|
+
DSPDoubleSplitComplex split;
|
|
1076
|
+
split.realp = real.data();
|
|
1077
|
+
split.imagp = imag.data();
|
|
1078
|
+
|
|
1079
|
+
vDSP_fft_zripD(setup, &split, 1, log2n, FFT_INVERSE);
|
|
1080
|
+
|
|
1081
|
+
double scale = 1.0 / len;
|
|
1082
|
+
vDSP_vsmulD(split.realp, 1, &scale, split.realp, 1, half);
|
|
1083
|
+
vDSP_vsmulD(split.imagp, 1, &scale, split.imagp, 1, half);
|
|
1084
|
+
|
|
1085
|
+
napi_value arraybuffer;
|
|
1086
|
+
void* data;
|
|
1087
|
+
napi_create_arraybuffer(env, len * sizeof(double), &data, &arraybuffer);
|
|
1088
|
+
double* output = static_cast<double*>(data);
|
|
1089
|
+
|
|
1090
|
+
vDSP_ztocD(&split, 1, (DSPDoubleComplex*)output, 2, half);
|
|
1091
|
+
|
|
1092
|
+
napi_value result;
|
|
1093
|
+
napi_create_typedarray(env, napi_float64_array, len, arraybuffer, 0, &result);
|
|
1094
|
+
|
|
1095
|
+
vDSP_destroy_fftsetupD(setup);
|
|
1096
|
+
|
|
1097
|
+
return result;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// Linear interpolation
|
|
1101
|
+
static napi_value Interp1D(napi_env env, napi_callback_info info) {
|
|
1102
|
+
size_t argc = 4;
|
|
1103
|
+
napi_value args[4];
|
|
1104
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1105
|
+
|
|
1106
|
+
size_t x_len, y_len, xi_len, yi_len;
|
|
1107
|
+
double* x = GetFloat64ArrayData(env, args[0], &x_len);
|
|
1108
|
+
double* y = GetFloat64ArrayData(env, args[1], &y_len);
|
|
1109
|
+
double* xi = GetFloat64ArrayData(env, args[2], &xi_len);
|
|
1110
|
+
double* yi = GetFloat64ArrayData(env, args[3], &yi_len);
|
|
1111
|
+
|
|
1112
|
+
if (!x || !y || !xi || !yi) {
|
|
1113
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// Simple linear interpolation implementation
|
|
1117
|
+
for (size_t i = 0; i < xi_len; i++) {
|
|
1118
|
+
double xi_val = xi[i];
|
|
1119
|
+
|
|
1120
|
+
// Find the interval
|
|
1121
|
+
size_t j = 0;
|
|
1122
|
+
while (j < x_len - 1 && x[j + 1] < xi_val) {
|
|
1123
|
+
j++;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
if (j >= x_len - 1) {
|
|
1127
|
+
yi[i] = y[x_len - 1];
|
|
1128
|
+
} else {
|
|
1129
|
+
// Linear interpolation
|
|
1130
|
+
double t = (xi_val - x[j]) / (x[j + 1] - x[j]);
|
|
1131
|
+
yi[i] = y[j] + t * (y[j + 1] - y[j]);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
return args[3];
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// Reverse vector
|
|
1139
|
+
static napi_value VectorReverse(napi_env env, napi_callback_info info) {
|
|
1140
|
+
size_t argc = 2;
|
|
1141
|
+
napi_value args[2];
|
|
1142
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1143
|
+
|
|
1144
|
+
size_t len_a, len_b;
|
|
1145
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1146
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1147
|
+
|
|
1148
|
+
if (!A || !B) {
|
|
1149
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1153
|
+
|
|
1154
|
+
// vDSP_vrvrsD reverses in-place, so copy first then reverse
|
|
1155
|
+
memcpy(B, A, len * sizeof(double));
|
|
1156
|
+
vDSP_vrvrsD(B, 1, len);
|
|
1157
|
+
|
|
1158
|
+
return args[1];
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
// Vector negate
|
|
1162
|
+
static napi_value VectorNegate(napi_env env, napi_callback_info info) {
|
|
1163
|
+
size_t argc = 2;
|
|
1164
|
+
napi_value args[2];
|
|
1165
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1166
|
+
|
|
1167
|
+
size_t len_a, len_b;
|
|
1168
|
+
double* A = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1169
|
+
double* B = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1170
|
+
|
|
1171
|
+
if (!A || !B) {
|
|
1172
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1176
|
+
vDSP_vnegD(A, 1, B, 1, len);
|
|
1177
|
+
|
|
1178
|
+
return args[1];
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// Sum of squares
|
|
1182
|
+
static napi_value SumOfSquares(napi_env env, napi_callback_info info) {
|
|
1183
|
+
size_t argc = 1;
|
|
1184
|
+
napi_value args[1];
|
|
1185
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1186
|
+
|
|
1187
|
+
size_t len;
|
|
1188
|
+
double* A = GetFloat64ArrayData(env, args[0], &len);
|
|
1189
|
+
|
|
1190
|
+
if (!A) {
|
|
1191
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
double result;
|
|
1195
|
+
vDSP_svesqD(A, 1, &result, len);
|
|
1196
|
+
|
|
1197
|
+
napi_value js_result;
|
|
1198
|
+
napi_create_double(env, result, &js_result);
|
|
1199
|
+
return js_result;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
// Mean magnitude
|
|
1203
|
+
static napi_value MeanMagnitude(napi_env env, napi_callback_info info) {
|
|
1204
|
+
size_t argc = 1;
|
|
1205
|
+
napi_value args[1];
|
|
1206
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1207
|
+
|
|
1208
|
+
size_t len;
|
|
1209
|
+
double* A = GetFloat64ArrayData(env, args[0], &len);
|
|
1210
|
+
|
|
1211
|
+
if (!A) {
|
|
1212
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
double result;
|
|
1216
|
+
vDSP_meamgvD(A, 1, &result, len);
|
|
1217
|
+
|
|
1218
|
+
napi_value js_result;
|
|
1219
|
+
napi_create_double(env, result, &js_result);
|
|
1220
|
+
return js_result;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// Mean square
|
|
1224
|
+
static napi_value MeanSquare(napi_env env, napi_callback_info info) {
|
|
1225
|
+
size_t argc = 1;
|
|
1226
|
+
napi_value args[1];
|
|
1227
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1228
|
+
|
|
1229
|
+
size_t len;
|
|
1230
|
+
double* A = GetFloat64ArrayData(env, args[0], &len);
|
|
1231
|
+
|
|
1232
|
+
if (!A) {
|
|
1233
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
double result;
|
|
1237
|
+
vDSP_measqvD(A, 1, &result, len);
|
|
1238
|
+
|
|
1239
|
+
napi_value js_result;
|
|
1240
|
+
napi_create_double(env, result, &js_result);
|
|
1241
|
+
return js_result;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
// ============================================================================
|
|
1245
|
+
// ADDITIONAL BLAS OPERATIONS
|
|
1246
|
+
// ============================================================================
|
|
1247
|
+
|
|
1248
|
+
// Vector copy: y = x
|
|
1249
|
+
static napi_value VectorCopy(napi_env env, napi_callback_info info) {
|
|
1250
|
+
size_t argc = 2;
|
|
1251
|
+
napi_value args[2];
|
|
1252
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1253
|
+
|
|
1254
|
+
size_t len_x, len_y;
|
|
1255
|
+
double* x = GetFloat64ArrayData(env, args[0], &len_x);
|
|
1256
|
+
double* y = GetFloat64ArrayData(env, args[1], &len_y);
|
|
1257
|
+
|
|
1258
|
+
if (!x || !y) {
|
|
1259
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
size_t len = len_x < len_y ? len_x : len_y;
|
|
1263
|
+
cblas_dcopy(len, x, 1, y, 1);
|
|
1264
|
+
|
|
1265
|
+
return args[1];
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// Vector swap: swap x and y
|
|
1269
|
+
static napi_value VectorSwap(napi_env env, napi_callback_info info) {
|
|
1270
|
+
size_t argc = 2;
|
|
1271
|
+
napi_value args[2];
|
|
1272
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1273
|
+
|
|
1274
|
+
size_t len_x, len_y;
|
|
1275
|
+
double* x = GetFloat64ArrayData(env, args[0], &len_x);
|
|
1276
|
+
double* y = GetFloat64ArrayData(env, args[1], &len_y);
|
|
1277
|
+
|
|
1278
|
+
if (!x || !y) {
|
|
1279
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
size_t len = len_x < len_y ? len_x : len_y;
|
|
1283
|
+
cblas_dswap(len, x, 1, y, 1);
|
|
1284
|
+
|
|
1285
|
+
return args[0];
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
// Vector norm (L2 norm / Euclidean length)
|
|
1289
|
+
static napi_value VectorNorm(napi_env env, napi_callback_info info) {
|
|
1290
|
+
size_t argc = 1;
|
|
1291
|
+
napi_value args[1];
|
|
1292
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1293
|
+
|
|
1294
|
+
size_t len;
|
|
1295
|
+
double* x = GetFloat64ArrayData(env, args[0], &len);
|
|
1296
|
+
|
|
1297
|
+
if (!x) {
|
|
1298
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
double result = cblas_dnrm2(len, x, 1);
|
|
1302
|
+
|
|
1303
|
+
napi_value js_result;
|
|
1304
|
+
napi_create_double(env, result, &js_result);
|
|
1305
|
+
return js_result;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// Vector sum of absolute values
|
|
1309
|
+
static napi_value VectorAbsSum(napi_env env, napi_callback_info info) {
|
|
1310
|
+
size_t argc = 1;
|
|
1311
|
+
napi_value args[1];
|
|
1312
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1313
|
+
|
|
1314
|
+
size_t len;
|
|
1315
|
+
double* x = GetFloat64ArrayData(env, args[0], &len);
|
|
1316
|
+
|
|
1317
|
+
if (!x) {
|
|
1318
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
double result = cblas_dasum(len, x, 1);
|
|
1322
|
+
|
|
1323
|
+
napi_value js_result;
|
|
1324
|
+
napi_create_double(env, result, &js_result);
|
|
1325
|
+
return js_result;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
// Index of maximum absolute value
|
|
1329
|
+
static napi_value VectorMaxAbsIndex(napi_env env, napi_callback_info info) {
|
|
1330
|
+
size_t argc = 1;
|
|
1331
|
+
napi_value args[1];
|
|
1332
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1333
|
+
|
|
1334
|
+
size_t len;
|
|
1335
|
+
double* x = GetFloat64ArrayData(env, args[0], &len);
|
|
1336
|
+
|
|
1337
|
+
if (!x) {
|
|
1338
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
size_t result = cblas_idamax(len, x, 1);
|
|
1342
|
+
|
|
1343
|
+
napi_value js_result;
|
|
1344
|
+
napi_create_uint32(env, result, &js_result);
|
|
1345
|
+
return js_result;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
// Rotation: apply Givens rotation
|
|
1349
|
+
static napi_value VectorRotation(napi_env env, napi_callback_info info) {
|
|
1350
|
+
size_t argc = 4;
|
|
1351
|
+
napi_value args[4];
|
|
1352
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1353
|
+
|
|
1354
|
+
size_t len_x, len_y;
|
|
1355
|
+
double* x = GetFloat64ArrayData(env, args[0], &len_x);
|
|
1356
|
+
double* y = GetFloat64ArrayData(env, args[1], &len_y);
|
|
1357
|
+
|
|
1358
|
+
if (!x || !y) {
|
|
1359
|
+
NAPI_THROW(env, "First two arguments must be Float64Arrays");
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
double c, s;
|
|
1363
|
+
NAPI_CHECK(napi_get_value_double(env, args[2], &c));
|
|
1364
|
+
NAPI_CHECK(napi_get_value_double(env, args[3], &s));
|
|
1365
|
+
|
|
1366
|
+
size_t len = len_x < len_y ? len_x : len_y;
|
|
1367
|
+
cblas_drot(len, x, 1, y, 1, c, s);
|
|
1368
|
+
|
|
1369
|
+
return args[0];
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
// ============================================================================
|
|
1373
|
+
// ADDITIONAL vDSP OPERATIONS
|
|
1374
|
+
// ============================================================================
|
|
1375
|
+
|
|
1376
|
+
// Vector fill with scalar
|
|
1377
|
+
static napi_value VectorFill(napi_env env, napi_callback_info info) {
|
|
1378
|
+
size_t argc = 2;
|
|
1379
|
+
napi_value args[2];
|
|
1380
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1381
|
+
|
|
1382
|
+
double scalar;
|
|
1383
|
+
NAPI_CHECK(napi_get_value_double(env, args[0], &scalar));
|
|
1384
|
+
|
|
1385
|
+
size_t len;
|
|
1386
|
+
double* vec = GetFloat64ArrayData(env, args[1], &len);
|
|
1387
|
+
|
|
1388
|
+
if (!vec) {
|
|
1389
|
+
NAPI_THROW(env, "Second argument must be Float64Array");
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
vDSP_vfillD(&scalar, vec, 1, len);
|
|
1393
|
+
|
|
1394
|
+
return args[1];
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
// Vector ramp: generate linear sequence
|
|
1398
|
+
static napi_value VectorRamp(napi_env env, napi_callback_info info) {
|
|
1399
|
+
size_t argc = 3;
|
|
1400
|
+
napi_value args[3];
|
|
1401
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1402
|
+
|
|
1403
|
+
double start, step;
|
|
1404
|
+
NAPI_CHECK(napi_get_value_double(env, args[0], &start));
|
|
1405
|
+
NAPI_CHECK(napi_get_value_double(env, args[1], &step));
|
|
1406
|
+
|
|
1407
|
+
size_t len;
|
|
1408
|
+
double* vec = GetFloat64ArrayData(env, args[2], &len);
|
|
1409
|
+
|
|
1410
|
+
if (!vec) {
|
|
1411
|
+
NAPI_THROW(env, "Third argument must be Float64Array");
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
vDSP_vrampD(&start, &step, vec, 1, len);
|
|
1415
|
+
|
|
1416
|
+
return args[2];
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
// Vector add with scalar: c = a + b (scalar)
|
|
1420
|
+
static napi_value VectorAddScalar(napi_env env, napi_callback_info info) {
|
|
1421
|
+
size_t argc = 3;
|
|
1422
|
+
napi_value args[3];
|
|
1423
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1424
|
+
|
|
1425
|
+
size_t len_a, len_c;
|
|
1426
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1427
|
+
|
|
1428
|
+
double scalar;
|
|
1429
|
+
NAPI_CHECK(napi_get_value_double(env, args[1], &scalar));
|
|
1430
|
+
|
|
1431
|
+
double* c = GetFloat64ArrayData(env, args[2], &len_c);
|
|
1432
|
+
|
|
1433
|
+
if (!a || !c) {
|
|
1434
|
+
NAPI_THROW(env, "First and third arguments must be Float64Arrays");
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
size_t len = len_a < len_c ? len_a : len_c;
|
|
1438
|
+
vDSP_vsaddD(a, 1, &scalar, c, 1, len);
|
|
1439
|
+
|
|
1440
|
+
return args[2];
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// Vector multiply and add: d = (a * b) + c
|
|
1444
|
+
static napi_value VectorMultiplyAdd(napi_env env, napi_callback_info info) {
|
|
1445
|
+
size_t argc = 4;
|
|
1446
|
+
napi_value args[4];
|
|
1447
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1448
|
+
|
|
1449
|
+
size_t len_a, len_b, len_c, len_d;
|
|
1450
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1451
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1452
|
+
double* c = GetFloat64ArrayData(env, args[2], &len_c);
|
|
1453
|
+
double* d = GetFloat64ArrayData(env, args[3], &len_d);
|
|
1454
|
+
|
|
1455
|
+
if (!a || !b || !c || !d) {
|
|
1456
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
size_t len = len_a;
|
|
1460
|
+
if (len_b < len) len = len_b;
|
|
1461
|
+
if (len_c < len) len = len_c;
|
|
1462
|
+
if (len_d < len) len = len_d;
|
|
1463
|
+
|
|
1464
|
+
vDSP_vmaD(a, 1, b, 1, c, 1, d, 1, len);
|
|
1465
|
+
|
|
1466
|
+
return args[3];
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
// Vector multiply and scalar add: d = (a * b) + c (scalar)
|
|
1470
|
+
static napi_value VectorMultiplyScalarAdd(napi_env env, napi_callback_info info) {
|
|
1471
|
+
size_t argc = 4;
|
|
1472
|
+
napi_value args[4];
|
|
1473
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1474
|
+
|
|
1475
|
+
size_t len_a, len_b, len_d;
|
|
1476
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1477
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1478
|
+
|
|
1479
|
+
double c;
|
|
1480
|
+
NAPI_CHECK(napi_get_value_double(env, args[2], &c));
|
|
1481
|
+
|
|
1482
|
+
double* d = GetFloat64ArrayData(env, args[3], &len_d);
|
|
1483
|
+
|
|
1484
|
+
if (!a || !b || !d) {
|
|
1485
|
+
NAPI_THROW(env, "First, second, and fourth arguments must be Float64Arrays");
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
size_t len = len_a;
|
|
1489
|
+
if (len_b < len) len = len_b;
|
|
1490
|
+
if (len_d < len) len = len_d;
|
|
1491
|
+
|
|
1492
|
+
vDSP_vmsaD(a, 1, b, 1, &c, d, 1, len);
|
|
1493
|
+
|
|
1494
|
+
return args[3];
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
// Linear interpolation between two vectors
|
|
1498
|
+
static napi_value VectorLinearInterpolate(napi_env env, napi_callback_info info) {
|
|
1499
|
+
size_t argc = 4;
|
|
1500
|
+
napi_value args[4];
|
|
1501
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1502
|
+
|
|
1503
|
+
size_t len_a, len_b, len_c;
|
|
1504
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1505
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1506
|
+
|
|
1507
|
+
double t;
|
|
1508
|
+
NAPI_CHECK(napi_get_value_double(env, args[2], &t));
|
|
1509
|
+
|
|
1510
|
+
double* c = GetFloat64ArrayData(env, args[3], &len_c);
|
|
1511
|
+
|
|
1512
|
+
if (!a || !b || !c) {
|
|
1513
|
+
NAPI_THROW(env, "First, second, and fourth arguments must be Float64Arrays");
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
size_t len = len_a;
|
|
1517
|
+
if (len_b < len) len = len_b;
|
|
1518
|
+
if (len_c < len) len = len_c;
|
|
1519
|
+
|
|
1520
|
+
vDSP_vintbD(a, 1, b, 1, &t, c, 1, len);
|
|
1521
|
+
|
|
1522
|
+
return args[3];
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
// Vector clear (set to zero)
|
|
1526
|
+
static napi_value VectorClear(napi_env env, napi_callback_info info) {
|
|
1527
|
+
size_t argc = 1;
|
|
1528
|
+
napi_value args[1];
|
|
1529
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1530
|
+
|
|
1531
|
+
size_t len;
|
|
1532
|
+
double* vec = GetFloat64ArrayData(env, args[0], &len);
|
|
1533
|
+
|
|
1534
|
+
if (!vec) {
|
|
1535
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
vDSP_vclrD(vec, 1, len);
|
|
1539
|
+
|
|
1540
|
+
return args[0];
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
// Vector limit (saturate)
|
|
1544
|
+
static napi_value VectorLimit(napi_env env, napi_callback_info info) {
|
|
1545
|
+
size_t argc = 4;
|
|
1546
|
+
napi_value args[4];
|
|
1547
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1548
|
+
|
|
1549
|
+
size_t len_a, len_c;
|
|
1550
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1551
|
+
|
|
1552
|
+
double low, high;
|
|
1553
|
+
NAPI_CHECK(napi_get_value_double(env, args[1], &low));
|
|
1554
|
+
NAPI_CHECK(napi_get_value_double(env, args[2], &high));
|
|
1555
|
+
|
|
1556
|
+
double* c = GetFloat64ArrayData(env, args[3], &len_c);
|
|
1557
|
+
|
|
1558
|
+
if (!a || !c) {
|
|
1559
|
+
NAPI_THROW(env, "First and fourth arguments must be Float64Arrays");
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
size_t len = len_a < len_c ? len_a : len_c;
|
|
1563
|
+
vDSP_vlimD(a, 1, &low, &high, c, 1, len);
|
|
1564
|
+
|
|
1565
|
+
return args[3];
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
// Vector maximum magnitude
|
|
1569
|
+
static napi_value VectorMaxMagnitude(napi_env env, napi_callback_info info) {
|
|
1570
|
+
size_t argc = 1;
|
|
1571
|
+
napi_value args[1];
|
|
1572
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1573
|
+
|
|
1574
|
+
size_t len;
|
|
1575
|
+
double* a = GetFloat64ArrayData(env, args[0], &len);
|
|
1576
|
+
|
|
1577
|
+
if (!a) {
|
|
1578
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
double result;
|
|
1582
|
+
vDSP_maxmgvD(a, 1, &result, len);
|
|
1583
|
+
|
|
1584
|
+
napi_value js_result;
|
|
1585
|
+
napi_create_double(env, result, &js_result);
|
|
1586
|
+
return js_result;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
// Vector minimum magnitude
|
|
1590
|
+
static napi_value VectorMinMagnitude(napi_env env, napi_callback_info info) {
|
|
1591
|
+
size_t argc = 1;
|
|
1592
|
+
napi_value args[1];
|
|
1593
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1594
|
+
|
|
1595
|
+
size_t len;
|
|
1596
|
+
double* a = GetFloat64ArrayData(env, args[0], &len);
|
|
1597
|
+
|
|
1598
|
+
if (!a) {
|
|
1599
|
+
NAPI_THROW(env, "Argument must be Float64Array");
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
double result;
|
|
1603
|
+
vDSP_minmgvD(a, 1, &result, len);
|
|
1604
|
+
|
|
1605
|
+
napi_value js_result;
|
|
1606
|
+
napi_create_double(env, result, &js_result);
|
|
1607
|
+
return js_result;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// ============================================================================
|
|
1611
|
+
// MORE MATH FUNCTIONS (vForce)
|
|
1612
|
+
// ============================================================================
|
|
1613
|
+
|
|
1614
|
+
// Inverse (reciprocal): b = 1/a
|
|
1615
|
+
static napi_value VectorReciprocal(napi_env env, napi_callback_info info) {
|
|
1616
|
+
size_t argc = 2;
|
|
1617
|
+
napi_value args[2];
|
|
1618
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1619
|
+
|
|
1620
|
+
size_t len_a, len_b;
|
|
1621
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1622
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1623
|
+
|
|
1624
|
+
if (!a || !b) {
|
|
1625
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1629
|
+
int n = (int)len;
|
|
1630
|
+
vvrec(b, a, &n);
|
|
1631
|
+
|
|
1632
|
+
return args[1];
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
// Inverse square root: b = 1/sqrt(a)
|
|
1636
|
+
static napi_value VectorInverseSqrt(napi_env env, napi_callback_info info) {
|
|
1637
|
+
size_t argc = 2;
|
|
1638
|
+
napi_value args[2];
|
|
1639
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1640
|
+
|
|
1641
|
+
size_t len_a, len_b;
|
|
1642
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1643
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1644
|
+
|
|
1645
|
+
if (!a || !b) {
|
|
1646
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1650
|
+
int n = (int)len;
|
|
1651
|
+
vvrsqrt(b, a, &n);
|
|
1652
|
+
|
|
1653
|
+
return args[1];
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
// Hyperbolic sine
|
|
1657
|
+
static napi_value VectorSinh(napi_env env, napi_callback_info info) {
|
|
1658
|
+
size_t argc = 2;
|
|
1659
|
+
napi_value args[2];
|
|
1660
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1661
|
+
|
|
1662
|
+
size_t len_a, len_b;
|
|
1663
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1664
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1665
|
+
|
|
1666
|
+
if (!a || !b) {
|
|
1667
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1671
|
+
int n = (int)len;
|
|
1672
|
+
vvsinh(b, a, &n);
|
|
1673
|
+
|
|
1674
|
+
return args[1];
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
// Hyperbolic cosine
|
|
1678
|
+
static napi_value VectorCosh(napi_env env, napi_callback_info info) {
|
|
1679
|
+
size_t argc = 2;
|
|
1680
|
+
napi_value args[2];
|
|
1681
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1682
|
+
|
|
1683
|
+
size_t len_a, len_b;
|
|
1684
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1685
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1686
|
+
|
|
1687
|
+
if (!a || !b) {
|
|
1688
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1692
|
+
int n = (int)len;
|
|
1693
|
+
vvcosh(b, a, &n);
|
|
1694
|
+
|
|
1695
|
+
return args[1];
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
// Hyperbolic tangent
|
|
1699
|
+
static napi_value VectorTanh(napi_env env, napi_callback_info info) {
|
|
1700
|
+
size_t argc = 2;
|
|
1701
|
+
napi_value args[2];
|
|
1702
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1703
|
+
|
|
1704
|
+
size_t len_a, len_b;
|
|
1705
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1706
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1707
|
+
|
|
1708
|
+
if (!a || !b) {
|
|
1709
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1713
|
+
int n = (int)len;
|
|
1714
|
+
vvtanh(b, a, &n);
|
|
1715
|
+
|
|
1716
|
+
return args[1];
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
// Inverse trig functions
|
|
1720
|
+
static napi_value VectorAsin(napi_env env, napi_callback_info info) {
|
|
1721
|
+
size_t argc = 2;
|
|
1722
|
+
napi_value args[2];
|
|
1723
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1724
|
+
|
|
1725
|
+
size_t len_a, len_b;
|
|
1726
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1727
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1728
|
+
|
|
1729
|
+
if (!a || !b) {
|
|
1730
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1734
|
+
int n = (int)len;
|
|
1735
|
+
vvasin(b, a, &n);
|
|
1736
|
+
|
|
1737
|
+
return args[1];
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
static napi_value VectorAcos(napi_env env, napi_callback_info info) {
|
|
1741
|
+
size_t argc = 2;
|
|
1742
|
+
napi_value args[2];
|
|
1743
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1744
|
+
|
|
1745
|
+
size_t len_a, len_b;
|
|
1746
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1747
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1748
|
+
|
|
1749
|
+
if (!a || !b) {
|
|
1750
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1754
|
+
int n = (int)len;
|
|
1755
|
+
vvacos(b, a, &n);
|
|
1756
|
+
|
|
1757
|
+
return args[1];
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
static napi_value VectorAtan(napi_env env, napi_callback_info info) {
|
|
1761
|
+
size_t argc = 2;
|
|
1762
|
+
napi_value args[2];
|
|
1763
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1764
|
+
|
|
1765
|
+
size_t len_a, len_b;
|
|
1766
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1767
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1768
|
+
|
|
1769
|
+
if (!a || !b) {
|
|
1770
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1774
|
+
int n = (int)len;
|
|
1775
|
+
vvatan(b, a, &n);
|
|
1776
|
+
|
|
1777
|
+
return args[1];
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
// Atan2: c = atan2(a, b)
|
|
1781
|
+
static napi_value VectorAtan2(napi_env env, napi_callback_info info) {
|
|
1782
|
+
size_t argc = 3;
|
|
1783
|
+
napi_value args[3];
|
|
1784
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1785
|
+
|
|
1786
|
+
size_t len_a, len_b, len_c;
|
|
1787
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1788
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1789
|
+
double* c = GetFloat64ArrayData(env, args[2], &len_c);
|
|
1790
|
+
|
|
1791
|
+
if (!a || !b || !c) {
|
|
1792
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
size_t len = len_a;
|
|
1796
|
+
if (len_b < len) len = len_b;
|
|
1797
|
+
if (len_c < len) len = len_c;
|
|
1798
|
+
int n = (int)len;
|
|
1799
|
+
vvatan2(c, a, b, &n);
|
|
1800
|
+
|
|
1801
|
+
return args[2];
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
// Ceiling
|
|
1805
|
+
static napi_value VectorCeil(napi_env env, napi_callback_info info) {
|
|
1806
|
+
size_t argc = 2;
|
|
1807
|
+
napi_value args[2];
|
|
1808
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1809
|
+
|
|
1810
|
+
size_t len_a, len_b;
|
|
1811
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1812
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1813
|
+
|
|
1814
|
+
if (!a || !b) {
|
|
1815
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1819
|
+
int n = (int)len;
|
|
1820
|
+
vvceil(b, a, &n);
|
|
1821
|
+
|
|
1822
|
+
return args[1];
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
// Floor
|
|
1826
|
+
static napi_value VectorFloor(napi_env env, napi_callback_info info) {
|
|
1827
|
+
size_t argc = 2;
|
|
1828
|
+
napi_value args[2];
|
|
1829
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1830
|
+
|
|
1831
|
+
size_t len_a, len_b;
|
|
1832
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1833
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1834
|
+
|
|
1835
|
+
if (!a || !b) {
|
|
1836
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1840
|
+
int n = (int)len;
|
|
1841
|
+
vvfloor(b, a, &n);
|
|
1842
|
+
|
|
1843
|
+
return args[1];
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// Truncate (round toward zero)
|
|
1847
|
+
static napi_value VectorTrunc(napi_env env, napi_callback_info info) {
|
|
1848
|
+
size_t argc = 2;
|
|
1849
|
+
napi_value args[2];
|
|
1850
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1851
|
+
|
|
1852
|
+
size_t len_a, len_b;
|
|
1853
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1854
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1855
|
+
|
|
1856
|
+
if (!a || !b) {
|
|
1857
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
size_t len = len_a < len_b ? len_a : len_b;
|
|
1861
|
+
int n = (int)len;
|
|
1862
|
+
vvint(b, a, &n);
|
|
1863
|
+
|
|
1864
|
+
return args[1];
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
// Copysign: c = copysign(a, b) - magnitude of a with sign of b
|
|
1868
|
+
static napi_value VectorCopysign(napi_env env, napi_callback_info info) {
|
|
1869
|
+
size_t argc = 3;
|
|
1870
|
+
napi_value args[3];
|
|
1871
|
+
NAPI_CHECK(napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
|
|
1872
|
+
|
|
1873
|
+
size_t len_a, len_b, len_c;
|
|
1874
|
+
double* a = GetFloat64ArrayData(env, args[0], &len_a);
|
|
1875
|
+
double* b = GetFloat64ArrayData(env, args[1], &len_b);
|
|
1876
|
+
double* c = GetFloat64ArrayData(env, args[2], &len_c);
|
|
1877
|
+
|
|
1878
|
+
if (!a || !b || !c) {
|
|
1879
|
+
NAPI_THROW(env, "Arguments must be Float64Arrays");
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
size_t len = len_a;
|
|
1883
|
+
if (len_b < len) len = len_b;
|
|
1884
|
+
if (len_c < len) len = len_c;
|
|
1885
|
+
int n = (int)len;
|
|
1886
|
+
vvcopysign(c, b, a, &n);
|
|
1887
|
+
|
|
1888
|
+
return args[2];
|
|
1889
|
+
}
|
|
1890
|
+
|
|
613
1891
|
// Module initialization
|
|
614
1892
|
static napi_value Init(napi_env env, napi_value exports) {
|
|
615
1893
|
napi_property_descriptor props[] = {
|
|
@@ -617,9 +1895,16 @@ static napi_value Init(napi_env env, napi_value exports) {
|
|
|
617
1895
|
{"matmul", nullptr, MatMulDouble, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
618
1896
|
{"matmulFloat", nullptr, MatMulFloat, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
619
1897
|
{"matvec", nullptr, MatVecMul, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1898
|
+
{"transpose", nullptr, MatrixTranspose, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
620
1899
|
|
|
621
1900
|
// BLAS operations
|
|
622
1901
|
{"axpy", nullptr, AXPY, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1902
|
+
{"copy", nullptr, VectorCopy, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1903
|
+
{"swap", nullptr, VectorSwap, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1904
|
+
{"norm", nullptr, VectorNorm, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1905
|
+
{"abssum", nullptr, VectorAbsSum, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1906
|
+
{"maxAbsIndex", nullptr, VectorMaxAbsIndex, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1907
|
+
{"rot", nullptr, VectorRotation, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
623
1908
|
|
|
624
1909
|
// Vector arithmetic
|
|
625
1910
|
{"dot", nullptr, DotProduct, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
@@ -628,25 +1913,86 @@ static napi_value Init(napi_env env, napi_value exports) {
|
|
|
628
1913
|
{"vmul", nullptr, VectorMul, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
629
1914
|
{"vdiv", nullptr, VectorDiv, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
630
1915
|
{"vscale", nullptr, VectorScale, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1916
|
+
{"vneg", nullptr, VectorNegate, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1917
|
+
{"vaddScalar", nullptr, VectorAddScalar, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1918
|
+
{"vma", nullptr, VectorMultiplyAdd, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1919
|
+
{"vmsa", nullptr, VectorMultiplyScalarAdd, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
631
1920
|
|
|
632
1921
|
// Vector functions
|
|
633
1922
|
{"vabs", nullptr, VectorAbs, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
634
1923
|
{"vsquare", nullptr, VectorSquare, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
635
1924
|
{"vsqrt", nullptr, VectorSqrt, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
636
1925
|
{"normalize", nullptr, VectorNormalize, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1926
|
+
{"vreverse", nullptr, VectorReverse, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1927
|
+
{"vfill", nullptr, VectorFill, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1928
|
+
{"vramp", nullptr, VectorRamp, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1929
|
+
{"vlerp", nullptr, VectorLinearInterpolate, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1930
|
+
{"vclear", nullptr, VectorClear, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1931
|
+
{"vlimit", nullptr, VectorLimit, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1932
|
+
|
|
1933
|
+
// Trigonometric
|
|
1934
|
+
{"vsin", nullptr, VectorSin, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1935
|
+
{"vcos", nullptr, VectorCos, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1936
|
+
{"vtan", nullptr, VectorTan, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1937
|
+
{"vasin", nullptr, VectorAsin, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1938
|
+
{"vacos", nullptr, VectorAcos, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1939
|
+
{"vatan", nullptr, VectorAtan, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1940
|
+
{"vatan2", nullptr, VectorAtan2, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1941
|
+
|
|
1942
|
+
// Hyperbolic
|
|
1943
|
+
{"vsinh", nullptr, VectorSinh, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1944
|
+
{"vcosh", nullptr, VectorCosh, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1945
|
+
{"vtanh", nullptr, VectorTanh, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1946
|
+
|
|
1947
|
+
// Exponential/Logarithmic
|
|
1948
|
+
{"vexp", nullptr, VectorExp, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1949
|
+
{"vlog", nullptr, VectorLog, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1950
|
+
{"vlog10", nullptr, VectorLog10, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1951
|
+
{"vpow", nullptr, VectorPow, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1952
|
+
{"vreciprocal", nullptr, VectorReciprocal, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1953
|
+
{"vrsqrt", nullptr, VectorInverseSqrt, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1954
|
+
|
|
1955
|
+
// Rounding
|
|
1956
|
+
{"vceil", nullptr, VectorCeil, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1957
|
+
{"vfloor", nullptr, VectorFloor, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1958
|
+
{"vtrunc", nullptr, VectorTrunc, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1959
|
+
{"vcopysign", nullptr, VectorCopysign, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1960
|
+
|
|
1961
|
+
// Clipping/Thresholding
|
|
1962
|
+
{"vclip", nullptr, VectorClip, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1963
|
+
{"vthreshold", nullptr, VectorThreshold, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
637
1964
|
|
|
638
1965
|
// Reductions
|
|
639
1966
|
{"sum", nullptr, VectorSum, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
640
1967
|
{"mean", nullptr, VectorMean, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
641
1968
|
{"max", nullptr, VectorMax, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
642
1969
|
{"min", nullptr, VectorMin, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1970
|
+
{"minmax", nullptr, VectorMinMax, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
643
1971
|
{"rms", nullptr, VectorRMS, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1972
|
+
{"variance", nullptr, VectorVariance, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1973
|
+
{"stddev", nullptr, VectorStdDev, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1974
|
+
{"sumOfSquares", nullptr, SumOfSquares, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1975
|
+
{"meanMagnitude", nullptr, MeanMagnitude, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1976
|
+
{"meanSquare", nullptr, MeanSquare, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1977
|
+
{"maxMagnitude", nullptr, VectorMaxMagnitude, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1978
|
+
{"minMagnitude", nullptr, VectorMinMagnitude, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
644
1979
|
|
|
645
1980
|
// Distance metrics
|
|
646
1981
|
{"euclidean", nullptr, EuclideanDistance, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
647
1982
|
|
|
648
1983
|
// Signal processing
|
|
649
1984
|
{"fft", nullptr, FFT, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1985
|
+
{"ifft", nullptr, IFFT, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1986
|
+
{"conv", nullptr, Convolve, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1987
|
+
{"xcorr", nullptr, CrossCorrelation, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1988
|
+
|
|
1989
|
+
// Window functions
|
|
1990
|
+
{"hamming", nullptr, HammingWindow, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1991
|
+
{"hanning", nullptr, HanningWindow, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1992
|
+
{"blackman", nullptr, BlackmanWindow, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
1993
|
+
|
|
1994
|
+
// Interpolation
|
|
1995
|
+
{"interp1d", nullptr, Interp1D, nullptr, nullptr, nullptr, napi_default, nullptr},
|
|
650
1996
|
};
|
|
651
1997
|
|
|
652
1998
|
napi_define_properties(env, exports, sizeof(props) / sizeof(props[0]), props);
|