···6363 let cov = call xtx "div" [Js.Unsafe.inject scale] in
6464 (* 5. SVD of symmetric covariance matrix.
6565 For symmetric PSD matrices, SVD gives eigendecomposition:
6666- V columns are eigenvectors, S values are eigenvalues. *)
6767- let svd_result = Js.Unsafe.meth_call (get tf "linalg") "svd"
6666+ V columns are eigenvectors, S values are eigenvalues.
6767+ tf.linalg.svd returns [s, u, v] as a JS array (not an object). *)
6868+ let svd_arr = Js.Unsafe.meth_call (get tf "linalg") "svd"
6869 [| Js.Unsafe.inject cov; Js.Unsafe.inject Js._true |] in
6969- let v_full = get svd_result "v" in
7070+ let svd_s = Js.array_get svd_arr 0 |> Js.Optdef.to_option |> Option.get in
7171+ let svd_u = Js.array_get svd_arr 1 |> Js.Optdef.to_option |> Option.get in
7272+ let v_full = Js.array_get svd_arr 2 |> Js.Optdef.to_option |> Option.get in
7073 (* 6. Take top n_components columns of V *)
7174 let v_top = Js.Unsafe.meth_call v_full "slice"
7275 [| Js.Unsafe.inject (Js.array [| 0; 0 |]);
···7881 let result = tensor_to_mat projected in
7982 (* 9. Clean up all tensors *)
8083 List.iter dispose [x; mean; x_centered; xt; xtx; scale; cov;
8181- get svd_result "s"; get svd_result "u"; v_full;
8282- v_top; projected];
8484+ svd_s; svd_u; v_full; v_top; projected];
8385 result