0% found this document useful (0 votes)
2 views

Intermediate OOP Applications

The document outlines the implementation of various mathematical and analytical applications in C++. It includes classes for fractions, matrices, complex numbers, polynomials, 3D vectors, and statistics, each with methods for performing relevant operations. Each section provides example code demonstrating the functionality of the respective classes.

Uploaded by

jedny456
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Intermediate OOP Applications

The document outlines the implementation of various mathematical and analytical applications in C++. It includes classes for fractions, matrices, complex numbers, polynomials, 3D vectors, and statistics, each with methods for performing relevant operations. Each section provides example code demonstrating the functionality of the respective classes.

Uploaded by

jedny456
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Mathematics and Analytical Applications

1. Fraction Operations: Create a class to represent fractions with methods for addition,
subtraction, multiplication, and division.

#include <iostream>
#include <numeric> // for std::gcd in C++17 or later
using namespace std;

class Fraction {
private:
int numerator;
int denominator;

// Helper function to simplify the fraction


void simplify() {
int gcd = std::gcd(numerator, denominator);
numerator /= gcd;
denominator /= gcd;
if (denominator < 0) { // Handle negative denominators
numerator = -numerator;
denominator = -denominator;
}
}

public:
// Constructor
Fraction(int num = 0, int denom = 1) {
if (denom == 0) {
throw invalid_argument("Denominator cannot be zero.");
}
numerator = num;
denominator = denom;
simplify();
}

// Display function
void display() const {
if (denominator == 1) {
cout << numerator << endl;
} else {
cout << numerator << "/" << denominator << endl;
}
}

// Addition
Fraction operator+(const Fraction &other) const {
int num = numerator * other.denominator + other.numerator *
denominator;
int denom = denominator * other.denominator;
return Fraction(num, denom);
}

// Subtraction
Fraction operator-(const Fraction &other) const {
int num = numerator * other.denominator - other.numerator *
denominator;
int denom = denominator * other.denominator;
return Fraction(num, denom);
}

// Multiplication
Fraction operator*(const Fraction &other) const {
int num = numerator * other.numerator;
int denom = denominator * other.denominator;
return Fraction(num, denom);
}

// Division
Fraction operator/(const Fraction &other) const {
if (other.numerator == 0) {
throw invalid_argument("Division by zero.");
}
int num = numerator * other.denominator;
int denom = denominator * other.numerator;
return Fraction(num, denom);
}
};

int main() {
try {
Fraction f1(3, 4); // 3/4
Fraction f2(2, 5); // 2/5

cout << "Fraction 1: ";


f1.display();

cout << "Fraction 2: ";


f2.display();

Fraction sum = f1 + f2;


cout << "Sum: ";
sum.display();

Fraction difference = f1 - f2;


cout << "Difference: ";
difference.display();

Fraction product = f1 * f2;


cout << "Product: ";
product.display();

Fraction quotient = f1 / f2;


cout << "Quotient: ";
quotient.display();

} catch (const exception &e) {


cout << "Error: " << e.what() << endl;
}

return 0;
}
2. Matrix Calculator: Develop a class to handle matrix operations such as addition, subtraction,
multiplication, and transpose.

#include <iostream>
#include <vector>

class Matrix {
public:
std::vector<std::vector<int>> mat;
int rows, cols;

// Constructor to initialize matrix with rows and columns


Matrix(int r, int c) : rows(r), cols(c) {
mat.resize(rows, std::vector<int>(cols));
}

// Input matrix elements


void input() {
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
std::cin >> mat[i][j];
}

// Display matrix
void display() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++)
std::cout << mat[i][j] << " ";
std::cout << std::endl;
}
}

