cvLevenbergMarquardtOptimizationで最小化
void cvLevenbergMarquardtOptimization(pointer_LMJac JacobianFunction, pointer_LMFunc function, CvMat *X0, CvMat *observRes, CvMat *resultX, int maxIter, double epsilon);
な,長い・・・
#geshi(c++,number){{
//cvaux/src/cvlevmartif.cppにTriFocalを求める過程でLevenbergMarqurdtが求められている. #include <cvlevmar.cpp> #include <cv.h> #include <cvaux.h> #include <cxcore.h> #include <highgui.h> #include <stdio.h> #include <math.h> #define A 100 #define B 102 #define PRECISION 100 #define DERIV_STEP 0.00001 void CalcDiff( const CvMat *src, CvMat *dst); void CalcDerivDiff( const CvMat *src, CvMat *dst); double coreCalculation( const CvMat *src, double x); int main(){ CvMat *src, *dst, *X0, *res; FILE *fp = fopen("./data", "w"); fclose(fp); X0 = cvCreateMat(2, 1, CV_64F); src = cvCreateMat(2, 1, CV_64F); dst = cvCreateMat(PRECISION, 1, CV_64F); res = cvCreateMat(X0->rows, X0->cols, CV_64F); cvmSet(X0, 0, 0, 100); cvmSet(X0, 1, 0, 102); CalcDiff(X0, dst); cvmSet(X0, 0, 0, 0); cvmSet(X0, 1, 0, 0); cvLevenbergMarquardtOptimization((pointer_LMJac)CalcDerivDiff, (pointer_LMFunc)CalcDiff, X0, dst, res, 50, 0.01); return 0; } void CalcDiff( const CvMat *src, CvMat *dst){ int i; double x, val; FILE *fp = fopen("./data", "a"); static count = 0; printf("%d repeat\n", count++); for(i = 0;i < PRECISION;i++){ x = CV_PI * ((double)i / PRECISION); val = coreCalculation(src, x); cvmSet(dst, i, 0, val); fprintf(fp, "%f\t", cvmGet(dst, i, 0)); } fprintf(fp, "\n"); } void CalcDerivDiff( const CvMat *src, CvMat *dst){ int i, j; double x, val, nextval; CvMat *next = cvCreateMat(src->rows,src->cols,src->type); for(j = 0;j < 2;j++){ cvCopy( src, next); cvmSet(next, j, 0, cvmGet(src, j, 0) + DERIV_STEP); for(i = 0;i < PRECISION;i++){ x = CV_PI * ((double)i / PRECISION); val = coreCalculation(src, x); nextval = coreCalculation(next, x); cvmSet(dst, i, j, nextval - val); } } } double coreCalculation( const CvMat *src, double x){ double a = cvmGet(src, 0, 0); double b = cvmGet(src, 1, 0); //return a*cos(b*x) + b*sin(a*x); return a*cos(3*x) + b*sin(60*x); }
}}