Browse Source

something problems

n0tmyself 11 months ago
parent
commit
17e5638135

+ 17 - 0
Orthogonal Polynomials/CMakeLists.txt

@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.12)
+
+# set( CMAKE_CXX_COMPILER "C:/msys64/mingw64/bin/g++.exe" )
+# set( CMAKE_C_COMPILER "C:/msys64/mingw64/bin/gcc.exe" )
+
+project(
+    OrthPol
+    LANGUAGES CXX
+)
+
+set(CMAKE_CXX_STANDARD 20)
+
+add_subdirectory(modules)
+add_subdirectory(bin)
+
+enable_testing()
+add_subdirectory(TEST)

+ 56 - 0
Orthogonal Polynomials/TEST/CMakeLists.txt

@@ -0,0 +1,56 @@
+include(FetchContent)
+
+FetchContent_Declare(
+  googletest
+  GIT_REPOSITORY https://github.com/google/googletest.git
+  GIT_TAG release-1.12.1
+)
+
+# For Windows: Prevent overriding the parent project's compiler/linker settings
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+FetchContent_MakeAvailable(googletest)
+
+enable_testing()
+
+add_executable(
+  OrthPolTEST
+  OrthPolTEST.cpp
+  ExplicitExpressions.cpp
+  ExplicitExpressions.h
+)
+
+target_link_libraries(
+  OrthPolTEST
+  GTest::gtest_main
+)
+
+target_include_directories(OrthPolTEST PUBLIC ${PROJECT_SOURCE_DIR})
+
+include(GoogleTest)
+
+gtest_discover_tests(OrthPolTEST)
+
+
+# cmake_minimum_required(VERSION 3.0)
+
+# project(OrthPolTEST)
+
+# find_package(GTest REQUIRED)
+# find_package(Threads REQUIRED)
+
+# set(CMAKE_CXX_STANDARD 11)
+# set(CMAKE_CXX_STANDARD_REQUIRED on)
+
+# include_directories(
+#     ${GTEST_INCLUDE_DIRS}
+# )
+
+# add_executable(
+#   OrthPolTEST ./OrthPolTEST.cpp
+# )
+
+# target_link_libraries(
+#   OrthPolTEST ${GTEST_LIBRARIES} Threads::Threads)
+
+# enable_testing()
+# add_test(OrthPolTEST "./OrthPolTEST")

+ 153 - 0
Orthogonal Polynomials/TEST/OrthPolTEST.cpp