// Matrix addition
Matrix add(const Matrix& m) {
Matrix result(rows, cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
result.mat[i][j] = mat[i][j] + m.mat[i][j];
return result;
}

// Matrix subtraction
Matrix subtract(const Matrix& m) {
Matrix result(rows, cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
result.mat[i][j] = mat[i][j] - m.mat[i][j];
return result;
}

// Matrix multiplication
Matrix multiply(const Matrix& m) {
Matrix result(rows, m.cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < m.cols; j++)
for (int k = 0; k < cols; k++)
result.mat[i][j] += mat[i][k] * m.mat[k][j];
return result;
}

// Matrix transpose
Matrix transpose() {
Matrix result(cols, rows);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
result.mat[j][i] = mat[i][j];
return result;
}
};

int main() {
int r, c;
std::cout << "Enter number of rows and columns: ";
std::cin >> r >> c;

Matrix m1(r, c), m2(r, c);


std::cout << "Enter elements of matrix 1:" << std::endl;
m1.input();
std::cout << "Enter elements of matrix 2:" << std::endl;
m2.input();

std::cout << "\nMatrix 1:" << std::endl;


m1.display();
std::cout << "Matrix 2:" << std::endl;
m2.display();

// Operations
std::cout << "\nAddition:" << std::endl;
Matrix result = m1.add(m2);
result.display();

std::cout << "\nSubtraction:" << std::endl;


result = m1.subtract(m2);
result.display();

std::cout << "\nMultiplication:" << std::endl;


result = m1.multiply(m2);
result.display();

std::cout << "\nTranspose of Matrix 1:" << std::endl;


result = m1.transpose();
result.display();

return 0;
}

3. Complex Number Calculator: Implement a class for complex numbers with methods for
arithmetic operations.
#include <iostream>
using namespace std;

class Complex {
private:
double real;
double imag;

public:
// Constructor
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}

// Methods for arithmetic operations


Complex operator+(const Complex& other) {
return Complex(real + other.real, imag + other.imag);
}

Complex operator-(const Complex& other) {


return Complex(real - other.real, imag - other.imag);
}

Complex operator*(const Complex& other) {


double newReal = real * other.real - imag * other.imag;
double newImag = real * other.imag + imag * other.real;
return Complex(newReal, newImag);
}

// Method to display the complex number


void display() {
cout << real << " + " << imag << "i" << endl;
}
};

int main() {
Complex c1(3.0, 4.0); // Represents 3 + 4i
Complex c2(2.0, -1.0); // Represents 2 - 1i

// Performing arithmetic operations


Complex sum = c1 + c2;
Complex diff = c1 - c2;
Complex prod = c1 * c2;

// Displaying results
cout << "Sum: ";
sum.display();
cout << "Difference: ";
diff.display();
cout << "Product: ";
prod.display();

return 0;
}

4. Polynomial Manipulation: Design a class to perform polynomial operations like addition,


multiplication, evaluation, and differentiation.

#include <iostream>
#include <vector>
using namespace std;

class Polynomial {
private:
vector<double> coefficients; // Stores the coefficients of the polynomial

public:
// Constructor to create a polynomial with given coefficients
Polynomial(const vector<double>& coeffs) : coefficients(coeffs) {}

// Method to display the polynomial


void display() {
int degree = coefficients.size() - 1;
for (int i = degree; i >= 0; --i) {
if (coefficients[i] != 0) {
if (i != degree) cout << (coefficients[i] > 0 ? " + " : " - ");
cout << abs(coefficients[i]);
if (i != 0) cout << "x^" << i;
}
}
cout << endl;
}

// Addition of two polynomials


Polynomial operator+(const Polynomial& other) {
int maxDegree = max(coefficients.size(), other.coefficients.size());
vector<double> resultCoeff(maxDegree, 0);

for (int i = 0; i < coefficients.size(); ++i) {


resultCoeff[i] += coefficients[i];
}
for (int i = 0; i < other.coefficients.size(); ++i) {
resultCoeff[i] += other.coefficients[i];
}
return Polynomial(resultCoeff);
}

// Multiplication of two polynomials


Polynomial operator*(const Polynomial& other) {
int degree1 = coefficients.size() - 1;
int degree2 = other.coefficients.size() - 1;
vector<double> resultCoeff(degree1 + degree2 + 1, 0);

for (int i = 0; i <= degree1; ++i) {


for (int j = 0; j <= degree2; ++j) {
resultCoeff[i + j] += coefficients[i] * other.coefficients[j];
}
}

return Polynomial(resultCoeff);
}

// Evaluate the polynomial at a given value of x


double evaluate(double x) {
double result = 0;
int degree = coefficients.size();
for (int i = 0; i < degree; ++i) {
result += coefficients[i] * pow(x, degree - 1 - i);
}
return result;
}

// Differentiate the polynomial


Polynomial differentiate() {
int degree = coefficients.size();
vector<double> resultCoeff(degree - 1, 0);

for (int i = 0; i < degree - 1; ++i) {


resultCoeff[i] = coefficients[i] * (degree - 1 - i);
}

return Polynomial(resultCoeff);
}
};

