/******************************************************** * ██████╗ ███████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗███████╗ ██║ ██║ * ██║ ██║╚════██║ ██║ ██║ * ╚██████╔╝███████║ ██║ ███████╗ * ╚═════╝ ╚══════╝ ╚═╝ ╚══════╝ * 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.h" #define M 100 #define N 90 // get random floating points double random_double(double l, double t) { return (t-l)*rand()*1.0/RAND_MAX + l; } // get random integral numbers int random_int(int small, int big) { return (rand() % (big - small)) + small; } class ex2 : public gctl::lgd_solver { protected: gctl::matrix kernel; gctl::array obs, tmp; protected: double LGD_Evaluate(const gctl::array &x, gctl::array &g); public: ex2(); virtual ~ex2(){} void CalObs(const gctl::array &x); }; ex2::ex2() { kernel.resize(M, N); tmp.resize(M); obs.resize(M); srand(time(0)); // 添加一些大数 int tmp_id, tmp_size; double tmp_val; for (int i = 0; i < M; i++) { tmp_size = random_int(25, 35); for (int j = 0; j < tmp_size; j++) { tmp_id = random_int(0, N); tmp_val = random_double(-10, 10); kernel[i][tmp_id] = tmp_val; } } } double ex2::LGD_Evaluate(const gctl::array &x, gctl::array &g) { for (int i = 0; i < M; i++) { tmp[i] = 0.0; for (int j = 0; j < N; j++) { tmp[i] += kernel[i][j] * x[j]; } tmp[i] -= obs[i]; //tmp[i] /= 1e-1; } for (int j = 0; j < N; j++) { g[j] = 0.0; for (int i = 0; i < M; i++) { g[j] += kernel[i][j]*tmp[i]; } g[j] *= 2.0/M; } double sum = 0.0; for (int i = 0; i < M; i++) { sum += tmp[i]*tmp[i]; } return sum/M; } void ex2::CalObs(const gctl::array &x) { // 计算正演值 for (int i = 0; i < M; i++) { obs[i] = 0.0; for (int j = 0; j < N; j++) { obs[i] += kernel[i][j]*x[j]; } // 添加噪声 obs[i] += random_double(-1e-3, 1e-3); } } int main(int argc, char const *argv[]) { gctl::array m(N, 0.0), mean_m(N, 0.0), stddev_m(N, 0.0), low(N), hig(N); // 生成一组正演解 包含一些大值和一些小值 gctl::array fm(N); int N2 = (int) N/2; for (int i = 0; i < N2; i++) { //fm[i] = random_double(5, 10); fm[i] = 10.0; } for (int i = N2; i < N; i++) { //fm[i] = random_double(1, 2); fm[i] = 1.0; } for (int i = 0; i < N2; i++) { low[i] = 9.0; // 对解的范围进行约束 hig[i] = 11.0; } for (int i = N2; i < N; i++) { low[i] = 0.0; hig[i] = 2.0; } ex2 e; e.CalObs(fm); gctl::lgd_para my_para = e.default_lgd_para(); my_para.flight_times = 20000; my_para.batch = 100; e.set_lgd_para(my_para); e.LGD_Minimize(m, mean_m, stddev_m, low, hig); for (int i = 0; i < N; i++) { std::cout << fm[i] << " " << m[i] << " " << mean_m[i] << " " << stddev_m[i] << " " << fabs(mean_m[i] - fm[i]) << std::endl; } return 0; }