Optimization with First-Order Surrogate Functions