## svd(mat, details, narrow)

SVD: singular value decomposition.

 mat The matrix to be SVD'd. details If U and V are to be calculated and returned (optional, defaults to false.) narrow For non-square matrices, if the returned matrices are to be narrow, c.f. description (optional, defaults to false.) return value The vectorr of singular values d (for 'wide' decomposition the diagonal matrix), or the structure {d:d, u:U, v:V}, depending on the parameter 'details'.

Matrix is decomposed as A=UDV, where U and V are unitary D is real diagonal.

For non-square matrices, the calculation might be narrow or wide. If the calculation is 'wide' and A is tall (rather than long), U will be square and unitary, and D will shape the matrix non-square, otherwise the matrices are smaller and D diagonal, but U is not unitary anymore. In particular, if A is nxm, 'wide' calculation will yield U nxn, D nxm, V mxm; while 'narrow' calculation will yield U nxm, D mxm, V mxm. For long matrices, the roles of U and V are to be replaced above. The function returns D, if a second optional parameter is set. It returns the structure {d:D, u:U, v:V}. The third optional parameter is 'narrow', which defaults to false.

``` A = [5+6i,6+7i,7+8i,8+9i;1+2i,2+3i,3+4i,4+5i;9+8i,8+7i,7+6i,6+5i;5+4i,4+3i,3+2i,2+1i] * 1J; print("Square matrix").title() A A = [5+6i,6+7i,7+8i,8+9i;1+2i,2+3i,3+4i,4+5i;9+8i,8+7i,7+6i,6+5i;5+4i,4+3i,3+2i,2+1i] * 1J s = ejs.svd(A,true) s.u*s.u' s.v*s.v' s.u*diag(s.d)*s.v print("Non-square matrix, wide U and D (D is non-square)").title() A = A[...;1...] s = ejs.svd(A,true) s.u*s.u' s.v*s.v' s.u*s.d*s.v print("Non-square matrix, narrow U and D (U is non-square)").title() A s = ejs.svd(A,true,true) s.u'*s.u //!! s.v*s.v' s.u*diag(s.d)*s.v ```