├── LICENSE ├── README.md ├── adaptive_spham_ExampleA_gau.py ├── adaptive_spham_ExampleA_t2.py ├── adaptive_spham_ExampleC_gau.py ├── adaptive_spham_ExampleC_t2.py ├── generate_exampleA.py ├── generate_exampleC.py ├── model.py └── utilities.py /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpHAM 2 | The source code used for [Huber Additive Models for Non-stationary Time Series Analysis](https://openreview.net/forum?id=9kpuB2bgnim), published in ICLR 2022. 3 | -------------------------------------------------------------------------------- /adaptive_spham_ExampleA_gau.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | from model import SpHAM as spham 4 | from utilities import write_files 5 | from generate_exampleA import generate_A 6 | 7 | 8 | 9 | ## data generating 10 | filename1 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/gau_A/exampleA_gau_true.npy' 11 | filename2 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/gau_A/exampleA_gau_noise.npy' 12 | 13 | generate_A(filename1, filename2, noise = 'gau') 14 | 15 | 16 | with open(filename1, 'rb') as f: 17 | big_y_true_t = np.load(f) 18 | with open(filename2, 'rb') as f: 19 | big_y_noise_t = np.load(f) 20 | 21 | 22 | ## parameter 23 | exp_T = 4000 24 | start = 1500 25 | interval = 400 26 | back = 2 27 | end = start + interval 28 | 29 | max_iteration = 2000 30 | num_pred = 100 31 | 32 | loss_huber_true = [] 33 | loss_huber_noise = [] 34 | 35 | 36 | for experiment in range(50): 37 | print("Experiment %d" % experiment) 38 | y_true = big_y_true_t[experiment] 39 | y_noise = big_y_noise_t[experiment] 40 | sys.stdout.flush() 41 | 42 | model_spham = spham(y_noise, y_true, huber_sigma=np.power(interval, 1./48.), start=start, interval=interval, backward=back, rbf_sigma=0.5, lamb=1./interval) 43 | alpha = model_spham.fit(max_iter=max_iteration) 44 | prediction = model_spham.predict(alpha, y_noise, y_true, start=end, repeat=num_pred, backward=back) 45 | loss_huber_true.append(np.linalg.norm(y_true[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 46 | loss_huber_noise.append(np.linalg.norm(y_noise[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 47 | 48 | loss_huber_true_print = np.mean(loss_huber_true) 49 | loss_huber_noise_print = np.mean(loss_huber_noise) 50 | 51 | loss_huber_true_print_std=np.std(loss_huber_true) 52 | loss_huber_noise_print_std=np.std(loss_huber_noise) 53 | 54 | print("SpHAM: ASE:%.3f, ASE std:%.3f, TD:%.3f, TD std:%.3f\n" % (loss_huber_noise_print, loss_huber_noise_print_std, loss_huber_true_print, loss_huber_true_print_std)) 55 | 56 | 57 | -------------------------------------------------------------------------------- /adaptive_spham_ExampleA_t2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | from model import SpHAM as spham 4 | from utilities import write_files 5 | from generate_exampleA import generate_A 6 | 7 | 8 | 9 | ## data generating 10 | filename1 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/t_A/exampleA_t_true.npy' 11 | filename2 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/t_A/exampleA_t_noise.npy' 12 | 13 | generate_A(filename1, filename2, noise = 't') 14 | 15 | 16 | with open(filename1, 'rb') as f: 17 | big_y_true_t = np.load(f) 18 | with open(filename2, 'rb') as f: 19 | big_y_noise_t = np.load(f) 20 | 21 | 22 | ## parameter 23 | exp_T = 4000 24 | start = 1500 25 | interval = 400 26 | back = 2 27 | end = start + interval 28 | 29 | max_iteration = 2000 30 | num_pred = 100 31 | 32 | loss_huber_true = [] 33 | loss_huber_noise = [] 34 | 35 | 36 | for experiment in range(50): 37 | print("Experiment %d" % experiment) 38 | y_true = big_y_true_t[experiment] 39 | y_noise = big_y_noise_t[experiment] 40 | sys.stdout.flush() 41 | 42 | model_spham = spham(y_noise, y_true, huber_sigma=np.power(interval, 1./48.), start=start, interval=interval, backward=back, rbf_sigma=0.5, lamb=1./interval) 43 | alpha = model_spham.fit(max_iter=max_iteration) 44 | prediction = model_spham.predict(alpha, y_noise, y_true, start=end, repeat=num_pred, backward=back) 45 | loss_huber_true.append(np.linalg.norm(y_true[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 46 | loss_huber_noise.append(np.linalg.norm(y_noise[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 47 | 48 | loss_huber_true_print = np.mean(loss_huber_true) 49 | loss_huber_noise_print = np.mean(loss_huber_noise) 50 | 51 | loss_huber_true_print_std=np.std(loss_huber_true) 52 | loss_huber_noise_print_std=np.std(loss_huber_noise) 53 | 54 | print("SpHAM: ASE:%.3f, ASE std:%.3f, TD:%.3f, TD std:%.3f\n" % (loss_huber_noise_print, loss_huber_noise_print_std, loss_huber_true_print, loss_huber_true_print_std)) 55 | 56 | 57 | -------------------------------------------------------------------------------- /adaptive_spham_ExampleC_gau.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | from utilities import write_files 4 | from model import nonStationary 5 | from model import SpHAM as spham 6 | from generate_exampleC import generate_C 7 | 8 | filename1 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/gau_B/exampleB_gau_true.npy' 9 | filename2 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/gau_B/exampleB_gau_noise.npy' 10 | 11 | generate_C(filename1, filename2, noise = 'gau') 12 | 13 | with open(filename1, 'rb') as f: 14 | big_y_true_gau = np.load(f) 15 | with open(filename2, 'rb') as f: 16 | big_y_noise_gau = np.load(f) 17 | 18 | 19 | exp_T = 4000 20 | start = 1500 21 | interval = 400 22 | back = 1 23 | end = start + interval 24 | max_iteration = 2000 25 | num_pred = 100 26 | 27 | loss_huber_true = [] 28 | loss_huber_noise = [] 29 | loss_adaptive_true = [] 30 | loss_adaptive_noise = [] 31 | 32 | for experiment in range(50): 33 | 34 | print("Experiment %d" % experiment) 35 | y_true = big_y_true_gau[experiment] 36 | y_noise = big_y_noise_gau[experiment] 37 | sys.stdout.flush() 38 | 39 | 40 | #spham 41 | model_spham = spham(y_noise, y_true, huber_sigma=np.power(interval, 1/48), start=start, interval=interval, backward=back, rbf_sigma=0.5, lamb=1/interval) 42 | alpha = model_spham.fit(max_iter=max_iteration) 43 | prediction = model_spham.predict(alpha, y_noise, y_true, start=end, repeat=num_pred, backward=back) 44 | loss_huber_true.append(np.linalg.norm(y_true[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 45 | loss_huber_noise.append(np.linalg.norm(y_noise[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 46 | 47 | #adaptive spham l=150 48 | model_aspham = nonStationary(y_noise, y_true, l=300, huber_sigma=np.power(interval, 1/48), 49 | start=start, interval=interval, lamb1=10000, lamb2=100, backward=back, 50 | rbf_sigma=0.5, lamb=1/interval, s_iter=20, out_iter=20) 51 | alpha = model_aspham.fit(max_iter=max_iteration) 52 | prediction = model_aspham.predict(alpha, y_noise, y_true, start=end, repeat=num_pred, backward=back) 53 | loss_adaptive_true.append(np.linalg.norm(y_true[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 54 | loss_adaptive_noise.append(np.linalg.norm(y_noise[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 55 | 56 | loss_huber_true_print=np.mean(loss_huber_true) 57 | loss_huber_noise_print=np.mean(loss_huber_noise) 58 | loss_adaptive_true_print=np.mean(loss_adaptive_true) 59 | loss_adaptive_noise_print=np.mean(loss_adaptive_noise) 60 | 61 | loss_huber_true_print_std = np.std(loss_huber_true) 62 | loss_huber_noise_print_std = np.std(loss_huber_noise) 63 | loss_adaptive_true_print_std=np.std(loss_adaptive_true) 64 | loss_adaptive_noise_print_std=np.std(loss_adaptive_noise) 65 | 66 | print("SpHAM: ASE:%.3f, ASE std:%.3f, TD:%.3f, TD std:%.3f\n" % (loss_huber_noise_print, loss_huber_noise_print_std, loss_huber_true_print, loss_huber_true_print_std)) 67 | print("ASpHAM l=300: ASE:%.3f, ASE std:%.3f, TD:%.3f, TD std:%.3f\n" % (loss_adaptive_noise_print, loss_adaptive_noise_print_std, loss_adaptive_true_print, loss_adaptive_true_print_std)) 68 | 69 | 70 | -------------------------------------------------------------------------------- /adaptive_spham_ExampleC_t2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | from utilities import write_files 4 | from model import nonStationary 5 | from model import SpHAM as spham 6 | from generate_exampleC import generate_C 7 | 8 | filename1 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/t_B/exampleB_t_true.npy' 9 | filename2 = '/Users/jacky/Desktop/Paper/2021_ICLR_Wang_SphAM/Source_code_git/result/t_B/exampleB_t_noise.npy' 10 | 11 | generate_C(filename1, filename2, noise = 't') 12 | 13 | with open(filename1, 'rb') as f: 14 | big_y_true_gau = np.load(f) 15 | with open(filename2, 'rb') as f: 16 | big_y_noise_gau = np.load(f) 17 | 18 | 19 | exp_T = 4000 20 | start = 1500 21 | interval = 400 22 | back = 1 23 | end = start + interval 24 | max_iteration = 2000 25 | num_pred = 100 26 | 27 | loss_huber_true = [] 28 | loss_huber_noise = [] 29 | loss_adaptive_true = [] 30 | loss_adaptive_noise = [] 31 | 32 | for experiment in range(50): 33 | 34 | print("Experiment %d" % experiment) 35 | y_true = big_y_true_gau[experiment] 36 | y_noise = big_y_noise_gau[experiment] 37 | sys.stdout.flush() 38 | 39 | 40 | #spham 41 | model_spham = spham(y_noise, y_true, huber_sigma=np.power(interval, 1/48), start=start, interval=interval, backward=back, rbf_sigma=0.5, lamb=1/interval) 42 | alpha = model_spham.fit(max_iter=max_iteration) 43 | prediction = model_spham.predict(alpha, y_noise, y_true, start=end, repeat=num_pred, backward=back) 44 | loss_huber_true.append(np.linalg.norm(y_true[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 45 | loss_huber_noise.append(np.linalg.norm(y_noise[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 46 | 47 | #adaptive spham l=150 48 | model_aspham = nonStationary(y_noise, y_true, l=300, huber_sigma=np.power(interval, 1/48), 49 | start=start, interval=interval, lamb1=10000, lamb2=100, backward=back, 50 | rbf_sigma=0.5, lamb=1/interval, s_iter=20, out_iter=20) 51 | alpha = model_aspham.fit(max_iter=max_iteration) 52 | prediction = model_aspham.predict(alpha, y_noise, y_true, start=end, repeat=num_pred, backward=back) 53 | loss_adaptive_true.append(np.linalg.norm(y_true[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 54 | loss_adaptive_noise.append(np.linalg.norm(y_noise[end:end+num_pred, :, 0] - prediction, 2) / num_pred) 55 | 56 | loss_huber_true_print=np.mean(loss_huber_true) 57 | loss_huber_noise_print=np.mean(loss_huber_noise) 58 | loss_adaptive_true_print=np.mean(loss_adaptive_true) 59 | loss_adaptive_noise_print=np.mean(loss_adaptive_noise) 60 | 61 | loss_huber_true_print_std = np.std(loss_huber_true) 62 | loss_huber_noise_print_std = np.std(loss_huber_noise) 63 | loss_adaptive_true_print_std=np.std(loss_adaptive_true) 64 | loss_adaptive_noise_print_std=np.std(loss_adaptive_noise) 65 | 66 | print("SpHAM: ASE:%.3f, ASE std:%.3f, TD:%.3f, TD std:%.3f\n" % (loss_huber_noise_print, loss_huber_noise_print_std, loss_huber_true_print, loss_huber_true_print_std)) 67 | print("ASpHAM l=300: ASE:%.3f, ASE std:%.3f, TD:%.3f, TD std:%.3f\n" % (loss_adaptive_noise_print, loss_adaptive_noise_print_std, loss_adaptive_true_print, loss_adaptive_true_print_std)) 68 | 69 | 70 | -------------------------------------------------------------------------------- /generate_exampleA.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | def generate_A(filename1, filename2, noise = 'gau'): 3 | exp_T = 4000 4 | big_y_true_gau = [] 5 | big_y_noise_gau = [] 6 | big_y_true_t2 = [] 7 | big_y_noise_t2 = [] 8 | for times in range(100): 9 | y_true_gau = np.zeros((exp_T, 1, 1)) 10 | y_true_gau[0] = np.random.rand() 11 | y_true_gau[1] = np.random.rand() 12 | y_true_t2 = np.zeros((exp_T, 1, 1)) 13 | y_true_t2[0] = np.random.rand() 14 | y_true_t2[1] = np.random.rand() 15 | y_noise_gau = y_true_gau.copy() 16 | y_noise_t2 = y_true_t2.copy() 17 | e_gau = np.random.normal(0, 0.3, (exp_T, 1)) 18 | e_t2 = np.random.standard_t(2, (exp_T,1)) 19 | y_noise_gau[0] = y_true_gau[0] + e_gau[0] 20 | y_noise_gau[1] = y_true_gau[1] + e_gau[1] 21 | y_noise_t2[0] = y_true_t2[0] + e_t2[0] 22 | y_noise_t2[1] = y_true_t2[1] + e_t2[1] 23 | for t in range(2, exp_T): 24 | y_true_gau[t] = (3./2.)*np.sin(np.pi / 2. * y_noise_gau[t - 1]) - np.sin(np.pi / 2. * y_noise_gau[t - 2]) 25 | y_noise_gau[t] = y_true_gau[t] + 2* e_gau[t] 26 | 27 | y_true_t2[t] = np.sin(np.pi / 2. * y_noise_t2[t - 1]) -np.sin(np.pi / 2. * y_noise_t2[t - 2]) 28 | y_noise_t2[t] = y_true_t2[t] + 2* e_t2[t] 29 | big_y_true_gau.append(y_true_gau) 30 | big_y_noise_gau.append(y_noise_gau) 31 | big_y_true_t2.append(y_true_t2) 32 | big_y_noise_t2.append(y_noise_t2) 33 | if noise == 'gau': 34 | with open(filename1, 'wb') as f: 35 | np.save(f, np.array(big_y_true_gau)) 36 | with open(filename2, 'wb') as f: 37 | np.save(f, np.array(big_y_noise_gau)) 38 | else: 39 | with open(filename1, 'wb') as f: 40 | np.save(f, np.array(big_y_true_t2)) 41 | with open(filename2, 'wb') as f: 42 | np.save(f, np.array(big_y_noise_t2)) 43 | -------------------------------------------------------------------------------- /generate_exampleC.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | def generate_C(filename1, filename2, noise = 'gau'): 3 | exp_T = 4000 4 | big_y_true_gau = [] 5 | big_y_noise_gau = [] 6 | big_y_true_t2 = [] 7 | big_y_noise_t2 = [] 8 | for times in range(100): 9 | e_t2 = np.random.standard_t(2, (exp_T,1)) 10 | e_gau = np.random.normal(0, 0.3, (exp_T, 1)) 11 | y_true_gau = np.zeros((exp_T, 1, 1)) 12 | y_true_t2 = np.zeros((exp_T, 1, 1)) 13 | y_true_gau[0][0] = np.random.rand() 14 | y_true_t2[0][0] = np.random.rand() 15 | y_noise_gau = y_true_gau.copy() 16 | y_noise_t2 = y_true_t2.copy() 17 | for t in range(1, exp_T): 18 | y_true_gau[t][0] = (t / 400.) * np.sin(y_noise_gau[t - 1][0]) 19 | y_true_t2[t][0] = (t / 400.) * np.sin(y_noise_t2[t - 1][0]) 20 | y_noise_gau[t][0] = y_true_gau[t][0] + 0.5* e_gau[t][0] 21 | y_noise_t2[t][0] = y_true_t2[t][0] + 0.5 * e_t2[t][0] 22 | 23 | big_y_true_gau.append(y_true_gau) 24 | big_y_noise_gau.append(y_noise_gau) 25 | big_y_true_t2.append(y_true_t2) 26 | big_y_noise_t2.append(y_noise_t2) 27 | if noise == 'gau': 28 | with open(filename1, 'wb') as f: 29 | np.save(f, np.array(big_y_true_gau)) 30 | with open(filename2, 'wb') as f: 31 | np.save(f, np.array(big_y_noise_gau)) 32 | else: 33 | with open(filename1, 'wb') as f: 34 | np.save(f, np.array(big_y_true_t2)) 35 | with open(filename2, 'wb') as f: 36 | np.save(f, np.array(big_y_noise_t2)) 37 | -------------------------------------------------------------------------------- /model.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from utilities import prox, get_gradient_sum, huber, rbf, calcK, createX, calcL, get_gradient, update_alpha, update_alpha2, calcK_pred, update_A, prox_box 3 | import sys 4 | import random 5 | 6 | class SpHAM: 7 | T = 0 8 | start = 0 9 | end = 0 10 | interval = 0 11 | p = 0 12 | m = 0 13 | back_t = 0 14 | y = 0 15 | y_true = 0 16 | y_orig = 0 17 | y_true_orig = 0 18 | rbf_sigma = 2. 19 | huber_sigma = 0 20 | lamb = 0.01 21 | X = 0 22 | 23 | def __init__(self, y, y_true, huber_sigma, start=0, interval=100, backward=1, rbf_sigma=1., lamb=0.0001): 24 | self.m = y.shape[1] 25 | self.p = self.m * backward 26 | self.y_orig = y 27 | self.y_true_orig = y_true 28 | self.y = y[start:start+interval] 29 | self.y_true = y_true[start:start+interval] 30 | self.start = start 31 | self.interval = interval 32 | self.end = start + interval 33 | self.back_t = backward 34 | self.rbf_sigma = rbf_sigma 35 | self.lamb = lamb 36 | self.T = interval 37 | self.huber_sigma = huber_sigma 38 | '''if square_loss: 39 | self.huber_sigma = 99999999999 40 | else: 41 | self.huber_sigma = np.sqrt(self.T)''' 42 | 43 | 44 | def fit(self, max_iter=1000, tol=1e-8, verbose=False, square_loss=False): 45 | # s: 1/T for stationary problems 46 | # L: the Lipschitz constant of gradient of f 47 | # lamb: the regularization parameter 48 | # max_iter: maxmimum number of iterations 49 | # tol: the algorithm will stop if difference between two successive alpha is smaller than this value 50 | # alpha_old = 0.1 * np.random.rand(T*p, 1) 51 | 52 | big_alpha = np.ones((self.T * self.p, self.m)) 53 | X = createX(self.y_orig, self.start, self.interval, self.p, self.m, self.back_t) 54 | self.X = X 55 | K = calcK(X, self.T, self.p, self.rbf_sigma) 56 | L = calcL(K, self.T) 57 | # print("Training:") 58 | for i in range(self.m): 59 | alpha_old = np.ones((self.T * self.p, 1)) 60 | 61 | t_old = 1 62 | iter = 1 63 | y_old = alpha_old.copy() 64 | 65 | while iter <= max_iter: 66 | alpha_new = update_alpha(y_old, self.y[:,i,:], L, self.T, self.p, self.lamb, self.huber_sigma, K, square_loss) 67 | t_new = 0.5 * (1 + np.sqrt(1 + 4 * t_old ** 2)) 68 | #print("t_new:",t_new.shape) 69 | y_new = alpha_new + (t_old - 1) / t_new * (alpha_new - alpha_old) 70 | #print("y_new.shape:",y_new.shape) 71 | 72 | prediction = np.empty(self.T) 73 | for t in range(self.T): 74 | prediction[t] = K[:, t].T @ alpha_new 75 | 76 | #print("prediction.shape",prediction.shape) 77 | loss1 = np.linalg.norm(prediction - self.y[:,i,0]) / self.T 78 | loss2 = np.linalg.norm(prediction - self.y_true[:,i,0]) / self.T 79 | 80 | 81 | if verbose and (iter == 1 or (iter >= 10 and iter % 10 == 0)): 82 | print("dimension %d, iteration: %d" % (i, iter)) 83 | print("loss : %.8f" % (loss1)) 84 | print("loss with ground truth: %.8f\n" % (loss2)) 85 | 86 | # check with tolerence 87 | e = np.linalg.norm((alpha_new - alpha_old), ord=1) / (self.T * self.p) 88 | if e < tol: 89 | break 90 | 91 | # update 92 | alpha_old = alpha_new 93 | t_old = t_new 94 | y_old = y_new 95 | iter += 1 96 | big_alpha[:,i] = alpha_old[:,0] 97 | return big_alpha 98 | 99 | # y and y_true are the entire ys, start is the initial time that we want to predict 100 | def predict(self, big_alpha, y, y_true, start, repeat, backward=1, verbose=False): 101 | my_y = y[start - backward:start, :, :] 102 | my_y2 = my_y.flatten() 103 | 104 | 105 | big_prediction = np.empty((repeat, self.m)) 106 | for count in range(repeat): 107 | prediction = np.empty(self.m) 108 | for i in range(self.m): 109 | 110 | k = np.empty((self.T * self.p)) 111 | for j in range(self.p): 112 | for t in range(self.T): 113 | #k[j*self.T + t] = rbf(self.X[t][j], my_y[:,j,:] , self.rbf_sigma) 114 | k[j * self.T + t] = rbf(self.X[t][j], my_y2[j], self.rbf_sigma) 115 | 116 | prediction[i] = k @ big_alpha[:,i] 117 | 118 | if verbose: 119 | print("prediction:",prediction) 120 | 121 | loss1 = np.linalg.norm(prediction - y[start+count, :, 0]) 122 | loss2 = np.linalg.norm(prediction - y_true[start+count, :, 0]) 123 | 124 | if verbose: 125 | print("At time %d dimension %d" % (start+count, i)) 126 | print("loss: %.8f" % loss1) 127 | print("loss with ground truth: %.8f\n" % loss2) 128 | 129 | big_prediction[count] = prediction 130 | 131 | # my_y2_temp = my_y2.copy() 132 | 133 | # for tp in range(len(my_y2) - self.m): 134 | # my_y2[tp] = my_y2_temp[tp + self.m] 135 | 136 | 137 | # prediction_idx = 0 138 | # for tp in range(len(my_y2) - self.m, len(my_y2)): 139 | # my_y2[tp] = prediction[prediction_idx] 140 | # prediction_idx += 1 141 | 142 | my_y = y[start + count + 1 - backward:start + count + 1, :, :] 143 | my_y2 = my_y.flatten() 144 | 145 | return big_prediction 146 | 147 | 148 | 149 | 150 | class nonStationary: 151 | T = 0 152 | start = 0 153 | end = 0 154 | interval = 0 155 | p = 0 156 | m = 0 157 | back_t = 0 158 | y = 0 159 | y_true = 0 160 | y_orig = 0 161 | y_true_orig = 0 162 | rbf_sigma = 2. 163 | huber_sigma = 0 164 | lamb = 0.01 165 | X = 0 166 | q = 0 167 | s = 0 168 | lamb1 = 0 169 | lamb2 = 0 170 | stepA_cons = 0 171 | l = 0 172 | s_iter = 0 173 | dccp_iter = 0 174 | dccp_tau = 0 175 | 176 | def __init__(self, y, y_true, l, huber_sigma, start=0, interval=100, backward=1, rbf_sigma=1., lamb=0.001, lamb1=100., lamb2=20., lambA=1000, s_iter=5, out_iter=5): 177 | self.m = y.shape[1] 178 | self.p = self.m * backward 179 | self.y_orig = y 180 | self.y_true_orig = y_true 181 | self.y = y[start:start + interval] 182 | self.y_true = y_true[start:start + interval] 183 | self.start = start 184 | self.interval = interval 185 | self.end = start + interval 186 | self.back_t = backward 187 | self.rbf_sigma = rbf_sigma 188 | self.lamb = lamb 189 | self.lamb1 = lamb1 190 | self.lamb2 = lamb2 191 | self.lambA = lambA 192 | self.c = 1 193 | self.T = interval 194 | self.huber_sigma = huber_sigma 195 | self.q = np.empty(interval) 196 | self.q[:interval-l] = 0. 197 | self.q[-l:] = 1./l 198 | self.l = l 199 | self.s = np.ones(interval) 200 | self.s_iter = s_iter 201 | self.out_iter = out_iter 202 | 203 | def fit(self, lr=0.00005, max_iter=1000, tol=1e-8, verbose=False, square_loss=False): 204 | # s: 1/T for stationary problems 205 | # L: the Lipschitz constant of gradient of f 206 | # lamb: the regularization parameter 207 | # max_iter: maxmimum number of iterations 208 | # tol: the algorithm will stop if difference between two successive alpha is smaller than this value 209 | 210 | # alpha_old = 0.1 * np.random.rand(T*p, 1) 211 | big_alpha = np.ones((self.T * self.p, self.m)) 212 | X = createX(self.y_orig, self.start, self.interval, self.p, self.m, self.back_t) 213 | self.X = X 214 | K = calcK(X, self.T, self.p, self.rbf_sigma) 215 | L = calcL(K, self.T) 216 | 217 | 218 | for dim in range(self.m): 219 | # Step A 220 | s_iter = 1 221 | s_old = np.zeros(self.T) 222 | # s_old = np.ones(self.T) 223 | sys.stdout.flush() 224 | while s_iter <= self.s_iter: 225 | # alpha 226 | alpha_old = 0.1*np.ones((self.T * self.p, 1)) 227 | alpha_new = 0.1*np.ones((self.T * self.p, 1)) 228 | iter = 1 229 | while iter <= self.out_iter: 230 | grad = get_gradient_sum(K, alpha_old, self.y, self.huber_sigma, self.T, self.p, range(self.interval), self.q-s_old) 231 | temp_alpha = alpha_old + lr * (grad - 2*self.lambA * alpha_old) 232 | value = np.linalg.norm(temp_alpha-alpha_old, 2) 233 | alpha_old = temp_alpha 234 | 235 | 236 | # check with tolerence 237 | e = np.linalg.norm((alpha_new - alpha_old), ord=1) / (self.T * self.p) 238 | if e < tol: 239 | break 240 | # update 241 | alpha_new = alpha_old.copy() 242 | iter += 1 243 | s_iter += 1 244 | # update A 245 | A = update_A(self.T, self.p, self.X, alpha_new, self.y[:,dim,:], self.rbf_sigma, self.huber_sigma) 246 | 247 | # update s 248 | s_new = s_old - lr * (-A[:,0] - 2*self.lamb1 * (self.q - s_old) + 2*self.lamb2 * s_old) 249 | s_new = prox_box(s_new, self.q, self.T) 250 | 251 | sum = 0 252 | for t in range(self.T): 253 | sum += A[t,0] * (s_new[t] - self.q[t]) 254 | 255 | sum += self.lamb1 * np.linalg.norm(self.q - s_new, 2) + self.lamb2 * np.linalg.norm(s_new,2) 256 | 257 | 258 | sys.stdout.flush() 259 | 260 | # check if s converged 261 | e = np.linalg.norm((s_new - s_old), ord=1) 262 | if e < 0.000001: 263 | break 264 | s_old = s_new 265 | s_iter += 1 266 | sys.stdout.flush() 267 | 268 | sys.stdout.flush() 269 | 270 | 271 | # step B 272 | alpha_old = np.ones((self.T * self.p, 1)) 273 | # print('the value of s', s_old[100:120]) 274 | t_old = 1 275 | iter = 1 276 | y_old = alpha_old.copy() 277 | 278 | 279 | while iter <= max_iter: 280 | alpha_new = update_alpha2(y_old, self.y[:,dim,:], L, self.T, self.p, self.lamb, self.huber_sigma, K, square_loss, s_old) 281 | t_new = 0.5 * (1 + np.sqrt(1 + 4 * t_old ** 2)) 282 | y_new = alpha_new + (t_old - 1) / t_new * (alpha_new - alpha_old) 283 | 284 | prediction = np.empty(self.T) 285 | for t in range(self.T): 286 | prediction[t] = K[:, t].T @ alpha_new 287 | 288 | loss1 = np.linalg.norm(prediction - self.y[:,dim,0]) / self.T 289 | loss2 = np.linalg.norm(prediction - self.y_true[:,dim,0]) / self.T 290 | 291 | if verbose and (iter == 1 or (iter >= 10 and iter % 10 == 0)): 292 | print("dimension %d, iteration: %d" % (dim, iter)) 293 | print("loss : %.8f" % (loss1)) 294 | print("loss with ground truth: %.8f\n" % (loss2)) 295 | 296 | # check with tolerence 297 | e = np.linalg.norm((alpha_new - alpha_old), ord=1)/(self.T * self.T) 298 | if e < tol: 299 | break 300 | 301 | # update 302 | alpha_old = alpha_new 303 | t_old = t_new 304 | y_old = y_new 305 | iter += 1 306 | big_alpha[:,dim] = alpha_old[:,0] 307 | return big_alpha 308 | 309 | def predict(self, big_alpha, y, y_true, start, repeat, backward=1, verbose=False): 310 | my_y = y[start - backward:start, :, :] 311 | my_y2 = my_y.flatten() 312 | 313 | big_prediction = np.empty((repeat, self.m)) 314 | for count in range(repeat): 315 | prediction = np.empty(self.m) 316 | for i in range(self.m): 317 | 318 | k = np.empty((self.T * self.p)) 319 | for j in range(self.p): 320 | for t in range(self.T): 321 | #k[j*self.T + t] = rbf(self.X[t][j], my_y[:,j,:] , self.rbf_sigma) 322 | k[j * self.T + t] = rbf(self.X[t][j], my_y2[j], self.rbf_sigma) 323 | 324 | prediction[i] = k @ big_alpha[:,i] 325 | 326 | if verbose: 327 | print("prediction:",prediction) 328 | 329 | #print("diff.shape",diff.shape) 330 | loss1 = np.linalg.norm(prediction - y[start+count, :, 0]) 331 | loss2 = np.linalg.norm(prediction - y_true[start+count, :, 0]) 332 | 333 | if verbose: 334 | print("At time %d dimension %d" % (start+count, i)) 335 | print("loss: %.8f" % loss1) 336 | print("loss with ground truth: %.8f\n" % loss2) 337 | 338 | big_prediction[count] = prediction 339 | 340 | 341 | 342 | my_y = y[start + count + 1 - backward:start + count + 1, :, :] 343 | my_y2 = my_y.flatten() 344 | 345 | 346 | return big_prediction 347 | -------------------------------------------------------------------------------- /utilities.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def write_files(filename, method, data1, data2, data3, data4): 4 | with open(filename, 'a') as f: 5 | f.write("TD, Loss with true data:\n") 6 | f.write("%s: %.10f \n" % (method, np.mean(np.array(data1)))) 7 | f.write("ASE, Loss with noise data: \n") 8 | f.write("%s: %.10f \n" % (method, np.mean(np.array(data2)))) 9 | f.write("TD, minimal:\n") 10 | f.write("%s: %.10f \n" % (method, data3)) 11 | f.write("ASE, minimal: \n") 12 | f.write("%s: %.10f \n" % (method, data4)) 13 | 14 | def rbf(x, y, sigma): 15 | return np.exp(-(np.sum((x - y) ** 2)) / (2 * sigma ** 2)) 16 | 17 | # Calculate the big matrix of K 18 | def calcK(X, T, p, sigma): 19 | K = np.empty((T * p, T)) 20 | for dimension in range(p): 21 | for t in range(T): 22 | for temp_t in range(T): 23 | K[dimension * T + t][temp_t] = rbf(X[temp_t][dimension], X[t][dimension], sigma) 24 | 25 | return K 26 | 27 | # Calculate the big matrix of K 28 | def calcK_group(X, T, sigma): 29 | K = np.empty((T * 7, T)) 30 | K1 = np.empty((T, T)) 31 | K2 = np.empty((T, T)) 32 | K3 = np.empty((T, T)) 33 | K12 = np.empty((T, T)) 34 | K13 = np.empty((T, T)) 35 | K23 = np.empty((T, T)) 36 | K123 = np.empty((T, T)) 37 | for t in range(T): 38 | for temp_t in range(T): 39 | K1[t][temp_t] = rbf(X[temp_t][0], X[t][0], sigma) 40 | K2[t][temp_t] = rbf(X[temp_t][1], X[t][1], sigma) 41 | K3[t][temp_t] = rbf(X[temp_t][2], X[t][2], sigma) 42 | a = np.array([X[temp_t][0], X[temp_t][1]]) 43 | b = np.array([X[t][0], X[t][1]]) 44 | K12[t][temp_t] = rbf(a, b, sigma) 45 | a = np.array([X[temp_t][0], X[temp_t][2]]) 46 | b = np.array([X[t][0], X[t][2]]) 47 | K13[t][temp_t] = rbf(a, b, sigma) 48 | a = np.array([X[temp_t][1], X[temp_t][2]]) 49 | b = np.array([X[t][1], X[t][2]]) 50 | K23[t][temp_t] = rbf(a, b, sigma) 51 | K123[t][temp_t] = rbf(X[temp_t, :], X[t, :], sigma) 52 | 53 | 54 | K = np.concatenate((K1, K2, K3, K12, K13, K23, K123), axis=0) 55 | 56 | return # Calculate the big matrix of K 57 | def calcK_group(X, T, sigma): 58 | K = np.empty((T * 7, T)) 59 | K1 = np.empty((T, T)) 60 | K2 = np.empty((T, T)) 61 | K3 = np.empty((T, T)) 62 | K12 = np.empty((T, T)) 63 | K13 = np.empty((T, T)) 64 | K23 = np.empty((T, T)) 65 | K123 = np.empty((T, T)) 66 | for t in range(T): 67 | for temp_t in range(T): 68 | K1[t][temp_t] = rbf(X[temp_t][0], X[t][0], sigma) 69 | K2[t][temp_t] = rbf(X[temp_t][1], X[t][1], sigma) 70 | K3[t][temp_t] = rbf(X[temp_t][2], X[t][2], sigma) 71 | a = np.array([X[temp_t][0], X[temp_t][1]]) 72 | b = np.array([X[t][0], X[t][1]]) 73 | K12[t][temp_t] = rbf(a, b, sigma) 74 | a = np.array([X[temp_t][0], X[temp_t][2]]) 75 | b = np.array([X[t][0], X[t][2]]) 76 | K13[t][temp_t] = rbf(a, b, sigma) 77 | a = np.array([X[temp_t][1], X[temp_t][2]]) 78 | b = np.array([X[t][1], X[t][2]]) 79 | K23[t][temp_t] = rbf(a, b, sigma) 80 | K123[t][temp_t] = rbf(X[temp_t, :], X[t, :], sigma) 81 | 82 | 83 | K = np.concatenate((K1, K2, K3, K12, K13, K23, K123), axis=0) 84 | 85 | return 86 | # Calculate the big matrix of K 87 | def calcK_group(X, T, sigma): 88 | K = np.empty((T * 7, T)) 89 | K1 = np.empty((T, T)) 90 | K2 = np.empty((T, T)) 91 | K3 = np.empty((T, T)) 92 | K12 = np.empty((T, T)) 93 | K13 = np.empty((T, T)) 94 | K23 = np.empty((T, T)) 95 | K123 = np.empty((T, T)) 96 | for t in range(T): 97 | for temp_t in range(T): 98 | K1[t][temp_t] = rbf(X[temp_t][0], X[t][0], sigma) 99 | K2[t][temp_t] = rbf(X[temp_t][1], X[t][1], sigma) 100 | K3[t][temp_t] = rbf(X[temp_t][2], X[t][2], sigma) 101 | a = np.array([X[temp_t][0], X[temp_t][1]]) 102 | b = np.array([X[t][0], X[t][1]]) 103 | K12[t][temp_t] = rbf(a, b, sigma) 104 | a = np.array([X[temp_t][0], X[temp_t][2]]) 105 | b = np.array([X[t][0], X[t][2]]) 106 | K13[t][temp_t] = rbf(a, b, sigma) 107 | a = np.array([X[temp_t][1], X[temp_t][2]]) 108 | b = np.array([X[t][1], X[t][2]]) 109 | K23[t][temp_t] = rbf(a, b, sigma) 110 | K123[t][temp_t] = rbf(X[temp_t, :], X[t, :], sigma) 111 | 112 | 113 | K = np.concatenate((K1, K2, K3, K12, K13, K23, K123), axis=0) 114 | 115 | return 116 | # Calculate the big matrix of K 117 | def calcK_group2(X, T, sigma): 118 | K = np.empty((T * 7, T)) 119 | K1 = np.empty((T, T)) 120 | K2 = np.empty((T, T)) 121 | K12 = np.empty((T, T)) 122 | for t in range(T): 123 | for temp_t in range(T): 124 | K1[t][temp_t] = rbf(X[temp_t][0], X[t][0], sigma) 125 | K2[t][temp_t] = rbf(X[temp_t][1], X[t][1], sigma) 126 | a = np.array([X[temp_t][0], X[temp_t][1]]) 127 | b = np.array([X[t][0], X[t][1]]) 128 | K12[t][temp_t] = rbf(a, b, sigma) 129 | 130 | 131 | K = np.concatenate((K1, K2, K12), axis=0) 132 | 133 | return K 134 | 135 | def calcK_pred(X_static,T,y,p,sigma): 136 | K = np.empty((T*p, 1)) 137 | for dim in range(p): 138 | for t in range(T): 139 | K[dim*T+t] = rbf(X_static[t][dim], y[dim], sigma) 140 | 141 | # Create X from y and given time interval 142 | def createX(y, start, interval, p, m, back_t): 143 | X = np.zeros((interval, p)) 144 | 145 | for t in range(interval): 146 | for dim in range(m): 147 | curr_t = t + start 148 | for temp_t in range(back_t): 149 | X[t][dim * back_t + temp_t] = y[curr_t - (back_t - temp_t)][dim] 150 | 151 | return X 152 | 153 | # Calculate the Lipschitz constant of gradient of f 154 | def calcL(K, T): 155 | max_val = -np.inf 156 | for t in range(T): 157 | norm = np.linalg.norm(K[:, t] @ K[:, t].T) 158 | if norm > max_val: 159 | max_val = norm 160 | 161 | return max_val 162 | 163 | def get_gradient(k, k_tj, alpha, y, sigma, T, square_loss): 164 | diff = k.T @ alpha - y 165 | if square_loss: 166 | ans = 2 * diff * k_tj 167 | return ans.reshape((T, 1)) 168 | else: 169 | if np.abs(diff) < sigma: 170 | #print("1!") 171 | ans = 2 * diff * k_tj 172 | return ans.reshape((T, 1)) 173 | elif diff > sigma: 174 | #print("2!") 175 | return 2 * sigma * np.ones((T, 1)) 176 | else: 177 | #print("3!") 178 | return -2 * sigma * np.ones((T, 1)) 179 | 180 | 181 | def get_gradient_sum(K, alpha, y, sigma, T,p, B,s_hat): 182 | sum = np.zeros((T*p, 1)) 183 | for i in B: 184 | temp = get_gradient(K[:, i], K[:,i], alpha, y[i], sigma, T*p, 0) 185 | sum += s_hat[i] * temp 186 | return sum 187 | 188 | def update_alpha(alpha, y, L, T, p, lamb, sigma, K, square_loss): 189 | v = np.empty((T * p, 1)) 190 | for dim in range(p): 191 | sum = np.zeros((T, 1)) 192 | for t in range(T): 193 | temp = get_gradient(K[:, t], K[dim * T:(dim + 1) * T][t], alpha, y[t], sigma, T, square_loss) 194 | sum += temp 195 | 196 | vj = alpha[dim * T:(dim + 1) * T] - (1 / (T * L)) * sum 197 | first = 1 - (lamb / np.linalg.norm(vj)) 198 | 199 | v[dim * T:(dim + 1) * T] = max(0, first) * vj 200 | 201 | return v 202 | 203 | def update_alpha2(alpha, y, L, T, p, lamb, sigma, K, square_loss, s): 204 | v = np.empty((T * p, 1)) 205 | for dim in range(p): 206 | sum = np.zeros((T, 1)) 207 | for t in range(T): 208 | temp = get_gradient(K[:, t], K[dim * T:(dim + 1) * T][t], alpha, y[t], sigma, T, square_loss) 209 | sum = s[t] * temp +sum 210 | 211 | vj = alpha[dim * T:(dim + 1) * T] - (1 / L) * sum 212 | first = 1 - (lamb / np.linalg.norm(vj)) 213 | 214 | v[dim * T:(dim + 1) * T] = max(0, first) * vj 215 | 216 | return v 217 | 218 | def prox(alpha, T, p, lamb): 219 | v = np.empty((T * p, 1)) 220 | for dim in range(p): 221 | vj = alpha[dim * T:(dim + 1) * T] 222 | first = 1 - (lamb / np.linalg.norm(vj)) 223 | v[dim * T:(dim + 1) * T] = max(0, first) * vj 224 | return v 225 | 226 | def prox_box(s,p,T): 227 | for dim in range(T): 228 | if s[dim] < 0: 229 | s[dim] = 0 230 | return s 231 | 232 | def huber(a, b, sigma): 233 | if np.abs(a-b) < sigma: 234 | return (a-b)**2 235 | else: 236 | return 2 * sigma * np.abs(a-b) - sigma**2 237 | 238 | def update_A(T, p, X, alpha, y, rbf_sigma, huber_sigma): 239 | A = np.empty((T, 1)) 240 | for t in range(T): 241 | k = np.empty((T * p)) 242 | for j in range(p): 243 | for inner_t in range(T): 244 | k[j * T + inner_t] = rbf(X[inner_t][j], X[t][j], rbf_sigma) 245 | 246 | prediction = k @ alpha 247 | loss = huber(prediction, y[t], huber_sigma) 248 | A[t] = loss 249 | 250 | return A 251 | 252 | --------------------------------------------------------------------------------