Lemma is an Electromagnetics API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utlogbarriercg.cpp 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // ===========================================================================
  2. //
  3. // Filename: utlogbarriercg.cpp
  4. //
  5. // Created: 12/29/2010 09:40:23 AM
  6. // Compiler: Tested with g++, icpc, and MSVC 2010
  7. //
  8. // Author: Trevor Irons (ti)
  9. //
  10. // Organisation: Colorado School of Mines (CSM)
  11. // United States Geological Survey (USGS)
  12. //
  13. // Email: tirons@mines.edu, tirons@usgs.gov
  14. //
  15. // This program is free software: you can redistribute it and/or modify
  16. // it under the terms of the GNU General Public License as published by
  17. // the Free Software Foundation, either version 3 of the License, or
  18. // (at your option) any later version.
  19. //
  20. // This program is distributed in the hope that it will be useful,
  21. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. // GNU General Public License for more details.
  24. //
  25. // You should have received a copy of the GNU General Public License
  26. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  27. //
  28. // ===========================================================================
  29. /**
  30. @file
  31. @author Trevor Irons
  32. @date 12/29/2010
  33. @version 0.0
  34. **/
  35. #include "LemmaObject.h"
  36. //#include "logbarriercg.h"
  37. //#include "datasnmr.h"
  38. #include <ctime>
  39. #ifdef HAVEBOOSTRANDOM
  40. #include <boost/random.hpp>
  41. #include <boost/random/normal_distribution.hpp>
  42. #endif
  43. using namespace std;
  44. using namespace Lemma;
  45. MatrixXr BuildG(const Real& T2, const Real& Larmor, const Real& T,
  46. const Real& dt, const VectorXr& nT2Bins, const Real& scale);
  47. MatrixXr BuildGw(const Real& T2, const Real& Larmor, const Real& T,
  48. const Real& dt, const VectorXr& nT2Bins, const Real& scale,
  49. const VectorXr& freqs);
  50. /// test driver program for log-barrier optimization algorithm
  51. int main() {
  52. return 0;
  53. }
  54. #ifdef AA
  55. // Parameters
  56. Real T2(.200);
  57. Real Larmor(2000); // Hz
  58. Real wL = 2.*PI * Larmor;
  59. Real T(.6);
  60. Real dt(1e-4);
  61. int nT2(20);
  62. Real T2Low(.020);
  63. Real T2Hi(.220);
  64. // T2 bins
  65. VectorXr T2Bins = VectorXr::LinSpaced(nT2, T2Low, T2Hi);
  66. // Build true model
  67. VectorXr m = VectorXr::Zero(T2Bins.size());
  68. //m[4] = .15;
  69. //m[5] = .15;
  70. //m[6] = .15;
  71. m[7] = .15;
  72. m[8] = .15;
  73. m[11] = .15;
  74. m[12] = .15;
  75. m[13] = .15;
  76. m[14] = .15;
  77. // Build G
  78. srand ( std::time(NULL) );
  79. Real scale = 1e-4*std::abs(VectorXr::Random(1)[0]);
  80. MatrixXr G = BuildG(T2, wL, T, dt, T2Bins, scale);
  81. #ifdef HAVEBOOSTRANDOM
  82. Real mean = 0;
  83. Real variance = scale*.05*(.5+.15);
  84. boost::mt19937 randgen(static_cast<unsigned int> (std::time(0)));
  85. boost::normal_distribution<Real> noise(mean, variance);
  86. boost::variate_generator<boost::mt19937, boost::normal_distribution<Real> > nD(randgen, noise);
  87. VectorXr noisy = G*m;
  88. // for (int i=0; i < noisy.size(); ++i) {
  89. // noisy(i) += nD();
  90. // }
  91. #else
  92. VectorXr d = G * m;
  93. VectorXr noisy = d.array();// + .05*( .5 + .15 ) *Eigen::ArrayXd::Random(d.size());
  94. #endif
  95. // Clean Data, and 10% random noise data
  96. VectorXr RefMod = VectorXr::Zero(m.size());
  97. // todo let alpha's be set.
  98. Real alpha_s = .0;
  99. Real alpha_t2 = 1.0;
  100. Eigen::SparseMatrix<Real> Wd (G.rows(), G.rows());
  101. Eigen::SparseMatrix<Real> Wm (G.cols(), G.cols());
  102. /////////////////
  103. // Model objective function
  104. int ii = 0;
  105. for (int iT2=0; iT2<nT2; ++iT2) {
  106. Wm.coeffRef(ii, ii) += alpha_s - alpha_t2;
  107. if (iT2 < nT2-1) {
  108. Wm.coeffRef(ii, ii+1) += alpha_t2;
  109. }
  110. ++ii;
  111. }
  112. Wm.finalize();
  113. std::fstream WmOut( "wmMatrix.dat" , std::ios::out);
  114. WmOut << Wm << std::endl;
  115. WmOut.close();
  116. // Data objective function
  117. /// @todo add measure of suspected std dev to this.
  118. for (int id=0; id<G.rows(); ++id) {
  119. Wd.coeffRef(id, id) = 1.; // 1/sigma(i);
  120. }
  121. Wd.finalize();
  122. // invert time-domain sinusoid exponent
  123. //LogBarrierCG(G, RefMod, noisy, (Real)0., (Real)1e5, nT2, Wd, Wm, scale*1e1);
  124. return EXIT_SUCCESS;
  125. // #if 0
  126. // // invert FD
  127. // Eigen::FFT<Real> fft;
  128. // fft.SetFlag(fft.HalfSpectrum);
  129. // VectorXcr dw;
  130. // fft.fwd(dw, noisy);
  131. //
  132. // // Compute freqs Hz
  133. // VectorXr freqs = DataSNMR::GetNMRSampledFrequencies(T/dt, dt);
  134. // Real df = freqs[1];
  135. // Real window = 300; // Hz
  136. // int iL = (int)(Larmor/df);
  137. // MatrixXr Gw = BuildGw(T2, wL, T, dt, T2Bins, scale, freqs.segment(iL-window/2, window));
  138. //
  139. // VectorXr dwu = VectorXr::Zero(2.*window);
  140. // dwu.head(window) = dw.segment(iL-window/2, window).real();
  141. // dwu.tail(window) = dw.segment(iL-window/2, window).imag();
  142. //
  143. // Eigen::DynamicSparseMatrix<Real> Wdw (Gw.rows(), Gw.rows());
  144. // for (int id=0; id<Gw.rows(); ++id) {
  145. // Wdw.coeffRef(id, id) = 1.; // 1/sigma(i);
  146. // }
  147. // Wdw.finalize();
  148. // std::cout << "psize " << (Gw*RefMod).size() << std::endl;
  149. // VectorXr dw2 = Gw*m;
  150. // //std::cout << dw2 << std::endl;
  151. // std::cout << "Gw " << Gw.rows() << "\t" << Gw.cols() << std::endl;
  152. // std::cout << "dwu " << dwu.size() << std::endl;
  153. // //RefMod.array() += .1;
  154. // VectorXr mod = LogBarrierCG(Gw, RefMod, dwu, 0., 3., nT2, Wdw, Wm,scale*1e5);
  155. // //VectorXr mod = LogBarrierCG(Gw, dwu, 0., 1e5);
  156. //
  157. // std::fstream Gws("gw.out", std::ios::out);
  158. // Gws << Gw << std::endl;
  159. // Gws.close();
  160. // #endif
  161. }
  162. #endif
  163. MatrixXr BuildG(const Real& T2, const Real& wL, const Real& T,
  164. const Real& dt, const VectorXr& T2Bins, const Real& scale) {
  165. std::cout << "scale " << scale << std::endl;
  166. int nt = T/dt;
  167. int nT2 = T2Bins.size();
  168. MatrixXr G = MatrixXr::Zero(nt,nT2);
  169. for (int iT2=0; iT2<nT2; ++iT2) {
  170. Real t=0;
  171. for (int it=0; it<nt; ++it) {
  172. G(it, iT2) = scale * exp(-t/T2Bins(iT2)) * sin(wL * t);
  173. t += dt;
  174. }
  175. }
  176. return G;
  177. }
  178. MatrixXr BuildGw(const Real& T2, const Real& wL, const Real& T,
  179. const Real& dt, const VectorXr& T2Bins, const Real& scale,
  180. const VectorXr &freqs) {
  181. VectorXr omegas = freqs.array() * 2.*PI;
  182. std::cout << "scale " << scale << std::endl;
  183. int nT2 = T2Bins.size();
  184. MatrixXr Gw = MatrixXr::Zero(2*freqs.size(), nT2);
  185. int nW = freqs.size();
  186. Real sc = 1./dt;
  187. for (int iT2=0; iT2<nT2; ++iT2) {
  188. for (int iw=0; iw<freqs.size(); ++iw) {
  189. Real a = 1./T2Bins(iT2);
  190. Complex T = wL / ( wL*wL + (a+Complex(0, omegas[iw]))*(a+Complex(0,omegas[iw])) ) ;
  191. Gw(iw, iT2) = sc * scale * std::real(T);
  192. Gw(iw+nW, iT2) = sc * scale * std::imag(T);
  193. }
  194. }
  195. return Gw;
  196. }