text:
/// @brief Hyperion logging facilities.
///
/// Hyperion's logging facilities are robust and composable.
/// Behavioral (Policy) configuration is configurable at compile time with via template parameters,
/// and output configuration is configurable by supplying the desired `Sink`s on creation
#pragma once

#include <Hyperion/BasicTypes.h>
#include <Hyperion/FmtIO.h>
#include <Hyperion/Logger.h>
#include <Hyperion/Option.h>
#include <Hyperion/logging/Config.h>
#include <Hyperion/logging/Entry.h>
#include <Hyperion/logging/Queue.h>
#include <Hyperion/logging/Sink.h>
#include <Hyperion/synchronization/ReadWriteLock.h>
#include <atomic>
#include <chrono>
#include <filesystem>
#include <gsl/gsl>
#include <iostream>
#include <memory>
#include <mutex>
#include <system_error>
#include <thread>

namespace hyperion {

	/// @brief Possible Error categories that can occur when using the logger
	enum class LoggerErrorCategory : i8 {
		/// @brief No Error occurred
		Success = 0,
		/// @brief failed to queue the entry for logging
		QueueingError,
		/// @brief the requested log level for the entry is
		/// lower than the minimum level for the logger
		LogLevelError,
		LoggerNotInitialized,
		Unknown = -1
	};

	/// @brief Alias for the Error type we might receive from the internal queue
	using QueueError = LoggingQueueError;

	class LoggerErrorDomain {
	  public:
		using value_type = LoggerErrorCategory;
		using LoggerStatusCode = error::StatusCode<LoggerErrorDomain>;
		using LoggerErrorCode = error::ErrorCode<LoggerErrorDomain>;

		static const constexpr char (&UUID)[error::num_chars_in_uuid] // NOLINT
			= "045dd371-9552-4ce1-bd4d-8e95b654fbe0";

		static constexpr u64 ID = error::parse_uuid_from_string(UUID);

		constexpr LoggerErrorDomain() noexcept = default;
		explicit constexpr LoggerErrorDomain(u64 uuid) noexcept : m_uuid(uuid) {
		}
		explicit constexpr LoggerErrorDomain(const error::UUIDString auto& uuid) noexcept
			: m_uuid(error::parse_uuid_from_string(uuid)) {
		}
		constexpr LoggerErrorDomain(const LoggerErrorDomain&) noexcept = default;
		constexpr LoggerErrorDomain(LoggerErrorDomain&&) noexcept = default;
		constexpr ~LoggerErrorDomain() noexcept = default;

		[[nodiscard]] inline constexpr auto id() const noexcept -> u64 {
			return m_uuid;
		}

		[[nodiscard]] inline constexpr auto name() const noexcept -> std::string_view { // NOLINT
			return "LoggerErrorDomain";
		}

		[[nodiscard]] inline constexpr auto message(value_type code) // NOLINT
			const noexcept -> std::string_view {
			if(code == value_type::Success) {
				return "Success";
			}
			else if(code == value_type::QueueingError) {
				return "Logger failed to queue log entry.";
			}
			else if(code == value_type::LogLevelError) {
				return "Requested log level for entry is lower than minimum level configured for "
					   "logger.";
			}
			else {
				return "Unknown Logger error.";
			}
		}

		[[nodiscard]] inline constexpr auto message(const LoggerStatusCode& code) // NOLINT
			const noexcept -> std::string_view {
			return message(code.code());
		}

		[[nodiscard]] inline constexpr auto is_error(const LoggerStatusCode& code) // NOLINT
			const noexcept -> bool {
			return code.code() != value_type::Success;
		}

		[[nodiscard]] inline constexpr auto is_success(const LoggerStatusCode& code) // NOLINT
			const noexcept -> bool {
			return code.code() == value_type::Success;
		}

		template<typename Domain2>
		[[nodiscard]] inline constexpr auto
		are_equivalent(const LoggerStatusCode& lhs,
					   const error::StatusCode<Domain2>& rhs) const noexcept -> bool {
			if constexpr(concepts::Same<LoggerStatusCode, error::StatusCode<Domain2>>) {
				return lhs.code() == rhs.code();
			}
			else {
				return false;
			}
		}

		[[nodiscard]] inline constexpr auto as_generic_code(const LoggerStatusCode& code) // NOLINT
			const noexcept -> error::GenericStatusCode {
			if(code.code() == value_type::Success || code.code() == value_type::Unknown) {
				return make_status_code(static_cast<error::Errno>(code.code()));
			}
			else {
				return make_status_code(error::Errno::Unknown);
			}
		}

		[[nodiscard]] inline static constexpr auto success_value() noexcept -> value_type {
			return value_type::Success;
		}

		template<typename Domain>
		friend inline constexpr auto
		operator==(const LoggerErrorDomain& lhs, const Domain& rhs) noexcept -> bool {
			return rhs.id() == lhs.id();
		}

		template<typename Domain>
		friend inline constexpr auto
		operator!=(const LoggerErrorDomain& lhs, const Domain& rhs) noexcept -> bool {
			return rhs.id() != lhs.id();
		}

		constexpr auto operator=(const LoggerErrorDomain&) noexcept -> LoggerErrorDomain& = default;
		constexpr auto operator=(LoggerErrorDomain&&) noexcept -> LoggerErrorDomain& = default;

	  private:
		u64 m_uuid = ID;
	};

	using LoggerStatusCode = LoggerErrorDomain::LoggerStatusCode;
	using LoggerErrorCode = LoggerErrorDomain::LoggerErrorCode;
	using LoggerError = error::Error<LoggerErrorDomain>;

} // namespace hyperion

template<>
inline constexpr auto
make_status_code_domain<hyperion::LoggerErrorDomain>() noexcept -> hyperion::LoggerErrorDomain {
	return {};
}

namespace hyperion {
	static_assert(error::StatusCodeDomain<LoggerErrorDomain>);

	template<>
	struct error::status_code_enum_info<LoggerErrorCategory> {
		using domain_type = LoggerErrorDomain;
		static constexpr bool value = true;
	};

	IGNORE_PADDING_START

	namespace detail {
#if HYPERION_HAS_JTHREAD
		using thread = std::jthread;
#else
		using thread = std::thread;
#endif
		static constexpr fmt::text_style MESSAGE_STYLE = fmt::fg(fmt::color::white);
		static constexpr fmt::text_style TRACE_STYLE = fmt::fg(fmt::color::steel_blue);
		static constexpr fmt::text_style INFO_STYLE
			= fmt::fg(fmt::color::light_green) | fmt::emphasis::italic;
		static constexpr fmt::text_style WARN_STYLE
			= fmt::fg(fmt::color::orange) | fmt::emphasis::bold;
		static constexpr fmt::text_style ERROR_STYLE
			= fmt::fg(fmt::color::red) | fmt::emphasis::bold;

		IGNORE_UNNEEDED_INTERNAL_DECL_START
		[[nodiscard]] inline static auto create_time_stamp() noexcept -> std::string {
			return fmt::format("[{:%Y-%m-%d|%H-%M-%S}]", fmt::localtime(std::time(nullptr)));
		}

		inline static auto
		create_default_sinks() noexcept -> Sinks { // NOLINT(bugprone-exception-escape)
			auto file = FileSink::create_file();
			auto file_sink = make_sink<FileSink>(file.expect("Failed to create default log file"));
			auto stdout_sink = make_sink<StdoutSink<>>();
			auto stderr_sink = make_sink<StderrSink<>>();
			return Sinks({std::move(file_sink), std::move(stdout_sink), std::move(stderr_sink)});
		}
		IGNORE_UNNEEDED_INTERNAL_DECL_STOP

		IGNORE_UNUSED_TEMPLATES_START
		template<LogLevel Level, typename... Args>
		inline static auto
		format_entry(Option<usize> thread_id, // NOLINT(bugprone-exception-escape)
					 fmt::format_string<Args...>&& format_string,
					 Args&&... args) noexcept -> Entry {
			const auto timestamp = create_time_stamp();
			const auto entry = fmt::format(format_string, std::forward<Args>(args)...);
			const auto id = thread_id.is_some() ?
								thread_id.unwrap() :
								  std::hash<std::thread::id>()(std::this_thread::get_id());

			std::string log_type;
			if constexpr(Level == LogLevel::MESSAGE) {
				log_type = "MESSAGE"s;
			}
			else if constexpr(Level == LogLevel::TRACE) {
				log_type = "TRACE"s;
			}
			else if constexpr(Level == LogLevel::INFO) {
				log_type = "INFO"s;
			}
			else if constexpr(Level == LogLevel::WARN) {
				log_type = "WARN"s;
			}
			else if constexpr(Level == LogLevel::ERROR) {
				log_type = "ERROR"s;
			}
			return make_entry<entry_level_t<Level>>("{0}  [Thread ID: {1}] [{2}]: {3}",
													timestamp,
													id,
													log_type,
													entry);
		}
		IGNORE_UNUSED_TEMPLATES_STOP

		template<LogLevel MinimumLevel = DefaultLogParameters::minimum_level,
				 LogThreadingPolicy ThreadingPolicy = DefaultLogParameters::threading_policy,
				 LogAsyncPolicy AsyncPolicy = DefaultLogParameters::async_policy,
				 usize QueueSize = DefaultLogParameters::queue_size>
		class LogBase;

		template<LogLevel MinimumLevel, LogAsyncPolicy AsyncPolicy>
		class LogBase<MinimumLevel, LogThreadingPolicy::SingleThreaded, AsyncPolicy> {
		  public:
			static constexpr auto THREADING_POLICY = LogThreadingPolicy::SingleThreaded;
			static constexpr auto ASYNC_POLICY = AsyncPolicy;
			static constexpr auto MINIMUM_LEVEL = MinimumLevel;

			LogBase() : LogBase(create_default_sinks()) {
			}
			explicit LogBase(Sinks&& sinks) noexcept : m_sinks(std::move(sinks)) {
			}
			LogBase(const LogBase&) = delete;
			LogBase(LogBase&&) noexcept = default;
			~LogBase() noexcept = default;

			template<LogLevel Level, typename... Args>
			inline auto log(Option<usize> thread_id,
							fmt::format_string<Args...>&& format_string,
							Args&&... args) noexcept -> void {
				const auto message = format_entry<Level>(std::move(thread_id),
														 std::move(format_string),
														 std::forward<Args>(args)...);

				std::for_each(m_sinks.begin(), m_sinks.end(), [&](Sink& sink) noexcept -> void {
					sink.sink(message);
				});
			}

