# Multivariable non-linear fitting

I have a function called "C" that I know it depends on 6 variable. I have a set of data points, 6 rows by 9 columns, in which in each row only one variable is changing and the rest of the variables are constant.

I was able to fit each row independently (one variable fitting and modeling) and I double checked on excel as shown below:

I would like to ask about the best way of fitting the function "C" as a function of all the 6 variables into a single equation.

For the single variable fitting, this is the code I used:

    data1 = {{2, 4.8128*10^-12}, {3, 7.5623*10^-12}, {4,
9.9060*10^-12}, {5, 1.1378*10^-11}, {6, 1.3474*10^-11}, {7,
1.5636*10^-11}, {8, 1.7803*10^-11}, {9, 2.0028*10^-11}, {10,
2.2438*10^-11}}; (* x1 and C data pairs*)
g1 = ListPlot[data1]
g2 = LinearModelFit[data1, x, x]

g22 = Normal[g2]
Show[Plot[g22, {x, 2, 10}], g1]
g2["ParameterConfidenceIntervalTable" ]

• Can you give us the full data set ? – Lotus Jul 1 '16 at 9:58
• @Lotus Sure, you can find the excel sheet in the following link. I also added the .nb file in which the whole data set is typed in a suitable format for mathematica: drive.google.com/open?id=0B86yrioiczo4WXJycG5idzl1VUE – HaneenSu Jul 1 '16 at 10:08
• What kind of basis functions are you looking for ? Polynomials ? Trig functions ? – Lotus Jul 1 '16 at 11:08
• @Lotus Polynomials, powers and possibly logarithms – HaneenSu Jul 1 '16 at 11:12
• Oh..its a whole subject in its own right. You will have to study it in some detail. Googling it gives you a bunch of articles. This can be a start. – Lotus Jul 1 '16 at 11:22

I have copied the data from your notebook and would like to share some information.

## Fit Individual Components

In order to facilitate the fitting and plotting I created groups of six {x,y} pairs, one group for each of the six variables.

