From adf998fb8bec09af01a39040082e39e32a9c3c8d Mon Sep 17 00:00:00 2001 From: Yi Zhang Date: Sat, 22 Feb 2025 18:10:15 +0800 Subject: [PATCH] tmp --- example/CMakeLists.txt | 21 +++---- example/cfg_ex.cpp | 46 ++++++++++++++ lib/optimization.h | 1 + lib/optimization/clcg.h | 1 + lib/optimization/cmn_grad.cpp | 110 ++++++++++++++++++++++++++++++++++ lib/optimization/cmn_grad.h | 92 ++++++++++++++++++++++++++++ lib/optimization/lbfgs.h | 1 + lib/optimization/sgd.h | 1 + 8 files changed, 263 insertions(+), 10 deletions(-) create mode 100644 example/cfg_ex.cpp create mode 100644 lib/optimization/cmn_grad.cpp create mode 100644 lib/optimization/cmn_grad.h diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 713d264..fb39569 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -10,13 +10,14 @@ macro(add_example name switch) endif() endmacro() -add_example(ex1 ON) -add_example(ex2 ON) -add_example(ex3 ON) -add_example(ex4 ON) -add_example(ex5 ON) -add_example(ex6 ON) -add_example(ex7 ON) -add_example(ex8 ON) -add_example(ex9 ON) -add_example(ex10 ON) \ No newline at end of file +add_example(ex1 OFF) +add_example(ex2 OFF) +add_example(ex3 OFF) +add_example(ex4 OFF) +add_example(ex5 OFF) +add_example(ex6 OFF) +add_example(ex7 OFF) +add_example(ex8 OFF) +add_example(ex9 OFF) +add_example(ex10 OFF) +add_example(cfg_ex ON) \ No newline at end of file diff --git a/example/cfg_ex.cpp b/example/cfg_ex.cpp new file mode 100644 index 0000000..1e5192d --- /dev/null +++ b/example/cfg_ex.cpp @@ -0,0 +1,46 @@ +/******************************************************** + * ██████╗ ███████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗███████╗ ██║ ██║ + * ██║ ██║╚════██║ ██║ ██║ + * ╚██████╔╝███████║ ██║ ███████╗ + * ╚═════╝ ╚══════╝ ╚═╝ ╚══════╝ + * Generic Scientific Template Library + * + * Copyright (c) 2022 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * The GSTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License (LGPL) along with + * this program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GSTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GSTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#include "../lib/optimization/cmn_grad.h" + +using namespace gctl; + +int main(int argc, char *argv[]) try +{ + common_gradient cmg; + cmg.init(2, 2); + cmg.fill_model_gradient(0, _1d_array({1.0, 0.5})); + cmg.fill_model_gradient(1, _1d_array({-0.6, 1.0})); + + _1d_array x = cmg.get_common_gradient(false); + std::cout << "x = (" << x[0] << ", " << x[1] << ")\n"; + return 0; +} +catch (const std::exception& e) +{ + GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0); +} \ No newline at end of file diff --git a/lib/optimization.h b/lib/optimization.h index 6d8f3a1..1ede1f8 100644 --- a/lib/optimization.h +++ b/lib/optimization.h @@ -39,5 +39,6 @@ #include "optimization/sgd.h" #include "optimization/gradnorm.h" #include "optimization/dwa.h" +#include "optimization/cmn_grad.h" #endif // _GCTL_OPTIMIZATION_H \ No newline at end of file diff --git a/lib/optimization/clcg.h b/lib/optimization/clcg.h index dabb5ff..8856ab7 100644 --- a/lib/optimization/clcg.h +++ b/lib/optimization/clcg.h @@ -28,6 +28,7 @@ #ifndef _GCTL_CLCG_H #define _GCTL_CLCG_H +#include "gctl/utility.h" #include "gctl/core.h" #include "gctl/maths.h" #include "gctl/algorithms.h" diff --git a/lib/optimization/cmn_grad.cpp b/lib/optimization/cmn_grad.cpp new file mode 100644 index 0000000..3404c6e --- /dev/null +++ b/lib/optimization/cmn_grad.cpp @@ -0,0 +1,110 @@ +/******************************************************** + * ██████╗ ██████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗██║ ██║ ██║ + * ██║ ██║██║ ██║ ██║ + * ╚██████╔╝╚██████╗ ██║ ███████╗ + * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ + * Geophysical Computational Tools & Library (GCTL) + * + * Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * GCTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License along with this + * program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GCTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GCTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#include "cmn_grad.h" + +gctl::common_gradient::common_gradient() +{ + set_lcg_message(LCG_THROW); +} + +gctl::common_gradient::common_gradient(size_t Ln, size_t Mn) +{ + init(Ln, Mn); +} + +gctl::common_gradient::~common_gradient(){} + +void gctl::common_gradient::LCG_Ax(const array &x, array &ax) +{ + matvec(t_, G_, x, NoTrans); + matvec(ax, G_, t_, Trans); + return; +} + +void gctl::common_gradient::set_solver(const lcg_para ¶) +{ + set_lcg_para(para); + return; +} + +void gctl::common_gradient::init(size_t Ln, size_t Mn) +{ + Ln_ = Ln; + Mn_ = Mn; + g_.resize(Mn_); + B_.resize(Mn_); + G_.resize(Ln_, Mn_); + t_.resize(Ln_); + gm_.resize(Ln_); + x_.resize(Ln_, 1.0); + filled_.resize(Ln_, false); + return; +} + +void gctl::common_gradient::fill_model_gradient(size_t id, const _1d_array &g) +{ + if (id >= Ln_) throw std::runtime_error("[gctl::common_gradient] Invalid index."); + if (g.size() != Mn_) throw std::runtime_error("[gctl::common_gradient] Invalid array size."); + + G_.fill_row(id, g); + filled_[id] = true; + gm_[id] = g.module(); + return; +} + +const gctl::_1d_array &gctl::common_gradient::get_common_gradient(bool normalized) +{ + for (size_t i = 0; i < Ln_; i++) + { + if (!filled_[i]) throw std::runtime_error("[gctl::common_gradient] Unfilled model gradient."); + } + filled_.assign(false); + + G_.normalize(RowMajor); + matvec(B_, G_, x_, Trans); + + g_.random_float(-1.0, 1.0, RdUniform); + g_.normalize(); + LCG_Minimize(g_, B_, LCG_CG); + + if (normalized) g_.normalize(); + else + { + g_.normalize(); + matvec(t_, G_, g_, NoTrans); + + double tmod = t_.module(L1); + double gmod = 0.0; + for (size_t i = 0; i < Ln_; i++) + { + gmod += gm_[i]*abs(t_[i])/tmod; + } + g_.scale(gmod); + } + return g_; +} \ No newline at end of file diff --git a/lib/optimization/cmn_grad.h b/lib/optimization/cmn_grad.h new file mode 100644 index 0000000..5fcb21e --- /dev/null +++ b/lib/optimization/cmn_grad.h @@ -0,0 +1,92 @@ +/******************************************************** + * ██████╗ ██████╗████████╗██╗ + * ██╔════╝ ██╔════╝╚══██╔══╝██║ + * ██║ ███╗██║ ██║ ██║ + * ██║ ██║██║ ██║ ██║ + * ╚██████╔╝╚██████╗ ██║ ███████╗ + * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ + * Geophysical Computational Tools & Library (GCTL) + * + * Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn) + * + * GCTL is distributed under a dual licensing scheme. You can redistribute + * it and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either version 2 + * of the License, or (at your option) any later version. You should have + * received a copy of the GNU Lesser General Public License along with this + * program. If not, see . + * + * If the terms and conditions of the LGPL v.2. would prevent you from using + * the GCTL, please consider the option to obtain a commercial license for a + * fee. These licenses are offered by the GCTL's original author. As a rule, + * licenses are provided "as-is", unlimited in time for a one time fee. Please + * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget + * to include some description of your company and the realm of its activities. + * Also add information on how to contact you by electronic and paper mail. + ******************************************************/ + +#ifndef _GCTL_COMMON_GRADIENT_H +#define _GCTL_COMMON_GRADIENT_H + +#include "lcg.h" + +namespace gctl +{ + class common_gradient : public lcg_solver + { + public: + common_gradient(); ///< 构造函数 + + /** + * @brief Construct a new common_gradient object + * + * @param Ln Number of loss functions + * @param Mn Number of model parameters + */ + common_gradient(size_t Ln, size_t Mn); + + virtual ~common_gradient(); ///< 析构函数 + + virtual void LCG_Ax(const array &x, array &ax); ///< 计算Ax + + /** + * @brief Configure the solver's setups + * + * @param para LCG solver parameters + */ + void set_solver(const lcg_para ¶); + + /** + * @brief Initialize the common_gradient object + * + * @param Ln Number of loss functions + * @param Mn Number of model parameters + */ + void init(size_t Ln, size_t Mn); + + /** + * @brief Fill the model gradient + * + * @param id Loss function index + * @param g Model gradient + */ + void fill_model_gradient(size_t id, const _1d_array &g); + + /** + * @brief Get the conflict free gradient + * + * @param normalized Normalize the output gradient + * @return Calculated model gradient + */ + const _1d_array &get_common_gradient(bool normalized = true); + + private: + size_t Ln_, Mn_; // Ln_: loss_func number,Mn_: model number + _2d_matrix G_; + _1d_array B_, g_, t_, x_; + _1d_array gm_; + array filled_; + }; +}; + +#endif // _GCTL_COMMON_GRADIENT_H \ No newline at end of file diff --git a/lib/optimization/lbfgs.h b/lib/optimization/lbfgs.h index 7b35850..7afb183 100644 --- a/lib/optimization/lbfgs.h +++ b/lib/optimization/lbfgs.h @@ -28,6 +28,7 @@ #ifndef _GCTL_LBFGS_H #define _GCTL_LBFGS_H +#include "gctl/utility.h" #include "gctl/core.h" #include "gctl/maths.h" #include "gctl/algorithms.h" diff --git a/lib/optimization/sgd.h b/lib/optimization/sgd.h index 0fd2607..cae9e91 100644 --- a/lib/optimization/sgd.h +++ b/lib/optimization/sgd.h @@ -28,6 +28,7 @@ #ifndef _GCTL_SGD_H #define _GCTL_SGD_H +#include "gctl/utility.h" #include "gctl/core.h" #include "gctl/algorithms.h"