@@ -0,0 +1,153 @@
+#include <gtest/gtest.h>
+#include "modules/OrthPol.cpp"
+#include "ExplicitExpressions.h"
+
+class OrthPolTest : public testing::Test {};
+
+// Test that OrthPol returns correct values if x=0
+TEST_F(OrthPolTest, ChebPolZeroCase) {
+   double zero = 0.0;
+   for (int i=0; i<=50; ++i) 
+   {
+
+      std::vector<double> res = OrthPol(1, i, 0);
+      if (i % 2 == 1)
+      {
+        EXPECT_DOUBLE_EQ(res[0], zero) << "Chebyshev polinom of the first kind " << i << "th-order are not equal 0";
+        EXPECT_DOUBLE_EQ(res[1], pow(-1.0, (i-1)/2)*i) << "Derivative of Chebyshev polinom of the first kind " << i << "th-order are not equal "<< i << "*(-1)^" << (i-1)/2;
+      }
+      else
+      {
+        EXPECT_DOUBLE_EQ(res[0], pow(-1.0, i/2)) << "Chebyshev polinom of the first kind " << i << "th-order are not equal (-1)^" << i/2;
+        EXPECT_DOUBLE_EQ(res[1], zero) << "Derivative of Chebyshev polinom of the first kind " << i << "th-order are not equal 0";
+      }
+   }
+   for (int i=0; i<=50; ++i) 
+   {
+      std::vector<double> res = OrthPol(2, i, 0);
+      if (i % 2 == 1)
+      {
+        EXPECT_DOUBLE_EQ(res[0], zero) << "Chebyshev polinom of the second kind " << i << "th-order are not equal 0";
+        EXPECT_DOUBLE_EQ(res[1], pow(-1.0, (i-1)/2)*(i+1)) << "Derivative of Chebyshev polinom of the second kind " << i << "th-order are not equal "<< (i+1) << "*(-1)^" << (i-1)/2;
+      }
+      else
+      {
+        EXPECT_DOUBLE_EQ(res[0], pow(-1.0, i/2)) << "Chebyshev polinom of the second kind " << i << "th-order are not equal (-1)^" << i/2;
+        EXPECT_DOUBLE_EQ(res[1], zero) << "Derivative of Chebyshev polinom of the second kind " << i << "th-order are not equal 0";
+      }
+   }
+}
+
+// Test that OrthPol returns correct values if x=+-1
+TEST_F(OrthPolTest, ChebPolOneCase) {
+   for (int i=0; i<=50; ++i) 
+   {
+    std::vector<double> res = OrthPol(1, i, 1);
+    EXPECT_DOUBLE_EQ(res[0], 1) << "Chebyshev polinom of the first kind " << i << "th-order are not equal " << 1;
+    EXPECT_DOUBLE_EQ(res[1], pow(i, 2)) << "Derivative of Chebyshev polinom of the first kind " << i << "th-order are not equal "<< pow(i, 2);
+
+    res = OrthPol(2, i, 1);
+    EXPECT_DOUBLE_EQ(res[0], i+1) << "Chebyshev polinom of the second kind " << i << "th-order are not equal " << i+1;
+    EXPECT_DOUBLE_EQ(res[1], i*(i+1)*(i+2)/3) << "Derivative of Chebyshev polinom of the first kind " << i << "th-order are not equal "<< i*(i+1)*(i+2)/3;
+
+    res = OrthPol(1, i, -1);
+    EXPECT_DOUBLE_EQ(res[0], pow(-1, i)) << "Chebyshev polinom of the first kind " << i << "th-order are not equal " << pow(-1, i);
+    EXPECT_DOUBLE_EQ(res[1], pow(-1, i-1) * pow(i, 2)) << "Derivative of Chebyshev polinom of the first kind " << i << "th-order are not equal "<< pow(-1, i-1) * pow(i, 2);
+
+    res = OrthPol(2, i, -1);
+    EXPECT_DOUBLE_EQ(res[0], pow(-1, i)*(i+1)) << "Chebyshev polinom of the first kind " << i << "th-order are not equal " << pow(-1, i)*(i+1);
+    EXPECT_DOUBLE_EQ(res[1], pow(-1, i+1) * (i*(i+1)*(i+2)/3)) << "Derivative of Chebyshev polinom of the first kind " << i << "th-order are not equal "<< pow(-1, i+1) * (i*(i+1)*(i+2)/3);
+   }
+}
+
+TEST_F(OrthPolTest, ExplicitExprChebyshevCase){
+    double x = -1; // the left boundary
+    double length = 2; //the length of the segmment
+    double step = 0.2;
+    std::vector<double> res_rec;
+    double res_expl;
+    for (int i=0; i <= static_cast<int>(length / step); ++i)
+    {
+        for (int j=0; j <= 20; ++j)
+        {
+            res_rec = OrthPol(1, j, x);
+            res_expl = ExplicitExpressionCheb(1, j, x);
+            if (res_rec[0] != 0.0)
+            {
+                EXPECT_NEAR(1, res_expl / res_rec[0], EPS_CHEB);
+            }
+            else
+            {
+                EXPECT_NEAR(res_rec[0], res_expl, EPS_CHEB);
+            }
+
+            res_rec = OrthPol(2, j, x);
+            res_expl = ExplicitExpressionCheb(2, j, x);
+            if (res_rec[0] != 0.0)
+            {
+                EXPECT_NEAR(1, res_expl / res_rec[0], EPS_CHEB);
+            }
+            else
+            {
+                EXPECT_NEAR(res_rec[0], res_expl, EPS_CHEB);
+            }
+
+        }
+        x += step;
+    }
+}
+
+TEST_F(OrthPolTest, ExplicitExprLaguerreCase){
+    double x = -10; // the left boundary
+    double length = 20; //the length of the segmment
+    double step = 0.5;
+    std::vector<double> res_rec;
+    double res_expl;
+    for (int i=0; i <= static_cast<int>(length / step); ++i)
+    {
+        for (int j=0; j <= 20; ++j)
+        {
+            res_rec = OrthPol(3, j, x);
+            res_expl = ExplicitExpressionLaguerre(j, x);
+            if (res_rec[0] != 0.0)
+            {
+                EXPECT_NEAR(1, res_expl / res_rec[0], EPS_LAG);
+            }
+            else
+            {
+                EXPECT_NEAR(res_rec[0], res_expl, EPS_LAG);
+            }
+        }
+        x += step;
+    }
+}
+
+TEST_F(OrthPolTest, ExplicitExprHermiteCase){
+    double x = -10; // the left boundary
+    double length = 20; //the length of the segmment
+    double step = 0.5;
+    std::vector<double> res_rec;
+    double res_expl;
+    for (int i=0; i <= static_cast<int>(length / step); ++i)
+    {
+        for (int j=0; j <= 20; ++j)
+        {
+            res_rec = OrthPol(4, j, x);
+            res_expl = ExplicitExpressionHermite(j, x);
+            if (res_rec[0] != 0.0)
+            {
+                EXPECT_NEAR(1, res_expl / res_rec[0], EPS_HERM);
+            }
+            else
+            {
+                EXPECT_NEAR(res_rec[0], res_expl, EPS_HERM);
+            }
+        }
+        x += step;
+    }
+}
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}

