vs2019解决方案源文件打包:区间消去法+二次插值法求极小值,并调用matlab绘制图像(c/c++程序)
#ifndef _Quadratic_interpolation_H
#define _Quadratic_interpolation_H
#include <iostream>
#include <vector>
#include <math.h>
#define f1 function_value[0]
#define f2 function_value[1]
#define f3 function_value[2]
#define X1 X_value[0]
#define X2 X_value[1]
#define X3 X_value[2]
#define f(x) this->solve_f_value(x-1)
//#define dataNum 100
class solve_problem
{
public:
solve_problem(void);
void quad_inter();
void Interval_elimination();
double solve_f_value(int Serial_number);
void span_left();
void span_right();
int draw_picture();
~solve_problem(void);
private:
double Coefficient_matrix[4];
double H=0;
double function_value[3] = {0,0,0};
double X_value[3] = { 0,0,0 };
int cnt=0;
double left_doit=0, right_doit=0;
double Precision_e = 0;
double xp = 0;
double f4 = 0;
};
#endif
/*Quadratic_interpolation.cpp*/
#include <iostream>
#include "Quadratic_interpolation.h"
#include "stdafx.h"
#include "draw_picture.h"
#define dataNum 100
using namespace std;
int main()
{
int select = 0;
while (!select)
{
solve_problem* one = new solve_problem();
one->Interval_elimination();
one->quad_inter();
one->draw_picture();
cout << "输入1开始新的计算,输入其他则退出程序" << endl;
cin >> select;
if (1 == select)
{
delete one;
select = 0;
}
else
{
return 0;
}
}
}
solve_problem::solve_problem(void)//构造函数
{
cout << "请输入方程的系数\t" << endl;
for (int i = 0; i<4; ++i)
{
cin >> Coefficient_matrix[i];
}
cout << "输入的方程为:f(x)=" << showpos << Coefficient_matrix[0] << "x^3" << Coefficient_matrix[1] << "x^2" << Coefficient_matrix[2] << "x" << Coefficient_matrix[3] << endl;
}//
solve_problem::~solve_problem(void)
{
cout << "计算结束" << endl;
}
void solve_problem::Interval_elimination()//区间消去函数
{
cout << "******************************求解单封区间***************************" << endl;
cout << "输入初始点X1和步长H" << endl;
cin >> X1 >> H;
cout << "初始点X1=" << noshowpos << X1 << "\t" << "步长H=" << H << endl;
cnt = sizeof(Coefficient_matrix) / sizeof(Coefficient_matrix[0]);//获取数组元素个数
f1 = f(1); X2 = X1 + H; f2 = f(2);
if (f1 <= f2)
{
H = -H; X3 = X1;f3 = f1;X1 = X2;f1 = f2;X2 = X3;f2 = f3;
}
H *= 2; X3 = X2 + H; f3 = f(3);
while (f3 <= f2)
{
X1 = X2;f1 = f2;X2 = X3;f2 = f3;H *= 2;X3 = X2 + H; f3 = f(3);
}
if (H > 0)
{
left_doit = X1; right_doit = X3;
}
else
{
left_doit = X3; right_doit = X1;
}
cout << "单封区间为[" << this->left_doit << "," << this->right_doit << "]" << endl;
}//区间消去函数
void solve_problem::quad_inter()//二次插值函数
{
cout << "*****************使用二次插值法求极值点************************" << endl;
cout << "输入收敛精度e" << endl;
cin >> Precision_e;
cout << "方程f(x)=" << showpos << Coefficient_matrix[0]
<< "x^3" << Coefficient_matrix[1]<< "x^2" << Coefficient_matrix[2]
<< "x" << Coefficient_matrix[3] << endl;
cout << "的单封区间为[" << this->left_doit << "," << this->right_doit << "]" << endl;
cout << "收敛精度为e=" << this->Precision_e << endl;
cout << "*****************************求解开始************************" << endl;
X1 = left_doit;
X3 = right_doit;
X2 = 0.5*(X1 + X3);
f1 = f(1);
f2 = f(2);
f3 = f(3);
span_left();
}
double solve_problem::solve_f_value(int Serial_number)
{
double value = 0;
for (int i = 0; i < 4; i++)
{
value += this->Coefficient_matrix[i] * (pow(X_value[Serial_number], cnt - i - 1));
}
return(value);
}
void solve_problem::span_left()
{
double c1 = (f3 - f1) / (X3 - X1);
double c2 = ((f2 - f1) / (X2 - X1) - c1) / (X2 - X3);
if (c2 != 0)
{
xp = 0.5 * (X1 + X3 - c1 / c2); if ((xp - X1) * (X3 - xp) > 0)
{
f4 = 0;
for (int i = 0; i < 4; i++)
{
f4 += this->Coefficient_matrix[i] * (pow(xp, cnt - i - 1));
}
if (abs(xp - X2) < Precision_e)
{
if (f4 < f2)
{
cout << "极限值在x=" << xp << "处取得" << endl;
cout << "f(" << xp << ")=" << f4 << endl;
}
else
{
cout << "极限值在x=" << X2 << "处取得" << endl;
cout << "f(" << X2 << ")=" << f2 << endl;
}
}
else
{
this->span_right(); //右边函数块
}
}
else
{
cout << "极限值在x=" << X2 << "处取得" << endl;
cout << "f(" << X2 << ")=" << f2 << endl;
}
}
else if (c2 == 0)
{
cout << "极限值在x=" << X2 << "处取得" << endl;
cout << "f(" << X2 << ")=" << f2 << endl;
}
}
void solve_problem::span_right()
{
if (xp > X2)
{
if (f2 > f4)
{
X1 = X2;
f1 = f2;
X2 = xp;
f2 = f4;
}
else
{
X3 = xp;
f3 = f4;
}
}
else if (f2>f4)
{
X3 = X2;
f3 = f2;
X2 = xp;
f2 = f4;
}
else
{
X1 = xp;
f1 = f4;
}
this->span_left();
}
int solve_problem::draw_picture()
{
Engine* eg = NULL;
if (!(eg = engOpen(NULL)))
{
printf("Open matlab enging fail!");
return 1;
}
int ret = 0;
double xtemp[dataNum] = { 0 };
double ytemp[dataNum] = { 0 };
double distance = this->right_doit - this->left_doit;
distance = 2*distance;
double value;
for (int i = 0; i < dataNum; i++)
{
xtemp[i] =(X1-0.5*distance)+ i * distance / dataNum;
value = 0;
for (int j = 0; j < 4; j++)
{
value += this->Coefficient_matrix[j] * pow(xtemp[i], cnt - j - 1);
}
ytemp[i] = value;
}
mat_plot(eg, xtemp, ytemp, dataNum, "-r", 1, 5);
for (int i = 0; i < dataNum; i++)
{
xtemp[i] = (X1 - 0.5*distance) + i * distance / dataNum;
value = 0;
for (int j = 0; j < 4; j++)
{
value += this->Coefficient_matrix[j] * pow(xtemp[i], cnt - j );
}
ytemp[i] = value;
}
mat_plot(eg, xtemp, ytemp, dataNum, "-r", 1, 5);
getchar();
if (eg)
engClose(eg);
return 0;
}
#ifndef _draw_picture_h_
#define _draw_picture_h_
#include "stdafx.h"
#include "draw_picture.h"
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<engine.h>
extern int mat_plot(Engine *eg, double *x, double *y, int N, char *LineStyle, double LineWidth, double MarkerSize);
#endif // !_draw_picture_h_
#pragma once
// draw_picture.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "draw_picture.h"
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<engine.h>
extern int mat_plot(Engine *eg, double *x, double *y, int N, char *LineStyle, double LineWidth, double MarkerSize);
//忽略4096错误
#pragma warning(disable:4996)
int mat_plot(Engine *eg, double *x, double *y, int N, char *LineStyle, double LineWidth, double MarkerSize)
{
int ret = 0;
mxArray *X = mxCreateDoubleMatrix(1, N, mxREAL);
mxArray *Y = mxCreateDoubleMatrix(1, N, mxREAL);
mxArray *MS = mxCreateDoubleScalar(MarkerSize);
memcpy(mxGetPr(X), x, N * sizeof(double));
memcpy(mxGetPr(Y), y, N * sizeof(double));
if ((ret = engPutVariable(eg, "X", X)) != 0)
printf("engPutVariable error:%d\n", ret);
if ((ret = engPutVariable(eg, "Y", Y)) != 0)
printf("engPutVariable error:%d\n", ret);
//gennerate the plot command
char plotCommand[256] = "fig=plot(X,Y,'";
//set line style and marker
if (strlen(LineStyle) > 0)
strncat(plotCommand, LineStyle, strlen(LineStyle));
else
{
strncat(plotCommand, "-", strlen("-"));
}
strncat(plotCommand, "',", strlen(LineStyle));
char temp[20] = "";
//set line width
if (LineWidth < 1.0)
LineWidth = 1.0;
strncat(plotCommand, "'LineWidth',", strlen("'LineWidth',"));
memset(temp, 0, sizeof(temp));
sprintf(temp, "%f,", LineWidth);
strncat(plotCommand, temp, strlen(temp));
//set marker size
strncat(plotCommand, "'MarkerSize',", strlen("'MarkerSize',"));
sprintf(temp, "%f", MarkerSize);
strncat(plotCommand, temp, strlen(temp));
strncat(plotCommand, ");", strlen(temp));
//plot
if ((ret = engEvalString(eg, plotCommand)) != 0)
{
printf("\nplot Command error:%s\n", plotCommand);
return ret;
}
engEvalString(eg, "set(gcf,'color','w');");
printf("plot Command ok:%s\n", plotCommand);
//destroy mxArray,but they are still in matlab workspace
mxDestroyArray(X);
mxDestroyArray(Y);
return 0;
}