Search code examples
matlabmathematical-optimization

Fitting a nonlinear model in Matlab


I have a cell array from 100 patients and each cell array has 4 signals: X{1}=4x10000, X{2}=4x10000 and so on up to X{100}. Correspondingly I have ground truth Y{1}=1x10000 and so on up to Y{100}. Now i want to fit a nonlinear model using nlmefitsa function in Matlab but i am not able to do so. Can someone please help me here? Below is the code i tried:

clc
clear
% Assuming X is a cell array where each cell contains the signals for a patient
% Each cell contains a matrix of signals for a patient, assuming 100 patients
% Assuming you have cell arrays X and Y with signals and ground truth for each patient
num_patients = 100;
num_samples_per_patient = 10000;
num_signals = 4;

X = cell(num_patients, 1);
Y = cell(num_patients, 1);

for i = 1:num_patients
    % Generate random signals for each patient
    signals = randn(num_signals, num_samples_per_patient);
    
    % Define ground truth based on some relationship with signals
    % Example: Y = sum of absolute values of signals for demonstration
    ground_truth = sum(abs(signals), 1);
    
    % Store signals and ground truth for each patient
    X{i} = signals;
    Y{i} = ground_truth;
end


% Combine signals and ground truth across patients
X_all = cell2mat(X);
Y_all = cell2mat(Y);

% Create a grouping variable for patients
group = repelem(1:num_patients, size(X{1}, 2)); % Grouping variable based on the number of samples in each patient

% Define the nonlinear model function
modelFun = @(b, t, X) b(1) * sin(X(:, 1)) + b(2) * exp(X(:, 2)) + ... % Define the custom nonlinear model here
    b(3) * log(1 + abs(X(:, 3))) + b(4) * X(:, 4).^2; 

% Initial values for the parameters (beta)
initialBeta = zeros(4, 1); % Modify the size based on the number of parameters in your model

% Create V matrix with independence within each patient's measurements
num_samples_per_patient = size(X{1}, 2); % Assuming all patients have the same number of samples
V = eye(num_samples_per_patient); % Assuming independence within each patient
V = repmat(V, num_patients, 1);

% Fit a nonlinear mixed-effects model
mdl = nlmefitsa(X_all, Y_all, group, modelFun, initialBeta, 'V', V, 'OptimFun', 'fminunc');

% Display model summary
disp(mdl);

% Get the coefficients of the model
coefficients = mdl.beta;

% Display the estimated coefficients
disp('Estimated Coefficients:');
disp(coefficients);

Solution

  • Your code is using a Y that is a matrix; if you go to mathworks nlmefitsa, you will see that this function works with a vector as Y, not a matrix. This means you should have a column Y with the values of all your groups (e.g. patient), and then the group variable will indicate for each row which patient is. Also, your variable X, X_all, should have as many rows as Y and 4 columns, one per signal, if these are your distinct predictor variables.

    For example, 100 patients for the samples 10000 should create a Y_all of one column and 1000000 rows (100*10000) and an X_all with 4 columns (one per each signal) and also 1000000 rows, plus your grouping variable, which should contain the number of the patient of each row, if you stacked them in order it should be the first 10000 patient one, from 10001 to 20000 patient 2 group, etc. I think this should solve your issue with the model not running.