int main() {
// Create polynomials
Polynomial p1({3, 2, 1}); // Represents 3 + 2x + x^2
Polynomial p2({1, 0, -1}); // Represents 1 - x^2

// Display polynomials
cout << "Polynomial 1: ";
p1.display();
cout << "Polynomial 2: ";
p2.display();

// Polynomial addition
Polynomial sum = p1 + p2;
cout << "Sum: ";
sum.display();

// Polynomial multiplication
Polynomial product = p1 * p2;
cout << "Product: ";
product.display();

// Evaluate polynomial at x = 2
double evalResult = p1.evaluate(2);
cout << "Evaluation of p1 at x = 2: " << evalResult << endl;

// Differentiate polynomial
Polynomial derivative = p1.differentiate();
cout << "Derivative of p1: ";
derivative.display();

return 0;
}

5. Vector Algebra: Implement a class to handle 3D vector operations such as dot product, cross
product, and magnitude calculation.

#include <iostream>
#include <cmath> // For sqrt
using namespace std;

class Vector3D {
private:
double x, y, z; // Coordinates of the 3D vector

public:
// Constructor to initialize the vector
Vector3D(double x = 0.0, double y = 0.0, double z = 0.0) : x(x), y(y), z(z) {}

// Dot product of two vectors


double dot(const Vector3D& other) {
return x * other.x + y * other.y + z * other.z;
}
// Cross product of two vectors
Vector3D cross(const Vector3D& other) {
double cx = y * other.z - z * other.y;
double cy = z * other.x - x * other.z;
double cz = x * other.y - y * other.x;
return Vector3D(cx, cy, cz);
}

// Magnitude of the vector


double magnitude() {
return sqrt(x * x + y * y + z * z);
}

// Method to display the vector


void display() const {
cout << "(" << x << ", " << y << ", " << z << ")" << endl;
}

// Setters for individual vector components (optional)


void setX(double val) { x = val; }
void setY(double val) { y = val; }
void setZ(double val) { z = val; }

// Getters for individual vector components (optional)


double getX() const { return x; }
double getY() const { return y; }
double getZ() const { return z; }
};

int main() {
// Create two vectors
Vector3D v1(3.0, -2.0, 5.0); // Represents vector (3, -2, 5)
Vector3D v2(1.0, 4.0, -3.0); // Represents vector (1, 4, -3)

// Display vectors
cout << "Vector v1: ";
v1.display();
cout << "Vector v2: ";
v2.display();

// Dot product
double dotProduct = v1.dot(v2);
cout << "Dot product of v1 and v2: " << dotProduct << endl;

// Cross product
Vector3D crossProduct = v1.cross(v2);
cout << "Cross product of v1 and v2: ";
crossProduct.display();

// Magnitude of vectors
cout << "Magnitude of v1: " << v1.magnitude() << endl;
cout << "Magnitude of v2: " << v2.magnitude() << endl;

return 0;
}

6. Statistics Calculator: Develop a class to compute mean, median, mode, variance, and standard
deviation for a dataset.

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <cmath>
using namespace std;

class Statistics {
private:
vector<double> data;

public:
// Constructor to initialize the dataset
Statistics(const vector<double>& dataset) : data(dataset) {}

// Mean (Average) of the dataset


double mean() {
double sum = 0;
for (double num : data) {
sum += num;
}
return sum / data.size();
}

// Median of the dataset


double median() {
int n = data.size();
sort(data.begin(), data.end());
if (n % 2 == 0) {
return (data[n / 2 - 1] + data[n / 2]) / 2;
} else {
return data[n / 2];
}
}

// Mode of the dataset (most frequent number)


vector<double> mode() {
unordered_map<double, int> frequency;
for (double num : data) {
frequency[num]++;
}

int maxFreq = 0;
for (const auto& pair : frequency) {
maxFreq = max(maxFreq, pair.second);
}

vector<double> modes;
for (const auto& pair : frequency) {
if (pair.second == maxFreq) {
modes.push_back(pair.first);
}
}

return modes;
}

// Variance of the dataset


double variance() {
double m = mean();
double sumSquaredDiffs = 0;
for (double num : data) {
sumSquaredDiffs += pow(num - m, 2);
}
return sumSquaredDiffs / data.size();
}

// Standard deviation of the dataset


double standardDeviation() {
return sqrt(variance());
}

// Display the dataset


void displayData() {
for (double num : data) {
cout << num << " ";
}
cout << endl;
}
};
int main() {
// Example dataset
vector<double> dataset = {1.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0, 6.0};

// Create Statistics object


Statistics stats(dataset);

// Display the dataset


cout << "Dataset: ";
stats.displayData();

// Compute and display statistics


cout << "Mean: " << stats.mean() << endl;
cout << "Median: " << stats.median() << endl;

vector<double> modes = stats.mode();


cout << "Mode: ";
for (double mode : modes) {
cout << mode << " ";
}
cout << endl;

cout << "Variance: " << stats.variance() << endl;


cout << "Standard Deviation: " << stats.standardDeviation() << endl;

return 0;
}

