Search code examples
parameterswolfram-mathematicaimplicittest-data

FindMinimum of function with Mathematica


I fitted some function via Mathematica in a way like this

parameter = {a, b};
parameter
data = {{0, 1.2}, {0, 0.1}, {0.1, 0.2}, {1.1, 0}}
Ftest[x_, y_] := a*x^2 + b*y^2
fit = FindMinimum[Total[(Ftest @@@ data - 2)^2], parameter]
ContourPlot[(Ftest[x, y] /. fit[[2]]) == 2, {x, 0, 1.5}, {y, 0, 1.5}, 
Epilog -> {Red, Point /@ data}]

With the appropriate outcome. However my actual function is more complex and consists of a sinus/cosinus/arccos functions with some exponent to the power of 8. Use my actual code with the actual function I get some error:

The function value {3.74166 (-2.+81. (256. Power[<<2>>]+256. Power[<<2>>]+256. Power[<<2>>]) (Times[<<4>>]+Times[<<2>>])^4)^2} is not a list of real numbers with dimensions {1} at {apb3d,bpb3d,cpb3d,fpb3d,gpb3d,hpb3d} = {1.,1.,1.,1.,1.,1.}. >>

The function I want to fit is in an area for x of 0 and 90 whereas y is between 0 and 2. However since it is a series of sinus functions the fitting function is symertical The parameters I want to fit are between the values of -2 and 2. Some test with known parameter values have been performed so the actual function is correct. Does Mathematica need some further input of where to limit the search for the parameters to?


Solution

  • Thank you for all the details of what you are trying to do. That is essential to getting an answer that you can use.

    To try to be very precise about this to track down the error, If I evaluate this

    mpb3d=8; sigxx=x; sigyy=y; sigzz=0; sigxy=z; sigxz=0; sigyz=0;
    Ab3d=(sigyy-sigzz)*apb3d; Bb3d=(sigzz-sigxx)*bpb3d;
    Cb3d=(sigxx-sigyy)*cpb3d; Fb3d=(sigyz)*fpb3d;
    Gb3d=(sigxz)*gpb3d; Hb3d=(sigxy)*hpb3d;
    I2b3d=(Fb3d^2+Gb3d^2+Hb3d^2)/3+((Ab3d-Cb3d)^2+(Cb3d-Bb3d)^2+(Bb3d-Ab3d)^2)/54;
    I3b3d=((Cb3d-Bb3d)*(Ab3d-Cb3d)*(Bb3d-Ab3d))/54+Fb3d*Gb3d*Hb3d-
      ((Cb3d-Bb3d)*Fb3d^2+(Ab3d-Cb3d)*Gb3d^2+(Bb3d-Ab3d)*Hb3d^2)/6;
    thetab3d = ArcCos[I3b3d/((I2b3d)^(3/2))];
    phib3d=(3*I2b3d)^(mpb3d/2)*((2*Cos[(2*thetab3d+Pi)/6])^mpb3d +
      (2*Cos[(2*thetab3d-3*Pi)/6])^mpb3d+(-2*Cos[(2*thetab3d+5*Pi)/6])^mpb3d);
    nYoFIT3D112212={{-(160/313),160/313,0},{1,0,0},{290/313,21/313, 78/313},
      {236/313,79/313,137/313},{8/17,8/17,152/313},{76/313,227/313,131/313},
      {21/313,294/313,79/313},{0,333/313,0}};
    parameter = {apb3d, bpb3d, cpb3d, hpb3d};
    Ftest[x_, y_, z_] := phib3d;
    Total[(Ftest @@@ nYoFIT3D112212 - 2)^2]
    

    to see exactly what you are going to give to FindMinimum then it displays

    8*(-2+81*(((bpb3d*x+cpb3d*(x-y))^2+(-(bpb3d*x)-apb3d*y)^2+(-(cpb3d*(x-y))+apb3d*y)^2)/54+
      (hpb3d^2*z^2)/3)^4*(256*Cos[(-3*Pi+2*ArcCos[(((bpb3d*x+cpb3d*(x-y))*(-(bpb3d*x)-apb3d*y)*
      etc, etc, etc.
    

    Notice that all your x,y,z remain and none were replaced by the triples in your nYoFIT3D112212 like I assume you were expecting had happened.

    This was the key step I was trying to get you to discover.

    There are probably several different ways to fix this. One is if I replace

    Total[(Ftest @@@ nYoFIT3D112212 - 2)^2]
    

    with

    Total[Map[(phib3d-2)^2/.{x->#[[1]],y->#[[2]],z->#[[3]]} &,nYoFIT3D112212]]
    

    then I do see all your x,y,z replaced with the coefficients from nYoFIT3D112212.

    Then this

    fittning=FindMinimum[
      Total[Map[(phib3d-2)^2/.{x->#[[1]],y->#[[2]],z->#[[3]]}&,nYoFIT3D112212]], parameter]
    

    no longer complains about not being a list of {Real}.

    Please check all this very carefully to make certain that the correct substitutions have been made for x,y,z in every step and that there are no other errors lurking in what I have done.