Kotaro Irisawa
/
brent_only
2021.12.22
main.cpp
- Committer:
- Kotttaro
- Date:
- 2021-12-23
- Revision:
- 1:5ec4a7674069
- Parent:
- 0:904ead7b9c3a
File content as of revision 1:5ec4a7674069:
#include "mbed.h" #define ITMAX 100 #define CGOLD 0.3819660 #define GOLD 1.618034 #define GLIMIT 100.0 #define TINY 1.0e-20 #define SHIFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d); #define ZEPS 1.0e-10 Serial pc(USBTX,USBRX); double f(double x); double brent(double min,double mid,double max,double tol); double SIGN(double x,double y); void mnbrak();//引数は全てグローバルで指定するとする double FMAX(double x,double y); double ax=0.0,bx=1.0,cx=0.0; double fa,fb,fc; void mnbrak() { double ulim,u,r,q,fu,dum,fa,fb,fc; fa=f(ax); fb=f(bx); pc.printf("fa=%lf,fb=%lf\r\n",fa,fb); if(fb>fa) { SHIFT(dum,ax,bx,dum); SHIFT(dum,fb,fa,dum); } cx=bx+GOLD*(bx-ax); fc=f(cx); while (fb>fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=bx-((bx-cx)*q-(bx-cx)*r)/ (2.0*SIGN(FMAX(fabs(q-r),TINY),q-r)); ulim=bx+GLIMIT*(cx-bx); if((bx-u)*(u-cx)>0.0) { fu=f(u); if(fu<fc) { ax=bx; bx=u; fa=fb; fb=fu; return; } else if(fu>fb) { cx=u; fc=fu; return; } u=cx*+GOLD*(cx-bx); fu=f(u); } else if((cx-u)*(u-ulim)>0.0) { fu=f(u); if(fu<fc) { SHIFT(bx,cx,u,cx+GOLD*(cx-bx)); SHIFT(fb,fc,fu,f(u)); } } else if((u-ulim)*(ulim-cx)>=0.0) { u=ulim; fu=f(u); } else { u=cx+GOLD*(cx-bx); fu=f(u); } SHIFT(ax,bx,cx,u); SHIFT(fa,fb,fc,fu); } } double brent(double ax,double bx,double cx,double tol) { pc.printf("bernt start"); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm,xmin; double e=0.0; a=(ax <cx ? ax : cx); b=(ax >cx ? ax : cx); x=w=v=bx; fw=fv=fx=f(x); for(iter=1;iter<=ITMAX;iter++) { //pc.printf("bernt loop"); xm=0.5*(a+b); tol2=2.0*(tol1=tol*fabs(x)+ZEPS); pc.printf("x =%lf,w = %lf,u = %lf\n\r",x,w,u); if(fabs(x-xm)<=(tol2-0.5*(b-a))) { //pc.printf("bernt out"); xmin=x; pc.printf("xmin=%lf\r\n",x); pc.printf("fx=%lf\r\n",fx); return xmin; } if(fabs(e)>tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if(q>0.0)p=-p; q=fabs(q); etemp=e; e=d; if(fabs(p)>=fabs(0.5*q*etemp)||p<=q*(a-x)||p>=q*(b-x)) { d=CGOLD*(e= (x>=xm ? a-x : b-x));} else { d=p/q; u=x+d; if(u-a < tol2 || b-u < tol2) {d=SIGN(tol1,xm-x);} } } else { d=CGOLD*(e= (x>=xm ? a-x : b-x)); } u=(fabs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f(u);///////注意 if(fu <= fx) { if(u >= x)a=x; else b=x; SHIFT(v,w,x,u); SHIFT(fv,fw,fx,fu); } else{ if(u < x){a=u;} else {b=u;} if(fu <= fw || w==x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v==x || v==w) { v=u; fv=fu; } } } pc.printf("xmin=%lf\r\n",x); pc.printf("fx=%lf\r\n",fx); return xmin; } //極小値を求めたい関数を定義 double f(double x){ double x_return; x_return=x*x*x-x; return x_return; } double SIGN(double x,double y) { double x_return; x_return=abs(x); if(y<0.0)x_return=-x_return; printf("f"); return x_return; } double FMAX(double x, double y) { if(x>y){return x;} if(y>x){return y;} } int main() { pc.baud(921600); pc.printf("loop start\r\n"); mnbrak(); pc.printf("(a,b,c)=(%lf,%lf,%lf)\r\n",ax,bx,cx); pc.printf("(fa,fb,fc)=(%lf,%lf,%lf)\r\n",fa,fb,fc); brent(ax,bx,cx,0.000001); return 0; }