7. Prime Number Generator: Create a class that generates prime numbers and checks for the
primality of given integers.

#include <iostream>
#include <cmath>
#include <vector>
using namespace std;

class PrimeNumberGenerator {
public:
// Function to check if a given number is prime
bool isPrime(int num) {
if (num <= 1) return false; // 0 and 1 are not prime numbers
if (num == 2) return true; // 2 is the only even prime number
if (num % 2 == 0) return false; // Other even numbers are not prime
int limit = sqrt(num);
for (int i = 3; i <= limit; i += 2) {
if (num % i == 0) return false;
}
return true;
}

// Function to generate prime numbers up to a given limit


vector<int> generatePrimes(int limit) {
vector<int> primes;
for (int i = 2; i <= limit; ++i) {
if (isPrime(i)) {
primes.push_back(i);
}
}
return primes;
}
};

int main() {
// Create a PrimeNumberGenerator object
PrimeNumberGenerator primeGen;

// Check if a number is prime


int num = 29;
if (primeGen.isPrime(num)) {
cout << num << " is a prime number." << endl;
} else {
cout << num << " is not a prime number." << endl;
}

// Generate prime numbers up to a given limit


int limit = 50;
vector<int> primes = primeGen.generatePrimes(limit);

cout << "Prime numbers up to " << limit << ": ";
for (int prime : primes) {
cout << prime << " ";
}
cout << endl;

return 0;
}

8. Root Finding Tool: Implement the Newton-Raphson and bisection methods for finding the roots
of functions.
#include <iostream>
#include <cmath>
#include <functional>
#include <limits>
using namespace std;

class RootFinder {
public:
// Newton-Raphson method to find the root of a function
double newtonRaphson(function<double(double)> f, function<double(double)> df, double
initialGuess, double tolerance = 1e-6, int maxIterations = 100) {
double x = initialGuess;
int iterations = 0;
while (iterations < maxIterations) {
double fx = f(x);
double dfx = df(x);

if (fabs(fx) < tolerance) {


cout << "Newton-Raphson converged in " << iterations << " iterations." << endl;
return x;
}

if (fabs(dfx) < tolerance) {


cout << "Derivative is close to zero. Newton-Raphson method may fail." << endl;
break;
}

x = x - fx / dfx;
iterations++;
}
cout << "Newton-Raphson method did not converge within the maximum iterations." << endl;
return x; // return the current estimate if it didn't converge
}

// Bisection method to find the root of a function


double bisection(function<double(double)> f, double a, double b, double tolerance = 1e-6, int
maxIterations = 100) {
if (f(a) * f(b) > 0) {
cout << "The Bisection method requires f(a) and f(b) to have opposite signs." << endl;
return std::numeric_limits<double>::quiet_NaN(); // Return NaN if the method can't
proceed
}

double c = a;
int iterations = 0;
while ((b - a) / 2 > tolerance && iterations < maxIterations) {
c = (a + b) / 2;
if (f(c) == 0.0) {
break; // Found exact root
}

if (f(c) * f(a) < 0) {


b = c; // Root is in the left half
} else {
a = c; // Root is in the right half
}

iterations++;
}

cout << "Bisection method converged in " << iterations << " iterations." << endl;
return c; // return the root estimate
}
};

int main() {
// Define a function and its derivative for Newton-Raphson
auto f = [](double x) { return x*x - 4; }; // Example function f(x) = x^2 - 4
auto df = [](double x) { return 2*x; }; // Derivative f'(x) = 2x

// Create RootFinder object


RootFinder rootFinder;

// Apply Newton-Raphson method


double initialGuess = 1.0;
double root_NR = rootFinder.newtonRaphson(f, df, initialGuess);
cout << "Root found by Newton-Raphson: " << root_NR << endl;

// Apply Bisection method


double a = 0.0, b = 3.0;
double root_Bisection = rootFinder.bisection(f, a, b);
cout << "Root found by Bisection: " << root_Bisection << endl;

return 0;
}

9. Linear Regression Model: Build a class to fit and evaluate a linear regression model on input
data points.

#include <iostream>
#include <vector>
#include <cmath>
#include <limits>
using namespace std;

