First-order Optimization Algorithms