怎么对点集继续傅里叶拟合

怎么对点集进行傅里叶拟合,MATLAB的cftool只能进行到8级,八级往上又该怎么实现

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 请看👉 :解决过拟合现象的六种姿势
  • 除此之外, 这篇博客: [Matlab] 单次测量的中误差、算数平均值的中误差、加权求最或然值、函数拟合、莫迪图的计算实例中的 4.函数拟合 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    来源:https://www.cnblogs.com/yabin/p/6417566.html

    在这里插入图片描述

    历史出错代码1

    % 自变量和应变量
    x = [
    14.5200
    15.2500
    15.6000
    16.4700
    16.9200];
    Y = [
    116.2000
    162.3000
    176.1000
    251.8000
    290.2000];
    
    % 被拟合的函数 用于 fit 函数
    linearFun1 = 'a*x+b';
    powerFun1 = 'a*x^b+c';
    indexFun1 = 'a*exp(b*x)+c';
    sinFun1 = 'a*sin(x+b)+c';
    Fun1_array = {
    linearFun1
    powerFun1
    indexFun1
    sinFun1};
    % 被拟合的函数的自变量 用于 fit 函数
    linearX1 = {'x'};
    powerX1 = {'x'};
    indexX1 = {'x'};
    sinX1 = {'x'};
    X1_array = {
    linearX1
    powerX1
    indexX1
    sinX1};
    % 被拟合的函数的系数 用于 fit 函数
    linearCo1 = {'a','b'};
    powerCo1 = {'a','b','c'};
    indexCo1 = {'a','b','c'};
    sinCo1 = {'a','b','c'};
    Co1_array = {
    linearCo1
    powerCo1
    indexCo1
    sinCo1};
    
    % 被拟合的函数 用于 nlinfit 函数
    linearFun2 = @(x,Co2) Co2(1).*x+Co2(2);
    powerFun2 = @(x,Co2) Co2(1).*x.^Co2(2)+Co2(3);
    indexFun2 = @(x,Co2) Co2(1).*exp(Co2(2).*x)+Co2(3);
    sinFun2 = @(x,Co2) Co2(1).*sin(x+Co2(2))+Co2(3);
    Fun2_array = {
    linearFun2
    powerFun2
    indexFun2
    sinFun2};
    
    % 设置系数的起始搜索点
    startPos = [1,1];
    
    % 待拟合函数的总数
    length = size(Fun1_array,1);
    % 拟合结果数组
    % fitFunResult = zeros(size(Fun1_array));
    % Co2Result = zeros(size(Fun1_array));
    
    for i = 1:1:length
        subplot(length,1,i);
        string(Fun1_array(i))
        string(X1_array(i))
        Co1_array(i)
        % 使用 fit 函数拟合
        funType = fittype(string(Fun1_array(i)),'independent',string(X1_array(i)),'coefficients',Co1_array(i));
        opt = fitoptions(funType);
        set(opt,'StartPoint',startPos);
        fitFunResult(i) = fit(x,Y,funType,opt);
        % 打印结果
        disp(fitFunResult(i));
        % 画图
        hold on;
        plot(fitFunResult(i),'r',x,Y,'*');
        % 使用 nlinfit 函数拟合 
        Co2Result(i) = nlinfit(x,Y,Fun2_array(i),startPos);
        % 打印结果
        disp('nlinfit拟合后的系数矩阵为:');
        disp(Co2Result(i));
        % 画图
        hold on;
        xmax = max(x);
        xmin = min(x);
        xnum = 2*length(x)+50;
        x = linspace(xmin,xmax,xnum);
        fun2 = Fun2_array(i);
        y = fun2(x,Co2Result(i));
        plot(x,y,'g');
        legend('原始数据','fit拟合','nlinfit拟合');
    end
    

    错误警报:

    错误使用 cellstr (第 44 行)
    元素 1 不是字符串标量或字符数组。元胞输入的所有元素都必须为字符串标量或字符数组。
     
    出错 fittype>iAssertValidVariableNames (第 1053 行)
    names = cellstr( names );
     
    出错 fittype>iSetVariableNames (第 1044 行)
    iAssertValidVariableNames( variableName );
     
    出错 fittype>iParseParameters (第 561 行)
    obj = iSetVariableNames( obj, ‘coeff’, value );
     
    出错 fittype>iCreateCustomFittype (第 429 行)
    obj = iParseParameters(obj,varargin(2:end));
     
    出错 fittype>iCreateFittype (第 353 行)
    obj = iCreateCustomFittype( obj, varargin{:} );
     
    出错 fittype (第 330 行)
    obj = iCreateFittype( obj, varargin{:} );

    主要是字符的传递有点费劲……
    我试过 tostring 也不行,就不想搞了,不在一棵树上吊死了

    之后试了一下,好像是因为元胞数组需要用 {} 提取数据hhh

    % 自变量和应变量
    x = [
    14.5200
    15.2500
    15.6000
    16.4700
    16.9200];
    Y = [
    116.2000
    162.3000
    176.1000
    251.8000
    290.2000];
    
    % 被拟合的函数 用于 nlinfit 函数
    linearFun = @(x,Co2) Co2(1).*x+Co2(2);
    powerFun = @(x,Co2) Co2(1).*x.^Co2(2)+Co2(3);
    indexFun = @(x,Co2) Co2(1).*exp(Co2(2).*x)+Co2(3);
    sinFun = @(x,Co2) Co2(1).*sin(x+Co2(2))+Co2(3);
    Fun_array = {
    linearFun
    powerFun
    indexFun
    sinFun};
    
    % 设置系数的起始搜索点
    startPos = [1,1];
    
    % 待拟合函数的总数
    length = size(Fun1_array,1);
    % 拟合结果数组
    % fitFunResult = zeros(size(Fun1_array));
    % CoResult = zeros(size(Fun1_array));
    
    for i = 1:1:length
        subplot(length,1,i);
        Fun_array{i}
        % 使用 nlinfit 函数拟合 
        CoResult(i) = nlinfit(x,Y,Fun_array{i},startPos);
        % 打印结果
        disp('nlinfit拟合后的系数矩阵为:');
        disp(CoResult(i));
        % 画图
        hold on;
        xmax = max(x);
        xmin = min(x);
        xnum = 2*length(x)+50;
        x = linspace(xmin,xmax,xnum);
        Fun = Fun_array(i);
        y = Fun(x,CoResult(i));
        plot(x,y,'g');
    end
    

    错误警告:

    错误使用 nlinfit (第 219 行)
    MODELFUN 必须为函数,它返回大小与 Y (5-by-1)相同的拟合值向量。您提供的模型函数返回结果 1-by-2。
     
    大小不匹配的常见原因之一是在函数中使用矩阵运算符(*、/、),而不是对应的元素运算符(.*、./、.)。

    然后我就根据这个改

    % 被拟合的函数 用于 nlinfit 函数
    linearFun = @(x,Co) Co(1)*x+Co(2);
    powerFun = @(x,Co) Co(1)*x^Co(2)+Co(3);
    indexFun = @(x,Co) Co(1)*exp(Co(2)*x)+Co(3);
    sinFun = @(x,Co) Co(1)*sin(x+Co(2))+Co(3);
    

    我改成了这样还是不行

    在这里插入图片描述

    我感觉我跟官方例子根本没有差别……
    好吧,或许是参数需要放在参数列表的前面

    改成这样,Co 放前面

    % 被拟合的函数 用于 nlinfit 函数
    linearFun = @(Co,x) Co(1)*x+Co(2);
    powerFun = @(Co,x) Co(1)*x^Co(2)+Co(3);
    indexFun = @(Co,x) Co(1)*exp(Co(2)*x)+Co(3);
    sinFun = @(Co,x) Co(1)*sin(x+Co(2))+Co(3);
    

    现在可以了,但是,嗯,秩亏了
    或许是我起始点选得不对

    嗯,之后试验过了,盲目选起始点会直接卡死hhh应该是永远都收敛不了

    完蛋了,那这样的话其实作为一个循环来说,一点普适性都没有了,还不如单写呢hhh

    clc;
    
    % 自变量和应变量
    x = [
    14.5200
    15.2500
    15.6000
    16.4700
    16.9200];
    Y = [
    116.2000
    162.3000
    176.1000
    251.8000
    290.2000];
    
    % 被拟合的函数 用于 nlinfit 函数
    linearFun = @(Co,x) Co(1)*x+Co(2);
    powerFun = @(Co,x) Co(1)*x^Co(2)+Co(3);
    indexFun = @(Co,x) Co(1)*exp(Co(2)*x)+Co(3);
    sinFun = @(Co,x) Co(1)*sin(x+Co(2))+Co(3);
    Fun_array = {
    linearFun
    powerFun
    indexFun
    sinFun};
    
    % 设置系数的起始搜索点
    startPos = {
        [50,-600]'
        [1,2,-100]'
        [2,0.25,50]'
        [100,0,-100]'};
        
    % 待拟合函数的总数
    count = size(Fun_array,1);
    
    for i = 1:1:count
        subplot(count,1,i);
        % 使用 nlinfit 函数拟合 
        CoResult = nlinfit(x,Y,Fun_array{i},startPos{i});
        % 打印结果
        disp('nlinfit拟合后的系数矩阵为:');
        disp(CoResult);
        % 画图
        hold on;
        xmax = max(x);
        xmin = min(x);
        xnum = 2*length(x)+50;
        x = linspace(xmin,xmax,xnum);
        Fun = Fun_array{i};
        y = Fun(CoResult,x);
        plot(x,y,'g');
    end
    

    接下来再简化,如果直接这样写的话,就会出现求幂的错误

    错误使用 nlinfit (第 213 行)
    计算模型函数 ‘@(Co,x)Co(1)*x^Co(2)+Co(3)’ 时出错。
     
    原因:
    错误使用 ^ (第 51 行)
    用于对矩阵求幂的维度不正确。请检查并确保矩阵为方阵并且幂为标量。要执行按元素矩阵求> 幂,请使用 ‘.^’。

    如果改成 .^,又会出现不允许 ^ 的错误

    错误使用 nlinfit (第 219 行)
    MODELFUN 必须为函数,它返回大小与 Y (5-by-1)相同的拟合值向量。您提供的模型函数返回结果 1-by-60。
     
    大小不匹配的常见原因之一是在函数中使用矩阵运算符(*、/、),而不是对应的元素运算符(.*、./、.)。

    虽然他这个报错的意思是我不能用 ^,但是当我把所有运算符都改成元素运算符时,还是不行……我不能理解

    最后发现是我自变量数组和匿名函数句柄里面的变量重名了……xs

    能正常跑的代码:

    clear;
    
    % 自变量和应变量
    X = [
    14.5200
    15.2500
    15.6000
    16.4700
    16.9200];
    Y = [
    116.2000
    162.3000
    176.1000
    251.8000
    290.2000];
    
    % 被拟合的函数 用于 nlinfit 函数
    linearFun = @(Co,x) Co(1).*x+Co(2);
    powerFun = @(Co,x) Co(1).*x.^Co(2)+Co(3);
    indexFun = @(Co,x) Co(1).*exp(Co(2).*x)+Co(3);
    sinFun = @(Co,x) Co(1).*sin(x+Co(2))+Co(3);
    Fun_array = {
    linearFun
    powerFun
    indexFun
    sinFun};
    
    % 设置系数的起始搜索点
    startPos = {
        [50,-600]'
        [1,2,-100]'
        [2,0.25,50]'
        [100,0,-100]'};
        
    % 待拟合函数的总数
    count = size(Fun_array,1);
    
    for i = 1:1:count
        subplot(count,1,i);
        % 使用 nlinfit 函数拟合 
        CoResult = nlinfit(X,Y,Fun_array{i},startPos{i});
        % 打印结果
        disp('nlinfit拟合后的系数矩阵为:');
        disp(CoResult);
        % 画图
        hold on;
        xmax = max(X);
        xmin = min(X);
        xnum = 2*length(X)+50;
        x = linspace(xmin,xmax,xnum);
        Fun = Fun_array{i};
        y = Fun(CoResult,x);
        plot(x,y,'g');
    end
    

    输出:

    nlinfit拟合后的系数矩阵为:
       73.0654
     -951.6060
    警告: 超出迭代限制。将返回最后一次迭代的结果。
    nlinfit拟合后的系数矩阵为:
        0.0003
        4.9155
      -39.7506
    nlinfit拟合后的系数矩阵为:
        3.4509
        0.2749
      -70.1296
    nlinfit拟合后的系数矩阵为:
      -90.9788
       -0.2107
      209.3732
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^