Octopus
compressed_sensing.F90
Go to the documentation of this file.
1!! Copyright (C) 2011 X. Andrade
2!!
3!! This program is free software: you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation, either version 3 of the License, or
6!! (at your option) any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program. If not, see <http://www.gnu.org/licenses/>.
15!!
16
17#include <global.h>
18
20 use blas_oct_m
21 use bpdn_oct_m
22 use debug_oct_m
23 use global_oct_m
24 use, intrinsic :: iso_fortran_env
27
28 implicit none
29
30 private
31
32 ! these values are copied from td/spectrum.f90
33 integer, parameter :: &
34 SPECTRUM_TRANSFORM_LAPLACE = 1, &
37
38 public :: &
43
45 private
46 real(real64) :: sigma
47 integer :: ntime
48 real(real64) :: dtime
49 real(real64) :: stime
50 integer :: nfreq
51 real(real64) :: dfreq
52 real(real64) :: sfreq
53 type(bpdn_matrix) :: fourier_matrix
55
56contains
57
58 subroutine compressed_sensing_init(this, transform_type, ntime, dtime, stime, nfreq, dfreq, sfreq, noise)
59 type(compressed_sensing_t), intent(out) :: this
60 integer, intent(in) :: transform_type
61 integer, intent(in) :: ntime
62 real(real64), intent(in) :: dtime
63 real(real64), intent(in) :: stime
64 integer, intent(in) :: nfreq
65 real(real64), intent(in) :: dfreq
66 real(real64), intent(in) :: sfreq
67 real(real64), intent(in) :: noise
68
69 integer :: itime, ifreq, type
70 real(real64) :: time, freq
71
73
74 this%sigma = noise
75
76 this%ntime = ntime
77 this%dtime = dtime
78 this%stime = stime
79 this%nfreq = nfreq
80 this%dfreq = dfreq
81 this%sfreq = sfreq
82
83 if (transform_type == spectrum_transform_laplace) then
84
85 call bpdn_matrix_init(this%fourier_matrix, this%ntime, this%nfreq, explicit_matrix)
86
87 do ifreq = 1, this%nfreq
88 freq = (ifreq - 1)*this%dfreq + this%sfreq
89
90 do itime = 1, this%ntime
91 time = (itime - 1)*this%dtime + this%stime
92 this%fourier_matrix%matrix(itime, ifreq) = exp(-freq*time)
93 end do
94
95 end do
96
97 else
98
99 select case (transform_type)
101 type = sin_matrix
103 type = cos_matrix
104 end select
105
106 call bpdn_matrix_init(this%fourier_matrix, this%ntime, this%nfreq, type)
107 call bpdn_matrix_set_delta(this%fourier_matrix, this%dtime, this%dfreq)
108
109 end if
110
113
114 ! -------------------------------------------------------------------
115
116 subroutine compressed_sensing_end(this)
117 type(compressed_sensing_t), intent(inout) :: this
118
119 push_sub(compressed_sensing_end)
120
121 call bpdn_matrix_end(this%fourier_matrix)
122
124 end subroutine compressed_sensing_end
125
126 ! -------------------------------------------------------------------
127
128 subroutine compressed_sensing_spectral_analysis(this, time_function, freq_function)
129 type(compressed_sensing_t), intent(inout) :: this
130 real(real64), intent(in) :: time_function(:)
131 real(real64), intent(out) :: freq_function(:)
132
133 integer :: ierr
134 real(real64), allocatable :: tf_normalized(:)
135 real(real64) :: nrm
136
138
139 safe_allocate(tf_normalized(1:this%ntime))
141 ! to avoid numerical problems we work with a normalized rhs
142 nrm = dnrm2(this%ntime, time_function(1), 1)
144 if (nrm > 1e-8_real64) then
145 tf_normalized(1:this%ntime) = time_function(1:this%ntime)/nrm
146 else
147 tf_normalized(1:this%ntime) = time_function(1:this%ntime)
148 nrm = m_one
149 end if
150
151 call bpdn(this%ntime, this%nfreq, this%fourier_matrix, tf_normalized, this%sigma, freq_function, ierr, activesetit = 50)
152
153 safe_deallocate_a(tf_normalized)
154
155 ! scale by the missing factors
156 freq_function(1:this%nfreq) = nrm/(this%dfreq*m_two/m_pi)*freq_function(1:this%nfreq)
157
158 if (ierr < 0) then
159 message(1) = 'The Basis Pursuit Denoising process failed to converge.'
160 call messages_warning(1)
161 end if
162
165
167
168!! Local Variables:
169!! mode: f90
170!! coding: utf-8
171!! End:
double exp(double __x) __attribute__((__nothrow__
This module contains interfaces for BLAS routines You should not use these routines directly....
Definition: blas.F90:118
subroutine, public compressed_sensing_init(this, transform_type, ntime, dtime, stime, nfreq, dfreq, sfreq, noise)
integer, parameter spectrum_transform_cos
integer, parameter spectrum_transform_sin
subroutine, public compressed_sensing_spectral_analysis(this, time_function, freq_function)
subroutine, public compressed_sensing_end(this)
real(real64), parameter, public m_two
Definition: global.F90:189
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:185
real(real64), parameter, public m_one
Definition: global.F90:188
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:543
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160