diff --git a/lectures/week6/struct-classes.pdf b/lectures/week6/struct-classes.pdf index ea6f509..d9d10f4 100644 Binary files a/lectures/week6/struct-classes.pdf and b/lectures/week6/struct-classes.pdf differ diff --git a/lectures/week7/code_snippets/CMakeLists.txt b/lectures/week7/code_snippets/CMakeLists.txt new file mode 100644 index 0000000..610d3a2 --- /dev/null +++ b/lectures/week7/code_snippets/CMakeLists.txt @@ -0,0 +1,12 @@ + +cmake_minimum_required(VERSION 2.6) +project(snippet) + +set(CMAKE_CXX_STANDARD 14) + +file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/*.cpp) +foreach(f ${SOURCES}) + get_filename_component(basename ${f} NAME_WE) + get_filename_component(dir ${f} DIRECTORY) + add_executable(${basename} ${f}) +endforeach() diff --git a/lectures/week7/code_snippets/abstract_class.hh b/lectures/week7/code_snippets/abstract_class.hh new file mode 100644 index 0000000..e1c6008 --- /dev/null +++ b/lectures/week7/code_snippets/abstract_class.hh @@ -0,0 +1,30 @@ +#include +class Animal { + +public: + Animal(std::string name) { this->name = name; } + virtual void scream() = 0; + +protected: + std::string name; +}; + +class Cat : public Animal { + +public: + Cat(const std::string &name) : Animal(name){}; + void scream() override { std::cout << name << ": MIAOU\n"; } +}; + +void makeItScream(Animal &a) { a.scream(); } + +int main() { + // this will lead to compilation error + Animal a("kitty"); + + Cat c("kitty"); // ok + Animal *ptr = &c; // ok + Animal &ref = c; // ok + + makeItScream(c); // ok +} \ No newline at end of file diff --git a/lectures/week7/code_snippets/animal.hh b/lectures/week7/code_snippets/animal.hh new file mode 100644 index 0000000..3073c5d --- /dev/null +++ b/lectures/week7/code_snippets/animal.hh @@ -0,0 +1,13 @@ +#include + +class Animal { + +public: + void scream() { + std::cout << name; + std::cout << ": AAAAAAA" << std::endl; + } + +private: + std::string name; +}; \ No newline at end of file diff --git a/lectures/week7/code_snippets/calling_mother.hh b/lectures/week7/code_snippets/calling_mother.hh new file mode 100644 index 0000000..bd59537 --- /dev/null +++ b/lectures/week7/code_snippets/calling_mother.hh @@ -0,0 +1,21 @@ +#include +class Animal { + +public: + Animal(const std::string &name) { this->name = name; } + virtual void scream() { std::cout << name << ": AAAAA" << std::endl; } + +protected: + std::string name; +}; + +class Dog : public Animal { + +public: + Dog(std::string &name) : Animal(name) {} + + void scream() override { + Animal::scream(); + std::cout << name << ": OUAFF" << std::endl; + } +}; \ No newline at end of file diff --git a/lectures/week7/code_snippets/cat_dog.hh b/lectures/week7/code_snippets/cat_dog.hh new file mode 100644 index 0000000..f61bfed --- /dev/null +++ b/lectures/week7/code_snippets/cat_dog.hh @@ -0,0 +1,25 @@ +#include + +class Cat { +public: + void scream() { std::cout << name << ": MIAOU\n"; } + +private: + std::string name; +}; + +class Dog { +public: + void scream() { std::cout << name << ": OUAFF\n"; } + +private: + std::string name; +}; + +int cannot_write() { + Cat list[2]; + Cat c; + Dog d; + list[0] = c; + list[1] = d; +} \ No newline at end of file diff --git a/lectures/week7/code_snippets/override.hpp b/lectures/week7/code_snippets/override.hpp new file mode 100644 index 0000000..3d5aafe --- /dev/null +++ b/lectures/week7/code_snippets/override.hpp @@ -0,0 +1,17 @@ +#include + +class Animal { +public: + virtual void scream() { std::cout << name << ": AAAAA\n"; } + +protected: + std::string name; +}; + +class Dog : public Animal { +public: + void scream() override { + Animal::scream(); + std::cout << name << ": OUAFF\n"; + } +}; \ No newline at end of file diff --git a/lectures/week7/code_snippets/type_casting.cpp b/lectures/week7/code_snippets/type_casting.cpp new file mode 100644 index 0000000..85d6e33 --- /dev/null +++ b/lectures/week7/code_snippets/type_casting.cpp @@ -0,0 +1,35 @@ +#include +class Animal { +public: + void scream() { std::cout << name << ": AAAAA\n"; } + +protected: + std::string name; +}; + +class Cat : public Animal { +public: + void scream() { std::cout << name << ": MIAOU\n"; } +}; + +class Dog : public Animal { +public: + void scream() { std::cout << name << ": OUAFF\n"; } +}; + +void casting() { + Cat c; + Animal *ptr = &c; + ptr->scream(); +} + +void makeItScream(Animal &a) { + // do not know if 'a' + // is Cat or Dog + a.scream(); +} + +int main() { + Cat c; + makeItScream(c); +} \ No newline at end of file diff --git a/lectures/week7/inheritance-classes.pdf b/lectures/week7/inheritance-classes.pdf new file mode 100644 index 0000000..bcdd1bc Binary files /dev/null and b/lectures/week7/inheritance-classes.pdf differ diff --git a/lectures/week8/code_snippets/CMakeLists.txt b/lectures/week8/code_snippets/CMakeLists.txt new file mode 100644 index 0000000..610d3a2 --- /dev/null +++ b/lectures/week8/code_snippets/CMakeLists.txt @@ -0,0 +1,12 @@ + +cmake_minimum_required(VERSION 2.6) +project(snippet) + +set(CMAKE_CXX_STANDARD 14) + +file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/*.cpp) +foreach(f ${SOURCES}) + get_filename_component(basename ${f} NAME_WE) + get_filename_component(dir ${f} DIRECTORY) + add_executable(${basename} ${f}) +endforeach() diff --git a/lectures/week8/code_snippets/arithmetic_series.cpp b/lectures/week8/code_snippets/arithmetic_series.cpp new file mode 100644 index 0000000..3068f40 --- /dev/null +++ b/lectures/week8/code_snippets/arithmetic_series.cpp @@ -0,0 +1,13 @@ +#include + +int arithmetic(int i) { + if (i == 1) + return 1; + return i + arithmetic(i - 1); +} + +int main() { + int a = 5; + std::cout << arithmetic(a); + std::cout << std::endl; +} \ No newline at end of file diff --git a/lectures/week8/code_snippets/arithmetic_series_meta_programming.cpp b/lectures/week8/code_snippets/arithmetic_series_meta_programming.cpp new file mode 100644 index 0000000..099064e --- /dev/null +++ b/lectures/week8/code_snippets/arithmetic_series_meta_programming.cpp @@ -0,0 +1,15 @@ +#include + +template int arithmetic_template() { + return i + arithmetic_template(); +} + +template <> int arithmetic_template<1>() { + // ends recursion + return 1; +} + +int main() { + std::cout << arithmetic_template<5>(); + std::cout << std::endl; +} \ No newline at end of file diff --git a/lectures/week8/code_snippets/get_maximum.cpp b/lectures/week8/code_snippets/get_maximum.cpp new file mode 100644 index 0000000..f228ef5 --- /dev/null +++ b/lectures/week8/code_snippets/get_maximum.cpp @@ -0,0 +1,17 @@ +int getMaximum(const int &a, const int &b) { + if (a > b) + return a; + return b; +} +double getMaximum(const double &a, const double &b) { + if (a > b) + return a; + return b; +} + +int main() { + double a, b; + double res_d = getMaximum(a, b); + int c, d; + int res_i = getMaximum(c, d); +} \ No newline at end of file diff --git a/lectures/week8/code_snippets/get_maximum_template.cpp b/lectures/week8/code_snippets/get_maximum_template.cpp new file mode 100644 index 0000000..1812171 --- /dev/null +++ b/lectures/week8/code_snippets/get_maximum_template.cpp @@ -0,0 +1,13 @@ +template +T getMaximum(const T & a, const T & b) { + if (a > b) + return a; + return b; +} + +int main(){ + double a,b; + double res_d = getMaximum(a,b); + int c,d; + int res_i = getMaximum(c,d); +} \ No newline at end of file diff --git a/lectures/week8/code_snippets/my_vector_ostream.cpp b/lectures/week8/code_snippets/my_vector_ostream.cpp new file mode 100644 index 0000000..8542e76 --- /dev/null +++ b/lectures/week8/code_snippets/my_vector_ostream.cpp @@ -0,0 +1,24 @@ +#include "myvector_template_dim.hh" +#include +#include + +// function to print in an ostream +template +std::ostream &operator<<(std::ostream &stream, const MyVector &vect) { + stream << "["; + for (int d = 0; d < dim; ++d) { + if (d != 0) + stream << ", "; + stream << vect[d]; + } + stream << "]"; + return stream; +} + +int main() { + // using it + MyVector vector_3d; + + // template parameters are guessed by the compiler + std::cout << vector_3d << std::endl; +} \ No newline at end of file diff --git a/lectures/week8/code_snippets/myvector_template.hh b/lectures/week8/code_snippets/myvector_template.hh new file mode 100644 index 0000000..6a67b23 --- /dev/null +++ b/lectures/week8/code_snippets/myvector_template.hh @@ -0,0 +1,11 @@ +// a generic Vector for any scalar type +template class MyVector { +public: + T &operator[](unsigned int dim) { return value[dim]; } + +private: + T value[3]; +}; + +MyVector real_vector; +MyVector integer_vector; \ No newline at end of file diff --git a/lectures/week8/code_snippets/myvector_template_dim.hh b/lectures/week8/code_snippets/myvector_template_dim.hh new file mode 100644 index 0000000..f1e6095 --- /dev/null +++ b/lectures/week8/code_snippets/myvector_template_dim.hh @@ -0,0 +1,15 @@ +// a generic Vector for any scalar type +// template dimension (default: 3) +template class MyVector { + +public: + T &operator[](unsigned int d) { return value[d]; } + + const T &operator[](unsigned int d) const { return value[d]; } + +private: + T value[dim]; +}; + +MyVector vector_3d; +MyVector vector_2d; \ No newline at end of file diff --git a/lectures/week8/code_snippets/scalar_product.cpp b/lectures/week8/code_snippets/scalar_product.cpp new file mode 100644 index 0000000..9078afe --- /dev/null +++ b/lectures/week8/code_snippets/scalar_product.cpp @@ -0,0 +1,23 @@ +#include "myvector_template_dim.hh" +#include + +// function to make the scalar product between to vectors +template +T scalarProduct(const MyVector &v1, // vector1 + const MyVector &v2 // vector2 +) { + + T res; + for (int d = 0; d < dim; ++d) + res += v1[d] * v2[d]; + return res; +} + +int main() { + // using it + MyVector vector1_3d; + MyVector vector2_3d; + + double res = scalarProduct(vector1_3d, vector2_3d); + std::cout << res << std::endl; +} \ No newline at end of file diff --git a/lectures/week8/code_snippets/specialization_vector.cpp b/lectures/week8/code_snippets/specialization_vector.cpp new file mode 100644 index 0000000..277e3a4 --- /dev/null +++ b/lectures/week8/code_snippets/specialization_vector.cpp @@ -0,0 +1,37 @@ +#include "myvector_template_dim.hh" + +template T getMaximum(const T &a, const T &b) { + if (a > b) + return a; + return b; +} + +// specialization for vectors +template <> +MyVector +getMaximum>(const MyVector &v1, + const MyVector &v2) { + + MyVector max; + for (int i = 0; i < 3; ++i) { + max[i] = getMaximum(v1[i], v2[i]); + } + return max; +} + +// overloading +template +MyVector getMaximum(const MyVector &v1, + const MyVector &v2) { + + MyVector max; + for (int i = 0; i < dim; ++i) { + max[i] = getMaximum(v1[i], v2[i]); + } + return max; +} + +int main() { + MyVector v1, v2; + MyVector res = getMaximum(v1, v2); +} \ No newline at end of file diff --git a/lectures/week8/code_snippets/variadic_template.cpp b/lectures/week8/code_snippets/variadic_template.cpp new file mode 100644 index 0000000..34f9d17 --- /dev/null +++ b/lectures/week8/code_snippets/variadic_template.cpp @@ -0,0 +1,16 @@ +#include + +template T adder(T v) { return v; } + +template +// template ...Args is a variadic template +T adder(T first, Args... args) { + return first + adder(args...); +} + +int main() { + std::cout << adder(1, 2, 3, 4); + std::cout << adder(1., 2, 3., 4); + std::cout << adder(std::string("a"), std::string("b")); + std::cout << std::endl; +} \ No newline at end of file diff --git a/lectures/week8/template.pdf b/lectures/week8/template.pdf new file mode 100644 index 0000000..8802d8c Binary files /dev/null and b/lectures/week8/template.pdf differ diff --git a/solutions/CMakeLists.txt b/solutions/CMakeLists.txt index dcc7b78..91cf5cc 100644 --- a/solutions/CMakeLists.txt +++ b/solutions/CMakeLists.txt @@ -1,7 +1,9 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(chapter-01) add_subdirectory(chapter-02) add_subdirectory(chapter-03) add_subdirectory(chapter-04) add_subdirectory(chapter-05) +add_subdirectory(chapter-06) +add_subdirectory(chapter-07) diff --git a/solutions/chapter-06/CMakeLists.txt b/solutions/chapter-06/CMakeLists.txt new file mode 100644 index 0000000..6c16bf5 --- /dev/null +++ b/solutions/chapter-06/CMakeLists.txt @@ -0,0 +1,14 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +# The next lines represent a list of all the executables in the folder (chapter) +# There is typically one executable per exercise. +# As you solve exercises, you need to add them here. +# The syntax is add_executable(executable_name source_file_name) + +add_executable(ch-06-ex-01-solution ch-06-ex-01-solution.cpp + ComplexMatrix3x3.cpp ComplexNumber.cpp) +add_executable(ch-06-ex-02-solution ch-06-ex-02-solution.cpp + DoubleMatrix2x2.cpp) +add_executable(test_complex_numbers test_complex_numbers.cpp + ComplexNumber.cpp) + \ No newline at end of file diff --git a/solutions/chapter-06/ComplexMatrix3x3.cpp b/solutions/chapter-06/ComplexMatrix3x3.cpp new file mode 100644 index 0000000..d56ebf6 --- /dev/null +++ b/solutions/chapter-06/ComplexMatrix3x3.cpp @@ -0,0 +1,160 @@ +/* + * ComplexMatrix3x3.cpp + * + * Created on: Oct 19, 2012 + * Author: rpopescu + */ + +#include "ComplexMatrix3x3.hpp" + +ComplexMatrix3x3::ComplexMatrix3x3() { + mMatrix = new ComplexNumber *[3]; + for (int i = 0; i < 3; ++i) { + mMatrix[i] = new ComplexNumber[3]; + for (int j = 0; j < 3; ++j) { + mMatrix[i][j] = 0; + } + } +} + +ComplexMatrix3x3::ComplexMatrix3x3(const ComplexMatrix3x3 &m) + : mMatrix(new ComplexNumber *[3]) { + for (int i = 0; i < 3; ++i) { + mMatrix[i] = new ComplexNumber[3]; + for (int j = 0; j < 3; ++j) { + mMatrix[i][j] = m.Get(i, j); + } + } +} + +ComplexMatrix3x3::~ComplexMatrix3x3() { + for (int i = 0; i < 3; ++i) { + delete[] mMatrix[i]; + } + delete[] mMatrix; +} + +ComplexNumber ComplexMatrix3x3::Get(const int i, const int j) const { + return mMatrix[i][j]; +} + +void ComplexMatrix3x3::Set(const int i, const int j, + const ComplexNumber &value) { + mMatrix[i][j] = value; +} + +bool ComplexMatrix3x3::IsZero() const { + double tol = 1e-10; + bool isZero = true; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + if ((mMatrix[i][j].GetRealPart() > tol) || + (mMatrix[i][j].GetImaginaryPart() > tol)) { + isZero = false; + } + } + } + + return isZero; +} + +ComplexMatrix3x3 ComplexMatrix3x3::PowerOverFact(const int n) const { + ComplexMatrix3x3 t(*this); + + for (int i = 1; i <= n; ++i) { + t = t * (*this) * (1.0 / i); + } + + return t; +} + +void ComplexMatrix3x3::Exponential(ComplexMatrix3x3 &E, const int power) const { + + if (power == 0) { + // Should it return 1 or I_3 ? + E.Set(0, 0, 1); + E.Set(1, 1, 1); + E.Set(2, 2, 1); + return; + } + if (IsZero()) { + // The empty constructor initializes to 0 so the next line is not + // needed in this case; I'm returning 0_3, not scalar 0 + /// E = ComplexMatrix3x3(); + } + + // Could also compute this like: + // E = 1 + A (1 + A/2 (1 + A/3 (1 + A/4 ..... + // const ComplexMatrix3x3& A(*this); + for (int i = 1; i <= power; ++i) { + E = E + PowerOverFact(i); + // E = (E * (A * (1.0 / i))) + 1.0; + } +} + +void ComplexMatrix3x3::Print(std::ostream &s) { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + s << mMatrix[i][j] << " "; + } + s << std::endl; + } +} + +ComplexMatrix3x3 &ComplexMatrix3x3::operator=(const ComplexMatrix3x3 &m) { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + mMatrix[i][j] = m.Get(i, j); + } + } + + return *this; +} + +ComplexMatrix3x3 ComplexMatrix3x3::operator*(const double d) const { + ComplexMatrix3x3 t; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + t.Set(i, j, mMatrix[i][j] * d); + } + } + + return t; +} + +ComplexMatrix3x3 ComplexMatrix3x3::operator+(const double d) const { + ComplexMatrix3x3 t; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + t.Set(i, j, mMatrix[i][j] + d); + } + } + + return t; +} + +ComplexMatrix3x3 ComplexMatrix3x3::operator+(const ComplexMatrix3x3 &m) const { + ComplexMatrix3x3 t; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + t.Set(i, j, mMatrix[i][j] + m.Get(i, j)); + } + } + + return t; +} + +ComplexMatrix3x3 ComplexMatrix3x3::operator*(const ComplexMatrix3x3 &m) const { + ComplexMatrix3x3 t; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + ComplexNumber accum(0.0); + for (int k = 0; k < 3; ++k) { + accum = accum + (mMatrix[i][k] * m.Get(k, j)); + } + t.Set(i, j, accum); + } + } + + return t; +} diff --git a/solutions/chapter-06/ComplexMatrix3x3.hpp b/solutions/chapter-06/ComplexMatrix3x3.hpp new file mode 100644 index 0000000..507655a --- /dev/null +++ b/solutions/chapter-06/ComplexMatrix3x3.hpp @@ -0,0 +1,45 @@ +/* + * ComplexMatrix3x3.hpp + * + * Created on: Oct 19, 2012 + * Author: rpopescu + */ + +#ifndef COMPLEXMATRIX3X3_HPP_ +#define COMPLEXMATRIX3X3_HPP_ + +#include + +#include "ComplexNumber.hpp" + +class ComplexMatrix3x3 { +public: + // Constructors and destructor + ComplexMatrix3x3(); + ComplexMatrix3x3(const ComplexMatrix3x3 &m); + virtual ~ComplexMatrix3x3(); + + // Get methods + ComplexNumber Get(const int i, const int j) const; + + // Set methods + void Set(const int i, const int j, const ComplexNumber &value); + + // Public methods + bool IsZero() const; + ComplexMatrix3x3 PowerOverFact(const int n) const; + void Exponential(ComplexMatrix3x3 &E, const int power) const; + void Print(std::ostream &s = std::cout); + + // Operators + ComplexMatrix3x3 &operator=(const ComplexMatrix3x3 &m); + ComplexMatrix3x3 operator*(const double d) const; + ComplexMatrix3x3 operator+(const double d) const; + ComplexMatrix3x3 operator+(const ComplexMatrix3x3 &m) const; + ComplexMatrix3x3 operator*(const ComplexMatrix3x3 &m) const; + +private: + ComplexNumber **mMatrix; +}; + +#endif /* COMPLEXMATRIX3X3_HPP_ */ diff --git a/solutions/chapter-06/ComplexNumber.cpp b/solutions/chapter-06/ComplexNumber.cpp new file mode 100644 index 0000000..5697810 --- /dev/null +++ b/solutions/chapter-06/ComplexNumber.cpp @@ -0,0 +1,126 @@ +#include "ComplexNumber.hpp" + +#include + +// Override default constructor +// Set real and imaginary parts to zero +ComplexNumber::ComplexNumber() { + mRealPart = 0.0; + mImaginaryPart = 0.0; +} + +// Constructor that sets complex number z=x+iy +ComplexNumber::ComplexNumber(double x, double y) { + mRealPart = x; + mImaginaryPart = y; +} + +// Copy constructor +ComplexNumber::ComplexNumber(const ComplexNumber &c) + : mRealPart(c.GetRealPart()), mImaginaryPart(c.GetImaginaryPart()) {} + +// Constructor for number with only real part +ComplexNumber::ComplexNumber(const double d) + : mRealPart(d), mImaginaryPart(0.0) {} + +// Get methods + +double ComplexNumber::GetRealPart() const { return mRealPart; } + +double ComplexNumber::GetImaginaryPart() const { return mImaginaryPart; } + +// Method for computing the modulus of a +// complex number +double ComplexNumber::CalculateModulus() const { + return sqrt(mRealPart * mRealPart + mImaginaryPart * mImaginaryPart); +} + +// Method for computing the argument of a +// complex number +double ComplexNumber::CalculateArgument() const { + return atan2(mImaginaryPart, mRealPart); +} + +// Method for raising complex number to the power n +// using De Moivre’s theorem - first complex +// number must be converted to polar form +ComplexNumber ComplexNumber::CalculatePower(double n) const { + double modulus = CalculateModulus(); + double argument = CalculateArgument(); + double mod_of_result = pow(modulus, n); + double arg_of_result = argument * n; + double real_part = mod_of_result * cos(arg_of_result); + double imag_part = mod_of_result * sin(arg_of_result); + ComplexNumber z(real_part, imag_part); + + return z; +} + +// Computes the complex conjugate +ComplexNumber ComplexNumber::CalculateConjugate() const { + return ComplexNumber(mRealPart, -mImaginaryPart); +} + +void ComplexNumber::SetConjugate() { mImaginaryPart = -mImaginaryPart; } + +// Overloading the = (assignment) operator +ComplexNumber &ComplexNumber::operator=(const ComplexNumber &z) { + mRealPart = z.mRealPart; + mImaginaryPart = z.mImaginaryPart; + return *this; +} + +// Overloading the unary - operator +ComplexNumber ComplexNumber::operator-() const { + ComplexNumber w; + w.mRealPart = -mRealPart; + w.mImaginaryPart = -mImaginaryPart; + return w; +} + +// Overloading the binary + operator +ComplexNumber ComplexNumber::operator+(const ComplexNumber &z) const { + ComplexNumber w; + w.mRealPart = mRealPart + z.mRealPart; + w.mImaginaryPart = mImaginaryPart + z.mImaginaryPart; + return w; +} + +// Overloading the binary - operator +ComplexNumber ComplexNumber::operator-(const ComplexNumber &z) const { + ComplexNumber w; + w.mRealPart = mRealPart - z.mRealPart; + w.mImaginaryPart = mImaginaryPart - z.mImaginaryPart; + return w; +} + +ComplexNumber ComplexNumber::operator*(const double d) const { + ComplexNumber t(mRealPart * d, mImaginaryPart * d); + + return t; +} + +ComplexNumber ComplexNumber::operator*(const ComplexNumber &z) const { + return ComplexNumber( + mRealPart * z.GetRealPart() - mImaginaryPart * z.GetImaginaryPart(), + mImaginaryPart * z.GetRealPart() + mRealPart * z.GetImaginaryPart()); +} + +// Overloading the insertion << operator +std::ostream &operator<<(std::ostream &output, const ComplexNumber &z) { + // Format as "(a + bi)" or as "(a - bi)" + output << "(" << z.mRealPart << " "; + if (z.mImaginaryPart >= 0.0) { + output << "+ " << z.mImaginaryPart << "i)"; + } else { + // z.mImaginaryPart < 0.0 + // Replace + with minus sign + output << "- " << -z.mImaginaryPart << "i)"; + } + + return output; +} + +double RealPart(const ComplexNumber &z) { return z.mRealPart; } + +double ImaginaryPart(const ComplexNumber &z) { return z.mImaginaryPart; } diff --git a/solutions/chapter-06/ComplexNumber.hpp b/solutions/chapter-06/ComplexNumber.hpp new file mode 100644 index 0000000..5fce3d3 --- /dev/null +++ b/solutions/chapter-06/ComplexNumber.hpp @@ -0,0 +1,43 @@ +#ifndef COMPLEXNUMBERHEADERDEF +#define COMPLEXNUMBERHEADERDEF + +#include + +class ComplexNumber { +private: + double mRealPart; + double mImaginaryPart; + +public: + // Constructors + ComplexNumber(); + ComplexNumber(double x, double y); + ComplexNumber(const ComplexNumber &c); + ComplexNumber(const double d); + + // Get methods + double GetRealPart() const; + double GetImaginaryPart() const; + + // Public methods + double CalculateModulus() const; + double CalculateArgument() const; + ComplexNumber CalculatePower(double n) const; + ComplexNumber CalculateConjugate() const; + void SetConjugate(); + + // Operators + ComplexNumber &operator=(const ComplexNumber &z); + ComplexNumber operator-() const; + ComplexNumber operator+(const ComplexNumber &z) const; + ComplexNumber operator-(const ComplexNumber &z) const; + ComplexNumber operator*(const double d) const; + ComplexNumber operator*(const ComplexNumber &z) const; + + // Friend functions + friend std::ostream &operator<<(std::ostream &output, const ComplexNumber &z); + friend double RealPart(const ComplexNumber &z); + friend double ImaginaryPart(const ComplexNumber &z); +}; + +#endif diff --git a/solutions/chapter-06/DoubleMatrix2x2.cpp b/solutions/chapter-06/DoubleMatrix2x2.cpp new file mode 100644 index 0000000..9895f92 --- /dev/null +++ b/solutions/chapter-06/DoubleMatrix2x2.cpp @@ -0,0 +1,88 @@ +/* + * DoubleMatrix2x2.cpp + * + * Created on: Oct 21, 2012 + * Author: radu + */ + +#include "DoubleMatrix2x2.hpp" + +DoubleMatrix2x2::DoubleMatrix2x2() { + mMatrix[0] = 0.0; + mMatrix[1] = 0.0; + mMatrix[2] = 0.0; + mMatrix[3] = 0.0; +} + +DoubleMatrix2x2::~DoubleMatrix2x2() {} + +DoubleMatrix2x2::DoubleMatrix2x2(const double m11, const double m12, + const double m21, const double m22) { + mMatrix[0] = m11; + mMatrix[1] = m12; + mMatrix[2] = m21; + mMatrix[3] = m22; +} + +DoubleMatrix2x2::DoubleMatrix2x2(const DoubleMatrix2x2 &m) { + mMatrix[0] = m.Get(0, 0); + mMatrix[1] = m.Get(0, 1); + mMatrix[2] = m.Get(1, 0); + mMatrix[3] = m.Get(1, 1); +} + +double DoubleMatrix2x2::Get(const int i, const int j) const { + return mMatrix[2 * i + j]; +} + +double DoubleMatrix2x2::Determinant() const { + return mMatrix[0] * mMatrix[3] - mMatrix[1] * mMatrix[2]; +} + +DoubleMatrix2x2 DoubleMatrix2x2::Inverse() const { + double det = Determinant(); + if (det == 0) { + std::cout << "The determinant is 0. Returning an zero matrix" << std::endl; + return DoubleMatrix2x2(); + } else { + return DoubleMatrix2x2(Get(1, 1) / det, -Get(0, 1) / det, -Get(1, 0) / det, + Get(0, 0) / det); + } +} + +DoubleMatrix2x2 &DoubleMatrix2x2::operator=(const DoubleMatrix2x2 &m) { + mMatrix[0] = m.Get(0, 0); + mMatrix[1] = m.Get(0, 1); + mMatrix[2] = m.Get(1, 0); + mMatrix[3] = m.Get(1, 1); + + return *this; +} + +DoubleMatrix2x2 DoubleMatrix2x2::operator-() const { + return DoubleMatrix2x2(-mMatrix[0], -mMatrix[1], -mMatrix[2], -mMatrix[3]); +} + +DoubleMatrix2x2 DoubleMatrix2x2::operator+(const DoubleMatrix2x2 &m) const { + return DoubleMatrix2x2(mMatrix[0] + m.Get(0, 0), mMatrix[1] + m.Get(0, 1), + mMatrix[2] + m.Get(1, 0), mMatrix[3] + m.Get(1, 1)); +} + +DoubleMatrix2x2 DoubleMatrix2x2::operator-(const DoubleMatrix2x2 &m) const { + return DoubleMatrix2x2(mMatrix[0] - m.Get(0, 0), mMatrix[1] - m.Get(0, 1), + mMatrix[2] - m.Get(1, 0), mMatrix[3] - m.Get(1, 1)); +} + +void DoubleMatrix2x2::Multiply(const double d) { + mMatrix[0] *= d; + mMatrix[1] *= d; + mMatrix[2] *= d; + mMatrix[3] *= d; +} + +std::ostream &operator<<(std::ostream &output, const DoubleMatrix2x2 &m) { + output << m.mMatrix[0] << " " << m.mMatrix[1] << std::endl; + output << m.mMatrix[2] << " " << m.mMatrix[3]; + + return output; +} diff --git a/solutions/chapter-06/DoubleMatrix2x2.hpp b/solutions/chapter-06/DoubleMatrix2x2.hpp new file mode 100644 index 0000000..d090b1a --- /dev/null +++ b/solutions/chapter-06/DoubleMatrix2x2.hpp @@ -0,0 +1,53 @@ +/* + * DoubleMatrix2x2.hpp + * + * Created on: Oct 21, 2012 + * Author: radu + */ + +#ifndef DOUBLEMATRIX2X2_HPP_ +#define DOUBLEMATRIX2X2_HPP_ + +#include + +class DoubleMatrix2x2 { +public: + // Empty constructor + DoubleMatrix2x2(); + + // Alternate constructor + DoubleMatrix2x2(const double m11, const double m12, const double m21, + const double m22); + + // Copy constructor + DoubleMatrix2x2(const DoubleMatrix2x2 &m); + + // Destructor + virtual ~DoubleMatrix2x2(); + + // Get methods + double Get(const int i, const int j) const; + + // Operators + DoubleMatrix2x2 &operator=(const DoubleMatrix2x2 &m); + DoubleMatrix2x2 operator-() const; + DoubleMatrix2x2 operator+(const DoubleMatrix2x2 &m) const; + DoubleMatrix2x2 operator-(const DoubleMatrix2x2 &m) const; + + // Other public methods + void Multiply(const double d); + double Determinant() const; + DoubleMatrix2x2 Inverse() const; + + // Friends + friend std::ostream &operator<<(std::ostream &output, + const DoubleMatrix2x2 &z); + +private: + // Private data members + // We can store the data members as a 1D array: + // M[i][j] = mMatrix[2 * i + j] + double mMatrix[4]; +}; + +#endif /* DOUBLEMATRIX2X2_HPP_ */ diff --git a/solutions/chapter-06/ch-06-ex-01-solution.cpp b/solutions/chapter-06/ch-06-ex-01-solution.cpp new file mode 100644 index 0000000..e4f6dec --- /dev/null +++ b/solutions/chapter-06/ch-06-ex-01-solution.cpp @@ -0,0 +1,35 @@ +/* + * chapter-06-exercise-01.cpp + * + * Complex matrix exponential + * + * Created on: Oct 18, 2012 + * Author: Radu Popescu + */ + +#include + +#include "ComplexMatrix3x3.hpp" + +int main(int argc, char *argv[]) { + // Allocate matrix A + ComplexMatrix3x3 A; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + A.Set(i, j, ComplexNumber(i, j)); + } + } + + // Calculate the exponential + ComplexMatrix3x3 E; + // There is a bug. Result doesn't correspond to Matlab + A.Exponential(E, 1000); + + std::cout << "The matrix A is: \n"; + A.Print(std::cout); + std::cout << "Exponential matrix is: \n"; + E.Print(std::cout); + std::cout << std::endl; + + return 0; +} diff --git a/solutions/chapter-06/ch-06-ex-02-solution.cpp b/solutions/chapter-06/ch-06-ex-02-solution.cpp new file mode 100644 index 0000000..fc8c2ca --- /dev/null +++ b/solutions/chapter-06/ch-06-ex-02-solution.cpp @@ -0,0 +1,47 @@ +/* + * chapter-06-exercise-02.cpp + * + * Test for class of 2x2 double precision matrix + * + * Created on: Oct 21, 2012 + * Author: Radu Popescu + */ + +#include + +#include "DoubleMatrix2x2.hpp" + +int main(int argc, char *argv[]) { + // Build a matrix with the empty constructor + DoubleMatrix2x2 A; + std::cout << "Matrix A is:\n" << A << std::endl; + + // Build a matrix with the non-empty constructor + DoubleMatrix2x2 B(1.0, 2.0, 3.0, 4.0); + std::cout << "Matrix B is:\n" << B << std::endl; + + // Build a matrix with the copy constructor + DoubleMatrix2x2 C(B); + std::cout << "Matrix C is:\n" << C << std::endl; + + // Test the determinant method + std::cout << "The determinant of C is: " << C.Determinant() << std::endl; + + // Test inverse + DoubleMatrix2x2 InvC = C.Inverse(); + std::cout << "The inverse of C is:\n" << InvC << std::endl; + + // Test the assignment operator + DoubleMatrix2x2 D; + D = C; + std::cout << "Matrix D is:\n" << D << std::endl; + + // Testing some operators + DoubleMatrix2x2 E(-D); + E = E + D; + E = E - D; + E.Multiply(2.0); + std::cout << "Matrix E is:\n" << E << std::endl; + + return 0; +} diff --git a/solutions/chapter-06/test_complex_numbers.cpp b/solutions/chapter-06/test_complex_numbers.cpp new file mode 100644 index 0000000..c1750bb --- /dev/null +++ b/solutions/chapter-06/test_complex_numbers.cpp @@ -0,0 +1,33 @@ +/* + * test_complex_numbers.cpp + * + * Complex matrix exponential + * + * Created on: Oct 19, 2012 + * Author: Radu Popescu + */ + +#include + +#include "ComplexNumber.hpp" + +int main(int argc, char *argv[]) { + ComplexNumber a(1.0, 0.0); + std::cout << "a = " << a << std::endl; + std::cout << "Re(a) = " << a.GetRealPart() + << " Im(a) = " << a.GetImaginaryPart() << std::endl; + ComplexNumber b(0.0, -1.0); + std::cout << "b = " << b << std::endl; + ComplexNumber c(2.0, 3.0); + std::cout << "c = " << c << std::endl; + + ComplexNumber d = a + b; + std::cout << "d = a + b = " << d << std::endl; + ComplexNumber e(a * b); + std::cout << "e = a * b = " << e << std::endl; + ComplexNumber f; + f = b * c; + std::cout << "f = b * c = " << f << std::endl; + + return 0; +} diff --git a/solutions/chapter-07/AbstractOdeSolver.cpp b/solutions/chapter-07/AbstractOdeSolver.cpp new file mode 100644 index 0000000..dd18fa7 --- /dev/null +++ b/solutions/chapter-07/AbstractOdeSolver.cpp @@ -0,0 +1,30 @@ +/* + * AbstractOdeSolver.cpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#include "AbstractOdeSolver.hpp" + +AbstractOdeSolver::AbstractOdeSolver() + : stepSize(), initialTime(), finalTime(), initialValue(), f_rhs(0) {} + +AbstractOdeSolver::~AbstractOdeSolver() {} + +void AbstractOdeSolver::SetStepSize(const double h) { stepSize = h; } + +void AbstractOdeSolver::SetTimeInterval(const double t0, const double t1) { + initialTime = t0; + finalTime = t1; +} + +void AbstractOdeSolver::SetInitialValue(const double y0) { initialValue = y0; } + +void AbstractOdeSolver::SetRightHandSide(double (*f)(double y, double t)) { + f_rhs = f; +} + +double AbstractOdeSolver::RightHandSide(double y, double t) const { + return f_rhs(y, t); +} diff --git a/solutions/chapter-07/AbstractOdeSolver.hpp b/solutions/chapter-07/AbstractOdeSolver.hpp new file mode 100644 index 0000000..20838bc --- /dev/null +++ b/solutions/chapter-07/AbstractOdeSolver.hpp @@ -0,0 +1,45 @@ +/* + * AbstractOdeSolver.hpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#ifndef ABSTRACTODESOLVER_HPP_ +#define ABSTRACTODESOLVER_HPP_ + +#include + +class AbstractOdeSolver { +public: + // Constructor and destructor + AbstractOdeSolver(); + virtual ~AbstractOdeSolver(); + + // Other public methods + void SetStepSize(const double h); + void SetTimeInterval(const double t0, const double t1); + void SetInitialValue(const double y0); + void SetRightHandSide(double (*f)(double y, double t)); + + double RightHandSide(double y, double t) const; + virtual void SolveEquation(std::ostream &stream) = 0; + + // Get methods + double GetFinalTime() const { return finalTime; } + + double GetInitialTime() const { return initialTime; } + + double GetInitialValue() const { return initialValue; } + + double GetStepSize() const { return stepSize; } + +private: + double stepSize; + double initialTime; + double finalTime; + double initialValue; + double (*f_rhs)(double y, double t); +}; + +#endif /* ABSTRACTODESOLVER_HPP_ */ diff --git a/solutions/chapter-07/CMakeLists.txt b/solutions/chapter-07/CMakeLists.txt new file mode 100644 index 0000000..31155f2 --- /dev/null +++ b/solutions/chapter-07/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +# The next lines represent a list of all the executables in the folder (chapter) +# There is typically one executable per exercise. +# As you solve exercises, you need to add them here. +# The syntax is add_executable(executable_name source_file_name) + +add_executable(ch-07-ex-01-solution ch-07-ex-01-solution.cpp Student.cpp + GraduateStudent.cpp PhDStudent.cpp) +add_executable(ch-07-ex-03-solution ch-07-ex-03-solution.cpp + AbstractOdeSolver.cpp ForwardEulerSolver.cpp + RungeKuttaSolver.cpp) + \ No newline at end of file diff --git a/solutions/chapter-07/ForwardEulerSolver.cpp b/solutions/chapter-07/ForwardEulerSolver.cpp new file mode 100644 index 0000000..08b1e0f --- /dev/null +++ b/solutions/chapter-07/ForwardEulerSolver.cpp @@ -0,0 +1,36 @@ +/* + * ForwardEulerSolver.cpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#include "ForwardEulerSolver.hpp" + +#include + +ForwardEulerSolver::ForwardEulerSolver() {} + +ForwardEulerSolver::~ForwardEulerSolver() {} + +void ForwardEulerSolver::SolveEquation(std::ostream &stream) { + double y_prev = GetInitialValue(); + double y_next; + + double t_prev = GetInitialTime(); + double t_next; + + double h = GetStepSize(); + int n = static_cast(std::floor((GetFinalTime() - GetInitialTime()) / h)); + + stream << t_prev << " " << y_prev << "\n"; + + for (int i = 1; i <= n; ++i) { + y_next = y_prev + h * RightHandSide(y_prev, t_prev); + t_next = t_prev + h; + + stream << t_next << " " << y_next << "\n"; + y_prev = y_next; + t_prev = t_next; + } +} diff --git a/solutions/chapter-07/ForwardEulerSolver.hpp b/solutions/chapter-07/ForwardEulerSolver.hpp new file mode 100644 index 0000000..e159b2a --- /dev/null +++ b/solutions/chapter-07/ForwardEulerSolver.hpp @@ -0,0 +1,21 @@ +/* + * ForwardEulerSolver.hpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#ifndef FORWARDEULERSOLVER_HPP_ +#define FORWARDEULERSOLVER_HPP_ + +#include "AbstractOdeSolver.hpp" + +class ForwardEulerSolver : public AbstractOdeSolver { +public: + ForwardEulerSolver(); + virtual ~ForwardEulerSolver(); + + virtual void SolveEquation(std::ostream &stream) override; +}; + +#endif /* FORWARDEULERSOLVER_HPP_ */ diff --git a/solutions/chapter-07/GraduateStudent.cpp b/solutions/chapter-07/GraduateStudent.cpp new file mode 100644 index 0000000..2d0842f --- /dev/null +++ b/solutions/chapter-07/GraduateStudent.cpp @@ -0,0 +1,16 @@ +/* + * GraduateStudent.cpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#include "GraduateStudent.hpp" + +GraduateStudent::GraduateStudent() : fullTime_(true) {} + +GraduateStudent::GraduateStudent(const std::string &name, const double fines, + const bool fullTime) + : Student(name, fines, 0.0), fullTime_(fullTime) {} + +double GraduateStudent::MoneyOwed() const { return GetFines(); } diff --git a/solutions/chapter-07/GraduateStudent.hpp b/solutions/chapter-07/GraduateStudent.hpp new file mode 100644 index 0000000..df4989e --- /dev/null +++ b/solutions/chapter-07/GraduateStudent.hpp @@ -0,0 +1,29 @@ +/* + * GraduateStudent.hpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#ifndef GRADUATESTUDENT_HPP_ +#define GRADUATESTUDENT_HPP_ + +#include "Student.hpp" + +class GraduateStudent : public Student { +public: + GraduateStudent(); + GraduateStudent(const std::string &name, const double fines = 0.0, + const bool fullTime = true); + + virtual ~GraduateStudent() {} + + // Total money owed by graduate student + virtual double MoneyOwed() const override; + +private: + // Private data + bool fullTime_; +}; + +#endif /* GRADUATESTUDENT_HPP_ */ diff --git a/solutions/chapter-07/PhDStudent.cpp b/solutions/chapter-07/PhDStudent.cpp new file mode 100644 index 0000000..57231ce --- /dev/null +++ b/solutions/chapter-07/PhDStudent.cpp @@ -0,0 +1,13 @@ +/* + * PhDStudent.cpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#include "PhDStudent.hpp" + +PhDStudent::PhDStudent(const std::string &name, const bool fullTime) + : GraduateStudent(name, 0.0, fullTime) {} + +double PhDStudent::MoneyOwed() const { return 0.0; } diff --git a/solutions/chapter-07/PhDStudent.hpp b/solutions/chapter-07/PhDStudent.hpp new file mode 100644 index 0000000..ede059e --- /dev/null +++ b/solutions/chapter-07/PhDStudent.hpp @@ -0,0 +1,23 @@ +/* + * PhDStudent.hpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#ifndef PHDSTUDENT_HPP_ +#define PHDSTUDENT_HPP_ + +#include "GraduateStudent.hpp" + +class PhDStudent : public GraduateStudent { +public: + PhDStudent() {} + PhDStudent(const std::string &name, const bool fullTime); + virtual ~PhDStudent() {} + + // PhD students don't owe money? + virtual double MoneyOwed() const override; +}; + +#endif /* PHDSTUDENT_HPP_ */ diff --git a/solutions/chapter-07/RungeKuttaSolver.cpp b/solutions/chapter-07/RungeKuttaSolver.cpp new file mode 100644 index 0000000..86a51d9 --- /dev/null +++ b/solutions/chapter-07/RungeKuttaSolver.cpp @@ -0,0 +1,41 @@ +/* + * RungeKuttaSolver.cpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#include "RungeKuttaSolver.hpp" + +#include + +RungeKuttaSolver::RungeKuttaSolver() {} + +RungeKuttaSolver::~RungeKuttaSolver() {} + +void RungeKuttaSolver::SolveEquation(std::ostream &stream) { + double y_prev = GetInitialValue(); + double y_next; + + double t_prev = GetInitialTime(); + double t_next; + + double h = GetStepSize(); + int n = static_cast(std::floor((GetFinalTime() - GetInitialTime()) / h)); + + stream << t_prev << " " << y_prev << "\n"; + + for (int i = 1; i <= n; ++i) { + double k1 = h * RightHandSide(y_prev, t_prev); + double k2 = h * RightHandSide(y_prev + 0.5 * k1, t_prev + 0.5 * h); + double k3 = h * RightHandSide(y_prev + 0.5 * k2, t_prev + 0.5 * h); + double k4 = h * RightHandSide(y_prev + k3, t_prev + h); + + y_next = y_prev + 1.0 / 6.0 * (k1 + 2 * k2 + 2 * k3 + k4); + t_next = t_prev + h; + + stream << t_next << " " << y_next << "\n"; + y_prev = y_next; + t_prev = t_next; + } +} diff --git a/solutions/chapter-07/RungeKuttaSolver.hpp b/solutions/chapter-07/RungeKuttaSolver.hpp new file mode 100644 index 0000000..cc5363a --- /dev/null +++ b/solutions/chapter-07/RungeKuttaSolver.hpp @@ -0,0 +1,21 @@ +/* + * RungeKuttaSolver.hpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#ifndef RUNGEKUTTASOLVER_HPP_ +#define RUNGEKUTTASOLVER_HPP_ + +#include "AbstractOdeSolver.hpp" + +class RungeKuttaSolver : public AbstractOdeSolver { +public: + RungeKuttaSolver(); + virtual ~RungeKuttaSolver(); + + virtual void SolveEquation(std::ostream &stream) override; +}; + +#endif /* RUNGEKUTTASOLVER_HPP_ */ diff --git a/solutions/chapter-07/Student.cpp b/solutions/chapter-07/Student.cpp new file mode 100644 index 0000000..dbccd17 --- /dev/null +++ b/solutions/chapter-07/Student.cpp @@ -0,0 +1,35 @@ +/* + * Student.cpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#include "Student.hpp" + +#include + +Student::Student() : name_(), fines_(0.0), fees_(0.0) {} + +Student::Student(const std::string &name) + : name_(name), fines_(0.0), fees_(0.0) {} + +Student::Student(const std::string &name, const double fines, const double fees) + : name_(name), fines_(fines), fees_(fees) { + SetFines(fines); +} + +double Student::GetFines() const { return fines_; } + +void Student::SetFines(const double fines) { + if (fines >= 0.0) { + fines_ = fines; + } else { + std::cout << "The fines owed by a student must " + << "be a non-negative number. Setting fines to zero." + << std::endl; + fines_ = 0.0; + } +} + +double Student::MoneyOwed() const { return fines_ + fees_; } diff --git a/solutions/chapter-07/Student.hpp b/solutions/chapter-07/Student.hpp new file mode 100644 index 0000000..9c90deb --- /dev/null +++ b/solutions/chapter-07/Student.hpp @@ -0,0 +1,40 @@ +/* + * Student.hpp + * + * Created on: Oct 25, 2012 + * Author: rpopescu + */ + +#ifndef STUDENT_HPP_ +#define STUDENT_HPP_ + +#include + +class Student { +public: + // Default constructor + Student(); + // Alternate constructors + Student(const std::string &name); + Student(const std::string &name, const double fines, const double fees); + + // Destructor + virtual ~Student() {} + + // Get methods + double GetFines() const; + + // Set methods + void SetFines(const double fines); + + // Return the total money owed by the student + virtual double MoneyOwed() const; + +private: + // Private data + std::string name_; + double fines_; + double fees_; +}; + +#endif /* STUDENT_HPP_ */ diff --git a/solutions/chapter-07/ch-07-ex-01-solution.cpp b/solutions/chapter-07/ch-07-ex-01-solution.cpp new file mode 100644 index 0000000..f737b34 --- /dev/null +++ b/solutions/chapter-07/ch-07-ex-01-solution.cpp @@ -0,0 +1,30 @@ +/* + * chapter-07-exercise-01.cpp + * + * Student management classes + * + * Created on: Oct 25, 2012 + * Author: Radu Popescu + */ + +#include + +#include "GraduateStudent.hpp" +#include "PhDStudent.hpp" +#include "Student.hpp" + +int main(int argc, char *argv[]) { + Student bill("Bill", 255.75, 999.99); + std::cout << "Bill owes: " << bill.MoneyOwed() << std::endl; + + Student jeff("Jeff", -50.2, 999.99); + std::cout << "Jeff owes: " << jeff.MoneyOwed() << std::endl; + + GraduateStudent dave("Dave", 10000.99, false); + std::cout << "Dave owes: " << dave.MoneyOwed() << std::endl; + + PhDStudent brian("Brian", true); + std::cout << "Brian owes: " << brian.MoneyOwed() << std::endl; + + return 0; +} diff --git a/solutions/chapter-07/ch-07-ex-03-solution.cpp b/solutions/chapter-07/ch-07-ex-03-solution.cpp new file mode 100644 index 0000000..17853a6 --- /dev/null +++ b/solutions/chapter-07/ch-07-ex-03-solution.cpp @@ -0,0 +1,68 @@ +/* + * chapter-07-exercise-03.cpp + * + * ODE solver + * + * Created on: Oct 25, 2012 + * Author: Radu Popescu + */ + +#include +#include +#include + +#include "AbstractOdeSolver.hpp" +#include "ForwardEulerSolver.hpp" +#include "RungeKuttaSolver.hpp" + +double fRhs(double y, double t) { return 1 + t; } + +int main(int argc, char *argv[]) { + if (argc != 3) { + std::cout << "Missing paremeter. Please run as:\n" + << " ./ch-07-ex-03-solution \n" + << "Aborting.\n"; + return 1; + } + + double initialTime = 0.0; + double finalTime = 1.0; + double initialValue = 2.0; + + AbstractOdeSolver *pSolver = 0; + + // Solving with forward-Euler + double stepSizeEuler = std::atof(argv[1]); + pSolver = new ForwardEulerSolver; + pSolver->SetInitialValue(initialValue); + pSolver->SetTimeInterval(initialTime, finalTime); + pSolver->SetStepSize(stepSizeEuler); + pSolver->SetRightHandSide(fRhs); + + std::ofstream eulerSolutionFile("solution_euler.dat"); + if (eulerSolutionFile.is_open()) { + pSolver->SolveEquation(eulerSolutionFile); + eulerSolutionFile.close(); + } else { + std::cout << "Couldn't open solution_euler.dat. Aborting." << std::endl; + return 1; + } + + double stepSizeRK = std::atof(argv[2]); + pSolver = new RungeKuttaSolver; + pSolver->SetInitialValue(initialValue); + pSolver->SetTimeInterval(initialTime, finalTime); + pSolver->SetStepSize(stepSizeRK); + pSolver->SetRightHandSide(fRhs); + + std::ofstream RKSolutionFile("solution_rk.dat"); + if (RKSolutionFile.is_open()) { + pSolver->SolveEquation(RKSolutionFile); + RKSolutionFile.close(); + } else { + std::cout << "Couldn't open solution_rk.dat. Aborting." << std::endl; + return 1; + } + + return 0; +}