			template<LogLevel, typename... Args>
			inline auto
			log(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept -> void {
				return log(None(), std::move(format_string), std::forward<Args>(args)...);
			}

			inline auto flush() const noexcept -> void {
				// intentionally does nothing
			}

			auto operator=(const LogBase&) -> LogBase& = delete;
			auto operator=(LogBase&&) noexcept -> LogBase& = default;

		  private:
			Sinks m_sinks;
		};

		template<LogLevel MinimumLevel, LogAsyncPolicy AsyncPolicy, usize QueueSize>
		class LogBase<MinimumLevel,
					  LogThreadingPolicy::SingleThreadedAsync,
					  AsyncPolicy,
					  QueueSize> {
		  public:
			static constexpr auto THREADING_POLICY = LogThreadingPolicy::SingleThreadedAsync;
			static constexpr auto ASYNC_POLICY = AsyncPolicy;
			static constexpr auto MINIMUM_LEVEL = MinimumLevel;
			static constexpr usize QUEUE_SIZE = QueueSize;

			LogBase() : LogBase(create_default_sinks()) {
			}
			explicit LogBase(Sinks&& sinks) noexcept : m_sinks(std::move(sinks)), m_queue() {
#if HYPERION_HAS_JTHREAD
				m_logging_thread = detail::thread(
					[&](const std::stop_token& token) { message_thread_function(token); });
#else
				m_logging_thread = detail::thread([&]() { message_thread_function(); });
#endif
			}
			LogBase(const LogBase&) = delete;
			LogBase(LogBase&& logger) noexcept {
				std::atomic_thread_fence(std::memory_order_acquire);
				logger.request_thread_stop();
				logger.m_logging_thread.join();
				// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
				m_sinks = std::move(logger.m_sinks);
				// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
				m_queue = std::move(logger.m_queue);
#if HYPERION_HAS_JTHREAD
				m_logging_thread = detail::thread(
					[&](const std::stop_token& token) { message_thread_function(token); });
#else
				m_logging_thread = detail::thread([&]() { message_thread_function(); });
#endif
				std::atomic_thread_fence(std::memory_order_release);
			}
			~LogBase() noexcept {
				request_thread_stop();
				m_logging_thread.join();
			}

			template<LogLevel Level, typename... Args>
			inline auto log(Option<usize> thread_id,
							fmt::format_string<Args...>&& format_string,
							Args&&... args) noexcept {
				if constexpr(Level >= MINIMUM_LEVEL && MINIMUM_LEVEL != LogLevel::DISABLED) {
					auto message = format_entry<Level>(std::move(thread_id),
													   std::move(format_string),
													   std::forward<Args>(args)...);
					if constexpr(ASYNC_POLICY == LogAsyncPolicy::DropWhenFull) {
						return log_dropping(std::move(message));
					}
					else if constexpr(ASYNC_POLICY == LogAsyncPolicy::FlushWhenFull) {
						log_flushing(std::move(message));
					}
					else {
						log_overwriting(std::move(message));
					}
				}
				else {
					ignore(format_string, std::forward<Args>(args)...);
					return Err(LoggerError(make_error_code(LoggerErrorCategory::LogLevelError)));
				}
			}

			template<LogLevel, typename... Args>
			inline auto log(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
				return log(None(), std::move(format_string), std::forward<Args>(args)...);
			}

			inline auto flush() noexcept -> void {
				m_flush.store(true);
			}

			auto operator=(const LogBase&) -> LogBase& = delete;
			auto operator=(LogBase&& logger) noexcept -> LogBase& {
				std::atomic_thread_fence(std::memory_order_acquire);
				if(this == &logger) {
					return *this;
				}

				logger.request_thread_stop();
				logger.m_logging_thread.join();
				m_sinks = std::move(logger.m_sinks);
				m_queue = std::move(logger.m_queue);

				std::atomic_thread_fence(std::memory_order_release);
				return *this;
			}

		  private:
			[[nodiscard]] inline static consteval auto get_queue_policy() noexcept -> QueuePolicy {
				if constexpr(ASYNC_POLICY == LogAsyncPolicy::DropWhenFull
							 || ASYNC_POLICY == LogAsyncPolicy::FlushWhenFull)
				{
					return QueuePolicy::ErrWhenFull;
				}
				else {
					return QueuePolicy::OverwriteWhenFull;
				}
			}
			using Queue = LoggingQueue<Entry, get_queue_policy(), QUEUE_SIZE>;

			Sinks m_sinks;
			Queue m_queue;
			std::atomic_bool m_flush = false;
#if !HYPERION_HAS_JTHREAD
			std::atomic_bool m_exit_flag = false;
#endif
			detail::thread m_logging_thread;

			inline auto request_thread_stop() noexcept -> void {
#if HYPERION_HAS_JTHREAD
				ignore(m_logging_thread.request_stop());
#else
				m_exit_flag.store(true);
#endif
			}

			inline auto log_dropping(Entry&& message) noexcept -> Result<bool, LoggerError>
			requires(ASYNC_POLICY == LogAsyncPolicy::DropWhenFull) {
				return m_queue.push(std::move(message))
					.map_err([]([[maybe_unused]] const QueueError& error) {
						return LoggerError(LoggerErrorCategory::QueueingError);
					});
			}

			inline auto log_overwriting(Entry&& message) noexcept
				-> void requires(ASYNC_POLICY == LogAsyncPolicy::OverwriteWhenFull) {
				m_queue.push(std::move(message));
			}

			inline auto log_flushing(Entry&& message) noexcept
				-> void requires(ASYNC_POLICY == LogAsyncPolicy::FlushWhenFull) {
				if(m_queue.full()) {
					m_flush.store(true);
				}

				const auto& mess = message;
				while(!m_queue.push(mess)) {
				}
			}

			inline auto try_read() noexcept -> Result<Entry, QueueError> {
				return m_queue.read();
			}

#if HYPERION_HAS_JTHREAD
			// NOLINTNEXTLINE(readability-function-cognitive-complexity)
			inline auto message_thread_function(const std::stop_token& token) noexcept -> void {
				while(!token.stop_requested()) {
#else
			// NOLINTNEXTLINE(readability-function-cognitive-complexity)
			inline auto message_thread_function() noexcept -> void {
				while(!m_exit_flag.load()) {
#endif

					auto res = try_read();
					if(res) {
						const auto message = res.unwrap();
						std::atomic_thread_fence(std::memory_order_acquire);
						std::for_each(m_sinks.begin(),
									  m_sinks.end(),
									  [&](Sink& sink) noexcept -> void { sink.sink(message); });
						std::atomic_thread_fence(std::memory_order_release);
					}

					if(m_flush.load()) {
						m_flush.store(false);
						do {
							auto res2 = m_queue.read();
							if(res2) {
								const auto message = res2.unwrap();
								std::atomic_thread_fence(std::memory_order_acquire);
								std::for_each(
									m_sinks.begin(),
									m_sinks.end(),
									[&](Sink& sink) noexcept -> void { sink.sink(message); });
								std::atomic_thread_fence(std::memory_order_release);
							}
							else {
								break;
							}
						} while(true);
					}
				}
				do {
					auto res2 = m_queue.read();
					if(res2) {
						const auto message = res2.unwrap();
						std::atomic_thread_fence(std::memory_order_acquire);
						std::for_each(m_sinks.begin(),
									  m_sinks.end(),
									  [&](Sink& sink) noexcept -> void { sink.sink(message); });
						std::atomic_thread_fence(std::memory_order_release);
					}
					else {
						break;
					}
				} while(true);
			}
		};

		template<LogLevel MinimumLevel, LogAsyncPolicy AsyncPolicy>
		class LogBase<MinimumLevel, LogThreadingPolicy::MultiThreaded, AsyncPolicy> {
		  public:
			static constexpr auto THREADING_POLICY = LogThreadingPolicy::MultiThreaded;
			static constexpr auto ASYNC_POLICY = AsyncPolicy;
			static constexpr auto MINIMUM_LEVEL = MinimumLevel;

			LogBase() : LogBase(create_default_sinks()) {
			}
			explicit LogBase(Sinks&& sinks) noexcept : m_sinks(std::move(sinks)) {
			}
			LogBase(const LogBase&) = delete;
			LogBase(LogBase&&) noexcept = default;
			~LogBase() noexcept = default;

			template<LogLevel Level, typename... Args>
			inline auto log(Option<usize> thread_id,
							fmt::format_string<Args...>&& format_string,
							Args&&... args) noexcept -> void {
				const auto message = format_entry<Level>(std::move(thread_id),
														 std::move(format_string),
														 std::forward<Args>(args)...);

				{
					auto sinks_guard = m_sinks.write();
					std::for_each(sinks_guard->begin(),
								  sinks_guard->end(),
								  [&](Sink& sink) noexcept -> void { sink.sink(message); });
				}
			}

			template<LogLevel, typename... Args>
			inline auto
			log(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept -> void {
				return log(None(), std::move(format_string), std::forward<Args>(args)...);
			}

			inline auto flush() const noexcept -> void {
				// intentionally does nothing
			}

			auto operator=(const LogBase&) -> LogBase& = delete;
			auto operator=(LogBase&&) noexcept -> LogBase& = default;

		  private:
			ReadWriteLock<Sinks> m_sinks;
		};

		template<LogLevel MinimumLevel, LogAsyncPolicy AsyncPolicy, usize QueueSize>
		class LogBase<MinimumLevel,
					  LogThreadingPolicy::MultiThreadedAsync,
					  AsyncPolicy,
					  QueueSize> {
		  public:
			static constexpr auto THREADING_POLICY = LogThreadingPolicy::MultiThreadedAsync;
			static constexpr auto ASYNC_POLICY = AsyncPolicy;
			static constexpr auto MINIMUM_LEVEL = MinimumLevel;
			static constexpr usize QUEUE_SIZE = QueueSize;

			LogBase() : LogBase(create_default_sinks()) {
			}
			explicit LogBase(Sinks&& sinks) noexcept : m_sinks(std::move(sinks)), m_queue() {
#if HYPERION_HAS_JTHREAD
				m_logging_thread = detail::thread(
					[&](const std::stop_token& token) { message_thread_function(token); });
#else
				m_logging_thread = detail::thread([&]() { message_thread_function(); });
#endif
			}
			LogBase(const LogBase&) = delete;
			LogBase(LogBase&& logger) noexcept {
				std::atomic_thread_fence(std::memory_order_seq_cst);
				logger.request_thread_stop();
				logger.m_logging_thread.join();
				// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
				m_sinks = std::move(logger.m_sinks);
				// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
				m_queue = std::move(logger.m_queue);
#if HYPERION_HAS_JTHREAD
				m_logging_thread = detail::thread(
					[&](const std::stop_token& token) { message_thread_function(token); });
#else
				m_logging_thread = detail::thread([&]() { message_thread_function(); });
#endif
				std::atomic_thread_fence(std::memory_order_seq_cst);
			}
			~LogBase() noexcept {
				request_thread_stop();
				m_logging_thread.join();
			}

			template<LogLevel Level, typename... Args>
			inline auto log(Option<usize> thread_id,
							fmt::format_string<Args...>&& format_string,
							Args&&... args) noexcept {
				if constexpr(Level >= MINIMUM_LEVEL && MINIMUM_LEVEL != LogLevel::DISABLED) {
					auto message = format_entry<Level>(std::move(thread_id),
													   std::move(format_string),
													   std::forward<Args>(args)...);
					if constexpr(ASYNC_POLICY == LogAsyncPolicy::DropWhenFull) {
						return log_dropping(std::move(message));
					}
					else if constexpr(ASYNC_POLICY == LogAsyncPolicy::FlushWhenFull) {
						log_flushing(std::move(message));
					}
					else {
						log_overwriting(std::move(message));
					}
				}
				else {
					ignore(format_string, std::forward<Args>(args)...);
					return Err(LoggerError(make_error_code(LoggerErrorCategory::LogLevelError)));
				}
			}

			template<LogLevel, typename... Args>
			inline auto log(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
				return log(None(), std::move(format_string), std::forward<Args>(args)...);
			}

			inline auto flush() noexcept -> void {
				m_flush.store(true);
			}

			auto operator=(const LogBase&) -> LogBase& = delete;
			auto operator=(LogBase&& logger) noexcept -> LogBase& {
				std::atomic_thread_fence(std::memory_order_seq_cst);
				if(this == &logger) {
					return *this;
				}

				logger.request_thread_stop();
				logger.m_logging_thread.join();
				m_sinks = std::move(logger.m_sinks);
				m_queue = std::move(logger.m_queue);

				std::atomic_thread_fence(std::memory_order_seq_cst);
				return *this;
			}

		  private:
			[[nodiscard]] inline static consteval auto get_queue_policy() noexcept -> QueuePolicy {
				if constexpr(ASYNC_POLICY == LogAsyncPolicy::DropWhenFull
							 || ASYNC_POLICY == LogAsyncPolicy::FlushWhenFull)
				{
					return QueuePolicy::ErrWhenFull;
				}
				else {
					return QueuePolicy::OverwriteWhenFull;
				}
			}
			using Queue = LoggingQueue<Entry, get_queue_policy(), QUEUE_SIZE>;

			Sinks m_sinks;
			Queue m_queue;
			std::atomic_bool m_flush = false;
#if !HYPERION_HAS_JTHREAD
			std::atomic_bool m_exit_flag = false;
#endif
			detail::thread m_logging_thread;

			inline auto request_thread_stop() noexcept -> void {
				std::atomic_thread_fence(std::memory_order_seq_cst);
#if HYPERION_HAS_JTHREAD
				ignore(m_logging_thread.request_stop());
#else
				m_exit_flag.store(true);
#endif
				std::atomic_thread_fence(std::memory_order_seq_cst);
			}

			inline auto log_dropping(Entry&& message) noexcept -> Result<bool, LoggerError>
			requires(ASYNC_POLICY == LogAsyncPolicy::DropWhenFull) {
				std::atomic_thread_fence(std::memory_order_seq_cst);
				auto res = m_queue.push(std::move(message))
							   .map_err([]([[maybe_unused]] const QueueError& error) {
								   return LoggerError(LoggerErrorCategory::QueueingError);
							   });
				std::atomic_thread_fence(std::memory_order_seq_cst);
				return res;
			}

			inline auto log_overwriting(Entry&& message) noexcept
				-> void requires(ASYNC_POLICY == LogAsyncPolicy::OverwriteWhenFull) {
				std::atomic_thread_fence(std::memory_order_seq_cst);
				m_queue.push(std::move(message));
				std::atomic_thread_fence(std::memory_order_seq_cst);
			}

			inline auto log_flushing(Entry&& message) noexcept
				-> void requires(ASYNC_POLICY == LogAsyncPolicy::FlushWhenFull) {
				std::atomic_thread_fence(std::memory_order_seq_cst);
				if(m_queue.full()) {
					m_flush.store(true);
				}

				const auto& mess = message;
				while(!m_queue.push(mess)) {
				}
				std::atomic_thread_fence(std::memory_order_seq_cst);
			}

			inline auto try_read() noexcept -> Result<Entry, QueueError> {
				std::atomic_thread_fence(std::memory_order_seq_cst);
				return m_queue.read();
			}

#if HYPERION_HAS_JTHREAD
			// NOLINTNEXTLINE(readability-function-cognitive-complexity)
			inline auto message_thread_function(const std::stop_token& token) noexcept -> void {
				while(!token.stop_requested()) {
#else
			// NOLINTNEXTLINE(readability-function-cognitive-complexity)
			inline auto message_thread_function() noexcept -> void {
				while(!m_exit_flag.load()) {
#endif

					auto res = try_read();
					if(res) {
						std::atomic_thread_fence(std::memory_order_seq_cst);
						const auto message = res.unwrap();
						std::for_each(m_sinks.begin(),
									  m_sinks.end(),
									  [&](Sink& sink) noexcept -> void { sink.sink(message); });
						std::atomic_thread_fence(std::memory_order_seq_cst);
					}

					if(m_flush.load()) {
						m_flush.store(false);
						do {
							std::atomic_thread_fence(std::memory_order_seq_cst);
							auto res2 = m_queue.read();
							if(res2) {
								const auto message = res2.unwrap();
								std::for_each(
									m_sinks.begin(),
									m_sinks.end(),
									[&](Sink& sink) noexcept -> void { sink.sink(message); });
								std::atomic_thread_fence(std::memory_order_seq_cst);
							}
							else {
								std::atomic_thread_fence(std::memory_order_seq_cst);
								break;
							}
						} while(true);
					}
				}
				do {
					std::atomic_thread_fence(std::memory_order_seq_cst);
					auto res2 = m_queue.read();
					if(res2) {
						const auto message = res2.unwrap();
						std::for_each(m_sinks.begin(),
									  m_sinks.end(),
									  [&](Sink& sink) noexcept -> void { sink.sink(message); });
						std::atomic_thread_fence(std::memory_order_seq_cst);
					}
					else {
						std::atomic_thread_fence(std::memory_order_seq_cst);
						break;
					}
				} while(true);
			}
		};
	} // namespace detail

	/// @brief Hyperion logging type for formatted logging.
	/// Uses fmtlib/fmt for entry formatting and stylizing
	///
	/// @tparam LogParameters - The parameters for how this logger should operate
	template<LoggerParametersType LogParameters = DefaultLogParameters>
	class Logger : public detail::LogBase<LogParameters::minimum_level,
										  LogParameters::threading_policy,
										  LogParameters::async_policy,
										  LogParameters::queue_size> {
	  public:
		static constexpr LogThreadingPolicy THREADING_POLICY = LogParameters::threading_policy;
		static constexpr LogAsyncPolicy ASYNC_POLICY = LogParameters::async_policy;
		static constexpr LogLevel MINIMUM_LEVEL = LogParameters::minimum_level;
		static constexpr usize QUEUE_SIZE = LogParameters::queue_size;
		using LogBase = detail::LogBase<LogParameters::minimum_level,
										LogParameters::threading_policy,
										LogParameters::async_policy,
										LogParameters::queue_size>;

		Logger() = default;
		explicit Logger(Sinks&& sinks) noexcept : LogBase(std::move(sinks)) {
		}
		Logger(const Logger& logger) noexcept = delete;
		Logger(Logger&& logger) noexcept = default;

		~Logger() noexcept = default;

		template<typename... Args>
		inline auto message(const Option<usize>& thread_id,
							fmt::format_string<Args...>&& format_string,
							Args&&... args) noexcept {
			return this->template log<LogLevel::MESSAGE>(thread_id,
														 std::move(format_string),
														 std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto message(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return message(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto trace(const Option<usize>& thread_id,
						  fmt::format_string<Args...>&& format_string,
						  Args&&... args) noexcept {
			return this->template log<LogLevel::TRACE>(thread_id,
													   std::move(format_string),
													   std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto trace(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return trace(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto info(const Option<usize>& thread_id,
						 fmt::format_string<Args...>&& format_string,
						 Args&&... args) noexcept {
			return this->template log<LogLevel::INFO>(thread_id,
													  std::move(format_string),
													  std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto info(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return info(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto warn(const Option<usize>& thread_id,
						 fmt::format_string<Args...>&& format_string,
						 Args&&... args) noexcept {
			return this->template log<LogLevel::WARN>(thread_id,
													  std::move(format_string),
													  std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto warn(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return warn(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto error(const Option<usize>& thread_id,
						  fmt::format_string<Args...>&& format_string,
						  Args&&... args) noexcept {
			return this->template log<LogLevel::ERROR>(thread_id,
													   std::move(format_string),
													   std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline auto error(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return error(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		auto operator=(const Logger& logger) noexcept -> Logger& = delete;
		auto operator=(Logger&& logger) noexcept -> Logger& = default;
	};
	IGNORE_PADDING_STOP

	IGNORE_UNUSED_TEMPLATES_START

#ifndef HYPERION_LOG_GLOBAL_LOGGER_PARAMETERS
	// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
	#define HYPERION_LOG_GLOBAL_LOGGER_PARAMETERS DefaultLogParameters
#endif

	struct GlobalLog {
		using Parameters = HYPERION_LOG_GLOBAL_LOGGER_PARAMETERS;
		static UniquePtr<Logger<Parameters>> GLOBAL_LOGGER; // NOLINT

		[[nodiscard]] inline static auto
		get_global_logger() noexcept -> Result<Logger<Parameters>*, LoggerError> {
			if(GLOBAL_LOGGER == nullptr) {
				return Err(LoggerError(LoggerErrorCategory::LoggerNotInitialized));
			}
			return Ok(GLOBAL_LOGGER.get());
		}

		inline static auto set_global_logger(Logger<Parameters>&& logger) noexcept -> void {
			GLOBAL_LOGGER = make_unique<Logger<Parameters>>(std::move(logger));
		}

		template<typename... Args>
		inline static auto MESSAGE(const Option<usize>& thread_id,
								   fmt::format_string<Args...>&& format_string,
								   Args&&... args) noexcept {
			return get_global_logger()
				.expect("Global Logger not initialized!")
				->message(thread_id, std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto
		MESSAGE(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return MESSAGE(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto TRACE(const Option<usize>& thread_id,
								 fmt::format_string<Args...>&& format_string,
								 Args&&... args) noexcept {
			return get_global_logger()
				.expect("Global Logger not initialized!")
				->trace(thread_id, std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto
		TRACE(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return TRACE(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto INFO(const Option<usize>& thread_id,
								fmt::format_string<Args...>&& format_string,
								Args&&... args) noexcept {
			return get_global_logger()
				.expect("Global Logger not initialized!")
				->info(thread_id, std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto
		INFO(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return INFO(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto WARN(const Option<usize>& thread_id,
								fmt::format_string<Args...>&& format_string,
								Args&&... args) noexcept {
			return get_global_logger()
				.expect("Global Logger not initialized!")
				->warn(thread_id, std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto
		WARN(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return WARN(None(), std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto ERROR(const Option<usize>& thread_id,
								 fmt::format_string<Args...>&& format_string,
								 Args&&... args) noexcept {
			return get_global_logger()
				.expect("Global Logger not initialized!")
				->error(thread_id, std::move(format_string), std::forward<Args>(args)...);
		}

		template<typename... Args>
		inline static auto
		ERROR(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
			return ERROR(None(), std::move(format_string), std::forward<Args>(args)...);
		}
	};

	UniquePtr<Logger<GlobalLog::Parameters>> GlobalLog::GLOBAL_LOGGER = nullptr; // NOLINT

	template<typename... Args>
	inline auto MESSAGE(const Option<usize>& thread_id,
						fmt::format_string<Args...>&& format_string,
						Args&&... args) noexcept {
		return GlobalLog::MESSAGE(thread_id, std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline static auto
	MESSAGE(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
		return GlobalLog::MESSAGE(None(), std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline static auto TRACE(const Option<usize>& thread_id,
							 fmt::format_string<Args...>&& format_string,
							 Args&&... args) noexcept {
		return GlobalLog::TRACE(thread_id, std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline static auto TRACE(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
		return GlobalLog::TRACE(None(), std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline auto INFO(const Option<usize>& thread_id,
					 fmt::format_string<Args...>&& format_string,
					 Args&&... args) noexcept {
		return GlobalLog::INFO(thread_id, std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline auto INFO(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
		return GlobalLog::INFO(None(), std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline auto WARN(const Option<usize>& thread_id,
					 fmt::format_string<Args...>&& format_string,
					 Args&&... args) noexcept {
		return GlobalLog::WARN(thread_id, std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline auto WARN(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
		return GlobalLog::WARN(None(), std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline auto ERROR(const Option<usize>& thread_id,
					  fmt::format_string<Args...>&& format_string,
					  Args&&... args) noexcept {
		return GlobalLog::ERROR(thread_id, std::move(format_string), std::forward<Args>(args)...);
	}

	template<typename... Args>
	inline auto ERROR(fmt::format_string<Args...>&& format_string, Args&&... args) noexcept {
		return GlobalLog::ERROR(None(), std::move(format_string), std::forward<Args>(args)...);
	}

	IGNORE_UNUSED_TEMPLATES_STOP
} // namespace hyperion


text:
#ifndef CONTROLLERS_FEATURE_DETECTOR_CONTROLLER_H
#define CONTROLLERS_FEATURE_DETECTOR_CONTROLLER_H

#include <QObject>

#include <QAction>

#include <s3d/cv/features/match_finder_cv.h>
#include <s3d/cv/disparity/disparity_analyzer_stan.h>

#include <gsl/gsl>

class FeatureDetectorControllerBase : QObject {
  Q_OBJECT

public:
  FeatureDetectorControllerBase(gsl::not_null<QAction*> action,
                                gsl::not_null<s3d::DisparityAnalyzerSTAN*> disparityAnalyzer);

  virtual std::unique_ptr<s3d::MatchFinderCV> createMatchFinder() = 0;

private:
  QAction* m_action;
  s3d::DisparityAnalyzerSTAN* m_disparityAnalyzer;
};

template <class T>
class FeatureDetectorController : public FeatureDetectorControllerBase {
  FeatureDetectorController(gsl::not_null<QAction*> action,
                            gsl::not_null<s3d::DisparityAnalyzerSTAN*> disparityAnalyzer)
    : FeatureDetectorControllerBase(action, disparityAnalyzer) {}

  std::unique_ptr<s3d::MatchFinderCV> createMatchFinder() override {
    return std::make_unique<T>();
  }
};

#endif //CONTROLLERS_FEATURE_DETECTOR_CONTROLLER_H

ext: h


text:
/**
 * Created when     :   2021.11.19;
 * Last Update      :   2021.12.02;
 * Author           :   G. Marino <gcmarino404@gmail.com>;
 * Notes            :   Header to the program Newton-main and correlated files.
 */

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <complex.h>
#include <gsl/gsl_rng.h>

//  Size of the visualization grid of area N*N;
#define N 1000
//  How close the guessed root given the point used as guest must be to the real root of the equation, Tol is for Tolerance;
#define Tol 1e-8
#define iterations 1000
#define phi (1+sqrt(5))/2

//  Struct used to create arrays of complex numbers which ones are the roots of the studied equation;
struct cmplx {
    double real;    //  Real part of the given complex number;
    double imag;    //  Imaginary part of the given complex number;
};

//  Output (op) function, print the results into .dat archives;
void op(int *arr) {
    int i, j;
    FILE *file;
    char name[100];

    sprintf(name, "dat/Fractal.dat");
    file = fopen(name, "w");
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) {
            fprintf(file, "%d ", arr[i*N+j]);
        };
        fprintf(file, "\n");
    };
    fclose(file);
};

max_stars_repo_name: Gabriel-Marino/marino-Newton-Fractal

max_issues_repo_name: Gabriel-Marino/marino-Newton-Fractal

max_forks_repo_name: Gabriel-Marino/marino-Newton-Fractal


text:
#ifndef MOBULA_INC_CONTEXT_CPU_CTX_H_
#define MOBULA_INC_CONTEXT_CPU_CTX_H_

#define MOBULA_KERNEL void
#define MOBULA_DEVICE

#include <algorithm>
#include <cmath>
#include <cstring>
#include <mutex>
#include <thread>
#include "../ctypes.h"
#include "./common.h"

namespace mobula {

#if USING_CBLAS
#include <cblas.h>
inline void blas_gemm(const int axis, const bool tA, const bool tB, const int M,
                      const int N, const int K, const float alpha,
                      const float *A, const int lda, const float *B,
                      const int ldb, const float beta, float *C,
                      const int ldc) {
  cblas_sgemm(axis == 0 ? CblasRowMajor : CblasColMajor,
              tA ? CblasTrans : CblasNoTrans, tB ? CblasTrans : CblasNoTrans, M,
              N, K, alpha, A, lda, B, ldb, beta, C, ldc);
}
#endif

using std::abs;
using std::max;
using std::min;

#if HOST_NUM_THREADS > 1 || USING_OPENMP
constexpr int NUM_MOBULA_ATOMIC_ADD_MUTEXES = HOST_NUM_THREADS * 8;
static std::mutex MOBULA_ATOMIC_ADD_MUTEXES[NUM_MOBULA_ATOMIC_ADD_MUTEXES];
inline MOBULA_DEVICE float atomic_add(const float val, float *address) {
  uintptr_t id = (reinterpret_cast<uintptr_t>(address) / sizeof(float)) %
                 NUM_MOBULA_ATOMIC_ADD_MUTEXES;
  MOBULA_ATOMIC_ADD_MUTEXES[id].lock();
  *address += val;
  MOBULA_ATOMIC_ADD_MUTEXES[id].unlock();
  return *address;
}
#else
// no lock for single thread mode
inline MOBULA_DEVICE float atomic_add(const float val, float *address) {
  *address += val;
  return *address;
}
#endif

template <typename T>
T *new_array(size_t size) {
  return new T[size];
}

template <typename T>
void del_array(T *p) {
  delete[] p;
}

template <typename T>
T *MemcpyHostToDev(T *dst, const T *src, size_t size) {
  if (dst == src) return dst;
  return static_cast<T *>(memcpy(dst, src, size));
}

template <typename T>
T *MemcpyDevToHost(T *dst, const T *src, size_t size) {
  if (dst == src) return dst;
  return static_cast<T *>(memcpy(dst, src, size));
}

template <typename T>
T *MemcpyDevToDev(T *dst, const T *src, size_t size) {
  if (dst == src) return dst;
  return static_cast<T *>(memcpy(dst, src, size));
}

}  // namespace mobula

#define KERNEL_RUN_BEGIN(device_id) \
  {                                 \
    UNUSED(device_id)
#define KERNEL_RUN_END() }
#define KERNEL_RUN_STREAM(a, strm) KERNEL_RUN(a)

#if USING_OPENMP
#include "./openmp_ctx.h"
#else
#include "./naive_ctx.h"
#endif

#endif  // MOBULA_INC_CONTEXT_CPU_CTX_H_

max_stars_repo_name: hustzxd/MobulaOP

max_issues_repo_name: hustzxd/MobulaOP

max_forks_repo_name: hustzxd/MobulaOP


text:
/*
 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
 */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <gsl.h>

#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/hardirq.h>
#include <linux/semaphore.h>

typedef struct _gsl_autogate_t {
    struct timer_list timer;
    spinlock_t lock;
    int active;
    /* pending indicate the timer has been fired but clock not yet disabled. */
    int pending;
    int timeout;
    gsl_device_t *dev;
    struct work_struct dis_task;
} gsl_autogate_t;

static gsl_autogate_t *g_autogate[2];
static DECLARE_MUTEX(sem_dev);

#define KGSL_DEVICE_IDLE_TIMEOUT 5000	/* unit ms */

static void clk_disable_task(struct work_struct *work)
{
	gsl_autogate_t *autogate;
	autogate = container_of(work, gsl_autogate_t, dis_task);
	if (autogate->dev->ftbl.device_idle)
		autogate->dev->ftbl.device_idle(autogate->dev, GSL_TIMEOUT_DEFAULT);
	kgsl_clock(autogate->dev->id, 0);
	autogate->pending = 0;
}

static int _kgsl_device_active(gsl_device_t *dev, int all)
{
	unsigned long flags;
	int to_active = 0;
	gsl_autogate_t *autogate = dev->autogate;
	if (!autogate) {
		printk(KERN_ERR "%s: autogate has exited!\n", __func__);
		return 0;
	}
//	printk(KERN_ERR "%s:%d id %d active %d\n", __func__, __LINE__, dev->id, autogate->active);

	spin_lock_irqsave(&autogate->lock, flags);
	if (in_interrupt()) {
		if (!autogate->active && !autogate->pending)
			BUG();
	} else {
		to_active = !autogate->active;
		autogate->active = 1;
	}
	mod_timer(&autogate->timer, jiffies + msecs_to_jiffies(autogate->timeout));
	spin_unlock_irqrestore(&autogate->lock, flags);
	if (to_active)
		kgsl_clock(autogate->dev->id, 1);
	if (to_active && all) {
		int index;
		index = autogate->dev->id == GSL_DEVICE_G12 ? GSL_DEVICE_YAMATO - 1 :
			GSL_DEVICE_G12 - 1;
		down(&sem_dev);
		if (g_autogate[index])
			_kgsl_device_active(g_autogate[index]->dev, 0);
		up(&sem_dev);
	}
	return 0;
}
int kgsl_device_active(gsl_device_t *dev)
{
	return _kgsl_device_active(dev, 0);
}

static void kgsl_device_inactive(unsigned long data)
{
	gsl_autogate_t *autogate = (gsl_autogate_t *)data;
	unsigned long flags;

//	printk(KERN_ERR "%s:%d id %d active %d\n", __func__, __LINE__, autogate->dev->id, autogate->active);
	del_timer(&autogate->timer);
	spin_lock_irqsave(&autogate->lock, flags);
	WARN(!autogate->active, "GPU Device %d is already inactive\n", autogate->dev->id);
	if (autogate->active) {
		autogate->active = 0;
		autogate->pending = 1;
		schedule_work(&autogate->dis_task);
	}
	spin_unlock_irqrestore(&autogate->lock, flags);
}

int kgsl_device_clock(gsl_deviceid_t id, int enable)
{
	int ret = GSL_SUCCESS;
	gsl_device_t *device;

	device = &gsl_driver.device[id-1];       // device_id is 1 based
	if (device->flags & GSL_FLAGS_INITIALIZED) {
		if (enable)
			kgsl_device_active(device);
		else
			kgsl_device_inactive((unsigned long)device);
	} else {
		printk(KERN_ERR "%s: Dev %d clock is already off!\n", __func__, id);
		ret = GSL_FAILURE;
	}

	return ret;
}

int kgsl_device_autogate_init(gsl_device_t *dev)
{
	gsl_autogate_t *autogate;

//	printk(KERN_ERR "%s:%d id %d\n", __func__, __LINE__, dev->id);
	autogate = kzalloc(sizeof(gsl_autogate_t), GFP_KERNEL);
	if (!autogate) {
		printk(KERN_ERR "%s: out of memory!\n", __func__);
		return -ENOMEM;
	}
	down(&sem_dev);
	autogate->dev = dev;
	autogate->active = 1;
	spin_lock_init(&autogate->lock);
	autogate->timeout = KGSL_DEVICE_IDLE_TIMEOUT;
	init_timer(&autogate->timer);
	autogate->timer.expires = jiffies + msecs_to_jiffies(autogate->timeout);
	autogate->timer.function = kgsl_device_inactive;
	autogate->timer.data = (unsigned long)autogate;
	add_timer(&autogate->timer);
	INIT_WORK(&autogate->dis_task, clk_disable_task);
	dev->autogate = autogate;
	g_autogate[dev->id - 1] = autogate;
	up(&sem_dev);
	return 0;
}

void kgsl_device_autogate_exit(gsl_device_t *dev)
{
	gsl_autogate_t *autogate = dev->autogate;

//	printk(KERN_ERR "%s:%d id %d active %d\n", __func__, __LINE__, dev->id,  autogate->active);
	down(&sem_dev);
	del_timer_sync(&autogate->timer);
	if (!autogate->active)
		kgsl_clock(autogate->dev->id, 1);
	flush_work(&autogate->dis_task);
	g_autogate[dev->id - 1] = NULL;
	up(&sem_dev);
	kfree(autogate);
	dev->autogate = NULL;
}

ext: c


text:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <time.h>
#include <math.h>

using namespace std;

max_stars_repo_name: EddieKHHo/AsexualMutAccum

max_issues_repo_name: EddieKHHo/AsexualMutAccum

max_forks_repo_name: EddieKHHo/AsexualMutAccum


text:
/* cdf/tdist.c
 *
 * Copyright (C) 2002 Jason H. Stover.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/*
 * Computes the Student's t cumulative distribution function using
 * the method detailed in
 *
 * W.J. Kennedy and J.E. Gentle, "Statistical Computing." 1980.
 * Marcel Dekker. ISBN 0-8247-6898-1.
 *
 * G.W. Hill and A.W. Davis. "Generalized asymptotic expansions
 * of Cornish-Fisher type." Annals of Mathematical Statistics,
 * vol. 39, 1264-1273. 1968.
 *
 * G.W. Hill. "Algorithm 395: Student's t-distribution," Communications
 * of the ACM, volume 13, number 10, page 617. October 1970.
 *
 * G.W. Hill, "Remark on algorithm 395: Student's t-distribution,"
 * Transactions on Mathematical Software, volume 7, number 2, page
 * 247. June 1982.
 */

#include <config.h>
#include <gsl/gsl_cdf.h>
#include <gsl/gsl_sf_gamma.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_errno.h>

#include "beta_inc.c"

static double
poly_eval (const double c[], unsigned int n, double x)
{
  unsigned int i;
  double y = c[0] * x;

  for (i = 1; i < n; i++)
    {
      y = x * (y + c[i]);
    }

  y += c[n];

  return y;
}

/*
 * Use the Cornish-Fisher asymptotic expansion to find a point u such
 * that gsl_cdf_gauss(y) = tcdf(t).
 *
 */

static double
cornish_fisher (double t, double n)
{
  const double coeffs6[10] = {
    0.265974025974025974026,
    5.449696969696969696970,
    122.20294372294372294372,
    2354.7298701298701298701,
    37625.00902597402597403,
    486996.1392857142857143,
    4960870.65,
    37978595.55,
    201505390.875,
    622437908.625
  };
  const double coeffs5[8] = {
    0.2742857142857142857142,
    4.499047619047619047619,
    78.45142857142857142857,
    1118.710714285714285714,
    12387.6,
    101024.55,
    559494.0,
    1764959.625
  };
  const double coeffs4[6] = {
    0.3047619047619047619048,
    3.752380952380952380952,
    46.67142857142857142857,
    427.5,
    2587.5,
    8518.5
  };
  const double coeffs3[4] = {
    0.4,
    3.3,
    24.0,
    85.5
  };

  double a = n - 0.5;
  double b = 48.0 * a * a;

  double z2 = a * log1p (t * t / n);
  double z = sqrt (z2);

  double p5 = z * poly_eval (coeffs6, 9, z2);
  double p4 = -z * poly_eval (coeffs5, 7, z2);
  double p3 = z * poly_eval (coeffs4, 5, z2);
  double p2 = -z * poly_eval (coeffs3, 3, z2);
  double p1 = z * (z2 + 3.0);
  double p0 = z;

  double y = p5;
  y = (y / b) + p4;
  y = (y / b) + p3;
  y = (y / b) + p2;
  y = (y / b) + p1;
  y = (y / b) + p0;

  if (t < 0)
    y *= -1;

  return y;
}

#if 0
/*
 * Series approximation for t > 4.0. This needs to be fixed;
 * it shouldn't subtract the result from 1.0. A better way is
 * to use two different series expansions. Figuring this out
 * means rummaging through Fisher's paper in Metron, v5, 1926,
 * "Expansion of Student's integral in powers of n^{-1}."
 */

#define MAXI 40

static double
normal_approx (const double x, const double nu)
{
  double y;
  double num;
  double diff;
  double q;
  int i;
  double lg1, lg2;

  y = 1 / sqrt (1 + x * x / nu);
  num = 1.0;
  q = 0.0;
  diff = 2 * GSL_DBL_EPSILON;
  for (i = 2; (i < MAXI) && (diff > GSL_DBL_EPSILON); i += 2)
    {
      diff = q;
      num *= y * y * (i - 1) / i;
      q += num / (nu + i);
      diff = q - diff;
    }
  q += 1 / nu;
  lg1 = gsl_sf_lngamma (nu / 2.0);
  lg2 = gsl_sf_lngamma ((nu + 1.0) / 2.0);

  diff = lg2 - lg1;
  q *= pow (y, nu) * exp (diff) / sqrt (M_PI);

  return q;
}
#endif

double
gsl_cdf_tdist_P (const double x, const double nu)
{
  double P;

  double x2 = x * x;

  if (nu > 30 && x2 < 10 * nu)
    {
      double u = cornish_fisher (x, nu);
      P = gsl_cdf_ugaussian_P (u);

      return P;
    }

  if (x2 < nu)
    {
      double u = x2 / nu;
      double eps = u / (1 + u);

      if (x >= 0)
        {
          P = beta_inc_AXPY (0.5, 0.5, 0.5, nu / 2.0, eps);
        }
      else
        {
          P = beta_inc_AXPY (-0.5, 0.5, 0.5, nu / 2.0, eps);
        }
    }
  else
    {
      double v = nu / (x * x);
      double eps = v / (1 + v);

      if (x >= 0)
        {
          P = beta_inc_AXPY (-0.5, 1.0, nu / 2.0, 0.5, eps);
        }
      else
        {
          P = beta_inc_AXPY (0.5, 0.0, nu / 2.0, 0.5, eps);
        }
    }

  return P;
}

double
gsl_cdf_tdist_Q (const double x, const double nu)
{
  double Q;

  double x2 = x * x;

  if (nu > 30 && x2 < 10 * nu)
    {
      double u = cornish_fisher (x, nu);
      Q = gsl_cdf_ugaussian_Q (u);

      return Q;
    }

  if (x2 < nu)
    {
      double u = x2 / nu;
      double eps = u / (1 + u);

      if (x >= 0)
        {
          Q = beta_inc_AXPY (-0.5, 0.5, 0.5, nu / 2.0, eps);
        }
      else
        {
          Q = beta_inc_AXPY (0.5, 0.5, 0.5, nu / 2.0, eps);
        }
    }
  else
    {
      double v = nu / (x * x);
      double eps = v / (1 + v);

      if (x >= 0)
        {
          Q = beta_inc_AXPY (0.5, 0.0, nu / 2.0, 0.5, eps);
        }
      else
        {
          Q = beta_inc_AXPY (-0.5, 1.0, nu / 2.0, 0.5, eps);
        }
    }

  return Q;
}

max_stars_repo_name: ielomariala/Hex-Game

max_issues_repo_name: Brian-ning/HMNE

max_forks_repo_name: Brian-ning/HMNE


text:
#define _GNU_SOURCE
#include <cblas.h>
#include <lapacke.h>

int main(int argc, char **argv)
{
  int N = 3;
  double X[] = { 1, 2, 3 };
  int INCX = 1;
	double res = cblas_dnrm2(N, X, INCX);
  return 0;
}

max_stars_repo_name: reneweb/opam-repository

max_issues_repo_name: fpottier/opam-repository

max_forks_repo_name: fpottier/opam-repository


text:
/*
Copyright (c) 2015, Patrick Weltevrede
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <time.h>
#include <sys/time.h>
#include <math.h>
#include <gsl/gsl_sort.h>
#include <gsl/gsl_cdf.h>
#include "psrsalsa.h"
long randomUnsignedInt()
{
  time_t seconds;
  struct timeval precisetime;
  time(&seconds);
  gettimeofday(&precisetime,0x0);
  return (long)seconds*(long)precisetime.tv_usec;
}
void randomize_idnum(long *idnum)
{
  *idnum = -randomUnsignedInt();
}
int find_peak_correlation(float *data1, float *data2, int ndata, int zeropad, int circularpad, int duplicate, int remove_baseline, int *lag, float *correl_max, verbose_definition verbose)
{
  int i, lag_max;
  int npoints;
  float *paddata1, *paddata2, *ans, ans_max, ans_min;
  if(duplicate)
    duplicate = ndata;
  if(verbose.verbose) {
    for(i = 0; i < verbose.indent; i++)
      printf(" ");
    printf("%d points in the data\n", ndata);
    if(zeropad != 0) {
      for(i = 0; i < verbose.indent; i++)
 printf(" ");
      printf("Padding at least %d points before and after data\n", zeropad);
    }
    if(duplicate) {
      for(i = 0; i < verbose.indent; i++)
 printf(" ");
      printf("Duplicating data to avoid wrap problems enabled.\n");
    }
  }
  i = (int) (log10(1.0 * (ndata+2*zeropad+duplicate))/0.301031);
  npoints = pow(2.0,(i+1));
  if(verbose.verbose) {
    for(i = 0; i < verbose.indent; i++)
      printf(" ");
    printf("Going to zero-pad it to %d points\n", npoints);
  }
  paddata1 = (float *)malloc(npoints*sizeof(float));
  paddata2 = (float *)malloc(npoints*sizeof(float));
  ans = (float *)malloc(2*npoints*sizeof(float));
  if(paddata1 == NULL || paddata2 == NULL || ans == NULL) {
    fflush(stdout);
    printerror(verbose.debug, "ERROR find_peak_correlation: Memory allocation error.");
    return 0;
  }
  zeropad = (npoints - duplicate - ndata)/2;
  for(i = 0; i < ndata; i++) {
    paddata1[i+zeropad] = data1[i];
    paddata2[i+zeropad] = data2[i];
    if(duplicate) {
      paddata1[i+ndata+zeropad] = data1[i];
      paddata2[i+ndata+zeropad] = data2[i];
    }
  }
  for(i = 0; i < zeropad; i++) {
    paddata1[i] = data1[i-zeropad+ndata];
    paddata2[i] = data2[i-zeropad+ndata];
  }
  for(i = ndata+duplicate+zeropad; i < npoints; i++) {
    paddata1[i] = data1[i-duplicate-zeropad-ndata];
    paddata2[i] = data2[i-duplicate-zeropad-ndata];
  }
  if(crosscorrelation_fft(paddata1, paddata2, npoints, ans, remove_baseline, verbose) == 0) {
    fflush(stdout);
    printerror(verbose.debug, "ERROR find_peak_correlation: Cross correlation failed.");
    return 0;
  }
  lag_max = 0;
  ans_max = ans[0];
  ans_min = ans[0];
  for(i = 1; i < npoints; i++) {
    if(ans[i] > ans_max) {
      ans_max = ans[i];
      lag_max = i;
    }
    if(ans[i] < ans_min)
      ans_min = ans[i];
  }
  if(lag_max >= npoints/2)
    lag_max -= npoints;
  *correl_max = ans_max/ans_min;
  *lag = lag_max;
  if(verbose.verbose) {
    for(i = 0; i < verbose.indent; i++)
      printf(" ");
    printf("Found a lag of %d (correlation %f higher)\n", *lag, *correl_max);
  }
  free(paddata1);
  free(paddata2);
  free(ans);
  return 1;
}
long calculate_bin_number(double x, double dx, double min_x, int centered_at_zero, double extra_phase)
{
  long bin, step, binzero;
  if(min_x < 0)
    step = -min_x/dx+10;
  else
    step = 0;
  bin = ( x+(step+0.5*centered_at_zero-extra_phase)*dx)/dx;
  binzero = (min_x+(step+0.5*centered_at_zero-extra_phase)*dx)/dx;
  bin -= binzero;
  return bin;
}
double calculate_bin_location(long binnr, double dx, double min_x, int centered_at_zero, double extra_phase)
{
  long step, binzero;
  double x;
  if(min_x < 0)
    step = -min_x/dx+10;
  else
    step = 0;
  binzero = (min_x+(step+0.5*centered_at_zero-extra_phase)*dx)/dx;
  binnr = binnr + binzero;
  x = binnr*dx - (step+0.5*centered_at_zero-extra_phase)*dx;
  x += 0.5*dx;
  return x;
}
double calculate_required_bin_width(double x, long binnr, double min_x, int centered_at_zero, double extra_phase, verbose_definition verbose)
{
  long lastbin, ok, timesinloop;
  double dx, offset;
  dx = (x - min_x)/(double)(binnr+0.5);
  timesinloop = 0;
  offset = 0;
  do {
    ok = 1;
    dx = (x - min_x)/(double)(binnr+0.5) + offset;
    lastbin = calculate_bin_number(x, dx, min_x, centered_at_zero, extra_phase);
    if(lastbin < binnr) {
      offset += (x-min_x-0.5*dx)/(double)(binnr+0.5) - dx;
      ok = 0;
    }else if(lastbin > binnr) {
      offset += (x-min_x+0.5*dx)/(double)(binnr+0.5) -dx;
      ok = 0;
    }
    timesinloop++;
    if(timesinloop > 10) {
      printerror(verbose.debug, "ERROR calculate_required_bin_width: Cannot find suitable binsize.\n");
      return dx;
    }
  }while(ok == 0);
  return dx;
}
int set_binning_histogram(double min_x_data, double max_x_data, int rangex_set, double rangex_min, double rangex_max, int nrbins_specified, long nrbins, int centered_at_zero, double extra_phase, double *min_x, double *max_x, double *dx, verbose_definition verbose)
{
  int reset;
  do {
    reset = 0;
    *min_x = min_x_data;
    *max_x = max_x_data;
    if(rangex_set) {
      *min_x = rangex_min;
      *max_x = rangex_max;
    }
    if(nrbins_specified) {
      *dx = calculate_required_bin_width(*max_x, nrbins-1, *min_x, centered_at_zero, extra_phase, verbose);
      if(verbose.verbose)
 fprintf(stdout, "Going to use binsize %e.\n", *dx);
    }
    {
      long firstbin;
      firstbin = calculate_bin_number(*min_x, *dx, *min_x, centered_at_zero, extra_phase);
      if(firstbin != 0) {
 printerror(verbose.debug, "ERROR set_binning_histogram: Expected first bin to be number zero (it is %ld).\n", firstbin);
 return 2;
      }
    }
    long i;
    double diff;
    i = calculate_bin_number(*max_x, *dx, *min_x, centered_at_zero, extra_phase);
    diff = *max_x - calculate_bin_location(i, *dx, *min_x, centered_at_zero, extra_phase);
    diff = diff/(*dx);
    if(verbose.debug) {
      printf("Current set max value (%e) is falling at phase=%e w.r.t. centre of last generated bin.\n", *max_x, diff);
    }
    if(diff > -0.501 && diff < -0.499) {
      if(rangex_set) {
 rangex_max -= 0.5*(*dx);
 printwarning(verbose.debug, "WARNING set_binning_histogram: Adjusting maximum value of the specified range to %e to avoid rounding errors. Going to reset choosen binning.", rangex_max);
 reset = 1;
      }
    }
    if(diff > 0.499 && diff < 0.501) {
      if(rangex_set) {
 rangex_max += 0.5*(*dx);
 printwarning(verbose.debug, "WARNING set_binning_histogram: Adjusting maximum value of the specified range to %e to avoid rounding errors. Going to reset choosen binning.", rangex_max);
 reset = 1;
      }else {
 *max_x += 0.5*(*dx);
 if(nrbins_specified) {
   printwarning(verbose.debug, "WARNING set_binning_histogram: Nr of bins might be different from what was requested to avoid rounding errors.");
 }
      }
    }
    i = calculate_bin_number(*min_x, *dx, *min_x, centered_at_zero, extra_phase);
    diff = *min_x - calculate_bin_location(i, *dx, *min_x, centered_at_zero, extra_phase);
    diff = diff/(*dx);
    if(verbose.debug) {
      printf("Current set min value (%e) is falling at phase=%e w.r.t. centre of first generated bin.\n", *min_x, diff);
    }
    if(diff > -0.501 && diff < -0.499) {
      if(rangex_set) {
 rangex_min -= 0.5*(*dx);
 printwarning(verbose.debug, "WARNING set_binning_histogram: Adjusting minimum value of the specified range to %e to avoid rounding errors. Going to reset choosen binning.", rangex_min);
 reset = 1;
      }else {
 *min_x -= 0.5*(*dx);
 if(nrbins_specified) {
   printwarning(verbose.debug, "WARNING set_binning_histogram: Nr of bins might be different from what was requested to avoid rounding errors.");
 }
      }
    }
    if(diff > 0.499 && diff < 0.501) {
      if(rangex_set) {
 rangex_min += 0.5*(*dx);
 printwarning(verbose.debug, "WARNING set_binning_histogram: Adjusting minimum value of the specified range to %e to avoid rounding errors. Going to reset choosen binning.", rangex_min);
 reset = 1;
      }
    }
    if(reset) {
      printwarning(verbose.debug, "WARNING set_binning_histogram: Re-adjusting choosen binning.\n", rangex_max);
    }
  }while(reset == 1);
  return 0;
}
double kstest_cdf_flat(double x, double min_x, double max_x)
{
  if(x <= min_x)
    return 0;
  if(x >= max_x)
    return 1;
  return (x-min_x)/(max_x-min_x);
}
double kstest_cdf_sin(double x)
{
  if(x <= 0)
    return 0;
  if(x >= 90)
    return 1;
  return 1-cos(x*M_PI/180.0);
}
void kstest(double *data1, long n1, double *data2, long n2, int cdf_type, double input_value1, double input_value2, double (*cdf)(double), double *max_diff, double *prob, verbose_definition verbose)
{
  long i1, i2;
  double effective_n, ks_statistic, sign, cur_term, last_term, coeff;
  int converged;
  gsl_sort(data1, 1, n1);
  if(n2 > 0 && data2 != NULL)
    gsl_sort(data2, 1, n2);
  *max_diff = 0;
  if(n2 > 0 && data2 != NULL) {
    i1 = 0;
    i2 = 0;
    while(i1 < n1 && i2 < n2) {
      double diff;
      if(data1[i1] == data2[i2]) {
 i1++;
 i2++;
      }else if(data1[i1] < data2[i2]) {
 i1++;
      }else {
 i2++;
      }
      diff = fabs(i1/(double)n1 - i2/(double)n2);
      if(diff > *max_diff)
 *max_diff = diff;
    }
    effective_n=n1*n2/(double)(n1+n2);
  }else {
    double cdf_right, cdf_left, cdf_model;
    cdf_left = 0;
    for(i1 = 0; i1 < n1; i1++) {
      cdf_right = (i1+1)/(double)n1;
      if(cdf_type == 0) {
 cdf_model = (*cdf)(data1[i1]);
      }else if(cdf_type == 1) {
 cdf_model = kstest_cdf_flat(data1[i1], data1[0], data1[n1-1]);
 if(i1 == 0) {
   printwarning(verbose.debug, "WARNING kstest: Probability will be overestimated, since the minimum/maximum of the uniform distribution is based on the input values.");
 }
      }else if(cdf_type == 3) {
 cdf_model = kstest_cdf_flat(data1[i1], input_value1, input_value2);
      }else if(cdf_type == 2) {
 cdf_model = kstest_cdf_sin(data1[i1]);
      }else {
 fflush(stdout);
 printerror(verbose.debug, "ERROR kstest: Undefined type of cdf is specified.");
 exit(0);
      }
      if(fabs(cdf_right-cdf_model) > *max_diff)
 *max_diff = fabs(cdf_right-cdf_model);
      if(fabs(cdf_left-cdf_model) > *max_diff)
 *max_diff = fabs(cdf_left-cdf_model);
      cdf_left = cdf_right;
    }
    effective_n=n1;
  }
  if(effective_n < 4) {
    printwarning(verbose.debug, "WARNING kstest: Number of data-points is too low to make use of approximations used in this implementation of the KS-test.");
  }
  effective_n=sqrt(effective_n);
  ks_statistic = (*max_diff)*(effective_n+0.12+0.11/effective_n);
  coeff = -2.0*ks_statistic*ks_statistic;
  *prob = 0;
  sign = 1;
  last_term = 0;
  converged = 0;
  for(i1 = 1; i1 <= 100; i1++) {
    cur_term = sign*2.0*exp(coeff*i1*i1);
    *prob += cur_term;
    if(fabs(cur_term) <= 1e-5*fabs(last_term) || fabs(cur_term) <= 1e-10*(*prob)) {
      converged = 1;
      break;
    }
    last_term = cur_term;
    sign = -sign;
  }
  if(!converged)
    *prob = 1;
  if(verbose.verbose) {
    printf("KS-test statistic max_diff: %lf = %e\n", *max_diff, *max_diff);
    printf("KS-test probability:        %lf = %e\nA small probability means the two sets of points are drawn from a different distribution.\n", *prob, *prob);
    printf("The null hypothesis ");
    if(n2 > 0 && data2 != NULL) {
      printf("(data sets are drawn from the same distribution) ");
    }else {
      printf("(data set is drawn from the specified distribution) ");
    }
#if GSL_VERSION_NUMBER >= 104
    printf("can be rejected at the %.2lf sigma level.\n", gsl_cdf_gaussian_Pinv(0.5*(1.0-*prob)+0.5, 1.0));
#else
    printf("can be rejected at the XXXX sigma level (need GSL >= 1.4 to get this number).\n");
#endif
  }
}

max_stars_repo_name: weltevrede/psrsalsa

max_issues_repo_name: weltevrede/psrsalsa

max_forks_repo_name: weltevrede/psrsalsa


text:
//          Copyright Jean Pierre Cimalando 2019.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE.md or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#pragma once
#include <SimpleIni.h>
#include <gsl/gsl>
#include <string>
#include <memory>

const std::string &get_configuration_dir();
std::string get_configuration_file(gsl::cstring_span name);

std::unique_ptr<CSimpleIniA> create_configuration();
std::unique_ptr<CSimpleIniA> load_configuration(gsl::cstring_span name);
bool save_configuration(gsl::cstring_span name, const CSimpleIniA &ini);

std::unique_ptr<CSimpleIniA> load_global_configuration();
bool save_global_configuration(const CSimpleIniA &ini);

max_stars_repo_name: jpcima/smf-dsp

max_issues_repo_name: jpcima/smf-dsp

max_forks_repo_name: jpcima/smf-dsp


text:
/* specfunc/gsl_sf_coupling.h
 *
 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Author:  G. Jungman */

#ifndef __GSL_SF_COUPLING_H__
#define __GSL_SF_COUPLING_H__

#include <gsl/gsl_sf_result.h>

#undef __BEGIN_DECLS
#undef __END_DECLS
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS /* empty */
# define __END_DECLS /* empty */
#endif

__BEGIN_DECLS

/* 3j Symbols:  / ja jb jc \
 *              \ ma mb mc /
 *
 * exceptions: GSL_EDOM, GSL_EOVRFLW
 */
int gsl_sf_coupling_3j_e(int two_ja, int two_jb, int two_jc,
                            int two_ma, int two_mb, int two_mc,
			    gsl_sf_result * result
			    );
double gsl_sf_coupling_3j(int two_ja, int two_jb, int two_jc,
                          int two_ma, int two_mb, int two_mc
                          );

/* 6j Symbols:  / ja jb jc \
 *              \ jd je jf /
 *
 * exceptions: GSL_EDOM, GSL_EOVRFLW
 */
int gsl_sf_coupling_6j_e(int two_ja, int two_jb, int two_jc,
                            int two_jd, int two_je, int two_jf,
			    gsl_sf_result * result
			    );
double gsl_sf_coupling_6j(int two_ja, int two_jb, int two_jc,
                          int two_jd, int two_je, int two_jf
                          );

/* 9j Symbols:  / ja jb jc \
 *              | jd je jf |
 *              \ jg jh ji /
 *
 * exceptions: GSL_EDOM, GSL_EOVRFLW
 */
int gsl_sf_coupling_9j_e(int two_ja, int two_jb, int two_jc,
                            int two_jd, int two_je, int two_jf,
			    int two_jg, int two_jh, int two_ji,
			    gsl_sf_result * result
			    );
double gsl_sf_coupling_9j(int two_ja, int two_jb, int two_jc,
                          int two_jd, int two_je, int two_jf,
                          int two_jg, int two_jh, int two_ji
                          );

__END_DECLS

#endif /* __GSL_SF_COUPLING_H__ */


text:
// Distributed under MIT License, see LICENSE file
// (c) 2018 Zbigniew Skowron, zbychs@gmail.com

#pragma once

#include "text_buffer.h"
#include "text_parser.h"
#include "text_renderer.h"
#include "geometry.h"

#include <string>
#include <vector>
#include <iostream>

#include <gsl/span>

namespace terminal_editor {

/// This class describes position in a TextBuffer.
/// Positions are logically between characters.
struct GraphemePosition : Position {
    int screenColumn; ///< Column on the screen (zero indexed).

    GraphemePosition() : screenColumn(0) {}
    GraphemePosition(Position position, int screenColumn) : Position(position), screenColumn(screenColumn) {}

    friend std::ostream& operator<<(std::ostream& os, GraphemePosition graphemePosition) {
        return os << "GraphemePosition{" << graphemePosition.row << ", " << graphemePosition.column << ", scrCol=" << graphemePosition.screenColumn << "}";
    }
};

/// This class is an editable container of lines of graphemes.
/// @note By screen coordinates below we mean coordinates that take into account rendered sizes of graphemes in screen cells, but not window position or text offset inside a window.
/// @note This is a very straighforward implementation. It is not efficient.
class GraphemeBuffer {
private:
    TextBuffer& m_textBuffer;
    std::vector<std::vector<Grapheme>> renderedLines; ///< Will always have at least one line.

public:
    GraphemeBuffer(TextBuffer& textBuffer);

    /// Empty virtual destructor.
    virtual ~GraphemeBuffer() {
    }

    /// Replaces contents of this text buffer with contents of given file.
    /// @param fileName     Name of file to load.
    virtual void loadFile(const std::string& fileName);

    /// Returns number of lines in this text buffer.
    /// @note It will always be 1 + number of LF's in file.
    int getNumberOfLines() const;

    /// Returns length of the longest line, on screen.
    int getLongestLineLength() const;

    /// Returns contents of given line.
    /// If row is less than zero or greater than number of lines - 1, empty span is returned.
    /// Span is valid only until next edit on the buffer.
    /// @param row          Row to return (zero indexed).
    gsl::span<const Grapheme> getLine(int row) const;

    /// Returns part of given line from colStart (inclusive) to colEnd (exclusive).
    /// colStart and colEnd are first clamped to the range 0 (inclusive) to line length (inclusive).
    /// Span is valid only until next edit on the buffer.
    /// @param row          Row to return (zero indexed).
    /// @param colStart     First grapheme to return (zero indexed).
    /// @param colEnd       One past last grapheme to return (zero indexed).
    gsl::span<const Grapheme> getLineRange(int row, int colStart, int colEnd) const;

    /// Returns Point that corresponds to screen coordinates of given Position.
    /// @param Position     Position of a grapheme (can be one past end of line).
    /// @return Point in screen coordinates of first cell of the grapheme.
    [[nodiscard]]
    Point positionToPoint(Position position);

    /// Returns Position that corresponds to given Point in screen coordinates.
    /// @note If point row is outside of row bounds, it is clamped to valid range.
    /// @note If point is after the line end, returns position one past end of line.
    /// @note If point is before the line start, returns position of first grapheme in line.
    /// @param point    Point in screen coordinates.
    /// @param after    If point is not on first screen cell of a grapheme, return position after a grapheme.
    ///                 Otherwise return position of grapheme under point.
    /// @return Position of grapheme under point (can be one past end of line).
    ///         Returned Position is clamped to valid line row/column.
    [[nodiscard]]
    Position pointToPosition(Point point, bool after);

    /// Inserts given text into this grapheme buffer.
    /// position is first clamped to a valid range.
    /// @param position     Position to insert into.
    /// @param text         Text to insert. May contain new lines. Doesn't have to be valid UTF-8.
    /// @returns Position of the end of inserted text in the new grapheme buffer.
    virtual Position insertText(Position position, const std::string& text);

    /// Deletes text between two positions: from startPosition (inclusive) to endPosition (exclusive).
    /// positions are first clamped to valid range.
    /// positions can be on different lines.
    /// If startPosition is past endPosition no characters are removed.
    /// @param startPosition    Start position. This is first position that will be removed.
    /// @param endPosition      End position. This is first position that will not be removed.
    /// @returns Characters removed (including newlines).
    virtual std::string deleteText(Position startPosition, Position endPosition);

    /// Clamps position to a valid range, so:
    /// - row is clamped to range from 0 to number of lines (inclusive),
    /// - column is clamped to range from 0 to line length (inclusive).
    [[nodiscard]]
    Position clampPosition(Position position) const;

protected:
    /// Maps grapheme position to position in underlying text buffer.
    [[nodiscard]]
    Position positionToTextPosition(Position position) const;

    /// Maps position in underlying text buffer to grapheme position.
    /// @param after    If position is not on first byte of a grapheme, return position after a grapheme.
    ///                 Otherwise return position of grapheme with given byte.
    [[nodiscard]]
    Position textPositionToPosition(Position textPosition, bool after) const;

    /// Re-renders all lines based on TextBuffer.
    /// renderedLines is re-initialized.
    void rerenderAllLines();

    /// Re-renders given line.
    void rerenderLine(int row);
};

} // namespace terminal_editor

max_stars_repo_name: Zbyl/terminal-editor

max_issues_repo_name: Zbyl/terminal-editor

max_forks_repo_name: Zbyl/terminal-editor


text:
/*
 * PARTICLE SWARM OPTIMIZATION
 * ===========================
 *
 * Author: Gabriel E Leventhal, 2011-12-02
 *
 * adapted from
 *   Author: Tomas V. Arredondo
 *   SimPSOLib: A simple yet flexible PSO implementation in C++.
 *
 */

#ifndef __PSO_SWARM__
#define __PSO_SWARM__

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <ctime>
#include <queue>
using namespace std;

#include "GSLRng.h"
#include <gsl/gsl_math.h>

#include "Particle.h"
#include "Point.h"
#include "Parameters.h"
#include "Network.h"

#ifdef USE_MPI
#include "mpi.h"
#endif

namespace PSO {
  class Swarm {
    public:
      Swarm() {}

      Swarm(int size, int np, Parameters* pars)
        : swarmSize(size), numParams(np), numEvals(0), curIt(0),
          numInform(3),
          phiPi(np,2.5), phiPf(np,0.5), phiGi(np,0.5),phiGf(np,2.5),
          omegai(np,0.721), omegaf(np,0.721), p(pars),
          bestVal(-INFINITY), bestParticle(-1),
          mpi_type(0), mpi_rank(0), mpi_ntasks(1)
      {
        bestPos = Point(np,0.0);
        setInformants(numInform);
      }

      virtual ~Swarm() { destroy(); }

      inline void setMPI(int type) { mpi_type = (type >= 0) ? type : 0; }

      inline void setVars(const Point& pp, const Point& pg, const Point& o) {
        phiPi = pp; phiGi = pg; omegai = o;
        phiPf = pp; phiGf = pg; omegaf = o;
        phiP = pp; phiG = pg; omega = o;
      }

      inline void setInformants(int K) {
        numInform = (K > swarmSize-1) ? swarmSize-1 : K;
        links.resize(swarmSize);
        init_network();
      }

      double maximum_swarm_radius() const;
      double search_space_diameter() const;

      // get everything ready to go
      void begin(int argc, char* argv[]);
      // finish up stuff
      void end();

      void initialize(int type = 0);
      void display(ostream* out = &cout, string prefix = "");

      virtual void evaluate(int vflag = 0, ostream* out = NULL, ostream* hist = NULL);
      virtual double evaluateParticle(int j);

      void updateVelocity(int j, bool bestVals = true);
      void updateVelocity(bool bestVals = true);

      void updatePosition(int j);
      void updatePosition();

      void randomizeInf(int maxTries = 1000);
      void randomPosition(int j);

      virtual void run(int numIt, int slowdown = 0, int vflag = 0,
                       ostream* out = NULL, ostream* hist = NULL);

      inline bool is_master() const { return (mpi_rank == 0); }

      inline void seed_rng(unsigned long seed) { rng.set(seed); }

      inline const Particle& at(size_t i) const { return *swarm[i]; }
      inline Particle best() const { return *swarm[bestParticle]; }

      inline double fitness(int i) const { return swarm.at(i)->fitness(); }

      inline int size() const { return swarmSize; }

      inline int nextIt() { return ++curIt; }
      inline void setIt(int i) { curIt = i; }

      double mean(int i) const;
      double var(int i) const;
      Point mean() const;
      Point var() const;

#ifdef USE_MPI
      virtual void evaluate_slave();
      void run_mpi(int numInt, int vflag = 0, ostream* out = NULL, ostream* hist = NULL);
      virtual void run_master(int numInt, int vflag, ostream* out, ostream* hist);
      inline void evaluate_master(int vflag = 0) { run_master(-1,vflag,NULL,NULL); }
#endif

    protected:
      void create();
      void destroy();

      void init_network();
      int find_best();

      int swarmSize;                            /* swarm size */
      vector<Particle*> swarm;                  /* swarm */
      int numParams;                            /* number of parameters */
      int numEvals;                             /* current number of function evaluations */
      int curIt;                                /* current swarm iteration */

      int numInform;                            /* number of informants */
      Network links;                            /* information network */

      Point phiP;
      Point phiG;
      Point omega;
      Point phiPi;                              /* phiP initial */
      Point phiPf;                              /* phiP final */
      Point phiGi;                              /* phiG initial */
      Point phiGf;                              /* phiG final */
      Point omegai;                             /* omega initial */
      Point omegaf;                             /* omega final */

      Parameters* p;

      double bestVal;                           /* current best value */
      Point bestPos;                            /* current best position */
      int bestParticle;

      myGSL::Rng rng;

      int mpi_type;
      int mpi_rank;
      int mpi_ntasks;
  };
}

#endif // __PSO_SWARM__


text:
#include <config.h>
#include <stddef.h>
#include <stdlib.h>
#include <math.h>

#include <gsl/gsl_errno.h>
#include <gsl/gsl_complex.h>

#include <gsl/gsl_fft_real.h>
#include <gsl/gsl_fft_real_float.h>

#define BASE_DOUBLE
#include "templates_on.h"
#include "real_pass.h"
#include "real_init.c"
#include "real_main.c"
#include "real_pass_2.c"
#include "real_pass_3.c"
#include "real_pass_4.c"
#include "real_pass_5.c"
#include "real_pass_n.c"
#include "real_radix2.c"
#include "real_unpack.c"
#include "templates_off.h"
#undef  BASE_DOUBLE

#define BASE_FLOAT
#include "templates_on.h"
#include "real_pass.h"
#include "real_init.c"
#include "real_main.c"
#include "real_pass_2.c"
#include "real_pass_3.c"
#include "real_pass_4.c"
#include "real_pass_5.c"
#include "real_pass_n.c"
#include "real_radix2.c"
#include "real_unpack.c"
#include "templates_off.h"
#undef  BASE_FLOAT

max_stars_repo_name: zzpwahaha/Chimera-Control-Trim

max_issues_repo_name: zzpwahaha/Chimera-Control-Trim

max_forks_repo_name: zzpwahaha/Chimera-Control-Trim


text:
/*
  NAME:
     logsum
  PURPOSE:
     calculate the log of the sum of numbers which are given as logs using as much of the dynamic range as possible
  CALLING SEQUENCE:
     logsum(gsl_matrix * q, int row, bool isrow,bool partial, int partial_indx[3])
  INPUT:
     q            - matrix of which we will sum a row/column
     row          - row/column number
     isrow        - are we summing a row or a column
  OUTPUT:
     log of the sum
  REVISION HISTORY:
     2008-09-21 - Written Bovy
*/
#include <stdbool.h>
#include <math.h>
#include <float.h>
#include <gsl/gsl_matrix.h>
#include <proj_gauss_mixtures.h>

double logsum(gsl_matrix * q, int row, bool isrow){
  double logxmin = log(DBL_MIN);
  double logxmax = log(DBL_MAX);
  int l = (isrow) ? q->size2 : q->size1;

  /* First find the maximum and mininum */
  double max, min;
  minmax(q,row,isrow,&min,&max);//,allfixed);

  min *= -1.;
  min += logxmin;
  max *= -1.;
  max += logxmax - log(l);
  (min >  max) ? (max=max) : (max=min);
  double loglike=0.0;
  int dd;
  if (isrow)
    for (dd = 0; dd != q->size2; ++dd)
	loglike += exp(gsl_matrix_get(q,row,dd)+max);
  else
    for (dd = 0; dd != q->size1; ++dd)
	loglike += exp(gsl_matrix_get(q,dd,row)+max);

  return log(loglike)-max;
}


text:
/* Author: Edward Hutter */

#ifndef SHARED
#define SHARED

// System includes
#include <fstream>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stdio.h>
#include <complex>
#include <vector>
#include <map>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cmath>
#include <string>
#include <assert.h>
#include <complex>

#include <mpi.h>
#include "mkl.h"

#ifdef CRITTER
#include "critter.h"
#else
//#ifdef PORTER
//#include <cblas.h>
//#include "/home/hutter2/hutter2/external/BLAS/OpenBLAS/lapack-netlib/LAPACKE/include/lapacke.h"
//#endif
#define CRITTER_START(ARG)
#define CRITTER_STOP(ARG)
#endif

template<typename ScalarType>
class mpi_type;

template<>
class mpi_type<float>{
public:
  constexpr static size_t type = MPI_FLOAT;
};
template<>
class mpi_type<double>{
public:
  constexpr static size_t type = MPI_DOUBLE;
};

#endif /*SHARED*/

max_stars_repo_name: tbennun/capital

max_issues_repo_name: tbennun/capital

max_forks_repo_name: tbennun/capital