+ 5 - 0
Orthogonal Polynomials/bin/CMakeLists.txt

@@ -0,0 +1,5 @@
+add_executable(${PROJECT_NAME} main.cpp)
+
+
+target_link_libraries(${PROJECT_NAME} PRIVATE Calc)
+target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR})

+ 40 - 0
Orthogonal Polynomials/bin/main.cpp

@@ -0,0 +1,40 @@
+#include "modules/OrthPol.h"
+#include <iomanip>
+#include <string>
+
+int main()
+{   std::cout << "Chebyshev Polynomial of the first kind" << std::endl;
+std::cout << "------------------------------------------------------------------------" << std::endl;
+    std::cout << std::setw(2) << "n     ";
+    for (int j=1; j <=5; j++)
+    {
+        if (j == 5)
+        {
+            std::cout << std::setw(5) << std::left << std::setprecision(8) << j * 0.2 << std::endl;
+        }
+        else
+        {
+            std::cout << std::setw(5) << std::left << std::setprecision(8) << j * 0.2 << "    ";
+        }
+    }
+    std::cout << "------------------------------------------------------------------------" << std::endl;
+    for (int i=0; i<=20; ++i)
+    {   
+        std::cout << std::setw(2) << i << "    ";
+        for (int j=1; j <=5; ++j)
+        {
+
+            std::vector<double> res = OrthPol(1, i, j*0.2);
+            if (j == 5)
+            {    
+                std::cout << std::to_string(res[0]).substr(0,8) << std::endl;        
+                //std::cout << std::setw(10) << std::right << std::setprecision(8) << res[0] << std::endl;
+            }
+            else
+            {
+                std::cout << std::to_string(res[0]).substr(0,8) << " ";  
+                //std::cout << std::setw(10) << std::right << std::setprecision(8) << res[0] << " " ;
+            }
+        }
+    }
+}

+ 1 - 0
Orthogonal Polynomials/modules/CMakeLists.txt