class LinearRegression {
private:
double slope; // The slope (m) of the regression line
double intercept; // The intercept (b) of the regression line

public:
// Constructor initializes slope and intercept to zero
LinearRegression() : slope(0), intercept(0) {}

// Fit the linear regression model to the data (using the least squares method)
void fit(const vector<double>& x, const vector<double>& y) {
if (x.size() != y.size() || x.empty()) {
cerr << "Error: x and y vectors must have the same size and cannot be empty." << endl;
return;
}

double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;


int n = x.size();

// Calculate the sums required for the least squares formula


for (int i = 0; i < n; ++i) {
sumX += x[i];
sumY += y[i];
sumXY += x[i] * y[i];
sumX2 += x[i] * x[i];
}

// Calculate the slope (m) and intercept (b)


slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
intercept = (sumY - slope * sumX) / n;
}

// Predict the value of y given an x value


double predict(double x) {
return slope * x + intercept;
}

// Calculate Mean Squared Error (MSE) for the predictions


double meanSquaredError(const vector<double>& x, const vector<double>& y) {
double mse = 0;
for (int i = 0; i < x.size(); ++i) {
double predicted = predict(x[i]);
mse += (predicted - y[i]) * (predicted - y[i]);
}
return mse / x.size();
}
// Calculate R-squared (coefficient of determination)
double rSquared(const vector<double>& x, const vector<double>& y) {
double meanY = 0;
for (double yi : y) {
meanY += yi;
}
meanY /= y.size();

double totalSumOfSquares = 0, residualSumOfSquares = 0;


for (int i = 0; i < x.size(); ++i) {
double predicted = predict(x[i]);
totalSumOfSquares += (y[i] - meanY) * (y[i] - meanY);
residualSumOfSquares += (y[i] - predicted) * (y[i] - predicted);
}

return 1 - (residualSumOfSquares / totalSumOfSquares);


}

// Display the model coefficients (slope and intercept)


void displayModel() {
cout << "Linear Regression Model: y = " << slope << "x + " << intercept << endl;
}
};

int main() {
// Example data: x (independent variable), y (dependent variable)
vector<double> x = {1, 2, 3, 4, 5};
vector<double> y = {1, 2, 1.9, 4.1, 5.2};

// Create LinearRegression object


LinearRegression model;

// Fit the model to the data


model.fit(x, y);

// Display the model parameters


model.displayModel();

// Predict for a new x value


double newX = 6;
cout << "Predicted y for x = " << newX << ": " << model.predict(newX) << endl;

// Evaluate the model with Mean Squared Error and R-squared


double mse = model.meanSquaredError(x, y);
double r2 = model.rSquared(x, y);

cout << "Mean Squared Error (MSE): " << mse << endl;
cout << "R-squared: " << r2 << endl;

return 0;
}

10. Numerical Integration: Create a class to compute definite integrals using methods like
Trapezoidal and Simpson’s rule.

#include <iostream>
#include <cmath>
#include <functional>

class NumericalIntegration {
public:
// Trapezoidal Rule Method
static double trapezoidalRule(std::function<double(double)> f, double a, double b, int n) {
double h = (b - a) / n;
double sum = (f(a) + f(b)) / 2.0;

for (int i = 1; i < n; i++) {


sum += f(a + i * h);
}

return sum * h;
}

// Simpson's Rule Method


static double simpsonsRule(std::function<double(double)> f, double a, double b, int n) {
if (n % 2 == 1) n++; // Simpson's rule requires an even number of subintervals

double h = (b - a) / n;
double sum = f(a) + f(b);

for (int i = 1; i < n; i += 2) {


sum += 4 * f(a + i * h);
}

for (int i = 2; i < n - 1; i += 2) {


sum += 2 * f(a + i * h);
}

return sum * h / 3.0;


}
};
int main() {
// Example function to integrate: f(x) = x^2
auto func = [](double x) -> double {
return x * x;
};

double a = 0.0; // Lower bound of integration


double b = 2.0; // Upper bound of integration
int n = 1000; // Number of intervals

// Using Trapezoidal Rule


double trapezoidalResult = NumericalIntegration::trapezoidalRule(func, a, b, n);
std::cout << "Trapezoidal Rule Result: " << trapezoidalResult << std::endl;

// Using Simpson's Rule


double simpsonsResult = NumericalIntegration::simpsonsRule(func, a, b, n);
std::cout << "Simpson's Rule Result: " << simpsonsResult << std::endl;

return 0;
}

You might also like