dataGroup =
Map[Transpose@
Join[{data7[[1 + (# - 1)*9 ;; #*9, #]],
data7[[1 + (# - 1)*9 ;; #*9, 7]]}] &, Range[6]];

varNames = {"Fingers", "Width", "Spacing", "Length", "Gap",
"Thickness"};


Next fit the individual groups using the models from your spreadsheet.

model = ConstantArray[0, 6]; param = ConstantArray[0, 6]; sol =
ConstantArray[0, 6];

model[[1]] = a1 x + b1; param[[1]] = {a1, b1};
model[[2]] = a2 Log[x] + b2; param[[2]] = {a2, b2};
model[[3]] = a3 x^-b3; param[[3]] = {a3, b3};
model[[4]] = a4 x + b4; param[[4]] = {a4, b4};
model[[5]] =  a5 x + b5; param[[5]] = {a5, b5};
model[[6]] = a6 x^2 + b6 x + c6; param[[6]] = {a6, b6, c6};


Use FindFit along with the arrays just created.

(sol[[#]] =
FindFit[dataGroup[[#]], model[[#]], param[[#]], x]) & /@ Range[6]
(* {{a1 -> 2.1325*10^-12, b1 -> 8.7591*10^-13},
{a2 -> 2.65771*10^-12, b2 -> 3.22181*10^-11},
{a3 -> 7.84083*10^-13, b3 -> 0.413135},
{a4 -> 3.69143*10^-10, b4 -> -2.19223*10^-13},
{a5 -> -6.16*10^-11, b5 -> 1.4081*10^-11},
{a6 -> 4.59524*10^-6, b6 -> 2.38786*10^-9, c6 -> 1.20616*10^-11}} *)


Plot the results

Grid@Partition[Module[
{
fun = model[[#]] /. sol[[#]],
xmin = Min[dataGroup[[#, All, 1]]],
xmax = Max[dataGroup[[#, All, 1]]]
},
Show[
ListPlot[
dataGroup[[#]],
PlotStyle -> {PointSize[Large], Red},
PlotLabel -> varNames[[#]]
],
Plot[fun, {x, xmin, xmax}, PlotStyle -> Black],
PlotRange -> All,
ImageSize -> 300
]
] & /@ Range[6],
2]


## Data problems

When an attempt was made to fit the data in one fell swoop, problems arose. This is due to three problems in the data.

Presumably all the variables were held constant and one allowed to vary in each of the six groups.

The constant inputs I will call the center point and equal:

data7[[5]]
(* {6, 1/1000, 1/1000, 19/500, 1/500, 1/5000, 1.3474*10^-11} *)


The first problem was relatively minor. For variable three (Spacing) the value of variable two (Width) is 0.0015 when it should have been 0.001.

More serious problems are present for variable five (Gap) and variable six (Thickness). They have the same input variables but a radically different capacitance.

{data7[[5]], data7[[37]], data7[[48]]}
(* {{6, 1/1000, 1/1000, 19/500, 1/500, 1/5000, 1.3474*10^-11},
{6, 1/1000, 1/1000, 19/500, 1/500, 1/5000, 1.3948*10^-11},
{6, 1/1000, 1/1000, 19/500, 1/500, 1/5000, 1.2764*10^-11}} *)


New synthetic data was created from the existing data and repaired using these steps:

group 3 (Spacing) - make variable 2 = 1/1000 and subtract from y so that it matches at the center

group 5 (Gap) - subtract from the y values so that there is a match at the center point

group 6 (Thickness) - add to the y values so that there is a match at the center point

dataF = data7;
dataF[[19 ;; 27, 2]] = 1/1000;
dataF[[19 ;; 27, 7]] = data7[[19;;27,7]] + (data7[[5,7]] - data7[[19,7]]);
dataF[[37 ;; 45, 7]] = data7[[37;; 45,7]] + (data7[[5,7]] - data7[[37,7]]);
dataF[[46 ;; 54, 7]] = data7[[46;;54,7]] + (data7[[5,7]] - data7[[48,7]]);

dataGroupF =
Map[Transpose@
Join[{dataF[[1 + (# - 1)*9 ;; #*9, #]],
dataF[[1 + (# - 1)*9 ;; #*9, 7]]}] &, Range[6]];


## Fit all of the data using center point

Fit the data in one fell swoop by using the form for the individual components and deviations from the center point. FindFit and NonlinearModelFit have the same input form. The latter produces a FittedModel and provides statistical information on the parameters.

Note: I am not recommending that this be the final solution. It would be much better if a valid theoretical model could be found.

My purpose here is to show the mechanics of how to optimize all of the data.

xF = data7[[5, 1 ;; 6]]; yF = data7[[5, 7]];

modelF = a1 (x1 - xF[[1]]) + a2 (Log[x2] - Log[xF[[2]]]) +
a3 (1/x3^b3 - 1/xF[[3]]^b3) + a4 (x4 - xF[[4]]) +
a5 (x5 - xF[[5]]) + a6 (x6 - xF[[6]])^2 + b6 (x6 - xF[[6]]) + yF;


Use NonlinearModelFit

solF = NonlinearModelFit[dataF, modelF,
paramF, {x1, x2, x3, x4, x5, x6}];

(* {{a1 -> 2.1325*10^-12}, {a2 -> 2.94108*10^-12},
{a3 -> 1.12959*10^-13, b3 -> 0.657385},
{a4 -> 3.7597*10^-10}, {a5 -> -6.07353*10^-11},
{a6 -> 3.88793*10^-6, b6 -> 4.23126*10^-9}} *)


Now plot the results

Grid@Partition[Module[
{
args = xF,
xmin = Min[dataGroupF[[#, All, 1]]],
xmax = Max[dataGroupF[[#, All, 1]]]
},

args[[#]] = x;

Show[
ListPlot[
dataGroupF[[#]],
PlotStyle -> {PointSize[Large], Red},
PlotLabel -> varNames[[#]]
],
ListPlot[{{xF[[#]], yF}}, PlotStyle -> {PointSize[Large], Blue}],
Plot[solF[Sequence @@ args], {x, xmin, xmax},
PlotStyle -> Black],
PlotRange -> All,
ImageSize -> 300
]
] & /@ Range[6],
2]


Information on the parameters

solF["ParameterTable"]


• Thanks a million for the very detailed comment and very nice explanation! Regarding the problems of the data: 1. (Spacing) Problem:that was a typo. I later found out. You are right it should be 0.001 2. (Gap) and (Thickness) Problem: You are absolutely right. These are actually simulation results. I have to double check my simulation for the (Gap) and (Thickness) parts as I am sure about the data of what you have called(center point). The rest of you explanation is quite clear, and the flow of the work is clear as well except from some of the code syntax which I am not very familiar with. – HaneenSu Aug 1 '16 at 12:35
• Regarding you suggestion of working out a theoretical equation, as far as I am familiar with the subject, it is possible at certain relative dimensions. For the relative dimensions I am working on, mostly fringing and higher order effects play important roles. That's why I am going for regression. On another note: Is what you have called (Center Point Method) a well-known and a documented method in the literature? If yes, can you please guide me to a reference where I can read about this and other used methods? I am really thankful for your contribution. – HaneenSu Aug 1 '16 at 12:35