72 lines
2.8 KiB
C++
72 lines
2.8 KiB
C++
/// @file
|
|
/// @brief Task2: implementation
|
|
|
|
#include "task2.hpp"
|
|
|
|
/// @todo Include standard library headers as needed
|
|
#include <cassert> // assert
|
|
#include <functional> // std::function
|
|
#include <vector> // std::vector
|
|
#include <cmath> // std::abs
|
|
|
|
/// @brief Creates a sequence of equidistant values in a given interval (inclusive).
|
|
/// @param start Start of the interval
|
|
/// @param end End of the interval
|
|
/// @param N Number of values; assumption: N >= 2
|
|
/// @return Sequence of equidistant values in increasing order
|
|
std::vector<double> range(double start, double end, unsigned int N) {
|
|
assert(N >= 2);
|
|
std::vector<double> values(N);
|
|
double step = (end - start) / (N - 1);
|
|
for (unsigned int i = 0; i < N; ++i) {
|
|
values[i] = start + i * step;
|
|
}
|
|
return values;
|
|
}
|
|
|
|
/// @brief Evaluates a one-dimensional scalar function at the provided discrete locations
|
|
/// @param values Sequence of discrete locations
|
|
/// @param func Callable with a signature compatible with f(double) -> double
|
|
/// @return Sequence of function values
|
|
std::vector<double> sample(std::vector<double> values, std::function<double(double)> func) {
|
|
std::vector<double> results(values.size());
|
|
for (unsigned int i = 0; i < values.size(); ++i) {
|
|
results[i] = func(values[i]);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
/// @brief Performs a numerical differentiation using a combined forward/center/backward difference scheme
|
|
/// @param x Discrete sequence of locations; assumption: two or more values, ascending, and equally spaced
|
|
/// @param y Discrete sequence of function values; assumption: same size as 'x'
|
|
/// @return Sequence of function values of the numerical derivative
|
|
std::vector<double> numdiff(std::vector<double> x, std::vector<double> y) {
|
|
assert(x.size() == y.size());
|
|
assert(x.size() >= 2);
|
|
std::vector<double> derivative(x.size());
|
|
double h = x[1] - x[0];
|
|
derivative[0] = (y[1] - y[0]) / h;
|
|
for (unsigned int i = 1; i < x.size() - 1; ++i) {
|
|
derivative[i] = (y[i + 1] - y[i - 1]) / (2 * h);
|
|
}
|
|
derivative[x.size() - 1] = (y[x.size() - 1] - y[x.size() - 2]) / h;
|
|
return derivative;
|
|
}
|
|
|
|
/// @brief Performs a numerical integration using the trapezoidal rule
|
|
/// @param x Discrete sequence of locations; assumption: two or more values, ascending, and equally spaced
|
|
/// @param y Discrete sequence of function values; assumption: same size as 'x'
|
|
/// @param C Constant of integration
|
|
/// @return Sequence of function values of the numerical antiderivative
|
|
std::vector<double> numint(std::vector<double> x, std::vector<double> y, double C) {
|
|
assert(x.size() == y.size());
|
|
assert(x.size() >= 2);
|
|
std::vector<double> integral(x.size());
|
|
double h = x[1] - x[0];
|
|
integral[0] = C;
|
|
for (unsigned int i = 1; i < x.size(); ++i) {
|
|
integral[i] = integral[i - 1] + (y[i - 1] + y[i]) * h / 2;
|
|
}
|
|
return integral;
|
|
}
|