matlab 利用分段线性函数低估f(x)

gcmastyq  于 2022-11-24  发布在  Matlab
关注(0)|答案(1)|浏览(204)

我正在尝试检查是否有任何Matlab/Python程序通过使用分段线性函数g(x)来低估f(x)。即g(x)需要小于或等于f(x)。请参见下面的图片和代码。您能帮助修改此代码以找到如何低估此函数吗?

x = 0.000000001:0.001:1;
 y = abs(f(x));

 %# Find section sizes, by using an inverse of the approximation of the derivative
 numOfSections = 5;
 totalRange = max(x(:))-min(x(:));

 %# The relevant nodes
 xNodes = x(1) + [ 0 cumsum(sectionSize)];
 yNodes = abs(f(xNodes));

 figure;plot(x,y);
 hold on;
 plot (xNodes,yNodes,'r');
 scatter (xNodes,yNodes,'r');
 legend('abs(f(x))','adaptive linear interpolation');
bvjveswy

bvjveswy1#

这一方法基于Luis Mendo的评论。其思想如下:
1.从原始曲线中选择若干点,你的最终分段线性曲线将通过这些点
1.对于每个点,计算原始曲线的切线方程。因为你的图形是凸的,所以样本中连续点的切线将在曲线下方相交
1.计算每组连续切线交点的x坐标。使用切线方程计算相应的y坐标

现在,在重新排序点之后,这将为您提供具有所需约束的分段线性近似。

h = 0.001;
x = 0.000000001:h:1;
y = abs(log2(x));

% Derivative of function on all the points
der = diff(y)/h;

NPts = 10; % Number of sample points

% Draw the index of the points by which the output will pass at random
% Still make sure you got first and last point
idx = randperm(length(x)-3,NPts-2);
idx = [1 idx+1 length(x)-1]; 
idx = sort(idx);
x_pckd = x(idx);
y_pckd = y(idx);
der_pckd = der(idx);

% Use obscure math to calculate the points of intersection
xder = der_pckd.*x_pckd;
x_2add = -(diff(y_pckd)-(diff(xder)))./diff(der_pckd);
y_2add = der_pckd(1:(end-1)).*(x_2add-(x_pckd(1:(end-1))))+y_pckd(1:(end-1));

% Calculate the error as the sum of the errors made at the middle points
Err_add = sum(abs(y_2add-interp1(x,y,x_2add))); 

% Get final x and y coordinates of interpolant
x_final = [reshape([x_pckd(1:end-1);x_2add],1,[]) x_pckd(end)];
y_final = [reshape([y_pckd(1:end-1);y_2add],1,[]) y_pckd(end)];

figure;
plot(x,y,'-k');
hold on
plot(x_final,y_final,'-or')

你可以在我的代码中看到,这些点是随机抽取的。如果你想做一些优化(例如,什么样的点集可以使误差最小化),你可以运行大量的时间,并跟踪最好的竞争者。例如,10000次随机抽取看到这个家伙的崛起:

相关问题