Help to Build Proper Expression for Complicated FuncFit Case

I need some help, as I am out of my league.

I have a sequence of functions F1, F2 ... FN that are summed to give a total function FT. Each function Fj can have different types (e.g. a full form or an approximation). Each form of each function has its own input parameters pjk. I have a control panel designed to allow a user to select what functions to sum (i.e. in some cases Fj = 0), what form of a function to use when it is to be summed, and what values of parameters to use in the function. IOW, I have a control panel that allows a user to show how various cases appear in a graph depending on expectations (which equation is / is not added to the set), approximations (type of function), and system conditions (input parameters).

I have no problems so far.

I add to this mix the option to generate "noise" on the FT using the gnoise(...) function. The result is a model noisy curve overlaying a theoretical true curve.

I still have no problems to here.

Now, I want to reverse one part of this process. I have one specific input parameter, call it A, that is fundamental to the entire system. I want to fit the model noisy data with the theoretical equations to obtain A ± \Delta A. IOW, I want to find out, for a given set of expectations + approximations + system conditions + noise what we could expect to obtain in the confidence in A.

For those still with me, this is called uncertainty budget analysis. I have a submitted paper on it from the theoretical side. I am now attacking the simulation/modeling side.

At the moment, I have only two Fj functions that are of immediate concern. I am in fact doing the test with only one to obtain the proof of concept. My problem is to determine how I can design a call to the FuncFit operation that will allow me to do what I need immediately (fit any type of F1 pre-selected by the user) and also not lock me out of growing the model to adding other Fj terms.

Here is an example of the function that generates the one Fj function that I have under design ...

//structure for vdWForces
// ww[0] - A
Structure vdWForces
    wave ww
    variable xx
    variable type
    variable Rs
    variable lambdac

// coefficients for vdW forces
// 0 - A; type; Rs; lambdac

Function generate_fcvdW(fs,z)
    STRUCT vdWForces &fs
    variable z
    // local variables
    variable rtn
    // returns at boundaries
    if (z <= 0)
        return NaN
    fs.xx = z

    // calculate
        case 0:     // unretarded short distance
            rtn = fvdWua(fs)
        case 1:     // unretarded full
            rtn = fvdWuf(fs)
        case 2:     // retarded
            rtn = fvdWrs(fs)
    return rtn

I am hoping to use two parts of FuncFit. First, I hope to use the string expression form to sum functions FuncFit {string=...} .... Secondly, I am hoping to stay with structure functions. But ... now the problem. First, I see that string expressions may only work with coefficient waves, not structure functions. OK, I tried that. My problem is, when I feed four parameters to the coefficient wave and only want ONE of them to vary (so I set holdstring = "1011"), I get singular matrix issues (e.g. no dependence on coef[0] or coef[3]).

Where should I go next? I am stubbornly reluctant to think that I should hard code this and then have to rebuild the hard code for each new case in the future. But, perhaps that is the best option here???

For those so interested, this is a van der Waals force term expression between two macroscopic bodies. Eventually this will end up with repulsive, capacitance, double-layer, and viscous fluid forces. It is heading toward models of data from force-distance curves obtained in atomic force microscopy or the surface force apparatus. Contact me off-line when you might have some interest in the details.

Recommendations would be appreciated.

If using string expressions to sum functions is giving you problems you can always create a single master fit function, especially when you are using structure fit functions. The structure you pass on to the master function simply needs to contains a parameter/wave/string which defines how you want the master function to calculate a value. It could be the string value of a listbox you pass on. Inside the master fit function you then need a StrSwitch or similar.
I will hard code the fitting function. Managing data structures or coefficient waves across what I have in mind is only going to work properly and with minimum frustration when at least one component of the fitting problem is immutable. Also ... Thanks @olelytken for the suggestion. The all-at-once fitting method is an interesting approach but truly overkill for this case.

It was probably the Friday-night sangria yesterday that helped me resolve my initial stubbornness. :-)

J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
You didn't post an actual string you used with string=... so I can't tell how you used the holds. When using the sum of fit functions feature, you must specify a separate hold string per fit function. You can also get into trouble if you have redundant coefficients in each fit function, i.e., when using the built-in fit functions that universally include a y0 coefficient, all but one y0 must be held.

John Weeks
WaveMetrics, Inc.

My test was with just one function in the string={...} call. Everything worked EXCEPT that I got singular matrix issues. By the time I was done thinking about the problem in greater breadth, I realized that I only have one parameter that I need as a coefficient. It really makes no sense to do anything other than a hard-coded fitting function that uses a coeff wave rather than a structure fit function. The one downside is, I have to pass fixed parameters in to the function. The hard parameters pjk are pulled from the panel input. I know how to pass the parameters as globals or through a structure initialization routine. The few upsides are that I am able to put the core functions Fj in to structure format (i.e. as FuncFit functions) and "hide" them in independent modules as static. I have a top-level function (non-static) that is the entry point to the independent module. That top-level function has takes the call imname#forceeqn(ww,xx). The coeff wave ww has only one parameter (the A parameter that I am reverse analyzing).

It all works rather nicely now!

J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH