Solutions for FCUP's Numerical Analysis Assignments
This commit is contained in:
6
3 - Splines/source/input.txt
Normal file
6
3 - Splines/source/input.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
0 1.4
|
||||
1 0.6
|
||||
2 1.0
|
||||
2.5 0.6
|
||||
3 0.6
|
||||
4 1.0
|
51
3 - Splines/source/matriz.txt
Normal file
51
3 - Splines/source/matriz.txt
Normal file
@@ -0,0 +1,51 @@
|
||||
mat:
|
||||
1,0,0,0,0,0,
|
||||
0.166667,0.666667,0.166667,0,0,0,
|
||||
0,0.166667,0.5,0.0833333,0,0,
|
||||
0,0,0.0833333,0.333333,0.0833333,0,
|
||||
0,0,0,0.0833333,0.5,0.166667,
|
||||
0,0,0,0,0,1,
|
||||
b:
|
||||
0
|
||||
1.2
|
||||
-1.2
|
||||
0.8
|
||||
0.4
|
||||
0
|
||||
x:
|
||||
0
|
||||
2.76846
|
||||
-3.87386
|
||||
3.30622
|
||||
0.248963
|
||||
0
|
||||
mat:
|
||||
1,0,0,0,0,0,0,0,0,
|
||||
0.0416667,0.166667,0.0416667,0,0,0,0,0,0,
|
||||
0,0.0416667,0.166667,0.0416667,0,0,0,0,0,
|
||||
0,0,0.0416667,0.166667,0.0416667,0,0,0,0,
|
||||
0,0,0,0.0416667,0.166667,0.0416667,0,0,0,
|
||||
0,0,0,0,0.0416667,0.166667,0.0416667,0,0,
|
||||
0,0,0,0,0,0.0416667,0.166667,0.0416667,0,
|
||||
0,0,0,0,0,0,0.0416667,0.166667,0.0416667,
|
||||
0,0,0,0,0,0,0,0,1,
|
||||
b:
|
||||
0
|
||||
7.862
|
||||
-10.7327
|
||||
12.1347
|
||||
2
|
||||
-8.13471
|
||||
14.7327
|
||||
-3.862
|
||||
0
|
||||
x:
|
||||
0
|
||||
73.9996
|
||||
-107.31
|
||||
97.6564
|
||||
7.91753
|
||||
-81.3265
|
||||
122.156
|
||||
-53.7109
|
||||
0
|
0
3 - Splines/source/new.foo
Normal file
0
3 - Splines/source/new.foo
Normal file
211
3 - Splines/source/newton.cpp
Normal file
211
3 - Splines/source/newton.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
using points_t = std::pair<std::vector<double>, std::vector<double>>;
|
||||
using matrix_t = std::vector<std::vector<double>>;
|
||||
|
||||
std::vector<double> newton_differences(points_t points) {
|
||||
std::vector<double> factors{};
|
||||
auto &[x, fx] = points;
|
||||
int n = points.first.size();
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
factors.push_back(fx[0]);
|
||||
for (int j = 0; j < (n - i); ++j) {
|
||||
fx[j] = (fx[j + 1] - fx[j]) / (x[j + i] - x[j]);
|
||||
}
|
||||
|
||||
}
|
||||
return factors;
|
||||
}
|
||||
|
||||
double newton_polynomial(points_t points, std::vector<double> factors, double x) {
|
||||
auto xs = points.first;
|
||||
int n = points.second.size() - 1;
|
||||
double val = 0;
|
||||
for (int k = 0; k <= n; ++k) {
|
||||
double acc = 1;
|
||||
for(int i = 0; i < k; ++i) {
|
||||
acc *= (x - xs[i]);
|
||||
}
|
||||
val += acc * factors[k];
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
void calculate_natural_cubic_spline_matrix(points_t points, matrix_t &mat) {
|
||||
auto &[xs, fx] = points;
|
||||
int n = xs.size();
|
||||
|
||||
// Construção da matriz
|
||||
for (int i = 1; i < n - 1; ++i) {
|
||||
mat[i][i - 1] = (xs[i] - xs[i - 1])/6;
|
||||
mat[i][i] = (xs[i + 1] - xs[i - 1])/3;
|
||||
mat[i][i + 1] = (xs[i + 1] - xs[i])/6;
|
||||
mat[i][n] = (fx[i + 1] - fx[i])/(xs[i + 1] - xs[i]) - (fx[i] - fx[i - 1])/(xs[i] - xs[i - 1]);
|
||||
}
|
||||
mat[0][0] = 1;
|
||||
mat[0][n - 1] = 0;
|
||||
mat[n - 1][n - 1] = 1;
|
||||
mat[n - 1][n] = 0;
|
||||
|
||||
std::ofstream matriz("matriz.txt", std::ios_base::app);
|
||||
|
||||
matriz << "mat:\n";
|
||||
for (auto i : mat){
|
||||
for (auto j = i.begin(); j != i.end() - 1; ++ j)
|
||||
matriz << *j << ",";
|
||||
matriz << "\n";
|
||||
}
|
||||
|
||||
matriz << "b:\n";
|
||||
for (auto i : mat){
|
||||
matriz << i[n] << '\n';
|
||||
}
|
||||
|
||||
// Passar para a forma triangular
|
||||
for (int k = 0; k < n; ++k) {
|
||||
for (int i = k + 1; i < n; ++i) {
|
||||
if (mat[k][k] != 0) {
|
||||
double mul = mat[i][k]/mat[k][k];
|
||||
for (int j = k; j < n; ++j) {
|
||||
mat[i][j] -= mul * mat[k][j];
|
||||
}
|
||||
mat[i][n] -= mul * mat[k][n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolução da matriz
|
||||
for (int i = n - 1; i > 0; --i) {
|
||||
if (mat[i][i] != 0) {
|
||||
double mul = mat[i - 1][i]/mat[i][i];
|
||||
for (int j = 1; j < n + 1; ++j) {
|
||||
mat[i - 1][j] -= mul * mat[i][j];
|
||||
}
|
||||
mat[i - 1][i] = 0;
|
||||
mat[i][n] /= mat[i][i];
|
||||
mat[i][i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
matriz << "x:\n";
|
||||
for (auto i : mat){
|
||||
matriz << i[n] << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
double natural_cubic_spline(points_t points, matrix_t &mat, double x) {
|
||||
|
||||
auto &[xs, fx] = points;
|
||||
int n = xs.size();
|
||||
|
||||
int i = 0;
|
||||
for (int i_ = 0; i_ < n; ++i_) {
|
||||
if (xs[i_] > x){
|
||||
i = i_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double hi = xs[i] - xs[i - 1];
|
||||
return mat[i - 1][n] * std::pow((xs[i] - x), 3)/(6 * hi) +
|
||||
mat[i][n] * std::pow((x - xs[i - 1]), 3)/(6 * hi) +
|
||||
(fx[i - 1] - mat[i - 1][n] * (hi * hi)/6)*(xs[i] - x)/hi +
|
||||
(fx[i] - mat[i][n] * (hi * hi)/6)*(x - xs[i - 1])/hi;
|
||||
|
||||
}
|
||||
|
||||
void exercise_a(points_t points) {
|
||||
auto &[xs, fx] = points;
|
||||
auto factors = newton_differences(points);
|
||||
std::ofstream poly{"a_polynomial.txt"};
|
||||
for(double x = 0; x < 4; x += 0.001)
|
||||
poly << x << " " << newton_polynomial(points, factors, x) << '\n';
|
||||
|
||||
std::ofstream spline{"a_spline.txt"};
|
||||
unsigned long n = xs.size();
|
||||
matrix_t mat(n, std::vector<double>(n + 1));
|
||||
calculate_natural_cubic_spline_matrix(points, mat);
|
||||
for(double x = 0; x < 4; x += 0.001)
|
||||
spline << x << " " << natural_cubic_spline(points, mat, x) << '\n';
|
||||
}
|
||||
|
||||
void exercise_b() {
|
||||
points_t points;
|
||||
auto &[xs, fx] = points;
|
||||
auto f = [](double x) { return 4 * std::pow(x, 2) + std::sin(9 * x); };
|
||||
|
||||
for (double x = -1; x <= 1; x += (1 - -1)/8.0) {
|
||||
xs.push_back(x);
|
||||
fx.push_back(f(x));
|
||||
}
|
||||
|
||||
std::ofstream poly{"b_polynomial.txt"};
|
||||
auto factors = newton_differences(points);
|
||||
for(double x = -1; x < 1; x += 0.001)
|
||||
poly << x << " " << newton_polynomial(points, factors, x) << '\n';
|
||||
|
||||
std::ofstream spline{"b_spline.txt"};
|
||||
unsigned long n = xs.size();
|
||||
matrix_t mat(n, std::vector<double>(n + 1));
|
||||
calculate_natural_cubic_spline_matrix(points, mat);
|
||||
for(double x = -1; x < 1; x += 0.001)
|
||||
spline << x << " " << natural_cubic_spline(points, mat, x) << '\n';
|
||||
|
||||
std::cout << "Erros poly: "
|
||||
<< std::abs(std::round((f(0.3) - newton_polynomial(points, factors, 0.3)) * 100.0) / 100.0) << " "
|
||||
<< std::abs(std::round((f(0.83) - newton_polynomial(points, factors, 0.83)) * 100.0) / 100.0) << '\n';
|
||||
|
||||
std::cout << "Erros spline: "
|
||||
<< std::abs(std::round((f(0.3) - natural_cubic_spline(points, mat, 0.3))*100.0)/100.0) << " "
|
||||
<< std::abs(std::round((f(0.83) - natural_cubic_spline(points, mat,0.83))*100.0)/100.0) << '\n';
|
||||
|
||||
std::cout << "p(0.3) = " << newton_polynomial(points, factors, 0.3) << ' '
|
||||
<< "p(0.83) = " << newton_polynomial(points, factors, 0.83) << '\n';
|
||||
|
||||
std::cout << "p(0.3) = " << natural_cubic_spline(points, mat, 0.3) << ' '
|
||||
<< "p(0.83) = " << natural_cubic_spline(points, mat, 0.83) << '\n';
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::istream *s;
|
||||
std::ifstream file;
|
||||
if (argc == 2) {
|
||||
if (argv[1] == "-"s) {
|
||||
s = &std::cin;
|
||||
} else {
|
||||
file.open(argv[1]);
|
||||
s = &file;
|
||||
}
|
||||
} else{
|
||||
std::cerr << "An argument required\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
points_t points;
|
||||
std::pair<double, double> p;
|
||||
while(true) {
|
||||
*s >> p.first >> p.second;
|
||||
if(s->eof())
|
||||
break;
|
||||
|
||||
points.first.push_back(p.first);
|
||||
points.second.push_back(p.second);
|
||||
}
|
||||
|
||||
exercise_a(points);
|
||||
exercise_b();
|
||||
|
||||
}
|
17
3 - Splines/source/old.foo
Normal file
17
3 - Splines/source/old.foo
Normal file
@@ -0,0 +1,17 @@
|
||||
Mat:
|
||||
1,0,0,0,0,0,0,
|
||||
0,1,-7.14916e-18,2.73077e-18,-4.18062e-19,0,2.76846,
|
||||
0,0,1,-7.50963e-18,1.14967e-18,0,-3.87386,
|
||||
0,0,-3.57458e-18,1,-4.38965e-18,0,3.30622,
|
||||
0,0,0,-7.50963e-18,1,0,0.248963,
|
||||
0,0,0,0,0,1,0,
|
||||
Mat:
|
||||
1,0,0,0,0,0,0,0,0,0,
|
||||
0,1,-1.73472e-18,4.64061e-19,2.85733e-19,5.30686e-20,-1.26382e-20,-4.49207e-21,0,73.9996,
|
||||
0,0,1,-1.74023e-18,-1.0715e-18,-1.99007e-19,4.73931e-20,1.68453e-20,0,-107.31,
|
||||
0,0,-1.73472e-18,1,4.00026e-18,7.4296e-19,-1.76934e-19,-6.2889e-20,0,97.6564,
|
||||
0,0,0,-1.74023e-18,1,-2.77283e-18,6.60344e-19,2.34711e-19,0,7.91753,
|
||||
0,0,0,0,4.00026e-18,1,-2.46444e-18,-8.75954e-19,0,-81.3265,
|
||||
0,0,0,0,0,-2.77283e-18,1,3.26911e-18,0,122.156,
|
||||
0,0,0,0,0,0,-2.46444e-18,1,0,-53.7109,
|
||||
0,0,0,0,0,0,0,0,1,0,
|
39
3 - Splines/source/residue.py
Executable file
39
3 - Splines/source/residue.py
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import numpy as np
|
||||
from scipy.linalg import solve
|
||||
from numpy.linalg import norm
|
||||
|
||||
# Matriz construída pelo programa em C++
|
||||
A = np.matrix([[1, 0, 0, 0, 0, 0],
|
||||
[0.166667, 0.666667, 0.166667, 0, 0, 0],
|
||||
[0, 0.166667, 0.5, 0.0833333, 0, 0],
|
||||
[0, 0, 0.0833333, 0.333333, 0.0833333, 0],
|
||||
[0, 0, 0, 0.0833333, 0.5, 0.166667],
|
||||
[0, 0, 0, 0, 0, 1]])
|
||||
|
||||
b = np.array([0, 1.2, -1.2, 0.8, 0.4, 0])
|
||||
|
||||
x2 = np.array([0, 2.76846, -3.87386, 3.30622, 0.248963, 0])
|
||||
|
||||
x = solve(A, b)
|
||||
|
||||
print(norm(x - x2))
|
||||
|
||||
A = np.matrix([[1, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0.0416667, 0.166667, 0.0416667, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0.0416667, 0.166667, 0.0416667, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0.0416667, 0.166667, 0.0416667, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0.0416667, 0.166667, 0.0416667, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0.0416667, 0.166667, 0.0416667, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0.0416667, 0.166667, 0.0416667, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0.0416667, 0.166667, 0.0416667],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 1]])
|
||||
|
||||
b = np.array([0, 7.862, -10.7327, 12.1347, 2, -8.13471, 14.7327, -3.862, 0])
|
||||
|
||||
x2 = np.array([0, 73.9996, -107.31, 97.6564, 7.91753, -81.3265, 122.156, -53.7109, 0])
|
||||
|
||||
x = solve(A, b)
|
||||
|
||||
print(norm(x - x2))
|
17
3 - Splines/source/test.foo
Normal file
17
3 - Splines/source/test.foo
Normal file
@@ -0,0 +1,17 @@
|
||||
Mat:
|
||||
1,0,0,0,0,0,0,
|
||||
0,1,0,0,0,0,2.76846,
|
||||
0,0,1,0,0,0,-3.87386,
|
||||
0,0,-3.57458e-18,1,0,0,3.30622,
|
||||
0,0,0,-7.50963e-18,1,0,0.248963,
|
||||
0,0,0,0,0,1,0,
|
||||
Mat:
|
||||
1,0,0,0,0,0,0,0,0,0,
|
||||
0,1,0,0,0,0,0,0,0,73.9996,
|
||||
0,0,1,0,0,0,0,0,0,-107.31,
|
||||
0,0,-1.73472e-18,1,0,0,0,0,0,97.6564,
|
||||
0,0,0,-1.74023e-18,1,0,0,0,0,7.91753,
|
||||
0,0,0,0,4.00026e-18,1,0,0,0,-81.3265,
|
||||
0,0,0,0,0,-2.77283e-18,1,0,0,122.156,
|
||||
0,0,0,0,0,0,-2.46444e-18,1,0,-53.7109,
|
||||
0,0,0,0,0,0,0,0,1,0,
|
Reference in New Issue
Block a user