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 = almafa.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 = almafa.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 = almafa.svd(A,true,true)
  s.u'*s.u //!!
  s.v*s.v'
  s.u*diag(s.d)*s.v