But I know Mathematica did not actually use any non-integer x in the fitting algorithm because if it had used, it would have encountered error: my basic functions are undefined for non-integer x.
It does throw an error as seen from the second example in your original post (emphasis is mine): "FindFit::fitm: Unable to solve for the fit parameters; the design matrix is nonrectangular, non-numerical, or could not be inverted." The same message is generated when non-integer x
is present in the data:
FindFit[{{1., 1}, {2, 1}, {3, 1}, {4, 1}}, (a + 1) sin2[x] + b cos2[x], {a, b}, x];
FindFit::fitm: Unable to solve for the fit parameters; the design matrix is nonrectangular, non-numerical, or could not be inverted. >>
From this message I suppose that when y
values aren't integers Mathematica does pass non-integer values for x
to your basic functions, hence the error.
Hence un-restricting x to integers has NO real benefit/significance for the actual Mathematica's fitting algorithm.
You can find what the algorithm is by using Trace
:
trace = Trace[FindFit[{1, 1, 1, 1}, (a + 1) sin2[x] + b cos2[x], {a, b}, x],
TraceInternal -> True];
trace[[6 ;;]]
From the output you see that in this case at first the objective function is evaluated for integer x
, then real values for Sin
and Cos
are calculated and passed to PseudoInverse
. It shouldn't be difficult to implement this algorithm yourself.
Or you can use FindMinimum
as follows (note that y = 1.
is non-integer):
sin2[n_Integer] := Sin[n]^2
cos2[n_Integer] := Cos[n]^2
FindMinimum[
Total[Table[(a + 1) sin2[x] + b cos2[x] - 1., {x, 1, 4}]^2], {a, b}]
{3.15853*10^-32, {a -> 0., b -> 1.}}
Alternatively you can relax your conditions as follows:
sin2[n_ /; FractionalPart[n] == 0] := Sin[n]^2
cos2[n_ /; FractionalPart[n] == 0] := Cos[n]^2
FindFit[{{1., 1.}, {2, 1}, {3, 1}, {4, 1}}, a sin2[x] + b cos2[x], {a, b}, x]
{a -> 1., b -> 1.}