wsh_wshkk 2024-04-20 17:35 采纳率: 70%
浏览 34

matlab的fmincon怎么用


%定义原始曲线
x_func =@(t)t;
y_func =@(t)t.^3+t;

%定于参数范围和采点的数量
num_point = 10;
t_values = linspace(0,1,num_point); %x在【0,1】

%计算采样点的坐标
x_samples = x_func(t_values);
y_samples = y_func(t_values);

%计算采样点的切线向量和法向量(一阶导)
dx_dt = gradient(x_samples)./gradient(t_values);
dy_dt = gradient(y_samples)./gradient(t_values);
tangent_vectors = [dx_dt;dy_dt];

%计算采样点的数据(二阶导)
dx2_dt2 =gradient(dx_dt)./gradient(t_values);
dy2_dt2 =gradient(dy_dt)./gradient(t_values);
%求曲率
curvatures =abs(dx_dt.*dy2_dt2 - dy_dt.*dx2_dt2)./(dx_dt.^2+dy_dt.^2).^(3/2);
k =curvatures;

x_values = x_samples;

%生成10个随机数(值得优化)
random_numbers = -3+6*rand(1,10);
y_initial =random_numbers;

%拟合的多项式次数
dgree = 3;

%使用polyfit函数进行多项式拟合
coeffs = polyfit(x_values,y_initial,dgree);

%使用拟合参数来预测拟合曲线上的点
x_fit = linspace(min(x_values),max(x_values),100); %生成密集的横坐标
y_fit_initial = polyval(coeffs,x_fit);

%绘制原始数据和拟合曲线
figure;
plot(x_values,y_initial,'o',x_fit,y_fit_initial,'-','LineWidth',1.5);
hold on;

%绘制原始曲线
x_original=linspace(0,1,100);
y_original = x_original.^3+x_original;
plot(x_original,y_original,'m--','LineWidth',1.5);
legend('原始数据','最初的拟合曲线','原始曲线');
title('最初的拟合曲线和原始曲线');


%定义多项式函数
poly_func = @(x)ployval(coeffs,x);

%定义二阶导数函数
poly_second_derivative = @(x) 2*coeffs(1) +6*coeffs(2)*x+12*coeffs(3)*x.^2;

%计算最初的曲率
curvature_valuea_initial =abs(poly_second_derivative(x_values))./(1+polyval(coeffs,x_values).^2).^(3/2);

%定义目标函数,是的每个曲率都无限接近给定的曲率
percentage_threshold=0.01;
objective_func = @(coeffs) sum(abs(curvature_valuea_initial - abs(poly_second_derivative(x_values))./(1+polyval(coeffs,x_values).^2).^(3/2))) < percentage_threshold;

%设置初始值
initial_guess = y_initial;
options=optimoptions('fmincon','MaxFunctionEvaluations',1000,'MaxIterations',1000);

%设置y值的约束范围
lb = -3*ones(size(initial_guess));
ub=3*ones(size(initial_guess));

%添加条件当x=0时候,y=0
x_zero_constarint =@(y) y(1);
A_eg =zeros(1,length(initial_guess));
A_eg(1)=1;
b_eq = 0;

%进行多次优化
num_optimizations =1000;
best_optimized_result=[];
best_optimized_score = Inf;

for i = 1:num_optimizations
    %初始值
    initial_guess =-5 +10*rand(1,10);
    %进行优化
    [y_optimized,fval,exitflag]=fmincon(objective_func,initial_guess,[],[],A_eg,b_eq,lb,ub,[],[]);
    
    %计算得分
    score = fval;

    if score<best_optimized_score
        best_optimized_result=y_optimized;
        best_optimized_score=score;
    end
end

%输出最佳结果
disp("最佳优化结果:");
disp(best_optimized_result);

%使用最佳优化结果重新拟合多项式
coeffs_best =polyfit(x_values,best_optimized_result,degree);

%使用拟合参数来预测拟合曲线上的点
y_fit_best = polyval(coeffs_best,x_fit);

%绘制原始数据和曲线
figure;
polt(x_values,best_optimized_result,'o',x_fit,y_fit_best,'-','LineWidth',1.5);
hold on;

%绘制原始曲线
plot(x_original,y_original,'m--','LineWidth',1.5);
legend('原始数据','最初的拟合曲线','原始曲线');
title('最初的拟合曲线和原始曲线');

报错在fmincon那一行

img


该如何修改正确

  • 写回答

6条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-20 17:36
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在尝试使用MATLAB中的fmincon函数来优化多项式系数,使得拟合曲线的曲率尽可能地接近给定的曲率。在你提供的代码中,报错信息表明fmincon要求函数返回的所有值为双精度数据类型,而你的目标函数似乎没有确保这一点。

    为了修复这个问题,你需要检查你的目标函数objective_func是否返回双精度浮点数的结果。在这种情况下,由于你的目标函数是基于比较两个向量,可能存在整型或单精度浮点数的操作。为了确保所有操作都是双精度的,我们可以将输入数组转换为double类型,并且在比较之前将所有的结果转换为double类型。下面是修改后的代码段:

    function objective_func = objective_func(coeffs)
        % 将输入转换为double类型
        coeffs = double(coeffs);
        curvature_valuea_initial = abs(poly_second_derivative(x_values))./(1+polyval(coeffs,x_values).^2).^(3/2);
        
        % 对比结果转为double类型
        result = abs(curvature_valuea_initial - abs(poly_second_derivative(x_values))./(1+polyval(coeffs,x_values).^2).^(3/2));
        
        % 返回double类型的向量
        objective_func = double(result);
    end
    

    然后,将你的objective_func函数替换为这个新版本,确保其他可能涉及数值运算的地方也采用相同的方法处理数据类型。这应该能解决报错的问题。

    接下来,运行这段代码,你应该可以得到预期的结果。如果你仍然遇到任何问题,或者有任何其他疑问,请随时告诉我。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月20日