It is confusing to me that no one has used the term "nonlinear least squares" to describe the technique commonly used to solve this general kind of problem, finding the parameters which minimize the (squared, summed) difference between a set of data and an equation of a known form with floating parameters, so I am going to say "nonlinear least squares". As Dave has pointed out the nonlinear part is not necessary for this particular problem, but if you had some unpleasant equation (in python) like
def gross_function(x, a, b, c, d):
return tanh(a*x + b*x**2) + cos(2*pi*x*c + d)
params, cov = scipy.optimize.curve_fit(gross_function, xdata, ydata)
will give you the least squares optimized values of the paramaters and the corresponding covariance matrix (or more likely fail to converge if you don't provide an initial guess for a moderately complex equation like this). There are many more optional parameters: initial guess, bounds, minimization method, errors to weight the points by, precomputed jacobian, but you can read the documentation to learn about those.
The default method used for unconstrainted problems is the Levenberg–Marquardt algorithm, which combines the Gauss-Newton algorithm and gradient descent.