nonlinear spline fit with unknown upper bound of interpolation domain

14 vues (au cours des 30 derniers jours)
SA-W
SA-W le 19 Fév 2025
Modifié(e) : SA-W le 15 Avr 2025
I want to fit the interpolation values of a spline, but I can not provide a good guess for the upper bound of the interpolation domain. That is, x(end) is so to speek an unknown too.
The value of the objective function is a pde residual and to compute it, the spline needs to be evaluated at certain points which can change during iterations. In the toy code below, I mock this by shrinking the interpolation domain over the iterations. For example, when fmincon does the last iteration, the spline was only evaluated at points xq in [0, 6] and the initial guess for the interpolation domain (x = linspace(3, 10, 5)) is not good anymore because the interpolation values defined at x > 6 have not been activated in the forward solve. As a consequence, no meaningful parameters are assigned at points x > 6.
So far, I did a multi-stage optimization: Optimizing with fixed points x, checking the final evaluation points, refining the points, optimizing again, etc. But this is very costly.
My ideas are the following:
  1. Changing the interpolation points in some iterations (if required): At iteration k, the sampled points xq are in [0, 5]. So the initial points (x = linspace(3, 10, 5)) are changed to x = linspace(3, 5, 5)) in the next iteration. With this strategy I am keeping the number of parameters constant (there is probably no chance to dynamically change the number of parameters for any solver?) I am not sure if this violates differentiability assumptions of the solvers.
  2. Since I really know x(end) roughly only, I may treat it as an unknown too. So the new parameter vector represents [y; x(end)]. However, in this strategy I want to guide the optimizer (via a penalty or so) in a way that it moves the current x(end) to the current active region. What I can do for instance is to compute the min/max of the evaluation points in every iteration. But I am not sure how to translate this into a penalty term since the min/max evaluation points are not constants.
Can you think of smarter ways to handle this? Maybe spline fit with unknown domain is a known problem.
% Define initial parameters
x = linspace(3, 10, 5); % Interpolation points
y0 = rand(size(x)); % Initial interpolation values
% Define optimization problem
options = optimoptions('fmincon', 'OutputFcn', @output_function); % Track iteration count
% Call fmincon optimizer
global iter_count;
iter_count = 0; % Iteration counter
[y_opt, fval] = fmincon(@objective_func, y0, [], [], [], [], [], [], [], options);
% Display results
fprintf('Optimized objective function value: %.4f\n', fval);
fprintf('Optimized spline values: [%s]\n', num2str(y_opt, '%.2f '));
function obj_val = objective_func(y)
global iter_count;
% Re-compute interpolation points
x = linspace(3, 10, numel(y));
% Create spline f
f = spapi(4, x, y);
% Mock shrinking of evaluation domain
shrink_factor = 1 - exp(-0.1 * iter_count); % Exponential decay
shrinked_domain = 5 + (10 - 5) * (1 - shrink_factor); % Starts at 10, slowly shrinks to 5
xq = linspace(3, shrinked_domain, 10); % PDE evaluation points
% Evaluate the spline at xq
spline_values = fnval(f, xq);
% Compute mock PDE residual (sum of squared differences)
obj_val = sum((spline_values - mean(spline_values)).^2);
% Debug print
% fprintf('Iter %d - Eval points: [%s]\n', iter_count, num2str(xq, '%.2f '));
end
function stop = output_function(~, ~, state)
global iter_count;
if strcmp(state, 'iter')
iter_count = iter_count + 1; % Update iteration count
end
stop = false; % Continue optimization
end
  6 commentaires
Matt J
Matt J le 19 Fév 2025
the spline was only evaluated at points xq in [0, 6] and the initial guess for the interpolation domain (x = linspace(3, 10, 5)) is not good anymore..because the interpolation values defined at x > 6 have not been activated in the forward solve
What does "good" mean in this context? Why do you care what the values for x>6 are if they don't impact your objective function?
SA-W
SA-W le 19 Fév 2025
What does "good" mean in this context?
That the initial guess of the interpolation domain is not appropriate for the final model.
Why do you care what the values for x>6 are if they don't impact your objective function?
You are right that the objective function is not impacted much by what is happening after x > 6. But the optimizer sets the parameters at x > 6 to values near the upper bound I am passing to the optimizer. The upper bound is way larger than the fitted parameters at x < 6, causing an extremly large curvature at x > 6 which makes the spline unemanable for evaluation beyond x > 6. When I use the trained model after optimizing, I may have to evaluate at x > 6 where the spline interpolates non-sense values.
Ideally, I would crop the spline after x > 6 by discarding the parameters defined at those points, but the thus obtained spline is of course different from the original one.

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 19 Fév 2025
Modifié(e) : Matt J le 19 Fév 2025
The upper bound is way larger than the fitted parameters at x < 6, causing an extremly large curvature at x > 6 which makes the spline unemanable for evaluation beyond x > 6.
If high curvature is the problem, perhaps put a penalty on curvature,
% Evaluate the spline at xq
spline_values = fnval(f, xq);
curv_values = fnval(fnder(f,2), x );
%Penalized objective
obj_val = norm( spline_values - mean(spline_values) ).^2 + weight*norm(curv_values).^2;
However, I find it strange that you cannot dictate xq (or at least min(xq), max(xq) ) to your PDE solver. I also find it strange that your PDE residual term has no dependence on any measured data.
  27 commentaires
SA-W
SA-W le 6 Avr 2025
I posted a follow-up question on the ksdensity calculation:
I appreciated if you could comment on that. Your ideas are always valuable!
SA-W
SA-W le 15 Avr 2025
Modifié(e) : SA-W le 15 Avr 2025
In case you are still following, maybe you can share your thoughts on the following:
bw = std(xq, 1)
[x_active, ~] = ksdensity(xq, 0.95, 'Function', 'icdf', 'Bandwidth', bw)
loss = data_loss + weight * (x_active - y)^2 % y: optimization variable
As we discussed in this chat, I am adding a loss term based on the smoothed inverse CDF obtained from ksdensity, where y is an optimization variable (the last interpolation point of the spline). Then, the constraint f''>=0 needs to be re-imposed as non-linear inequality constraints as the interp domain changes...
I observed that when passing a constant bandwidth to ksdensity, the optimization works very well and robust. But when the sampled values xq are densed, the bandwidth will become small and I used the standard deviation for the bandwidth. Doing so, the optimizer stops at a point where the first-order-optimality value is large (>100). This often indicates a point of non-differentiability.
So when setting the bandwidth to the std, can this theoretically lead to such problems?

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by