glm.cpp
Go to the documentation of this file.
1 
10 #include <target/glm.hpp>
11 
12 namespace target {
13 
14  // Softmax transformation using sum-log-exp trick to avoid overflow
15  arma::mat softmax(arma::mat lp, bool ref = true, bool log = false) {
16  if (ref) lp.insert_cols(0, arma::zeros(lp.n_rows));
17  arma::colvec lpmax = arma::max(lp, 1);
18  lp.each_col() -= lpmax;
19  arma::colvec denom = sum(exp(lp), 1);
20  lp.each_col() -= arma::log(denom);
21  if (log) return(lp);
22  return(exp(lp));
23  }
24 
25  // Softmax transformation using sum-log-exp trick to avoid overflow
26  arma::vec softmax(arma::vec u) {
27  double umax = u.max();
28  u -= umax;
29  double denom = sum(exp(u));
30  return u - log(denom);
31  }
32 
33  // template arma::mat expit<double>(const arma::mat&);
34  // template arma::cx_mat expit<Complex>(const arma::cx_mat&);
35 
36  arma::mat expit(arma::mat x) {
37  for (unsigned i=0; i < x.n_elem; i++) {
38  double z = x(i);
39  if (z >= 0) {
40  x(i) = 1/(1+exp(-z));
41  } else {
42  z = exp(z);
43  x(i) = z/(1+z);
44  }
45  }
46  return(x);
47  }
48 
49  arma::cx_mat expit(arma::cx_mat x) {
50  return 1.0/(1+exp(-x));
51  }
52 
53  // template arma::mat expit<double>(const arma::mat&);
54  // template arma::cx_mat expit<Complex>(const arma::cx_mat&);
55 
56 
57  IID logistic_iid(const arma::vec &y,
58  const arma::vec &p,
59  const arma::mat &x,
60  const arma::vec &w) {
61  arma::vec r = (y-p);
62  arma::vec s = r%w;
63  arma::mat U = x;
64  for (unsigned i=0; i < x.n_cols; i++)
65  U.col(i) %= s;
66  arma::vec v = p%(1-p)%w;
67  arma::mat H = arma::zeros(x.n_cols, x.n_cols);
68  for (unsigned i=0; i < x.n_rows; i++) {
69  H += v[i]*(trans(x.row(i))*x.row(i));
70  }
71  return IID(U, H.i());
72  }
73 
74  IID linear_iid(const arma::vec &y,
75  const arma::vec &p,
76  const arma::mat &x,
77  const arma::vec &w) {
78  arma::vec r = (y-p);
79  double df = y.n_elem-x.n_cols;
80  arma::vec s = r%w;
81  double sigma2 = sum(r%s)/df;
82  arma::mat U = x;
83  for (unsigned i=0; i < x.n_cols; i++)
84  U.col(i) %= s/sigma2;
85  arma::mat H = arma::zeros(x.n_cols, x.n_cols);
86  for (unsigned i=0; i < x.n_rows; i++) {
87  H += w[i]*trans(x.row(i))*x.row(i);
88  }
89  return IID(U, sigma2*H.i());
90  }
91 
92 } // namespace target
93 
94 
95 
96 // arma::mat logistic_score(const arma::vec &beta,
97 // const arma::vec &y,
98 // const arma::mat &x,
99 // const arma::vec &weights) {
100 // arma::vec p = expit(x*beta);
101 // arma::vec s = (y-p)%weights;
102 // arma::vec res = x;
103 // for (unsigned i=0; i < x.n_cols; i++)
104 // res.col(i) %= s;
105 // return res;
106 // }
107 // arma::mat logistic_vcov(const arma::vec &beta,
108 // const arma::mat &x,
109 // const arma::vec &weights) {
110 // arma::vec p = expit(x*beta);
111 // arma::vec v = p%(1-p)%weights;
112 // arma::mat V = arma::zeros(beta.n_elem,beta.n_elem);
113 // for (unsigned i=0; i < x.n_rows; i++) {
114 // V += weights[i]*x.row(i)*x.row(i).t();
115 // }
116 // return V.i();
117 // }
118 // arma::mat linear_score(const arma::vec &beta,
119 // const arma::vec &y,
120 // const arma::mat &x,
121 // const arma::vec &weights) {
122 // arma::vec r = y-x*beta;
123 // double df = y.n_elem-beta.n_elem;
124 // arma::vec s = r%weights;
125 // double sigma2 = sum(r%s)/df;
126 // arma::vec res = x;
127 // for (unsigned i=0; i < x.n_cols; i++)
128 // res.col(i) %= s/sigma2;
129 // return res;
130 // }
131 // arma::mat linear_vcov(const arma::vec &beta,
132 // const arma::vec &y,
133 // const arma::mat &x,
134 // const arma::vec &weights) {
135 // arma::vec r = y-x*beta;
136 // double df = y.n_elem-beta.n_elem;
137 // arma::vec s = r%weights;
138 // double sigma2 = sum(r%s)/df;
139 // arma::mat V = arma::zeros(beta.n_elem,beta.n_elem);
140 // for (unsigned i=0; i < x.n_rows; i++) {
141 // V += weights[i]*x.row(i)*x.row(i).t();
142 // }
143 // return( sigma2*V.i() );
144 // }
Utility functions for Generalized Linear Models.