@@ -0,0 +1 @@
+add_library(Calc OrthPol.cpp OrthPol.h)

+ 79 - 0
Orthogonal Polynomials/modules/OrthPol.cpp

@@ -0,0 +1,79 @@
+// #include <iostream> 
+// #include <string>
+// #include <vector>
+#include  "OrthPol.h"
+
+/**
+ * Purpose: Compute orthogonal polynomials: Chebyshev, Laguerre, Hermite polynomials, and their derivatives
+ * 
+ * @param KF
+ *      KF = 1 for Chebyshev polynomial of the first kind
+ *      KF = 2 for Chebyshev polynomial of the second kind
+ *      KF = 3 for Laguerre polynomial
+ *      KF = 4 for Hermite polynomial
+ * @param n - Integer order of orthogonal polynomial.
+ * @param x - Argument of orthogonal polynomial.
+ * @return Vector with values of the orthogonal polynomial (the first place) of order n with argument x, and its first derivatives (the second place).
+ * @throws None
+ */
+std::vector<double> OrthPol(const int& KF, const int& n, const double& x)
+{
+    std::vector<double> result;
+
+    double* PL = new double[n + 1];
+    double* DPL = new double[n + 1];
+    
+    double A = 2.0;
+    double B = 0.0;
+    double C = 1.0;
+    double Y0 = 1.0;
+    double Y1 = 2.0 * x;
+    double DY0 = 0.0;
+    double DY1 = 2.0;
+    PL[0] = 1.0;
+    PL[1] = 2.0 * x;
+    DPL[0] = 0.0;
+    DPL[1] = 2.0;
+
+    if (KF == 1)
+    {
+        Y1 = x;
+        DY1 = 1.0;
+        PL[1] = x;
+        DPL[1] = 1.0;
+    }
+    else if (KF == 3)
+    {
+        Y1 = 1.0 - x;
+        DY1 = -1.0;
+        PL[1] = 1.0 - x;
+        DPL[1] = -1.0;
+    }
+    
+    for (int k = 2; k <= n; k++)
+    {
+        if (KF == 3)
+        {   
+            A = -1.0 / k;
+            B = 2.0 + A;
+            C = 1.0 + A;
+        }
+        else if (KF == 4)
+        {
+            C = 2.0 * (k - 1.0);
+        }
+        double YN = (A * x + B) * Y1 - C * Y0;
+        double DYN = A * Y1 + (A * x + B) * DY1 - C * DY0;
+        PL[k] = YN;
+        DPL[k] = DYN;
+        Y0 = Y1;
+        Y1 = YN;
+        DY0 = DY1;
+        DY1 = DYN;        
+    }
+    
+    result.push_back(PL[n]);
+    result.push_back(DPL[n]);
+
+    return result;
+}

+ 6 - 0
Orthogonal Polynomials/modules/OrthPol.h

@@ -0,0 +1,6 @@
+#pragma once
+#include <iostream> 
+#include <string>
+#include <vector>  
+
+std::vector<double> OrthPol(const int& KF, const int& n, const double& x);

+ 16 - 0
README.md

@@ -0,0 +1,16 @@
+## Orthogonal Polynomials
+
+**Description:**
+The OrthPol(KF, n, x) function computes orthogonal polynomials: Chebyshev, Laguerre, Hermite polynomials, and their derivatives using recurrence relations.
+
+**Parameters:**
+1. KF - parameter specifying the orthogonal polynomial
+    * KF = 1 for Chebyshev polynomial of the first kind
+    * KF = 2 for Chebyshev polynomial of the second kind
+    * KF = 3 for Laguerre polynomial
+    * KF = 4 for Hermite polynomial
+2. n - integer order of orthogonal polynomial.
+3. x - argument of orthogonal polynomial.
+
+**Return:**
+Vector with values of the orthogonal polynomial (the first place) of order n with argument x, and its first derivatives (the second place).