scf_celebic/ex1/code/mylib.cpp
2025-11-03 22:35:52 +01:00

354 lines
8.2 KiB
C++

#include "mylib.h"
#include "mayer_primes.h"
#include <cassert> // assert
#include <vector>
#include <iostream>
#include <cmath>
#include <tuple>
#include <string>
#include <algorithm>
#include <fstream>
#include <stdexcept>
#include <random>
#include <list>
using namespace std;
// -------------- Task A --------------
tuple<double, double, double> means0(double a, double b, double c){
double arith = (a+b+c) / 3;
double geo = pow((a*b*c), 1.0/3);
double harm = 3 / ((1.0/a) + (1.0/b) + (1.0/c));
return make_tuple(arith, geo, harm);
}
tuple<double, double, double> means(const vector<double>& v){
size_t n = v.size();
double sum = 0;
double logsum = 0;
double invsum = 0;
for (size_t i = 0; i<n; ++i){
sum += v[i];
logsum += log(v[i]);
invsum += 1.0/v[i];
}
double arith = sum / static_cast<double>(n);
double geo = exp(1.0/static_cast<double>(n) * logsum);
double harm = static_cast<double>(n) / invsum;
return make_tuple(arith, geo, harm);
}
// -------------- Task B --------------
void fill_vector(istream& istr, vector<double>& v)
{
double d=0;
while ( istr >> d) v.push_back(d); // Einlesen
if (!istr.eof())
{ // Fehlerbehandlung
cout << " Error handling \n";
if ( istr.bad() ) throw runtime_error("Schwerer Fehler in istr");
if ( istr.fail() ) // Versuch des Aufraeumens
{
cout << " Failed in reading all data.\n";
istr.clear();
}
}
v.shrink_to_fit(); // C++11
return;
}
void read_vector_from_file(const string& file_name, vector<double>& v)
{
ifstream fin(file_name); // Oeffne das File im ASCII-Modus
if( fin.is_open() ) // File gefunden:
{
v.clear(); // Vektor leeren
fill_vector(fin, v);
}
else // File nicht gefunden:
{
cout << "\nFile " << file_name << " has not been found.\n\n" ;
assert( fin.is_open() && "File not found." ); // exeption handling for the poor programmer
}
return;
}
void write_vector_to_file(const string& file_name, const vector<double>& v)
{
ofstream fout(file_name); // Oeffne das File im ASCII-Modus
if( fout.is_open() )
{
for (size_t k=0; k<v.size(); ++k)
{
fout << v.at(k) << endl;
}
}
else
{
cout << "\nFile " << file_name << " has not been opened.\n\n" ;
assert( fout.is_open() && "File not opened." ); // exeption handling for the poor programmer
}
return;
}
// -------------- Task C --------------
long int sum_of_spec(int n)
{
long int sum = 0;
for (long int i=1; i<n+1; i++){
if (i % 3 == 0 || i % 5 == 0){
sum += i;
}
}
return sum;
}
double formula(int n)
{
double div_by_3 = floor( n / 3.0 );
double div_by_5 = floor( n / 5.0 );
double div_by_15 = floor( n / 15.0 );
double S_3 = 3.0 * (div_by_3*((div_by_3+1)/2.0));
double S_5 = 5.0 * (div_by_5*((div_by_5+1)/2.0));
double S_15 = 15.0 * (div_by_15*((div_by_15+1)/2.0));
double sum = S_3 + S_5 - S_15;
return sum;
}
// -------------- Task D --------------
#ifdef __GNUC__
#pragma GCC push_options
#pragma GCC optimize("O1")
#endif
long double Kahan_skalar(vector<double> const &input)
{
long double sum = 0.0;
long double c = 0.0;
for (long unsigned int i=0; i<input.size(); i++){
long double y = input[i] - c;
long double t = sum + y;
c = (t-sum) - y;
sum = t;
}
return sum;
}
long double normal_sum(vector<double> const &input)
{
long double sum = 0.0;
for (long unsigned int i=0; i<input.size(); i++){
sum += input[i];
}
return sum;
}
#ifdef __GNUC__
#pragma GCC pop_options
#endif
// -------------- Task E --------------
void insert_into_vector(vector<int>& vec, int n) {
random_device rd; // random device
mt19937 gen(rd()); // seed
uniform_int_distribution<> dist(1, n); // define range
for (int i = 0; i < n; ++i) {
int rand_num = dist(gen);
auto pos = lower_bound(vec.begin(), vec.end(), rand_num);
vec.insert(pos, rand_num);
}
assert(is_sorted(vec.begin(), vec.end()));
}
void insert_into_list(list<int>& lst, int n) {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dist(1, n);
for (int i = 0; i < n; ++i) {
int rand_num = dist(gen);
auto pos = lower_bound(lst.begin(), lst.end(), rand_num);
lst.insert(pos, rand_num);
}
assert(is_sorted(lst.begin(), lst.end()));
}
// -------------- Task F --------------
int single_goldbach(int k) {
const vector<int> primes = get_primes(k);
int count = 0;
for (size_t i = 0; i < primes.size(); i++) {
for (size_t j = i; j < primes.size(); j++) {
if (primes[i] + primes[j] == k) {
count++;
}
}
}
return count;
}
vector<int> count_goldbach(int n) {
const vector<int> primes = get_primes(n);
vector<int> counts(n+1);
for (size_t i = 1; i < primes.size(); i++) {
for (size_t j = i; j < primes.size(); j++) {
int sum = primes[i] + primes[j];
if (sum <= n) {
counts[sum]++;
}
}
}
return counts;
}
void print_decomps(int k) {
const vector<int> primes = get_primes(k);
cout << "\nDecompositions for k = " << k << ": ";
for (size_t i = 0; i < primes.size(); i++) {
for (size_t j = i; j < primes.size(); j++) {
if (primes[i] + primes[j] == k) {
cout << primes[i] << " + " << primes[j] << ", ";
}
}
}
cout << endl;
}
// -------------- Task G --------------
double sigmoid(double x)
{
return 1.0 / (1.0 + std::exp(-x));
}
double DenseMatrix::sigmoid(double x)
{
return 1.0 / (1.0 + exp(-x));
}
DenseMatrix::DenseMatrix(size_t n, size_t m) : rows(n), cols(m), matrix(n*m)
{
size_t nm = max(n, m);
for (size_t i = 0; i < rows; i++)
{
for (size_t j = 0; j < cols; j++)
{
double x_i = 10.0*static_cast<double>(i)/(nm-1) - 5.0;
double x_j = 10.0*static_cast<double>(j)/(nm-1) - 5.0;
matrix[i*cols + j] = sigmoid(x_i) * sigmoid(x_j);
}
}
}
vector<double> DenseMatrix::Mult(const vector<double>& vec) const
{
assert(vec.size() == cols);
vector<double> result(rows, 0.0);
for (size_t i = 0; i < rows; ++i)
{
for (size_t j = 0; j < cols; ++j)
{
result[i] += matrix[i*cols + j] * vec[j];
}
}
return result;
}
vector<double> DenseMatrix::MultT(const vector<double>& vec) const
{
assert(vec.size() == rows);
vector<double> result(cols, 0.0);
for (size_t i = 0; i < cols; ++i)
{
for (size_t j = 0; j < rows; ++j)
{
result[i] += matrix[j*cols + i] * vec[j];
}
}
return result;
}
void DenseMatrix::print() const {
size_t count(0);
cout.precision(5);
for (double val : matrix) {
printf("%.6f ", val);
count++;
if(count%cols == 0){cout << endl;}
}
}
// #################################################
DenseMatrix2::DenseMatrix2(vector<double> const u, vector<double> const v) : rows(u.size()), cols(v.size()), u_(u), v_(v) {}
vector<double> DenseMatrix2::Mult(const vector<double>& vec) const
{
assert(vec.size() == cols);
vector<double> result(rows, 0.0);
double scalar(0.0);
for (size_t i = 0; i < vec.size(); i++)
{
scalar += v_[i] * vec[i];
}
for (size_t i = 0; i < u_.size(); i++)
{
result[i] = scalar*u_[i];
}
return result;
}
vector<double> DenseMatrix2::MultT(const vector<double>& vec) const
{
assert(vec.size() == rows);
vector<double> result(cols, 0.0);
double scalar(0.0);
for (size_t i = 0; i < u_.size(); i++)
{
scalar += u_[i] * vec[i];
}
for (size_t i = 0; i < v_.size(); i++)
{
result[i] = scalar*v_[i];
}
return result;
}
void task_a();
void task_b();
void task_c();
void task_d();
void task_e();
void task_f();
void task_g();