diff --git a/CMakeLists.txt b/CMakeLists.txt index 20da984..a2c8977 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,7 +130,6 @@ if (${GLOBALIZER_ONE_MPI_PROCESS_PER_NODE}) add_definitions(-DONE_MPI_PROCESS_PER_NODE) endif() - #add MPFR_GMP_MPIR if (${GLOBALIZER_USE_MP}) add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/mpfr_gmp_mpir) @@ -374,6 +373,7 @@ endif() include_directories(${Python_INCLUDE_DIRS} ${Python_NumPy_INCLUDE_DIRS}) + if (${IS_CLANG_COMPILER}) target_link_libraries(${GLOBALIZER_LIB_NAME} diff --git a/cmake/globalizer_lib.cmake b/cmake/globalizer_lib.cmake index 3cf84c3..6c09325 100644 --- a/cmake/globalizer_lib.cmake +++ b/cmake/globalizer_lib.cmake @@ -7,8 +7,8 @@ endfunction (setup_mpir) function (setup_gmp arg_libdir arg_libname) get_platform_depended_library_path(LIB_PATH_PART) set(${arg_libname} gmp PARENT_SCOPE) - set(${arg_libdir} ${PROJECT_BINARY_DIR}/lib/$ PARENT_SCOPE) -endfunction (setup_mpfr) + set(${arg_libdir} ${GLOBALIZER_OUTPUT_DIRECTORY} PARENT_SCOPE) +endfunction (setup_gmp) function (setup_mpfr arg_libdir arg_libname) get_platform_depended_library_path(LIB_PATH_PART) diff --git a/globalizer/evolvent/include/Evolvent.h b/globalizer/evolvent/include/Evolvent.h index 8d2eb35..fd5e8cb 100644 --- a/globalizer/evolvent/include/Evolvent.h +++ b/globalizer/evolvent/include/Evolvent.h @@ -31,6 +31,7 @@ #include "Common.h" #include "Extended.h" +#include "EvolventInterface.h" #include // ------------------------------------------------------------------------------------------------ @@ -41,7 +42,7 @@ Класс #Evolvent предоставляет средства для преобразования координат между гиперкубом [-1/2, 1/2]^N и гиперинтервалом D. */ -class Evolvent +class Evolvent : public IEvolvent { protected: /// Точность разложения гиперкуба @@ -64,18 +65,18 @@ class Evolvent Extended nexpExtended; - void CalculateNumbr(Extended* s, long long* u, long long* v, long long* l); + virtual void CalculateNumbr(Extended* s, long long* u, long long* v, long long* l); /// вычисление вспомогательного центра u(s) и соответствующих ему v(s) и l(s) - void CalculateNode(Extended is, int n, long long* u, long long* v, long long* l); + virtual void CalculateNode(Extended is, int n, long long* u, long long* v, long long* l); /// Преобразование из гиперкуба P в гиперинтервал D - void transform_P_to_D(); + virtual void transform_P_to_D(); /// Преобразование из гиперинтервала D в гиперкуб P - void transform_D_to_P(); + virtual void transform_D_to_P(); /// Получить точку y по x - double* GetYOnX(const Extended& _x); + virtual double* GetYOnX(const Extended& _x); /// Получить x по точке y - Extended GetXOnY(); + virtual Extended GetXOnY(); public: @@ -95,17 +96,17 @@ class Evolvent /** \brief Возвращает левые границы поисковой области (A) */ - const double* getA() const { return A; } + virtual const double* getA() const { return A; } /** \brief Возвращает правые границы поисковой области (B) */ - const double* getB() const { return B; } + virtual const double* getB() const { return B; } /** \brief Установка границ поисковой области */ - void SetBounds(const double* _A, const double* _B); + virtual void SetBounds(const double* _A, const double* _B); /** \brief Преобразование x в y (x -> y) @@ -115,7 +116,7 @@ class Evolvent /** \brief Преобразование y в x (y -> x) */ - void GetInverseImage(double* _y, Extended& x); + virtual void GetInverseImage(double* _y, Extended& x); /** \brief Преобразование y в x (y -> x) @@ -125,7 +126,7 @@ class Evolvent /** \brief Оператор присваивания */ - Evolvent& operator=(const Evolvent& evolvent); + virtual Evolvent& operator=(const Evolvent& evolvent); /** \brief Вычисляет функцию существования точки в развертки EvolventNum для y, <0 - существует diff --git a/globalizer/evolvent/include/EvolventFactory.h b/globalizer/evolvent/include/EvolventFactory.h new file mode 100644 index 0000000..a20886d --- /dev/null +++ b/globalizer/evolvent/include/EvolventFactory.h @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2026 by UNN. // +// All Rights Reserved. // +// // +// File: evolvent_factory.h // +// // +// Purpose: Header file for evolvent factory class // +// // +// Author(s): Zaitsev A. // +// // +///////////////////////////////////////////////////////////////////////////// + +#ifndef __EVOLVENT_FACTORY_H__ +#define __EVOLVENT_FACTORY_H__ + +#include "Common.h" +#include "Parameters.h" +#include "Evolvent.h" + +class EvolventFactory +{ +public: + static IEvolvent* CreateEvolvent(int _N, int _m); +}; + +#endif +// - end of file ---------------------------------------------------------------------------------- diff --git a/globalizer/evolvent/include/EvolventInterface.h b/globalizer/evolvent/include/EvolventInterface.h new file mode 100644 index 0000000..1acf63a --- /dev/null +++ b/globalizer/evolvent/include/EvolventInterface.h @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: evolventinterface.h // +// // +// Purpose: Header file for evolvent interface classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// + + +/** +\file evolventinterface.h + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Объявление класса #Evolvent + +\details Объявление класса #Evolvent и сопутствующих типов данных +*/ + +#ifndef __EVOLVENT_INTERFACE_H__ +#define __EVOLVENT_INTERFACE_H__ + +#include "Common.h" +#include "Extended.h" +#include + +// ------------------------------------------------------------------------------------------------ + +/** +\brief Класс, реализующий отображение между гиперкубом и гиперинтервалом + +Класс #Evolvent предоставляет средства для преобразования координат между +гиперкубом [-1/2, 1/2]^N и гиперинтервалом D. +*/ +class IEvolvent +{ +protected: + /// Точность разложения гиперкуба + int m; + /// Размерность задачи + int N; + /// Левые границы поисковой области + double A[MaxDim]; + /// Правые границы поисковой области + double B[MaxDim]; + /// Точка из гиперкуба [-1/2, 1/2]^N + double* y; + + /// Extended(0.0) + const Extended extNull; + /// = Extended(1.0) + const Extended extOne; + /// = Extended(0.5) + const Extended extHalf; + Extended nexpExtended; + + + virtual void CalculateNumbr(Extended* s, long long* u, long long* v, long long* l) = 0; + + /// вычисление вспомогательного центра u(s) и соответствующих ему v(s) и l(s) + virtual void CalculateNode(Extended is, int n, long long* u, long long* v, long long* l) = 0; + /// Преобразование из гиперкуба P в гиперинтервал D + virtual void transform_P_to_D() = 0; + /// Преобразование из гиперинтервала D в гиперкуб P + virtual void transform_D_to_P() = 0; + /// Получить точку y по x + virtual double* GetYOnX(const Extended& _x) = 0; + /// Получить x по точке y + virtual Extended GetXOnY() = 0; + +public: + /** + \brief Возвращает левые границы поисковой области (A) + */ + virtual const double* getA() const = 0; + + /** + \brief Возвращает правые границы поисковой области (B) + */ + virtual const double* getB() const = 0; + + /** + \brief Установка границ поисковой области + */ + virtual void SetBounds(const double* _A, const double* _B) = 0; + + /** + \brief Преобразование x в y (x -> y) + */ + virtual void GetImage(const Extended& x, double* _y, int EvolventNum = 0) = 0; + + /** + \brief Преобразование y в x (y -> x) + */ + virtual void GetInverseImage(double* _y, Extended& x) = 0; + + /** + \brief Преобразование y в x (y -> x) + */ + virtual void GetPreimages(double* _y, Extended* x) = 0; + + /** + \brief Неинъективное преобразование y в x (y -> x) + */ + virtual int GetNoninjectivePreimages(double* _y, Extended* x) { return 0; }; + + /** + \brief Вычисляет функцию существования точки в развертки EvolventNum для y, <0 - существует + */ + virtual double ZeroConstraintCalc(const double* _y, int EvolventNum = 0) = 0; +}; + +#endif +// - end of file ---------------------------------------------------------------------------------- \ No newline at end of file diff --git a/globalizer/evolvent/include/TLinearEvolvent.h b/globalizer/evolvent/include/TLinearEvolvent.h new file mode 100644 index 0000000..88d62ce --- /dev/null +++ b/globalizer/evolvent/include/TLinearEvolvent.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: linarevolvent.h // +// // +// Purpose: Header file for linar evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// + + +/** +\file linarevolvent.h + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Объявление класса #LinearEvolvent + +\details Объявление класса #LinearEvolvent и сопутствующих типов данных +*/ + +#ifndef __LINAREVOLVENT_H__ +#define __LINAREVOLVENT_H__ + +#include "Evolvent.h" +#include "Common.h" +#include "Extended.h" +#include + +// ------------------------------------------------------------------------------------------------ + +/** +\brief Класс, реализующий отображение между гиперкубом и гиперинтервалом + +Класс #LinearEvolvent предоставляет средства для преобразования координат между +гиперкубом [-1/2, 1/2]^N и гиперинтервалом D. +*/ + +class LinearEvolvent : public Evolvent +{ +protected: + Extended mneExtended; +public: + + /** + \brief Конструктор класса #LinearEvolvent + */ + LinearEvolvent(int _N = 2, int _m = 10); + + /// Деструктор класса #LinearEvolvent + virtual ~LinearEvolvent(); + + /** + \brief Преобразование x в y (x -> y) + */ + void GetImage(const Extended& x, double* _y, int EvolventNum = 0); + + /** + \brief Преобразование y в x (y -> x) + */ + void GetInverseImage(double* _y, Extended& x); +}; + +#endif +// - end of file ---------------------------------------------------------------------------------- \ No newline at end of file diff --git a/globalizer/evolvent/include/TNoninjectiveEvolvent.h b/globalizer/evolvent/include/TNoninjectiveEvolvent.h new file mode 100644 index 0000000..a5d7a30 --- /dev/null +++ b/globalizer/evolvent/include/TNoninjectiveEvolvent.h @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: noninjectiveevolvent.h // +// // +// Purpose: Header file for noninjective evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// + + +/** +\file noninjectiveevolvent.h + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Объявление класса #NoninjectiveEvolvent + +\details Объявление класса #NoninjectiveEvolvent и сопутствующих типов данных +*/ + +#ifndef __NONINJECTIVEEVOLVENT_H__ +#define __NONINJECTIVEEVOLVENT_H__ + +#include "Evolvent.h" +#include "Common.h" +#include "Extended.h" +#include + +// ------------------------------------------------------------------------------------------------ + +/** +\brief Класс, реализующий отображение между гиперкубом и гиперинтервалом + +Класс #NoninjectiveEvolvent предоставляет средства для преобразования координат между +гиперкубом [-1/2, 1/2]^N и гиперинтервалом D. +*/ +class NoninjectiveEvolvent : public Evolvent +{ +protected: + + /// максимальное количество прообразов + int max_preimages; + + Extended mneExtended; +public: + + /** + \brief Конструктор класса #NoninjectiveEvolvent + */ + NoninjectiveEvolvent(int _N = 2, int _m = 10, int _max_preimages = 64); + + /// Деструктор класса #NoninjectiveEvolvent + virtual ~NoninjectiveEvolvent(); + + /** + \brief Преобразование x в y (x -> y) + */ + void GetImage(const Extended& x, double* _y, int EvolventNum = 0); + + /** + \brief Неинъективное преобразование y в x (y -> x) + */ + int GetNoninjectivePreimages(double* _y, Extended* x); + + /// Получить максимальное количество прообразов + int GetMaxPreimagesNumber() const { return max_preimages; }; +}; + +#endif +// - end of file ---------------------------------------------------------------------------------- \ No newline at end of file diff --git a/globalizer/evolvent/include/TRotatedEvolvent.h b/globalizer/evolvent/include/TRotatedEvolvent.h new file mode 100644 index 0000000..be18f0e --- /dev/null +++ b/globalizer/evolvent/include/TRotatedEvolvent.h @@ -0,0 +1,147 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: rotatedevolvent.h // +// // +// Purpose: Header file for rotatedevolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// + + +/** +\file rotatedevolvent.h + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Объявление класса #RotatedEvolvent + +\details Объявление класса #RotatedEvolvent и сопутствующих типов данных +*/ + +#ifndef __ROTATEDEVOLVENT_H__ +#define __ROTATEDEVOLVENT_H__ + +#include "Evolvent.h" +#include "Common.h" +#include "Extended.h" +#include + +// ------------------------------------------------------------------------------------------------ + +/** +\brief Класс, реализующий отображение между гиперкубом и гиперинтервалом + +Класс #RotatedEvolvent предоставляет средства для преобразования координат между +гиперкубом [-1/2, 1/2]^N и гиперинтервалом D. +*/ +class RotatedEvolvent : public Evolvent +{ +protected: + + /// Количество развёрток, по умолчанию 1, означает, что используется одна развёртка + int L; + + /// текущее количество уровней + int PlaneCount; // current number of planes + + /// массив осей + int Planes[MaxDim * (MaxDim - 1) / 2][2]; + + /// Статический массив хранящий степени 1/2 + double PowOfHalf[MaxM + 2]; + + void GetAllPlanes(); +public: + + /** + \brief Конструктор класса #RotatedEvolvent + */ + RotatedEvolvent(int _N = 2, int _m = 10, int _L = 0); + + /// Деструктор класса #RotatedEvolvent + virtual ~RotatedEvolvent(); + + /** + \brief Преобразование x в y (x -> y) + */ + void GetImage(const Extended& x, double* _y, int EvolventNum = 0) override { + if (L == 1 || EvolventNum == 0) + { + Evolvent::GetImage(x, _y); + return; + } + + int PlaneIndex = EvolventNum - 1; // теперь PlaneIndex - номер перестановки + PlaneIndex = PlaneIndex % PlaneCount; + + GetYOnX(x); + + // shift to center for convenient rotation + //for (int i = 0; i < N; i++) + // y[i] += PowOfHalf[m + 1]; + + // rotate + double tmpCoord = y[Planes[PlaneIndex][1]]; + y[Planes[PlaneIndex][1]] = y[Planes[PlaneIndex][0]]; + y[Planes[PlaneIndex][0]] = -tmpCoord; + + //Меняем знак преобразования, если число разверток больше числа плоскостей + if (EvolventNum > PlaneCount) + { + y[Planes[PlaneIndex][0]] = -y[Planes[PlaneIndex][0]]; + y[Planes[PlaneIndex][1]] = -y[Planes[PlaneIndex][1]]; + } + + // shift back to corner + //for (int i = 0; i < N; i++) + // y[i] -= PowOfHalf[m + 1]; + + transform_P_to_D(); + memcpy(_y, y, N * sizeof(double)); + } + + /** + \brief Преобразование y в x (y -> x) + */ + void GetPreimages(double* _y, Extended* x) override { + memcpy(y, _y, N * sizeof(double)); + transform_D_to_P(); + // прообраз для первой развертки + x[0] = GetXOnY(); + + if (L == 1) + return; + + for (int i = 1; i < L; i++) + { + memcpy(y, _y, N * sizeof(double)); + transform_D_to_P(); + // обратное преобразование координат + int PlaneIndex = (i - 1) % PlaneCount; + + double tmpCoord = y[Planes[PlaneIndex][1]]; + y[Planes[PlaneIndex][1]] = -y[Planes[PlaneIndex][0]]; + y[Planes[PlaneIndex][0]] = tmpCoord; + + if (i > PlaneCount)//Меняем знак преобразования, если число разверток больше числа плоскостей + { + y[Planes[PlaneIndex][0]] = -y[Planes[PlaneIndex][0]]; + y[Planes[PlaneIndex][1]] = -y[Planes[PlaneIndex][1]]; + } + + // прообраз для i - 1 развертки + x[i] = GetXOnY(); + } + } +}; + +#endif +// - end of file ---------------------------------------------------------------------------------- \ No newline at end of file diff --git a/globalizer/evolvent/include/TShiftedEvolvent.h b/globalizer/evolvent/include/TShiftedEvolvent.h new file mode 100644 index 0000000..70e96df --- /dev/null +++ b/globalizer/evolvent/include/TShiftedEvolvent.h @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: shiftedevolvent.h // +// // +// Purpose: Header file for shifted evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// + + +/** +\file shiftedevolvent.h + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Объявление класса #ShiftedEvolvent + +\details Объявление класса #ShiftedEvolvent и сопутствующих типов данных +*/ + +#ifndef __SHIFTEDEVOLVENT_H__ +#define __SHIFTEDEEVOLVENT_H__ + +#include "Evolvent.h" +#include "Common.h" +#include "Extended.h" +#include + +// ------------------------------------------------------------------------------------------------ + +/** +\brief Класс, реализующий отображение между гиперкубом и гиперинтервалом + +Класс #ShiftedEvolvent предоставляет средства для преобразования координат между +гиперкубом [-1/2, 1/2]^N и гиперинтервалом D. +*/ +class ShiftedEvolvent : public Evolvent +{ +protected: + + /// Количество развёрток - 1, по умолчанию 0, означает, что используется одна развёртка + int L; + + /// Статический массив хранящий степени 2 + double PowOf2[MaxDim * MaxL + 1]; + + void transform_P_to_Pl(int EvolventNum); + + void transform_Pl_to_P(int EvolventNum); + + double ZeroConstraint(); +public: + + /** + \brief Конструктор класса #ShiftedEvolvent + */ + ShiftedEvolvent(int _N = 2, int _m = 10, int _L = 0); + + /// Деструктор класса #ShiftedEvolvent + virtual ~ShiftedEvolvent(); + + /** + \brief Преобразование x в y (x -> y) + */ + void GetImage(const Extended& x, double* _y, int EvolventNum = 0) override { + /* + double* tmp = NULL; + int i; + //непонятно, зачем в GlobalExpert данная точка была вынесена в отдельную ветку + + if (x == extNull) + { + for (i = 0; i < N; i++) + { + _y[i] = 0.0; + } + } + else + */ + GetYOnX(x); + + transform_P_to_Pl(EvolventNum); + transform_P_to_D(); + + memcpy(_y, y, N * sizeof(double)); + } + + /** + \brief Преобразование y в x (y -> x) + */ + void GetPreimages(double* _y, Extended* x) override { + for (int i = 0; i <= L; i++) + { + memcpy(y, _y, N * sizeof(double)); + transform_D_to_P(); + transform_Pl_to_P(i); + x[i] = GetXOnY(); + } + } + + /// Вычисляет функцию существования точки в развертки EvolventNum для y, <0 - существует + double ZeroConstraintCalc(const double* _y, int EvolventNum = 0) override { + // копируем y + memcpy(y, _y, N * sizeof(double)); + // центрируем и нормируем область + transform_D_to_P(); + // сдвигаем область в соответствии с разверткой + transform_Pl_to_P(EvolventNum); + // вычисляем функционал + return ZeroConstraint(); + } +}; +#endif +// - end of file ---------------------------------------------------------------------------------- \ No newline at end of file diff --git a/globalizer/evolvent/include/TSmoothEvolvent.h b/globalizer/evolvent/include/TSmoothEvolvent.h new file mode 100644 index 0000000..a857319 --- /dev/null +++ b/globalizer/evolvent/include/TSmoothEvolvent.h @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: smoothevolvent.h // +// // +// Purpose: Header file for smooth evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// + + +/** +\file smoothevolvent.h + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Объявление класса #SmoothEvolvent + +\details Объявление класса #SmoothEvolvent и сопутствующих типов данных +*/ + +#ifndef __SMOOTHEVOLVENT_H__ +#define __SMOOTHEVOLVENT_H__ + +#include "Evolvent.h" +#include "Common.h" +#include "Extended.h" +#include "Exception.h" +#include + +// ------------------------------------------------------------------------------------------------ + +/** +\brief Класс, реализующий отображение между гиперкубом и гиперинтервалом + +Класс #SmoothEvolvent предоставляет средства для преобразования координат между +гиперкубом [-1/2, 1/2]^N и гиперинтервалом D. +*/ +class SmoothEvolvent : public Evolvent +{ +protected: + + /// Гладкость + double h; + int smoothPointCount; + bool continuously; + std::vector tmp_y, tmp_y_; + + + void GetYOnXSmooth(double x, std::vector& y, std::vector& y_); +public: + + /** + \brief Конструктор класса #SmoothEvolvent + */ + SmoothEvolvent(int _N = 2, int _m = 10, double _h = 0.25); + + /// Деструктор класса #SmoothEvolvent + virtual ~SmoothEvolvent(); + + /** + \brief Преобразование x в y (x -> y) + */ + void GetImage(const Extended& x, double* _y, int EvolventNum = 0) override { + if ((x < 0) || (x > 1)) + { + throw EXCEPTION("x is out of range"); + } + // x ---> y + GetYOnXSmooth(x.toDouble(), tmp_y, tmp_y_); + std::copy(tmp_y.begin(), tmp_y.end(), y); + transform_P_to_D(); + + memcpy(_y, y, N * sizeof(double)); + } + + /** + \brief Преобразование y в x (y -> x) + */ + void GetInverseImage(double* _y, Extended& x); +}; + +#endif +// - end of file ---------------------------------------------------------------------------------- \ No newline at end of file diff --git a/globalizer/evolvent/src/EvolventFactory.cpp b/globalizer/evolvent/src/EvolventFactory.cpp new file mode 100644 index 0000000..c6b6753 --- /dev/null +++ b/globalizer/evolvent/src/EvolventFactory.cpp @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: evolvent_factory.cpp // +// // +// Purpose: Source file for evolvent factory class // +// // +// Author(s): Zaitsev A. // +// // +///////////////////////////////////////////////////////////////////////////// + +#include "EvolventFactory.h" +#include "Evolvent.h" +#include "TLinearEvolvent.h" +#include "TNoninjectiveEvolvent.h" +#include "TRotatedEvolvent.h" +#include "TShiftedEvolvent.h" +#include "TSmoothEvolvent.h" + + + +// ------------------------------------------------------------------------------------------------ +IEvolvent* EvolventFactory::CreateEvolvent(int _N, int _m) +{ + IEvolvent* pEvolvent = nullptr; + if (parameters.MapType == mpBase) + pEvolvent = new Evolvent(_N, _m); + if (parameters.MapType == mpLinar) + pEvolvent = new LinearEvolvent(_N, _m); + if (parameters.MapType == mpNoninjective) + pEvolvent = new NoninjectiveEvolvent(_N, _m,1<<_N); + if (parameters.MapType == mpRotated) + pEvolvent = new RotatedEvolvent(_N, _m); + if (parameters.MapType == mpShifted) + pEvolvent = new ShiftedEvolvent(_N, _m); + if (parameters.MapType == mpSmooth) + pEvolvent = new SmoothEvolvent(_N, _m); + + + return pEvolvent; +} \ No newline at end of file diff --git a/globalizer/evolvent/src/TLinearEvolvent.cpp b/globalizer/evolvent/src/TLinearEvolvent.cpp new file mode 100644 index 0000000..2fe0caf --- /dev/null +++ b/globalizer/evolvent/src/TLinearEvolvent.cpp @@ -0,0 +1,410 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: linarevolvent.cpp // +// // +// Purpose: Source file for linar evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// +#pragma warning(disable:4996) + +/** +\file linarevolvent.cpp + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Реализация класса #LinearEvolvent + +\details Реализация методов класса #LinearEvolvent +*/ + +#include +#include +#include +#include +#include + +#include "TLinearEvolvent.h" +#include "Exception.h" + +namespace +{ + // ------------------------------------------------------------------------------------------------ + void numbr(Extended* iss, const int n1, const Extended& nexp, + int& l, int* iu, int* iv, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate s(u)=is,l(u)=l,v(u)=iv by u=iu */ + + Extended iff, is; + int n, k1, k2, l1; + + n = n1 + 1; + iff = nexp; + is = extZero; + k1 = -1; + for (int i = 0; i < n; i++) + { + iff = iff * extHalf; + k2 = -k1 * iu[i]; + iv[i] = iu[i]; + k1 = k2; + if (k2 < 0) l1 = i; + else { is += iff; l = i; } + } + if (is == extZero) l = n1; + else + { + iv[n1] = -iv[n1]; + if (is == (nexp - extOne)) l = n1; + else if (l1 == n1) iv[l] = -iv[l]; + else l = l1; + } + *iss = is; + } + + // ------------------------------------------------------------------------------------------------ + void xyd(Extended* xx, int m, double y[], int n, + const Extended& nexp, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate preimage x for nearest level m center to y */ + /* (x - left boundary point of level m interval) */ + // int n1, l, iq, iu[MaxDim], iv[MaxDim]; + int n1, l, iu[MaxDim]{}, iv[MaxDim]{}; + + Extended r1, x; + double r; + int iw[MaxDim + 1]{}; + int it; + Extended is; + + n1 = n - 1; + for (int i = 0; i < n; i++) + { + iw[i] = 1; + } + r = 0.5; + r1 = extOne; + x = extZero; + it = 0; + for (int j = 0; j < m; j++) + { + r *= 0.5; + for (int i = 0; i < n; i++) + { + iu[i] = (y[i] < 0) ? -1 : 1; + y[i] -= r * iu[i]; + iu[i] *= iw[i]; + } + std::swap(iu[0], iu[it]); + numbr(&is, n1, nexp, l, iu, iv, extOne, extZero, extHalf); + std::swap(iv[0], iv[it]); + for (int i = 0; i < n; i++) + iw[i] = -iw[i] * iv[i]; + if (l == 0) l = it; + else if (l == it) l = 0; + it = l; + r1 = r1 / nexp; + x += r1 * is; + } + *xx = x; + } + + // ------------------------------------------------------------------------------------------------ + void invmad(int m, Extended xp[], int kp, + int* kxx, double p[], int n, int incr, + const Extended& nexp, + const Extended& mne, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate kx preimage p node */ + /* node type mapping m level */ + + Extended dr, dd, del, d1, x; + double r, d, u[MaxDim], y[MaxDim]; + int i, k, kx; + + kx = 0; + kp--; + for (int i = 0; i < n; i++) + { + u[i] = -1.0; + } + dr = nexp; + for (r = 0.5, i = 0; i < m; i++) + { + r *= 0.5; + } + dr = mne / nexp; + + dr = dr - fmod(dr.toDouble(), extOne.toDouble()); + //dr = (dr>0) ? floor(dr) : ceil(dr); + + del = extOne / (mne - dr); + d1 = del * (incr + 0.5); + for (kx = -1; kx < kp;) + { + for (i = 0; i < n; i++) + { /* label 2 */ + d = p[i]; + y[i] = d - r * u[i]; + } + for (i = 0; (i < n) && (fabs(y[i]) < 0.5); i++); + if (i >= n) + { + xyd(&x, m, y, n, nexp, extOne, extZero, extHalf); + dr = x * mne; + dd = dr - fmod(dr.toDouble(), extOne.toDouble()); + //dd = (dr>0) ? floor(dr) : ceil(dr); + dr = dd / nexp; + dd = dd - dr + fmod(dr.toDouble(), extOne.toDouble()); + //dd = dd - ((dr>0) ? floor(dr) : ceil(dr)); + x = dd * del; + if (kx > kp) break; + k = kx++; /* label 9 */ + if (kx == 0) xp[0] = x; + else + { + while (k >= 0) + { + dr = fabs(x - xp[k]); /* label 11 */ + if (dr <= d1) { + for (kx--; k < kx; k++, xp[k] = xp[k + 1]); + goto m6; + } + else + if (x <= xp[k]) + { + xp[k + 1] = xp[k]; k--; + } + else break; + } + xp[k + 1] = x; + } + } + m6: for (i = n - 1; (i >= 0) && (u[i] = (u[i] <= 0.0) ? 1 : -1) < 0; i--); + if (i < 0) break; + } + *kxx = ++kx; + + } + + // ------------------------------------------------------------------------------------------------ + void node(Extended is, int n1, Extended nexp, int& l, int& iq, int iu[], int iv[], + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate iu=u[s], iv=v[s], l=l[s] by is=s */ + + Extended iff; + + int n = n1 + 1; + if (is == extZero) + { + l = n1; + for (int i = 0; i < n; i++) + { + iu[i] = -1; iv[i] = -1; + } + } + else if (is == (nexp - extOne)) + { + l = n1; + iu[0] = 1; + iv[0] = 1; + for (int i = 1; i < n; i++) { + iu[i] = -1; iv[i] = -1; + } + iv[n1] = 1; + } + else + { + iff = nexp; + int k1 = -1, k2; + for (int i = 0; i < n; i++) + { + iff = iff / 2; + if (is >= iff) { + if ((is == iff) && (is != extOne)) { l = i; iq = -1; } + is = is - iff; + k2 = 1; + } + else + { + k2 = -1; + if ((is == (iff - extOne)) && (is != extZero)) { l = i; iq = 1; } + } + int j = -k1 * k2; + iv[i] = j; + iu[i] = j; + k1 = k2; + } + iv[l] = iv[l] * iq; + iv[n1] = -iv[n1]; + } + } + + // ------------------------------------------------------------------------------------------------ + void mapd(Extended x, int m, double* y, int n, int key, + const Extended& nexp, + const Extended& mne, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* mapping y(x) : 1 - center, 2 - line, 3 - node */ + // use key = 1 + + int n1, l, iq, iu[MaxDim], iv[MaxDim]; + Extended d, is; + double p, r; + int iw[MaxDim]; + int it, k; + + p = 0.0; + n1 = n - 1; + d = x; + r = 0.5; + it = 0; + for (int i = 0; i < n; i++) + { + iw[i] = 1; y[i] = 0.0; + } + + if (key == 2) + { + d = d * (extOne - extOne / mne); k = 0; + } + else if (key > 2) + { + Extended dr = mne / nexp; + dr = dr - fmod(dr.toDouble(), extOne.toDouble()); + //dr=(dr>0)?floor(dr):ceil(dr); + Extended dd = mne - dr; + dr = d * dd; + dd = dr - fmod(dr.toDouble(), extOne.toDouble()); + //dd=(dr>0)?floor(dr):ceil(dr); + dr = dd + (dd - extOne) / (nexp - extOne); + dd = dr - fmod(dr.toDouble(), extOne.toDouble()); + //dd=(dr>0)?floor(dr):ceil(dr); + d = dd * (extOne / (mne - extOne)); + } + + for (int j = 0; j < m; j++) + { + iq = 0; + if (x == extOne) + { + is = nexp - extOne; d = extZero; + } + else + { + d = d * nexp; + is = floor(d); + //is = (int)d.toDouble(); //опасное преобразование при n > 32 + d = d - is; + } + node(is, n1, nexp, l, iq, iu, iv, extOne, extZero, extHalf); + std::swap(iu[0], iu[it]); + std::swap(iv[0], iv[it]); + if (l == 0) + l = it; + else if (l == it) l = 0; + if ((iq > 0) || ((iq == 0) && (is == 0))) k = l; + else if (iq < 0) k = (it == n1) ? 0 : n1; + r = r * 0.5; + it = l; + for (int i = 0; i < n; i++) + { + iu[i] = iu[i] * iw[i]; + iw[i] = -iv[i] * iw[i]; + p = r * iu[i]; + p = p + y[i]; + y[i] = p; + } + } + if (key == 2) + { + int i; + if (is == (nexp - extOne)) i = -1; + else i = 1; + p = 2 * i * iu[k] * r * d.toDouble(); + p = y[k] - p; + y[k] = p; + } + else if (key == 3) + { + for (int i = 0; i < n; i++) + { + p = r * iu[i]; + p = p + y[i]; + y[i] = p; + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +LinearEvolvent::LinearEvolvent(int _N, int _m) : + Evolvent(_N, _m) +{ + nexpExtended = extOne; + for (int i = 0; i < _N; nexpExtended *= 2, i++); + mneExtended = extOne; + for (int i = 0; i < _m; mneExtended *= nexpExtended, i++); +} + +// ------------------------------------------------------------------------------------------------ +LinearEvolvent::~LinearEvolvent() +{ +} + +// ------------------------------------------------------------------------------------------------ +void LinearEvolvent::GetImage(const Extended& x, double* _y, int EvolventNum) +{ + if ((x < 0) || (x > 1)) + { + throw EXCEPTION("x is out of range"); + } + // x ---> y + if (N == 1) + { + y[0] = x.toDouble() - 0.5; + return; + } + mapd(x, m, y, N, 2, nexpExtended, mneExtended, extOne, extNull, extHalf); + transform_P_to_D(); + memcpy(_y, y, N * sizeof(double)); +} + +// ------------------------------------------------------------------------------------------------ +void LinearEvolvent::GetInverseImage(double* _y, Extended& x) +{ + // y ---> x + memcpy(y, _y, N * sizeof(double)); + transform_D_to_P(); + if (N == 1) + { + x = y[0] + 0.5; + return; + } + xyd(&x, m, y, N, nexpExtended, extOne, extNull, extHalf); +} + +// - end of file ---------------------------------------------------------------------------------- diff --git a/globalizer/evolvent/src/TNoninjectiveEvolvent.cpp b/globalizer/evolvent/src/TNoninjectiveEvolvent.cpp new file mode 100644 index 0000000..e6207fd --- /dev/null +++ b/globalizer/evolvent/src/TNoninjectiveEvolvent.cpp @@ -0,0 +1,428 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: noninjectiveevolvent.cpp // +// // +// Purpose: Source file for noninjective evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// +#pragma warning(disable:4996) + +/** +\file noninjectiveevolvent.cpp + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Реализация класса #NoninjectiveEvolvent + +\details Реализация методов класса #NoninjectiveEvolvent +*/ + +#include +#include +#include +#include +#include + +#include "TNoninjectiveEvolvent.h" +#include "Exception.h" + +namespace +{ + // ------------------------------------------------------------------------------------------------ + void numbr(Extended* iss, const int n1, const Extended& nexp, + int& l, int* iu, int* iv, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate s(u)=is,l(u)=l,v(u)=iv by u=iu */ + + Extended iff, is; + int n, k1, k2, l1; + + n = n1 + 1; + iff = nexp; + is = extZero; + k1 = -1; + for (int i = 0; i < n; i++) + { + iff = iff * extHalf; + k2 = -k1 * iu[i]; + iv[i] = iu[i]; + k1 = k2; + if (k2 < 0) l1 = i; + else { is += iff; l = i; } + } + if (is == extZero) l = n1; + else + { + iv[n1] = -iv[n1]; + if (is == (nexp - extOne)) l = n1; + else if (l1 == n1) iv[l] = -iv[l]; + else l = l1; + } + *iss = is; + } + + // ------------------------------------------------------------------------------------------------ + void xyd(Extended* xx, int m, double y[], int n, + const Extended& nexp, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate preimage x for nearest level m center to y */ + /* (x - left boundary point of level m interval) */ + // int n1, l, iq, iu[MaxDim], iv[MaxDim]; + int n1, l, iu[MaxDim]{}, iv[MaxDim]{}; + + Extended r1, x; + double r; + int iw[MaxDim + 1]{}; + int it; + Extended is; + + n1 = n - 1; + for (int i = 0; i < n; i++) + { + iw[i] = 1; + } + r = 0.5; + r1 = extOne; + x = extZero; + it = 0; + for (int j = 0; j < m; j++) + { + r *= 0.5; + for (int i = 0; i < n; i++) + { + iu[i] = (y[i] < 0) ? -1 : 1; + y[i] -= r * iu[i]; + iu[i] *= iw[i]; + } + std::swap(iu[0], iu[it]); + numbr(&is, n1, nexp, l, iu, iv, extOne, extZero, extHalf); + std::swap(iv[0], iv[it]); + for (int i = 0; i < n; i++) + iw[i] = -iw[i] * iv[i]; + if (l == 0) l = it; + else if (l == it) l = 0; + it = l; + r1 = r1 / nexp; + x += r1 * is; + } + *xx = x; + } + + // ------------------------------------------------------------------------------------------------ + void invmad(int m, Extended xp[], int kp, + int* kxx, double p[], int n, int incr, + const Extended& nexp, + const Extended& mne, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate kx preimage p node */ + /* node type mapping m level */ + + Extended dr, dd, del, d1, x; + double r, d, u[MaxDim], y[MaxDim]; + int i, k, kx; + + kx = 0; + kp--; + for (int i = 0; i < n; i++) + { + u[i] = -1.0; + } + dr = nexp; + for (r = 0.5, i = 0; i < m; i++) + { + r *= 0.5; + } + dr = mne / nexp; + + dr = dr - fmod(dr.toDouble(), extOne.toDouble()); + //dr = (dr>0) ? floor(dr) : ceil(dr); + + del = extOne / (mne - dr); + d1 = del * (incr + 0.5); + for (kx = -1; kx < kp;) + { + for (i = 0; i < n; i++) + { /* label 2 */ + d = p[i]; + y[i] = d - r * u[i]; + } + for (i = 0; (i < n) && (fabs(y[i]) < 0.5); i++); + if (i >= n) + { + xyd(&x, m, y, n, nexp, extOne, extZero, extHalf); + dr = x * mne; + dd = dr - fmod(dr.toDouble(), extOne.toDouble()); + //dd = (dr>0) ? floor(dr) : ceil(dr); + dr = dd / nexp; + dd = dd - dr + fmod(dr.toDouble(), extOne.toDouble()); + //dd = dd - ((dr>0) ? floor(dr) : ceil(dr)); + x = dd * del; + if (kx > kp) break; + k = kx++; /* label 9 */ + if (kx == 0) xp[0] = x; + else + { + while (k >= 0) + { + dr = fabs(x - xp[k]); /* label 11 */ + if (dr <= d1) { + for (kx--; k < kx; k++, xp[k] = xp[k + 1]); + goto m6; + } + else + if (x <= xp[k]) + { + xp[k + 1] = xp[k]; k--; + } + else break; + } + xp[k + 1] = x; + } + } + m6: for (i = n - 1; (i >= 0) && (u[i] = (u[i] <= 0.0) ? 1 : -1) < 0; i--); + if (i < 0) break; + } + *kxx = ++kx; + + } + + // ------------------------------------------------------------------------------------------------ + void node(Extended is, int n1, Extended nexp, int& l, int& iq, int iu[], int iv[], + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* calculate iu=u[s], iv=v[s], l=l[s] by is=s */ + + Extended iff; + + double is_tmp = is.toDouble(); + double extZero_tmp = extZero.toDouble(); + double nexp_tmp = nexp.toDouble(); + double extOne_tmp = extOne.toDouble(); + + int n = n1 + 1; + if (is == extZero) + { + l = n1; + for (int i = 0; i < n; i++) + { + iu[i] = -1; iv[i] = -1; + } + } + else if (is == (nexp - extOne)) + { + l = n1; + iu[0] = 1; + iv[0] = 1; + for (int i = 1; i < n; i++) { + iu[i] = -1; iv[i] = -1; + } + iv[n1] = 1; + } + else + { + iff = nexp; + int k1 = -1, k2; + for (int i = 0; i < n; i++) + { + iff = iff / 2; + if (is >= iff) { + if ((is == iff) && (is != extOne)) { l = i; iq = -1; } + is = is - iff; + k2 = 1; + } + else + { + k2 = -1; + if ((is == (iff - extOne)) && (is != extZero)) { l = i; iq = 1; } + } + int j = -k1 * k2; + iv[i] = j; + iu[i] = j; + k1 = k2; + } + iv[l] = iv[l] * iq; + iv[n1] = -iv[n1]; + } + } + + /*Extended ceil(const Extended& x, const Extended& extZero) + { + Extended floor_val = floor(x); + Extended frac = x - floor_val; + if (frac == extZero) + { + return floor_val; + } + else + { + return floor_val + Extended(1); + } + }*/ + + // ------------------------------------------------------------------------------------------------ + void mapd(Extended x, int m, double* y, int n, int key, + const Extended& nexp, + const Extended& mne, + const Extended& extOne, + const Extended& extZero, + const Extended& extHalf) + { + /* mapping y(x) : 1 - center, 2 - line, 3 - node */ + // use key = 1 + + int n1, l, iq, iu[MaxDim], iv[MaxDim]; + Extended d, is; + double p, r; + int iw[MaxDim]; + int it, k; + + p = 0.0; + n1 = n - 1; + d = x; + r = 0.5; + it = 0; + for (int i = 0; i < n; i++) + { + iw[i] = 1; y[i] = 0.0; + } + + if (key == 2) + { + d = d * (extOne - extOne / mne); k = 0; + } + else if (key > 2) + { + Extended dr = mne / nexp; + //dr = dr - fmod(dr.toDouble(), extOne.toDouble()); // нужно заменить fmod на функцию для типа данных Extended + dr=(dr>0)?floor(dr):ceil(dr, extZero); + Extended dd = mne - dr; + dr = d * dd; + //dd = dr - fmod(dr.toDouble(), extOne.toDouble()); // нужно заменить fmod на функцию для типа данных Extended + dd=(dr>0)?floor(dr):ceil(dr, extZero); + dr = dd + (dd - extOne) / (nexp - extOne); + //dd = dr - fmod(dr.toDouble(), extOne.toDouble()); // нужно заменить fmod на функцию для типа данных Extended + dd=(dr>0)?floor(dr):ceil(dr, extZero); + d = dd * (extOne / (mne - extOne)); + } + + for (int j = 0; j < m; j++) + { + iq = 0; + if (x == extOne) + { + is = nexp - extOne; d = extZero; + } + else + { + d = d * nexp; + is = floor(d); + //is = (int)d.toDouble(); //опасное преобразование при n > 32 + d = d - is; + } + node(is, n1, nexp, l, iq, iu, iv, extOne, extZero, extHalf); + std::swap(iu[0], iu[it]); + std::swap(iv[0], iv[it]); + if (l == 0) + l = it; + else if (l == it) l = 0; + if ((iq > 0) || ((iq == 0) && (is == 0))) k = l; + else if (iq < 0) k = (it == n1) ? 0 : n1; + r = r * 0.5; + it = l; + for (int i = 0; i < n; i++) + { + iu[i] = iu[i] * iw[i]; + iw[i] = -iv[i] * iw[i]; + p = r * iu[i]; + p = p + y[i]; + y[i] = p; + } + } + if (key == 2) + { + int i; + if (is == (nexp - extOne)) i = -1; + else i = 1; + p = 2 * i * iu[k] * r * d.toDouble(); + p = y[k] - p; + y[k] = p; + } + else if (key == 3) + { + for (int i = 0; i < n; i++) + { + p = r * iu[i]; + p = p + y[i]; + y[i] = p; + } + } + } +} + +NoninjectiveEvolvent::NoninjectiveEvolvent(int _N, int _m, int _max_preimages) : + Evolvent(_N, _m) +{ + max_preimages = _max_preimages; + nexpExtended = extOne; + for (int i = 0; i < _N; nexpExtended *= 2, i++); + mneExtended = extOne; + for (int i = 0; i < _m; mneExtended *= nexpExtended, i++); +} + +// ------------------------------------------------------------------------------------------------ +NoninjectiveEvolvent::~NoninjectiveEvolvent() +{ +} + +// ------------------------------------------------------------------------------------------------ +void NoninjectiveEvolvent::GetImage(const Extended& x, double* _y, int EvolventNum) +{ + if ((x < 0) || (x > 1)) + { + throw EXCEPTION("x is out of range"); + } + // x ---> y + if (N == 1) + { + y[0] = x.toDouble() - 0.5; + return; + } + mapd(x, m, y, N, 3, nexpExtended, mneExtended, extOne, extNull, extHalf); + transform_P_to_D(); + memcpy(_y, y, N * sizeof(double)); +} + +// ------------------------------------------------------------------------------------------------ +int NoninjectiveEvolvent::GetNoninjectivePreimages(double* _y, Extended* x) +{ + memcpy(y, _y, N * sizeof(double)); + transform_D_to_P(); + int preimNumber = 1; + if (N == 1) + x[0] = y[0] + 0.5; + else + invmad(m, x, max_preimages, &preimNumber, y, N, 1, nexpExtended, mneExtended, extOne, extNull, extHalf); + return preimNumber; +} + +// - end of file ---------------------------------------------------------------------------------- diff --git a/globalizer/evolvent/src/TRotatedEvolvent.cpp b/globalizer/evolvent/src/TRotatedEvolvent.cpp new file mode 100644 index 0000000..ec53049 --- /dev/null +++ b/globalizer/evolvent/src/TRotatedEvolvent.cpp @@ -0,0 +1,108 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: rotatedevolvent.cpp // +// // +// Purpose: Source file for rotated evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// +#pragma warning(disable:4996) + +/** +\file rotatedevolvent.cpp + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Реализация класса #RotatedEvolvent + +\details Реализация методов класса #RotatedEvolvent +*/ + +#include +#include +#include +#include +#include + +#include "TRotatedEvolvent.h" +#include "Exception.h" + +RotatedEvolvent::RotatedEvolvent(int _N, int _m, int _L) : + Evolvent(_N, _m) +{ + L = _L; + // !!!!!!!!!!!!! + if (N == 1) + return; + // !!!!!!!!!!!!! + PlaneCount = N * (N - 1) / 2; + if ((L < 1) || (L > 2 * PlaneCount + 1)) + { + throw EXCEPTION("L is out of range"); + } + GetAllPlanes(); + PowOfHalf[0] = 1; + for (int i = 1; i < m + 2; i++) + PowOfHalf[i] = PowOfHalf[i - 1] / 2; +} + +// ------------------------------------------------------------------------------------------------ +RotatedEvolvent::~RotatedEvolvent() +{ +} + +// ------------------------------------------------------------------------------------------------ +void RotatedEvolvent::GetAllPlanes() +{ + const int k = 2; // Подмножества из двух элементов + int plane[k]; // Два номера под элементы + + for (int i = 0; i < k; i++) + plane[i] = i; + + if (N <= k) + { + for (int i = 0; i < k; i++) + { + Planes[0][i] = plane[i]; + } + return; + } + int p = k - 1; + int counter = 0; //счетчик числа перестановок + while (p >= 0) + { + for (int i = 0; i < k; i++) + { + Planes[counter][i] = plane[i]; + } + counter++; + + if (plane[k - 1] == N - 1) + { + p--; + } + else + { + p = k - 1; + } + + if (p >= 0) + { + for (int i = k - 1; i >= p; i--) + { + plane[i] = plane[p] + i - p + 1; + } + } + } +} + +// - end of file ---------------------------------------------------------------------------------- diff --git a/globalizer/evolvent/src/TShiftedEvolvent.cpp b/globalizer/evolvent/src/TShiftedEvolvent.cpp new file mode 100644 index 0000000..d05542e --- /dev/null +++ b/globalizer/evolvent/src/TShiftedEvolvent.cpp @@ -0,0 +1,113 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: shiftedevolvent.cpp // +// // +// Purpose: Source file for shifted evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// +#pragma warning(disable:4996) + +/** +\file shiftedevolvent.cpp + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Реализация класса #ShiftedEvolvent + +\details Реализация методов класса #ShiftedEvolvent +*/ + +#include +#include +#include +#include +#include + +#include "TShiftedEvolvent.h" +#include "Exception.h" + +// ------------------------------------------------------------------------------------------------ +ShiftedEvolvent::ShiftedEvolvent(int _N, int _m, int _L) : + Evolvent(_N, _m) +{ + if ((_L < 0) || (_L >= m)) + { + throw EXCEPTION("L is out of range"); + } + L = _L; + //Инициализация массива степеней двойки + PowOf2[0] = 1; + for (int i = 1; i <= L * N; i++) + PowOf2[i] = PowOf2[i - 1] * 2; + +} + +// ------------------------------------------------------------------------------------------------ +ShiftedEvolvent::~ShiftedEvolvent() +{ +} + +// ------------------------------------------------------------------------------------------------ +void ShiftedEvolvent::transform_P_to_Pl(int EvolventNum) +{ + // if (N == 1) return; + // transformation from hypercube P to hypercube P[l] + double temp; + if (EvolventNum == 0) + { + temp = 0.0; + } + else + { + temp = 1.0 / PowOf2[EvolventNum]; // temp = 1 / 2^l (l = 1,...,L) + } + for (int i = 0; i < N; i++) + { + y[i] = y[i] * 2 + 0.5 - temp; + } +} + +// ------------------------------------------------------------------------------------------------ +void ShiftedEvolvent::transform_Pl_to_P(int EvolventNum) +{ + // if (N == 1) return; + // transformation from hypercube P to hypercube P[l] + double temp; + if (EvolventNum == 0) + { + temp = 0; + } + else + { + temp = 1.0 / PowOf2[EvolventNum]; // temp = 1 / 2^l (l = 1,...,L) + } + for (int i = 0; i < N; i++) + { + y[i] = (y[i] - 0.5 + temp) / 2; + } +} + +// ------------------------------------------------------------------------------------------------ +double ShiftedEvolvent::ZeroConstraint() +{ + double CurZ = -MaxDouble; + for (int i = 0; i < N; i++) + { + if (fabs(y[i]) - 0.5 > CurZ) + { + CurZ = fabs(y[i]) - 0.5; + } + } + return CurZ; +} + +// - end of file ---------------------------------------------------------------------------------- diff --git a/globalizer/evolvent/src/TSmoothEvolvent.cpp b/globalizer/evolvent/src/TSmoothEvolvent.cpp new file mode 100644 index 0000000..cadd6fe --- /dev/null +++ b/globalizer/evolvent/src/TSmoothEvolvent.cpp @@ -0,0 +1,312 @@ +///////////////////////////////////////////////////////////////////////////// +// // +// LOBACHEVSKY STATE UNIVERSITY OF NIZHNY NOVGOROD // +// // +// Copyright (c) 2015 by UNN. // +// All Rights Reserved. // +// // +// File: smoothevolvent.cpp // +// // +// Purpose: Source file for smooth evolvent classes // +// // +// Author(s): Barkalov K., Sysoyev A. // +// // +///////////////////////////////////////////////////////////////////////////// +#pragma warning(disable:4996) + +/** +\file smoothevolvent.cpp + +\authors Баркалов К., Сысоев А. +\date 2015-2016 +\copyright ННГУ им. Н.И. Лобачевского + +\brief Реализация класса #SmoothEvolvent + +\details Реализация методов класса #SmoothEvolvent +*/ + +#include +#include +#include +#include +#include + +#include "TSmoothEvolvent.h" +#include "Exception.h" + +namespace +{ + // ------------------------------------------------------------------------------------------------ + int _Pow_int(int x, int n) + { + int val = 1; + for (int i = 0; i < n; i++) + val *= x; + return val; + } + + // ------------------------------------------------------------------------------------------------ + double Hermit(double y0, double d0, double y1, double d1, double h, double x) + { + return y0 + (x + h) * (d0 + (x + h) * (d0 - (y0 - y1) / (-2 * h) + + (x - h) * (d0 - 2 * (y0 - y1) / (-2 * h) + d1) / (-2 * h)) / (-2 * h)); + } + + // ------------------------------------------------------------------------------------------------ + double HermitDer(double y0, double d0, double y1, double d1, double h, double x) + { + return pow(h, -3) * (d0 * h * (-0.25 * h * h - 0.5 * h * x + 0.75 * x * x) + + d1 * h * (-0.25 * h * h + 0.5 * h * x + 0.75 * x * x) + - 0.75 * h * h * y0 + 0.75 * h * h * y1 + + 0.75 * x * x * y0 + - 0.75 * x * x * y1); + } + + // ------------------------------------------------------------------------------------------------ + int node_smooth(int is, int n, int& iq, int nexp, int* iu, int* iv) + { + /* calculate iu=u[s], iv=v[s], l=l[s] by is=s */ + iq = 0; + int k1, k2, iff; + static int l = 0; + if (is == 0) + { + l = n - 1; + for (int i = 0; i < n; i++) + { + iu[i] = -1; + iv[i] = -1; + } + } + else + if (is == (nexp - 1)) + { + l = n - 1; + iu[0] = 1; + iv[0] = 1; + for (int i = 1; i < n; i++) + { + iu[i] = -1; + iv[i] = -1; + } + iv[n - 1] = 1; + } + else + { + iff = nexp; + k1 = -1; + for (int i = 0; i < n; i++) + { + iff /= 2; + if (is >= iff) + { + if ((is == iff) && (is != 1)) { l = i; iq = -1; } + is = is - iff; + k2 = 1; + } + else + { + k2 = -1; + if ((is == (iff - 1)) && (is != 0)) { l = i; iq = 1; } + } + iu[i] = iv[i] = -k1 * k2; + k1 = k2; + } + iv[l] *= iq; + iv[n - 1] = -iv[n - 1]; + } + return l; + } + + // ------------------------------------------------------------------------------------------------ + void SmoothEvolventDer(double x, int n, int m, std::vector& y, std::vector& y_, bool c) + { + if (y.size() != n) + y.assign(n, .0); + if (y_.size() != n) + y_.assign(n, .0); + int l = 0, iq = 0; + std::vector iu(n, 0); + std::vector iv(n, 0); + int nexp = _Pow_int(2, n); // nexp=2**n */ + double mnexp = _Pow_int(nexp, m); // mnexp=2**(nm) + double d = 1.0 / mnexp; + std::vector iw(n, 0); + double xd = x; + int it = 0; + double dr = nexp; + for (int i = 0; i < n; i++) + { + iw[i] = 1; + y[i] = 0; + } + int k = 0; + double r = 0.5; + int ic; + for (int j = 0; j < m; j++) + { + if (x == 1.0 - d) + { + ic = nexp - 1; + xd = 0.0; + } + else + { + xd = xd * nexp; + ic = (int)xd; + xd = xd - ic; + } + iq = 0; + l = node_smooth(ic, n, iq, nexp, iu.data(), iv.data()); + int swp = iu[it]; + iu[it] = iu[0]; + iu[0] = swp; + swp = iv[it]; + iv[it] = iv[0]; + iv[0] = swp; + if (l == 0) + l = it; + else if (l == it) + l = 0; + if ((iq > 0) || ((iq == 0) && (ic == 0))) + k = l; + else if (iq < 0) + { + if (it == n - 1) + k = 0; + else + k = n - 1; + } + r *= 0.5; + it = l; + for (int i = 0; i < n; i++) + { + iu[i] *= iw[i]; + iw[i] *= -iv[i]; + y[i] += r * iu[i]; + } + } + if (c) + { + if (ic == (nexp - 1)) + { + y[k] += 2 * iu[k] * r * xd; + y_[k] = ((iu[k] > 0) ? 1 : (iu[k] < 0) ? -1 : 0) * pow(2, m * (n - 1)); + } + else + { + y[k] -= 2 * iu[k] * r * xd; + y_[k] = -((iu[k] > 0) ? 1 : (iu[k] < 0) ? -1 : 0) * pow(2, m * (n - 1)); + } + if (x == 1.0 - d) + { + std::vector y0(n, 0); + y_[k] = 0; + ::SmoothEvolventDer(x - d / 2, n, m, y0, y_, true); + } + } + } +} + +SmoothEvolvent::SmoothEvolvent(int _N, int _m, double _h) : + Evolvent(_N, _m) +{ + if (_N > 2) + { + std::cout << "Warning: smooth evolvent is very slow when problem dimension > 2\n"; + } + h = _h; + if (h < 0 || h > 1) + { + throw EXCEPTION("h is out of range"); + } + continuously = h != 1. ? true : false; + smoothPointCount = 0; + tmp_y.resize(N); + tmp_y_.resize(N); +} + +// ------------------------------------------------------------------------------------------------ +void SmoothEvolvent::GetInverseImage(double* _y, Extended& x) +{ + throw EXCEPTION("This method is not implemented for the smooth evolvent"); +} + +// ------------------------------------------------------------------------------------------------ +void SmoothEvolvent::GetYOnXSmooth(double x, std::vector& y, std::vector& y_) +{ + y.assign(N, .0); + y_.assign(N, .0); + + if (N == 1) + { + y[0] = x - 0.5; + return; + } + + int l = 0, iq = 0; + std::vector iu(N, 0); + std::vector iv(N, 0); + int nexp = _Pow_int(2, N); // nexp=2**n + double mnexp = pow(nexp, m); // mnexp=2**(nm) + double d = 1.0 / mnexp; + double dh = d * h; + double xc = 0; + while (xc < x) + xc += d; + if (((h > 0) && (h <= .5) && (x > dh) && (x < 1 - d - dh) && ((xc - x < dh) || (xc - x > d - dh))) && continuously) + { + smoothPointCount++; + + std::vector y0(N, 0); + std::vector y1(N, 0); + std::vector y0_(N, 0); + std::vector y1_(N, 0); + double xh = 0; + if (xc - x < dh) + { + xh += x - xc; + SmoothEvolventDer(xc - dh, N, m, y0, y0_, true); + SmoothEvolventDer(xc + dh, N, m, y1, y1_, true); + } + else + { + xh += x - xc + d; + SmoothEvolventDer(xc - d - dh, N, m, y0, y0_, true); + SmoothEvolventDer(xc - d + dh, N, m, y1, y1_, true); + } + int i0 = -1, i1 = -1; + for (int i = 0; i < N; i++) + { + if (y1[i] != y0[i]) + { + if (i0 == -1) + i0 = i; + else + i1 = i; + } + else + { + y[i] = y0[i]; + y_[i] = 0; + } + } + if (i0 != -1 && i1 != -1) + { + y[i0] = Hermit(y0[i0], y0_[i0], y1[i0], y1_[i0], dh, xh); + y_[i0] = HermitDer(y0[i0], y0_[i0], y1[i0], y1_[i0], dh, xh); + y[i1] = Hermit(y0[i1], y0_[i1], y1[i1], y1_[i1], dh, xh); + y_[i1] = HermitDer(y0[i1], y0_[i1], y1[i1], y1_[i1], dh, xh); + return; + } + } + SmoothEvolventDer(x, N, m, y, y_, continuously); +} + +// ------------------------------------------------------------------------------------------------ +SmoothEvolvent::~SmoothEvolvent() +{ +} + +// - end of file ---------------------------------------------------------------------------------- diff --git a/globalizer/extended/include/Extended.h b/globalizer/extended/include/Extended.h index a1b0df7..daa8842 100644 --- a/globalizer/extended/include/Extended.h +++ b/globalizer/extended/include/Extended.h @@ -117,6 +117,7 @@ class Extended friend Extended operator/(const double& e1, const Extended& e2); friend Extended fabs(const Extended& e); + friend Extended ceil(const Extended& x, const Extended& extZero); friend double floor(const Extended& e); friend Extended pow(const Extended& e, double degree); // this method is used for distance between two points diff --git a/globalizer/extended/src/Extended.cpp b/globalizer/extended/src/Extended.cpp index 471a71e..b57cb56 100644 --- a/globalizer/extended/src/Extended.cpp +++ b/globalizer/extended/src/Extended.cpp @@ -600,7 +600,7 @@ Extended Extended::operator/(const double& e) const } //------------------------------------------ -// friend operations (+,-,*,/,floor,pow,root) +// friend operations (+,-,*,/,ceil,floor,pow,root) //------------------------------------------ Extended operator+(const double& e1, const Extended& e2) @@ -653,8 +653,23 @@ Extended fabs(const Extended& e) return res; } +Extended ceil(const Extended& x, const Extended& extZero) +{ + Extended floor_val = floor(x); + Extended frac = x - floor_val; + if (frac == extZero) + { + return floor_val; + } + else + { + return floor_val + Extended(1); + } +} + double floor(const Extended& e) { + double e_tmp = e.toDouble(); double res = 0.0; switch (Extended::type) { diff --git a/globalizer/include/Common.h b/globalizer/include/Common.h index d482032..8ce960a 100644 --- a/globalizer/include/Common.h +++ b/globalizer/include/Common.h @@ -164,7 +164,17 @@ enum ETypeSolver enum EMapType { ///Базовый, одиночный вариант - mpBase + mpBase, + + mpLinar, + + mpNoninjective, + + mpRotated, + + mpShifted, + + mpSmooth }; ///Тип распределения начальных точек diff --git a/globalizer/include/GlobProcess.h b/globalizer/include/GlobProcess.h index f96ccaf..75cebbd 100644 --- a/globalizer/include/GlobProcess.h +++ b/globalizer/include/GlobProcess.h @@ -23,7 +23,12 @@ #include "Parameters.h" #include "Performance.h" #include "ProblemInterface.h" -#include "Evolvent.h" +#include "EvolventInterface.h" +//#include "TLinearEvolvent.h" +//#include "TNoninjectiveEvolvent.h" +//#include "TRotatedEvolvent.h" +//#include "TShiftedEvolvent.h" +//#include "TSmoothEvolvent.h" #include "CalculationFactory.h" //extern const int MaxNumOfTaskLevels; @@ -58,7 +63,7 @@ class Process - множественная сдвиговая развертка - множественная вращаемая развертка */ - Evolvent* evolvent; + IEvolvent* pEvolvent; /// Вычислитель Calculation* calculation; diff --git a/globalizer/method/calculation/include/CalculationFactory.h b/globalizer/method/calculation/include/CalculationFactory.h index cf75335..b5dcc99 100644 --- a/globalizer/method/calculation/include/CalculationFactory.h +++ b/globalizer/method/calculation/include/CalculationFactory.h @@ -27,7 +27,7 @@ #define __CALCULATION_FACTORY_H__ #include "Calculation.h" -#include "Evolvent.h" +#include "EvolventInterface.h" /** * \brief Класс-фабрика для создания объектов-вычислителей. @@ -47,7 +47,7 @@ class CalculationFactory * \param evolvent Указатель на эвольвенту (опционально). * \return Указатель на объект #Calculation. */ - static Calculation* CreateCalculation(Task& _pTask, Evolvent* evolvent = 0); + static Calculation* CreateCalculation(Task& _pTask, IEvolvent* evolvent = 0); /** * \brief Создает или возвращает существующий вычислитель (альтернативная логика). * @@ -55,7 +55,7 @@ class CalculationFactory * \param evolvent Указатель на эвольвенту (опционально). * \return Указатель на объект #Calculation. */ - static Calculation* CreateCalculation2(Task& _pTask, Evolvent* evolvent = 0); + static Calculation* CreateCalculation2(Task& _pTask, IEvolvent* evolvent = 0); /** * \brief Всегда создает новый экземпляр вычислителя. @@ -65,7 +65,7 @@ class CalculationFactory * \param evolvent Указатель на эвольвенту (опционально). * \return Указатель на новый объект #Calculation. */ - static Calculation* CreateNewCalculation(Task& _pTask, Evolvent* evolvent = 0); + static Calculation* CreateNewCalculation(Task& _pTask, IEvolvent* evolvent = 0); }; diff --git a/globalizer/method/calculation/src/CalculationFactory.cpp b/globalizer/method/calculation/src/CalculationFactory.cpp index 9f453c5..f287e86 100644 --- a/globalizer/method/calculation/src/CalculationFactory.cpp +++ b/globalizer/method/calculation/src/CalculationFactory.cpp @@ -22,7 +22,7 @@ // ------------------------------------------------------------------------------------------------ -Calculation* CalculationFactory::CreateCalculation2(Task& _pTask, Evolvent* evolvent) +Calculation* CalculationFactory::CreateCalculation2(Task& _pTask, IEvolvent* evolvent) { Calculation* calculation = 0; @@ -111,7 +111,7 @@ Calculation* CalculationFactory::CreateCalculation2(Task& _pTask, Evolvent* evol // ------------------------------------------------------------------------------------------------ -Calculation* CalculationFactory::CreateCalculation(Task& _pTask, Evolvent* evolvent) +Calculation* CalculationFactory::CreateCalculation(Task& _pTask, IEvolvent* evolvent) { Calculation* calculation = 0; @@ -191,7 +191,7 @@ Calculation* CalculationFactory::CreateCalculation(Task& _pTask, Evolvent* evolv return calculation; } -Calculation* CalculationFactory::CreateNewCalculation(Task& _pTask, Evolvent* evolvent) +Calculation* CalculationFactory::CreateNewCalculation(Task& _pTask, IEvolvent* evolvent) { Calculation* calculation = 0; diff --git a/globalizer/method/include/Method.h b/globalizer/method/include/Method.h index 332411a..008477d 100644 --- a/globalizer/method/include/Method.h +++ b/globalizer/method/include/Method.h @@ -80,7 +80,7 @@ class Method : public IMethod - множественная сдвиговая развертка - множественная вращаемая развертка */ - Evolvent& evolvent; + IEvolvent& evolvent; // ---------------------------------------------------------------------------- // Внутренние данные метода @@ -244,7 +244,7 @@ class Method : public IMethod public: Method(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent); + Calculation& _Calculation, IEvolvent& _Evolvent); virtual ~Method(); /** Функция выполняет первую итерацию метода diff --git a/globalizer/method/include/MethodFactory.h b/globalizer/method/include/MethodFactory.h index d5d2439..cdeea02 100644 --- a/globalizer/method/include/MethodFactory.h +++ b/globalizer/method/include/MethodFactory.h @@ -23,7 +23,7 @@ class MethodFactory { public: static IMethod* CreateMethod(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent); + Calculation& _Calculation, IEvolvent& _Evolvent); }; #endif diff --git a/globalizer/method/include/MixedIntegerMethod.h b/globalizer/method/include/MixedIntegerMethod.h index f7193bc..81d3e8b 100644 --- a/globalizer/method/include/MixedIntegerMethod.h +++ b/globalizer/method/include/MixedIntegerMethod.h @@ -72,7 +72,7 @@ class MixedIntegerMethod : public Method public: MixedIntegerMethod(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent); + Calculation& _Calculation, IEvolvent& _Evolvent); virtual ~MixedIntegerMethod(); /** Функция выполняет первую итерацию метода diff --git a/globalizer/method/include/RSAMethod.hpp b/globalizer/method/include/RSAMethod.hpp index 5436eba..27c52ea 100644 --- a/globalizer/method/include/RSAMethod.hpp +++ b/globalizer/method/include/RSAMethod.hpp @@ -78,7 +78,7 @@ class Method_RSA : public IMethod - - */ - Evolvent& evolvent; + IEvolvent& evolvent; // ---------------------------------------------------------------------------- // @@ -223,7 +223,7 @@ class Method_RSA : public IMethod public: Method_RSA(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent); + Calculation& _Calculation, IEvolvent& _Evolvent); virtual ~Method_RSA(); /** diff --git a/globalizer/method/include/Trial.h b/globalizer/method/include/Trial.h index 2dd5479..2aa1a39 100644 --- a/globalizer/method/include/Trial.h +++ b/globalizer/method/include/Trial.h @@ -79,7 +79,7 @@ class Trial */ void SetX(Extended d); - /// Присвоение координаты точки в одномерном прогстранстве + /// Присвоение координаты точки в одномерном пространстве virtual Trial& operator = (Extended d); /// Возвращает координату точки diff --git a/globalizer/method/src/Method.cpp b/globalizer/method/src/Method.cpp index 767b94b..72e8379 100644 --- a/globalizer/method/src/Method.cpp +++ b/globalizer/method/src/Method.cpp @@ -40,7 +40,7 @@ // ------------------------------------------------------------------------------------------------ Method::Method(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent) : + Calculation& _Calculation, IEvolvent& _Evolvent) : pTask(_pTask), pData(&_pData), calculation(_Calculation), evolvent(_Evolvent) { diff --git a/globalizer/method/src/MethodFactory.cpp b/globalizer/method/src/MethodFactory.cpp index b4a8fe5..82a598f 100644 --- a/globalizer/method/src/MethodFactory.cpp +++ b/globalizer/method/src/MethodFactory.cpp @@ -22,7 +22,7 @@ // ------------------------------------------------------------------------------------------------ IMethod* MethodFactory::CreateMethod(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent) + Calculation& _Calculation, IEvolvent& _Evolvent) { IMethod* pMethod = 0; if (parameters.TypeMethod == StandartMethod) diff --git a/globalizer/method/src/MixedIntegerMethod.cpp b/globalizer/method/src/MixedIntegerMethod.cpp index b4f533a..3a282f0 100644 --- a/globalizer/method/src/MixedIntegerMethod.cpp +++ b/globalizer/method/src/MixedIntegerMethod.cpp @@ -42,7 +42,7 @@ // ------------------------------------------------------------------------------------------------ MixedIntegerMethod::MixedIntegerMethod(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent) : Method(_pTask, _pData, _Calculation, _Evolvent) + Calculation& _Calculation, IEvolvent& _Evolvent) : Method(_pTask, _pData, _Calculation, _Evolvent) { } diff --git a/globalizer/method/src/RSAMethod.cpp b/globalizer/method/src/RSAMethod.cpp index 292fe5b..1e9a97e 100644 --- a/globalizer/method/src/RSAMethod.cpp +++ b/globalizer/method/src/RSAMethod.cpp @@ -40,7 +40,7 @@ // ------------------------------------------------------------------------------------------------ Method_RSA::Method_RSA(Task& _pTask, SearchData& _pData, - Calculation& _Calculation, Evolvent& _Evolvent) : + Calculation& _Calculation, IEvolvent& _Evolvent) : pTask(_pTask), pData(&_pData), calculation(_Calculation), evolvent(_Evolvent) { @@ -184,7 +184,14 @@ void Method_RSA::CalculateImage(Trial& pCurTrialsj) void Method_RSA::CalculateCurrentPoint(Trial& pCurTrialsj, SearchInterval* BestIntervalsj) { // Вычисляем x - pCurTrialsj.SetX(0.5 * (BestIntervalsj->xl() + BestIntervalsj->xr())); + //Extended delta_x = BestIntervalsj->xr() - BestIntervalsj->xl(); + Extended left_x = BestIntervalsj->xl(), right_x = BestIntervalsj->xr(); + double left_z = BestIntervalsj->LeftPoint->GetValue(), right_z = BestIntervalsj->RightPoint->GetValue(); + Extended delta_x = right_x - left_x; + double sign = right_z - left_z < 0.0 ? -1.0 : 1.0; + Extended point_x = 0.5 * (left_x + right_x);// -sign * 0.25 * pow(abs(right_z - left_z) / (right_z + left_z), pTask.GetN()) * delta_x; + pCurTrialsj.SetX(point_x); + //pCurTrialsj.SetX(0.5 * (BestIntervalsj->xl() + BestIntervalsj->xr())); pCurTrialsj.leftInterval = BestIntervalsj; pCurTrialsj.rightInterval = BestIntervalsj; @@ -538,22 +545,6 @@ void Method_RSA::Recalc() { if (pData->IsRecalc()) { - // Обновить текущие значение минимумов - for (int v = 0; v <= pData->GetBestTrial()->index; v++) - { - if (v < pData->GetBestTrial()->index) - { - pData->Z[v] = -pData->M[v] * parameters.rEps; - } - else - { - if (pData->GetBestTrial()->FuncValues[v] != MaxDouble) - pData->Z[v] = pData->GetBestTrial()->FuncValues[v]; - else - pData->Z[v] = 0; - } - } - pData->ClearQueue(); for (SearcDataIterator it = pData->GetBeginIterator(); it; ++it) { @@ -1079,38 +1070,121 @@ SearchInterval* Method_RSA::AddCurrentPoint(Trial& pCurTrialsj, SearchInterval* // ------------------------------------------------------------------------------------------------ void Method_RSA::RenewSearchData() { + for (unsigned int j = 0; j < iteration.pCurTrials.size(); j++) + { + SearchInterval* interval = iteration.pCurTrials[j]->leftInterval; + pData->PushToQueue((interval)); + } + for (unsigned int j = 0; j < iteration.pCurTrials.size(); j++) { if (iteration.pCurTrials[j] == 0) continue; - SearchInterval* p = 0; - SearchInterval* interval = iteration.pCurTrials[j]->leftInterval; - p = AddCurrentPoint(*iteration.pCurTrials[j], interval); + SearchInterval* p; + SearchInterval* interval; - if (p == 0) - continue; + if (parameters.MapType == mpNoninjective) { + Extended* x_ = new Extended[1 << parameters.Dimension]; + int kpp = evolvent.GetNoninjectivePreimages(iteration.pCurTrials[j]->y, x_); + + std::vector tmp(kpp+1); + + for (int i = 0; i < kpp+1; ++i) + { + tmp[i] = TrialFactory::CreateTrial(iteration.pCurTrials[j]); + pData->GetTrials().push_back(tmp[i]); + } + + for (int i = 0; i < kpp+1; ++i) + { + if (i < kpp) + tmp[i]->SetX(x_[i]); + p = 0; + interval = 0; + p = AddCurrentPoint(*tmp[i], 0); + interval = tmp[i]->leftInterval; + + if (p == 0) + continue; + + //Обработка началной итерации + if (iteration.IterationCount == 1) + { + pData->SetRecalc(true); + } + + // Если полный пересчет не нужен - обновляем только очереди характеристик + p->R = CalculateGlobalR(p); + pData->PushToQueue(p); + + (interval)->R = CalculateGlobalR((interval)); + + pData->TrickleUp(interval); + + } - if (interval == 0) + delete[] x_; + } + else if(parameters.MapType == mpLinar){ + p = 0; interval = iteration.pCurTrials[j]->leftInterval; + p = AddCurrentPoint(*iteration.pCurTrials[j], interval); - //Обработка началной итерации - if (iteration.IterationCount == 1) - { - pData->SetRecalc(true); + if (p == 0) + continue; + + if (interval == 0) + interval = iteration.pCurTrials[j]->leftInterval; + + //Обработка началной итерации + if (iteration.IterationCount == 1) + { + pData->SetRecalc(true); + } + + // Если полный пересчет не нужен - обновляем только очереди характеристик + if (!pData->IsRecalc()) + { + // Удалять интервалы из очереди не надо - они уже удалены в GetBestIntervals + // Вставляем два новых интервала + p->R = CalculateGlobalR(p); + pData->PushToQueue(p); + + (interval)->R = CalculateGlobalR((interval)); + + pData->PushToQueue((interval)); + } } + else { + p = 0; + interval = iteration.pCurTrials[j]->leftInterval; + p = AddCurrentPoint(*iteration.pCurTrials[j], interval); - // Если полный пересчет не нужен - обновляем только очереди характеристик - if (!pData->IsRecalc()) - { - // Удалять интервалы из очереди не надо - они уже удалены в GetBestIntervals - // Вставляем два новых интервала - p->R = CalculateGlobalR(p); - pData->PushToQueue(p); + if (p == 0) + continue; - (interval)->R = CalculateGlobalR((interval)); + if (interval == 0) + interval = iteration.pCurTrials[j]->leftInterval; - pData->PushToQueue((interval)); + //Обработка началной итерации + if (iteration.IterationCount == 1) + { + pData->SetRecalc(true); + } + + // Если полный пересчет не нужен - обновляем только очереди характеристик + if (!pData->IsRecalc()) + { + // Удалять интервалы из очереди не надо - они уже удалены в GetBestIntervals + // Вставляем два новых интервала + p->R = CalculateGlobalR(p); + pData->PushToQueue(p); + + (interval)->R = CalculateGlobalR((interval)); + + pData->PushToQueue((interval)); + } } } isFindInterval = false; diff --git a/globalizer/src/GlobProcess.cpp b/globalizer/src/GlobProcess.cpp index 58d1d84..12000cb 100644 --- a/globalizer/src/GlobProcess.cpp +++ b/globalizer/src/GlobProcess.cpp @@ -23,6 +23,7 @@ #include "Common.h" #include "GlobProcess.h" #include "MethodFactory.h" +#include "EvolventFactory.h" #include "MPICalculationAsync.h" @@ -44,14 +45,11 @@ pData(&data), pTask(&task) { isFirstRun = true; - if (parameters.MapType == mpBase) - evolvent = new Evolvent(parameters.Dimension - pTask->GetNumberOfDiscreteVariable(), parameters.m); - else - throw EXCEPTION("Unknown type of evolvent"); + pEvolvent = EvolventFactory::CreateEvolvent(parameters.Dimension, parameters.m); - calculation = CalculationFactory::CreateCalculation(*pTask, evolvent); + calculation = CalculationFactory::CreateCalculation(*pTask, pEvolvent); - pMethod = MethodFactory::CreateMethod(*pTask, *pData, *calculation, *evolvent); + pMethod = MethodFactory::CreateMethod(*pTask, *pData, *calculation, *pEvolvent); functionCalculationCount.resize(pTask->GetNumOfFunc()); @@ -68,7 +66,7 @@ Process::~Process() { delete calculation; delete pMethod; - delete evolvent; + delete pEvolvent; } // ------------------------------------------------------------------------------------------------ @@ -157,21 +155,35 @@ void Process::Reset(SearchData* data, Task* task) isFirstRun = true; pData = data; pTask = task; - if (evolvent == 0) + if (pEvolvent == 0) { - if (parameters.MapType == mpBase) - evolvent = new Evolvent(parameters.Dimension, parameters.m); + //Task* _pTask = TaskFactory::CreateTask(_problem, 0); + + pEvolvent = EvolventFactory::CreateEvolvent(parameters.Dimension, parameters.m); + + /*if (parameters.MapType == mpBase) + evolvent = new Evolvent(Factory); + else if (parameters.MapType == mpLinar) + evolvent = new LinearEvolvent(parameters.Dimension, parameters.m); + else if (parameters.MapType == mpNoninjective) + evolvent = new NoninjectiveEvolvent(parameters.Dimension, parameters.m); + else if (parameters.MapType == mpRotated) + evolvent = new RotatedEvolvent(parameters.Dimension, parameters.m); + else if (parameters.MapType == mpShifted) + evolvent = new ShiftedEvolvent(parameters.Dimension, parameters.m); + else if (parameters.MapType == mpSmooth) + evolvent = new SmoothEvolvent(parameters.Dimension, parameters.m); else - throw EXCEPTION("Unknown type of evolvent"); + throw EXCEPTION("Unknown type of evolvent");*/ } if (calculation == 0) - calculation = CalculationFactory::CreateCalculation(*pTask, evolvent); + calculation = CalculationFactory::CreateCalculation(*pTask, pEvolvent); else calculation->SetTask(pTask); if (pMethod != 0) delete pMethod; - pMethod = MethodFactory::CreateMethod(*pTask, *pData, *calculation, *evolvent); + pMethod = MethodFactory::CreateMethod(*pTask, *pData, *calculation, *pEvolvent); functionCalculationCount.clear(); functionCalculationCount.resize(pTask->GetNumOfFunc()); @@ -742,6 +754,7 @@ void Process::DoIteration() pMethod->CalculateFunctionals(); + for (int j = 0; j < pTask->GetNumOfFunc(); j++) { functionCalculationCount[j] += pMethod->GetFunctionCalculationCount()[j]; diff --git a/third_party/Problems b/third_party/Problems index dd5d9bc..3bb7a8f 160000 --- a/third_party/Problems +++ b/third_party/Problems @@ -1 +1 @@ -Subproject commit dd5d9bc050e3e534d911530aa685e3f34fbfa0f0 +Subproject commit 3bb7a8f9871c4210e80c944d7852c08a70469b9c