Vary model parameters to fit measured data in Matlab - matlab

I have a Matlab function (of 10 independent variables) based on a model (which generates an oscillating curve with varying period). I need to suitably vary the variables to fit measured data to extract model parameters.
The measured data is a two column vector, M (L, P). The model function is
P = ModelFunction (L, a, b, c, d....), where a, b, c, d...are the independent variables which needs to be varied to match the measured data.
I do not have Matlab's optimization toolbox. Is there a Matlab function which can already do this. Else please could someone guide me on how to to approach this problem?

Related

Fittype Matlab - not enough inputs

my problem consists of two parts:
PART I:
I am trying to create my own fit function, see below. T0 is a single fixed value, Ni, MS, and dP are independent variables (arrays of the same size), and m, n, a, b, c are coefficients that are meant to be changed in order to fit the equation to a [dP,y] dataset. However, matlab tells me that there are "not enough inputs to FITTYPE function". What am I doing wrong?
ft = fittype('((T0+m*(Ni*MS)^2+n*Ni*MS)*((dP/a+1)^b)*exp(-c*dP*Ni*MS)','dependent',{'Tm'},'independent',{'T0','dP','Ni','MS'},'coefficients',{'m','n','a','b','c'});
PART II:
I would like to apply this fit to several [dP,y] datasets simultaneously in order to constrain coefficients values that are associated with a global minimum. How can this be done?
Cheers,
Thilo

Is it possible to train a neural netowrk using a loss function on unseen data (data different from input data)?

Normally, a loss function may be defined as
L(y_hat, y) or L(f(X), y), where f is the neural network, X is the input data, y is the target.
Is it possible to implement (preferably in PyTorch) a loss function that depends not only on the input data X, but also on X' (X != X)?
For example, let's say I have a neural network f, input data (X,y) and X'. Can I construct a loss function such that
f(X) is as close as possible to y, and also
f(X') > f(X)?
The first part can be easily implemented (PyTorch: nn.MSELoss()), the second part seems to be way harder.
P.S: this question is a reformulation of Multiple regression while avoiding line intersections using neural nets, which was closed. In the original data, input data and photos with a theoretical example are available.
Yes it is possible.
For instance, you can add a loss term using ReLU as follows:
loss = nn.MSELoss()(f(X),y) + lambd * nn.ReLU()(f(X)-f(X'))
where lambd is a hyperparameter.
Note that this corresponds to f(X') >= f(X) but it's easily modifiable to f(X') > f(X) by adding an epsilon<0 (small enough in absolute value) constant inside the ReLU.

How does covariance matrix (P) in Kalman filter get updated in relation to measurements and state estimate?

I am in the midst of implementing a Kalman filter based AHRS in C++. There's something rather strange to me in the equations of the filter.
I can't find the part where the P (covariance) matrix is actually updated to represent uncertainty of predictions.
During the "predict" step P estimate is calculated from its previous value, A and Q. From what I understand A (system matrix) and Q (covariance of noise) are constant. Then during "Correct" P is calculated from K, H and predicted P. H (observation matrix) is constant, so the only variable that affects P is K (Kalman gain). But K is calculated from predicted P, H and R (observation noise) that are either constants or the P itself. So where is the part of the equations that makes P relate to x? To me it seems like P is recursively looping here depending only on the constants and initial value of P. This doesn't make any sense. What am I missing?
You are not missing anything.
It can come as a surprise to realise that, indeed, the state error covariance matrix (P) in a linear kalman filter does not depend on the the data (z). One way to lessen the surprise is to note what the covariance is saying: it is how uncertain you should be in the estimated state, given that the models you are using (effectively A,Q and H,R) are accurate. It is not saying: this is the uncertainty. By judicious tweaking of Q and R you could change P arbitrarily. In particular you should not interpret P as a 'quality' figure, but rather look at the observation residuals. You could, for example, make P smaller by reducing R. However then the residuals would be larger compared with their computed sds.
When the observations come in at a constant rate, and always the same set of observations, P will tend to a steady state that could, in principal, be computed ahead of time.
However there is no difficulty in applying the kalman filter when you have varying times between observations and varying sets of observations at each time, for example if you have various sensor systems with different sampling periods. In this case you will see more variation in P, though again in principal this could be computed ahead of time.
Further the kalman filter can be extended (in various ways, eg the extended kalman filter and the unscented kalman filter) to handle non linear dynamics and non linear observations. In this case because the transition matrix (A) and the observation model matrix (H) have a state dependency, so too will P.

Nonlinear curve fitting of a matrix function in python

I have the following problem. I have a N x N real matrix called Z(x; t), where x and t might be vectors in general. I have N_s observations (x_k, Z_k), k=1,..., N_s and I'd like to find the vector of parameters t that better approximates the data in the least square sense, which means I want t that minimizes
S(t) = \sum_{k=1}^{N_s} \sum_{i=1}^{N} \sum_{j=1}^N (Z_{k, i j} - Z(x_k; t))^2
This is in general a non-linear fitting of a matrix function. I'm only finding examples in which one has to fit scalar functions which are not immediately generalizable to a matrix function (nor a vector function). I tried using the scipy.optimize.leastsq function, the package symfit and lmfit, but still I don't manage to find a solution. Eventually, I'm ending up writing my own code...any help is appreciated!
You can do curve-fitting with multi-dimensional data. As far as I am aware, none of the low-level algorithms explicitly support multidimensional data, but they do minimize a one-dimensional array in the least-squares sense. And the fitting methods do not really care about the "independent variable(s)" x except in that they help you calculate the array to be minimized - perhaps to calculate a model function to match to y data.
That is to say: if you can write a function that would take the parameter values and calculate the matrix to be minimized, just flatten that 2-d (on n-d) array to one dimension. The fit will not mind.

Multiparametric model optimization

I have a small model that I use to estimate the growth of a population of fungi given the environmental condition. The model, practically, is a MATLAB function in the following form:
growth=myfunction(envdata,params)
where growth is how much my fungi grow (duh!), envdata is a matrix of enviromental variables (one row per timestep, each column is a different variable such as temperature, humidity, etc. etc. etc.) and params are the parameters of my model. The latter are the ones that I would like to optimize and they include such things as the (unknown) initial fungal population, maximum fungi that can exist as a certain time, etcetera etcetera.
At the same time I have a vector of growth measured in the lab (my observations) and my objective is now to fit my model to the observations by varying the input parameters.
My natural answer would have been to use something such as fminsearch, but it has no option of using an observation vector as a minimum. Or am I wrong?
You want to fit the difference between your observations and the model's fitted growth rate as closely as possible but, as you pointed out, fminsearch doesn't allow you to use a target vector.
The solution is to define a wrapper function that defines the thing you are trying to minimize (often called the loss). One popular loss is the mean-square error,
MSE(x, y) = Σ (x - y)2
so you could define, for example,
function loss = objectiveFun(observations, envdata, params)
growth = myfunction(envdata, params);
loss = sum((observation - growth).^2); // or your favorite loss function
end
and then run
paramsInit = 0; // whatever initial value you have for params
paramsOpt = fminsearch(#(x) objectiveFun(observations, envdata, x), paramsInit);