# How should I put parameter constraint to remove this error?

FindFit[data, {a/(1 + i*b*x^2), Element[{a, b}, Reals]}, {a, b}, x]


FindFit::nrgnum: The gradient is not a vector of real numbers at {a,b} = {1.,1.}. FindFit::grad: Evaluation of the gradient of function ExperimentalNumericalFunction[{Hold[<<1>>],Block},{0,{{{},1,0,Hold[a],0,0},{{},1,1,Hold[b],0,0}}},{{{1,2,817},{{{Hold[Block[{<<4>>},CompoundExpression[<<3>>]]],Block},Automatic,None,1,Automatic},{}}}},{8,3,{},0},{904,MachinePrecision,{None,{Hold[Block[{x={<<1000>>},OptimizationFindFity$45202={<<1000>>}},1/2 > Subtract[<<2>>].Subtract[<<2>>]]],Block}},True,{{Automatic,CleanUpRegisters->False,WarningMessages->False,EvaluateSymbolically->False,RuntimeErrorHandler->($Failed&)},{},Automatic,WVM},FindFit,Automatic,None},{None,None,None}] failed at {1.,1.}.

• The issue seems to be the i. Do you mean the complex unit I? – Henrik Schumacher Nov 26 '17 at 8:58
• yes , I am trying to fit this complex function with real parameters . – Subhamita Sengupta Nov 26 '17 at 18:29

To my suprise there seems to be no method for nonlinear model fits to maps into $\mathbb{R}^n$ or to $\mathbb{C}$. Here is a simple implementation of the Gauss-Newton method that works at least in the given example:

MyNonlinearModelFit[pts0_, vals_, model_, pars_, vars_, pguess_] :=
Module[{p, modelfun, cmodel, cDmodel, error, Derror, gradfit,
residual, iter, pts},
pts = If[VectorQ[pts0],
Transpose[{pts0}],
pts0
];

Quiet[Block[{p, pp, x, xx},
pp = Table[p[[i]], {i, 1, Length[pars]}];
xx = Table[x[[i]], {i, 1, Length[vars]}];
modelfun = {x, p} \[Function]
With[{code = N[modelfun[xx, pp]] /. Part -> CompileGetElement},
cmodel = Compile[{{x, _Real, 1}, {p, _Real, 1}},
code,
CompilationTarget -> "C",
Parallelization -> True,
RuntimeAttributes -> {Listable}
]
];

With[{code =
N[D[modelfun[xx, pp], {pp, 1}]] /.
Part -> CompileGetElement},
cDmodel = Compile[{{x, _Real, 1}, {p, _Real, 1}},
code,
CompilationTarget -> "C",
Parallelization -> True,
RuntimeAttributes -> {Listable}
]
];
]];

p = pguess;
error = Flatten[cmodel[pts, p] - vals];
Derror = Flatten[cDmodel[pts, p], 1];
iter = 0;
While[residual > 1. 10^-12,
++iter;
p = p -
Method -> "Cholesky"];
error = Flatten[cmodel[pts, p] - vals];
Derror = Flatten[cDmodel[pts, p], 1];
];
]


Here is an example for the model given by the OP:

n = 100;
ptrue = {3., 2.};
SeedRandom;
model = ComplexExpand[ReIm[a/(1 + I b x^2)]];
ftrue = x \[Function] Evaluate[model /. Thread[{a, b} -> ptrue]];
pts = RandomReal[{-1, 1}, {n}];
vals = ftrue /@ pts + RandomVariate[
MultinormalDistribution[{0, 0}, DiagonalMatrix[{1, 1}]], {n}];
pars = {a, b};
vars = {x};
pguess = {1., 0.};
fit = MyNonlinearModelFit[pts, vals, model, pars, vars, pguess]; //AbsoluteTiming
fit
ffitted = x \[Function] Evaluate[model /. fit];
Show[
ParametricPlot3D[
Evaluate[{Join[{x}, ftrue[x]], Join[{x}, ffitted[x]]}],
{x, Min[pts], Max[pts]},
PlotLegends -> {"fitted curve", "true curve"}],
Graphics3D[Point[Join[Transpose[{pts}], vals, 2]]],
PlotRange -> All
]
`

{0.150965, Null}

{a -> 3.04508, b -> 1.93957} Since there are only two parameters involved, this works fine even for quite high amounts of data. (I tested it for up to 10 million data points.)