openGPMP
Open Source Mathematics Package
differential.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  *
3  * Project
4  * _____ _____ __ __ _____
5  * / ____| __ \| \/ | __ \
6  * ___ _ __ ___ _ __ | | __| |__) | \ / | |__) |
7  * / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/
8  *| (_) | |_) | __/ | | | |__| | | | | | | |
9  * \___/| .__/ \___|_| |_|\_____|_| |_| |_|_|
10  * | |
11  * |_|
12  *
13  * Copyright (C) Akiel Aries, <akiel@akiel.org>, et al.
14  *
15  * This software is licensed as described in the file LICENSE, which
16  * you should have received as part of this distribution. The terms
17  * among other details are referenced in the official documentation
18  * seen here : https://akielaries.github.io/openGPMP/ along with
19  * important files seen in this project.
20  *
21  * You may opt to use, copy, modify, merge, publish, distribute
22  * and/or sell copies of the Software, and permit persons to whom
23  * the Software is furnished to do so, under the terms of the
24  * LICENSE file.
25  *
26  *
27  *
28  * This software is distributed on an AS IS basis, WITHOUT
29  * WARRANTY OF ANY KIND, either express or implied.
30  *
31  ************************************************************************/
32 
33 /*
34  * Implementing various derivative related functions in C++
35  */
36 #include <algorithm>
37 #include <cmath>
38 #include <cstdlib>
39 #include <iostream>
41 #include <sstream>
42 #include <stdio.h>
43 #include <string>
44 
45 void gpmp::Differential::add_term(double coefficient, int exponent) {
46  terms.emplace_back(coefficient, exponent);
47 }
48 
50  for (size_t i = 0; i < terms.size(); ++i) {
51  const auto &term = terms[i];
52  if (term.exponent > 1) {
53  std::cout << term.coefficient << "*x^" << term.exponent;
54  } else if (term.exponent == 1) {
55  std::cout << term.coefficient << "*x";
56  } else {
57  std::cout << term.coefficient;
58  }
59 
60  if (i < terms.size() - 1) {
61  std::cout << " + ";
62  }
63  }
64  std::cout << std::endl;
65 }
66 
68  gpmp::Differential result;
69  for (const auto &term : terms) {
70  if (term.exponent > 0) {
71  double new_coefficient = term.coefficient * term.exponent;
72  int new_exponent = term.exponent - 1;
73  result.add_term(new_coefficient, new_exponent);
74  }
75  }
76  return result;
77 }
78 
81  gpmp::Differential result;
82 
83  for (const auto &outer_term : terms) {
84  // Apply the chain rule to each term of the outer function
85  gpmp::Differential inner_derivative = inner.power_rule();
86 
87  // Multiply each term of inner_derivative by the coefficient of the
88  // outer term
89  for (auto &inner_term : inner_derivative.terms) {
90  inner_term.coefficient *= outer_term.coefficient;
91  }
92 
93  // Multiply the inner derivative by the derivative of the outer term
94  for (const auto &inner_term : inner_derivative.terms) {
95  double new_coefficient = inner_term.coefficient;
96  int new_exponent = outer_term.exponent + inner_term.exponent;
97  result.add_term(new_coefficient, new_exponent);
98  }
99  }
100 
101  return result;
102 }
103 
105  gpmp::Differential result = *this;
106  for (int i = 0; i < n; ++i) {
107  result = result.power_rule();
108  }
109  return result;
110 }
111 
112 double gpmp::Differential::eval(double x) const {
113  double result = 0.0;
114  for (const auto &term : terms) {
115  result += term.coefficient * std::pow(x, term.exponent);
116  }
117  return result;
118 }
119 
120 double gpmp::Differential::limit_at(double x) const {
121  double result = 0.0;
122 
123  for (const auto &term : terms) {
124  result += term.coefficient * std::pow(x, term.exponent);
125  }
126 
127  return result;
128 }
129 
131  // Calculate the limit as x approaches infinity using the highest exponent
132  // term
133  if (!terms.empty()) {
134  const auto &highest_term =
135  *std::max_element(terms.begin(),
136  terms.end(),
137  [](const auto &a, const auto &b) {
138  return a.exponent < b.exponent;
139  });
140 
141  if (highest_term.exponent > 0) {
142  // If the highest term has a positive exponent, the limit is
143  // infinity or negative infinity
144  return (highest_term.coefficient > 0)
145  ? std::numeric_limits<double>::infinity()
146  : -std::numeric_limits<double>::infinity();
147  } else {
148  // If the highest term has a zero exponent, the limit is the
149  // constant term
150  return highest_term.coefficient;
151  }
152  }
153 
154  // If the differential is empty, the limit is undefined
155  return std::numeric_limits<double>::quiet_NaN();
156 }
Calculus Class with methods pertaining to basic operations.
double limit_at_infinity() const
Calculate the limit of the polynomial as x approaches infinity.
Differential power_rule() const
Computes the derivative using the power rule.
double limit_at(double x) const
Calculate the limit of the polynomial at a specific point.
void add_term(double coefficient, int exponent)
Adds a term to the Differential object.
Differential chain_rule(const Differential &inner) const
Computes the derivative using the chain rule.
void display() const
Displays the polynomial in a readable format.
std::vector< Term > terms
Differential nth_derivative(int n) const
Computes the nth derivative of the current Differential object.
double eval(double x) const
Evaluates the polynomial for a given value of x.