SedSat3 1.1.6
Sediment Source Apportionment Tool - Advanced statistical methods for environmental pollution research
Loading...
Searching...
No Matches
multiplelinearregression.cpp
Go to the documentation of this file.
2#include <gsl/gsl_multifit.h>
3#include "Vector.h"
4#include <gsl/gsl_statistics_double.h>
5#include <gsl/gsl_cdf.h>
6#include <qjsonarray.h>
7
8
13
49
50double MultipleLinearRegression::SSE_reduced_model(const vector<vector<double>> &independent, const vector<double> dependent, int eliminated_var)
51{
52 if (independent.size()==0) return false;
53 if (independent[0].size()!=dependent.size()) return false;
54 int number_of_data_points = dependent.size();
55 int number_of_variables = independent.size();
56
57 gsl_matrix *X, *cov;
58 gsl_vector *y, *w, *c;
59
60 double SSE=0;
61
62 if (number_of_variables==1)
63 {
65 SSE = pow(CVector(dependent).stdev(),2)*(dependent.size()-1);
66 else
67 SSE = pow(CVector(dependent).Log().stdev(),2)*(dependent.size()-1);
68 return SSE;
69 }
70
71 X = gsl_matrix_alloc (number_of_data_points, number_of_variables);
72 y = gsl_vector_alloc (number_of_data_points);
73 w = gsl_vector_alloc (number_of_data_points);
74
75 c = gsl_vector_alloc (number_of_variables);
76 cov = gsl_matrix_alloc (number_of_variables, number_of_variables);
77
78 for (int i = 0; i < number_of_data_points; i++)
79 {
80 gsl_matrix_set (X, i, 0, 1.0);
81 for (int j=0; j<number_of_variables; j++)
82 {
83 if (j<eliminated_var)
85 gsl_matrix_set (X, i, j+1, independent[j][i]);
86 else
87 gsl_matrix_set (X, i, j+1, log(independent[j][i]));
88 }
89 else if (j>eliminated_var)
91 gsl_matrix_set (X, i, j, independent[j][i]);
92 else
93 gsl_matrix_set (X, i, j, log(independent[j][i]));
94 }
96 gsl_vector_set (y, i, dependent[i]);
97 else
98 gsl_vector_set (y, i, log(dependent[i]));
99 gsl_vector_set (w, i, 1.0);
100 }
101 }
102
103 {
104 gsl_multifit_linear_workspace * work
105 = gsl_multifit_linear_alloc (number_of_data_points, number_of_variables);
106 gsl_multifit_wlinear (X, w, y, c, cov,&SSE, work);
107 gsl_multifit_linear_free (work);
108 }
109
110 return SSE;
111
112}
113
114double MultipleLinearRegression::Regress(const vector<vector<double>> &independent, const vector<double> dependent, const vector<string> &indep_var_names)
115{
116 if (independent.size()==0) return false;
117 if (independent[0].size()!=dependent.size()) return false;
118 independent_variables_names = indep_var_names;
119 int number_of_data_points = dependent.size();
120 int number_of_variables = independent.size();
121
122 gsl_matrix *X, *cov;
123 gsl_vector *y, *w, *c;
124
125 X = gsl_matrix_alloc (number_of_data_points, number_of_variables+1);
126 y = gsl_vector_alloc (number_of_data_points);
127 w = gsl_vector_alloc (number_of_data_points);
128
129 c = gsl_vector_alloc (number_of_variables+1);
130 cov = gsl_matrix_alloc (number_of_variables+1, number_of_variables+1);
131 independent_data = independent;
132 dependent_data = dependent;
133 for (int i = 0; i < number_of_data_points; i++)
134 {
135
136 gsl_matrix_set (X, i, 0, 1.0);
137 vector<double> independent_column;
138 for (int j=0; j<number_of_variables; j++)
139 {
141 gsl_matrix_set (X, i, j+1, independent[j][i]);
142 else
143 gsl_matrix_set (X, i, j+1, log(independent[j][i]));
144
145 }
146
148 gsl_vector_set (y, i, dependent[i]);
149 else
150 gsl_vector_set (y, i, log(dependent[i]));
151 gsl_vector_set (w, i, 1.0);
152 }
153
154 {
155 gsl_multifit_linear_workspace * work
156 = gsl_multifit_linear_alloc (number_of_data_points, number_of_variables+1);
157 gsl_multifit_wlinear (X, w, y, c, cov,&chisq, work);
158 gsl_multifit_linear_free (work);
159 }
160
161
162 coefficients_intercept_.resize(number_of_variables+1);
163 for (int i=0; i<number_of_variables+1; i++)
164 {
165 coefficients_intercept_[i] = gsl_vector_get(c,i);
166 }
167
168 correlation_matrix_ = CMBMatrix(number_of_variables+1);
169 for (int i=0; i<number_of_variables+1; i++)
170 for (int j=0; j<number_of_variables+1; j++)
171 correlation_matrix_[i][j] = gsl_matrix_get(cov,i,j);
172
173 double var_y = gsl_stats_tss(y->data, y->stride, y->size);
174
175 R2 = 1-chisq/var_y;
176 R2_adj = 1-(chisq/(number_of_data_points-(number_of_variables+1))/(var_y/(number_of_data_points-1)));
177 p_value.clear();
178 make_effective.clear();
179 for (unsigned int i=0; i<number_of_variables; i++)
180 {
181 double SSE_reduced = SSE_reduced_model(independent,dependent, i);
182 double F = (SSE_reduced - chisq)/chisq*(number_of_data_points-number_of_variables-1);
183 p_value.push_back(gsl_cdf_fdist_Q (F, number_of_variables, number_of_data_points-(number_of_variables)));
185 make_effective.push_back(true);
186 else
187 make_effective.push_back(false);
188 qDebug()<<chisq<<","<<SSE_reduced<<","<<F<<","<<p_value[i];
189
190 }
191
192 gsl_matrix_free (X);
193 gsl_vector_free (y);
194 gsl_vector_free (w);
195 gsl_vector_free (c);
196 gsl_matrix_free (cov);
197
198 return chisq;
199
200}
202{
203 QJsonObject out;
205 out["form"]="Linear";
206 else
207 out["form"]="Power";
208 out["Intercept"] = coefficients_intercept_[0];
209 QJsonArray json_dependent_data;
210 for (unsigned int i = 0; i < dependent_data.size(); i++)
211 json_dependent_data << dependent_data[i];
212
213 out["Dependent Data"] = json_dependent_data;
214
215
216 QJsonArray json_independent_data;
217 for (unsigned int j = 0; j < independent_data.size(); j++)
218 {
219 QJsonArray json_independent_data_item;
220 for (unsigned int i = 0; i < independent_data[j].size(); i++)
221 json_independent_data_item.append(independent_data[j][i]);
222
223 json_independent_data.append(json_independent_data_item);
224 }
225
226 out["Independent Data"] = json_independent_data;
227
228
229 for (unsigned int i=1; i<coefficients_intercept_.size(); i++)
230 {
231
232 out[QString::fromStdString("Coefficient for;" + aquiutils::numbertostring(i)+";" + independent_variables_names[i-1])] = coefficients_intercept_[i];
233 out[QString::fromStdString("P-value for;" + aquiutils::numbertostring(i)+";" + independent_variables_names[i-1])] = p_value[i-1];
234 out[QString::fromStdString("Effective for;" + aquiutils::numbertostring(i)+";" + independent_variables_names[i-1])] = Effective(i-1);
235 }
236
237
238 out["Chisq"] = chisq;
239 out["R2"] = R2;
240 out["R2_adjusted"]=R2_adj;
241
242
243 return out;
244
245}
246bool MultipleLinearRegression::ReadFromJsonObject(const QJsonObject &jsonobject)
247{
250 p_value.clear();
251 if (jsonobject["form"]=="Power")
253 else
255 coefficients_intercept_.push_back(jsonobject["Intercept"].toDouble());
256 int i=1;
257 for(QString key: jsonobject.keys() ) {
258 if (key.contains("Coefficient for"))
259 { coefficients_intercept_.push_back(jsonobject[key].toDouble());
260 independent_variables_names.push_back(key.split(";")[2].toStdString());
261
262 }
263 if (key.contains("P-value for"))
264 {
265 p_value.push_back(jsonobject[key].toDouble());
266 }
267 if (key.contains("Effective for"))
268 {
269 make_effective.push_back(jsonobject[key].toBool());
270 }
271 }
272
273// Read dependent and independent data here
274 QJsonArray json_dependent_data = jsonobject["Dependent Data"].toArray();
275 for (unsigned int i = 0; i < json_dependent_data.size(); i++)
276 {
277 dependent_data.push_back(json_dependent_data[i].toDouble());
278 }
279
280 QJsonArray json_independent_data = jsonobject["Independent Data"].toArray();
281 for (unsigned int i = 0; i < json_independent_data.size(); i++)
282 {
283 vector<double> independent_data_item;
284 QJsonArray json_independent_data_item = json_independent_data[i].toArray();
285 for (unsigned int j = 0; j < json_independent_data_item.size(); j++)
286 {
287 independent_data_item.push_back(json_independent_data_item[j].toDouble());
288 }
289 independent_data.push_back(independent_data_item);
290 }
291
292 R2 = jsonobject["R2"].toDouble();
293 R2_adj = jsonobject["R2_adjusted"].toDouble();
294 chisq = jsonobject["Chisq"].toDouble();
295 return true;
296}
297
302
303
305{
306 return CVector(independent_data[i]).mean();
307}
308
310{
311 return exp(CVector(independent_data[i]).Log().mean());
312}
314{
315 string out;
317 { out += "form: Linear\n";
318 out += "Coefficient: " + QString::number(coefficients_intercept_[0]).toStdString() + "\n";
319 }
320 else
321 { out += "form: Power\n";
322 out += "Coefficient: " + QString::number(coefficients_intercept_[0]).toStdString() + "\n";
323 }
324
325 for (unsigned int i=1; i<coefficients_intercept_.size(); i++)
326 {
328 out += "Coefficient for " + independent_variables_names[i-1] +":" + QString::number(coefficients_intercept_[i]).toStdString() + "\n";
329 else
330 out += "Exponent for " + independent_variables_names[i-1] +":" + QString::number(coefficients_intercept_[i]).toStdString() + "\n";
331 out += "P-value for " + independent_variables_names[i-1] +":" + QString::number(p_value[i-1]).toStdString() + "\n";
332
333 }
334 out += "Chisq: " + QString::number(chisq).toStdString() + "\n";
335 out += "R2: " + QString::number(R2).toStdString() + "\n";
336 out += "Adusted R2: " + QString::number(R2_adj).toStdString() + "\n";
337 return out;
338}
339
340vector<double> &MultipleLinearRegression::IndependentData(const string &var_name)
341{
342 for (int i=0; i<independent_variables_names.size(); i++)
343 if (var_name == independent_variables_names[i])
344 return independent_data[i];
345
346}
347
Matrix class with labeled rows and columns for Chemical Mass Balance analysis.
Definition cmbmatrix.h:19
Abstract base class providing common serialization and visualization interface.
Definition interface.h:65
Interface & operator=(const Interface &intf)
Assignment operator.
Definition interface.cpp:14
QJsonObject toJsonObject() const override
Serialize object to JSON format.
vector< double > & IndependentData(const string &var_name)
MultipleLinearRegression & operator=(const MultipleLinearRegression &mp)
double SSE_reduced_model(const vector< vector< double > > &independent, const vector< double > dependent, int eliminated_var)
string ToString() const override
Convert object to string representation.
double Regress(const vector< vector< double > > &independent, const vector< double > dependent, const vector< string > &indep_vars_names)
vector< double > CoefficientsIntercept() const
bool ReadFromJsonObject(const QJsonObject &jsonobject) override
Deserialize object from JSON format.
vector< vector< double > > independent_data
vector< string > independent_variables_names