Rank-Constrained Optimization: A Riemannian Manifold Approach