我有一个有效的Integrator
类,它将计算单个变量的基本函数的确定积分。我已经测试了一些基本功能的集成,并且看来工作正常。
我现在想扩展此类,以便能够执行相同功能的多个积分……这就是我遇到的障碍...
这是我的集成器类和一些基本用法示例:
Integrator.h
#pragma once
#include <algorithm>
#include <utility>
#include <functional>
struct Limits {
double lower;
double upper;
Limits() : lower{ 0 }, upper{ 0 } {}
Limits(double a, double b) : lower{ a }, upper{ b } {
if (a > b) std::swap(lower, upper);
}
void applyLimits(double a, double b) {
lower = a;
upper = b;
if (a > b) std::swap(lower, upper);
}
};
class Integrator {
private:
Limits limits_;
std::function<double(double)> integrand_;
double dx_;
double dy_;
double integral_;
int step_size_;
public:
Integrator(Limits limits, int stepSize, std::function<double(double)> integrand, double dy = 0)
: limits_{ limits },
step_size_{ stepSize },
integrand_{ integrand },
dx_{ 0 }, dy_{ 0 }
{}
~Integrator() = default;
constexpr double dx() const { return this->dx_; }
constexpr double dy() const { return this->dy_; }
constexpr double integral() const { return this->integral_; }
Limits limits() const { return limits_; }
std::function<double(double)>* integrand() { return &this->integrand_; }
// This is always a 1st order of integration!
constexpr double evaluate() {
double distance = limits_.upper - limits_.lower; // Distance is defined as X0 to XN. (upperLimit - lowerLimit)
dx_ = distance / step_size_; // Calculate the amount of iterations by dividing
// the x-distance by the dx stepsize
integral_ = 0; // Initialize area to zero
for (auto i = 0; i < step_size_; i++) { // For each dx step or iteration calculate the area at Xi
dy_ = integrand_(limits_.lower + i * dx_);
double area = dy_ * dx_; // Where the width along x is defines as dxStepSize*i
integral_ += area; // and height(dy) is f(x) at Xi. Sum all of the results
}
return integral_;
}
};
main.cpp
#include <iostream>
#include <exception>
#include <cmath>
#include "Integrator.h"
constexpr double PI = 3.14159265358979;
constexpr double funcA(double x) {
return x;
}
constexpr double funcB(double x) {
return (x*x);
}
constexpr double funcC(double x) {
return ((0.5*(x*x)) + (3*x) - (1/x));
}
double funcD(double x) {
return sin(x);
}
int main() {
try {
std::cout << "Integration of f(x) = x from a=3.0 to b=5.0\nwith an expected output of 8\n";
Integrator integratorA(Limits(3.0, 5.0), 10000, &funcA);
std::cout << integratorA.evaluate() << '\n';
std::cout << "\n\nIntegration of f(x) = x^2 from a=2.0 to b=20.0\nwith an expected output of 2664\n";
Integrator integratorB(Limits(2.0, 20.0), 10000, &funcB);
std::cout << integratorB.evaluate() << '\n';
std::cout << "\n\nIntegration of f(x) = (1\\2)x^2 + 3x - (1\\x) from a=1.0 to b=10.0\nwith an expected output of 312.6974\n";
Integrator integratorC(Limits(1.0, 10.0), 10000, &funcC);
std::cout << integratorC.evaluate() << '\n';
std::cout << "\n\nIntegration of f(x) = sin(x) from a=0.0 to b=" <<PI<< "\nwith an expected output of 2\n";
Integrator integratorD(Limits(0.0, PI), 10000, &funcD);
std::cout << integratorD.evaluate() << '\n';
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
输出
Integration of f(x) = x from a=3.0 to b=5.0
with an expected output of 8
7.9998
Integration of f(x) = x^2 from a=2.0 to b=20.0
with an expected output of 2664
2663.64
Integration of f(x) = (1\2)x^2 + 3x - (1\x) from a=1.0 to b=10.0
with an expected output of 312.6974
312.663
Integration of f(x) = sin(x) from a=0.0 to b=3.14159
with an expected output of 2
2
我正在考虑向该类添加类似于其evaluate()
函数的另一个函数...目前看起来像这样:
double integrate(Limits limits, double dy) {
double total = 0;
dy_ = dy;
for (int i = 0; i < step_size_; i++) {
double yi = limits_.lower*i*dy_;
double dx = static_cast<double>(yi - limits.lower) / stepSize;
double innerArea = 0;
for (int j = 0; j < step_size_; j++) {
Integrator inner(limits, step_size_, integrand_, dy_);
innerArea += inner.evaluate();
}
double outerArea = innerArea * dy_;
total += outerArea;
}
integral_ = total;
return integral_;
}
这就是我感到困惑或困惑的地方。当涉及到内部和外部积分的积分极限时,我不确定如何正确实现此功能。
例如,下面的整数:
内部积分的上限基于每次计算迭代的y,这必须动态完成。从[3,5]
到[1,y]
,外部积分是笔直的。
我认为我走在正确的轨道上,但是上述方法中的某些方法完全不可用...我从预期或预期值中得到了完全错误的值...
非常欢迎任何建议和技巧!
编辑-注意-我在上面提供了错误的图像,该图像已更新...
期望的输出应该是:65.582
,带有正确提供的功能f(x) = 1/2x^2 + 3x - (1/x)
。当我尝试计算双积分时,我最终得到了这个...
这是添加到驱动程序或main.cpp
...]中的代码>
std::cout << "\n\nTesting Double Integration of f(x) = (1\\2)x^2 + 3x - (1\\x) from [3,5] and [1,y]\nwith an expected output of 65.582\n"; Integrator integratorE(Limits(3, 5), 1000, &funcC); double dy = integratorE.limits().upper - integratorE.limits().lower; integratorE.integrate(Limits(1, integratorE.integral()), dy); std::cout << integratorE.integral() << '\n';
但是,它没有在控制台上打印任何内容...
编辑
我没有得到足够的输出,因为我没有等待足够长的时间。迭代由step_size定义为1000
。最终将生成1000^1000
个总迭代...在构建Integrator对象时,我已经忽略了这一点。我已经在代码中将此值更改为step_size为100
。现在我的应用程序正在输出2.68306e+189
的值,这显然是错误的!当我将step_size
增大到500
时,它给了我大约6.62804e+190
的顺序,但这仍然是错误的。
我有一个有效的Integrator类,它将计算单个变量的基本函数的确定积分。我已经测试了一些基本功能的集成,并且似乎可以正常使用...
返回并再次观看视频后,我开始分解类的integrate()
函数中的双循环结构。