Skip to content

Commit 611aed7

Browse files
committed
[BugFixes] Fix bugs in python interface of SampEn2D.
1 parent 0d6b4e6 commit 611aed7

8 files changed

+51
-29
lines changed

include/sample_entropy_calculator2d.h

+10-5
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,14 @@ class SampleEntropyCalculator2DSampling : public SampleEntropyCalculator2D<T> {
206206
unsigned dilation_factor,
207207
unsigned sample_size, unsigned sample_num,
208208
double real_entropy, double real_a_norm,
209-
double real_b_norm, OutputLevel output_level)
209+
double real_b_norm, bool random_,
210+
OutputLevel output_level)
210211
: SampleEntropyCalculator2D<T>(first, last, m, r, width, height,
211212
moving_step_size, dilation_factor,
212213
output_level),
213214
_sample_size(sample_size), _sample_num(sample_num),
214215
_real_entropy(real_entropy), _real_a_norm(real_a_norm),
215-
_real_b_norm(real_b_norm) {
216+
_real_b_norm(real_b_norm), _random(random_) {
216217
if (_num_templates < _sample_size) {
217218
MSG_ERROR(-1, "Sample size (N0) exceeds the number of templates.\n");
218219
}
@@ -224,13 +225,15 @@ class SampleEntropyCalculator2DSampling : public SampleEntropyCalculator2D<T> {
224225
unsigned dilation_factor,
225226
unsigned sample_size, unsigned sample_num,
226227
double real_entropy, double real_a_norm,
227-
double real_b_norm, OutputLevel output_level)
228+
double real_b_norm, bool random_,
229+
OutputLevel output_level)
228230
: SampleEntropyCalculator2DSampling(data.cbegin(), data.cend(), m, r,
229231
width, height, moving_step_size,
230232
dilation_factor,
231233
sample_size, sample_num,
232234
real_entropy, real_a_norm,
233-
real_b_norm, output_level) {}
235+
real_b_norm, random_,
236+
output_level) {}
234237
vector<long long> get_a_vec() {
235238
if (!_computed)
236239
ComputeSampleEntropy();
@@ -294,6 +297,7 @@ class SampleEntropyCalculator2DSampling : public SampleEntropyCalculator2D<T> {
294297
const double _real_entropy;
295298
const double _real_a_norm;
296299
const double _real_b_norm;
300+
const bool _random;
297301
vector<long long> _a_vec, _b_vec;
298302
};
299303

@@ -322,6 +326,7 @@ class SampleEntropyCalculator2DSampling : public SampleEntropyCalculator2D<T> {
322326
using SampleEntropyCalculator2DSampling<T>::_real_entropy;\
323327
using SampleEntropyCalculator2DSampling<T>::_real_a_norm;\
324328
using SampleEntropyCalculator2DSampling<T>::_real_b_norm;\
329+
using SampleEntropyCalculator2DSampling<T>::_random;\
325330
using SampleEntropyCalculator2DSampling<T>::_a_vec;\
326331
using SampleEntropyCalculator2DSampling<T>::_b_vec;\
327332
using SampleEntropyCalculator2DSampling<T>::_IsMatchedK;\
@@ -389,7 +394,7 @@ template <typename T>
389394
void SampleEntropyCalculator2DSamplingDirect<T>::_ComputeSampleEntropy() {
390395
unsigned num_templates = _num_steps_x * _num_steps_y;
391396
RandomIndicesSamplerWR sampler(num_templates, _sample_size, _sample_num,
392-
RandomType::SWR_UNIFORM);
397+
RandomType::SWR_UNIFORM, _random);
393398
const auto random_indices_array = sampler.GetSampleArrays();
394399
_a_vec.clear();
395400
_b_vec.clear();

python/sample_entropy_calculator2d.pxd

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ cdef extern from "sample_entropy_calculator2d.h" namespace "sampen":
4545
double real_entropy,
4646
double real_a_norm,
4747
double real_b_norm,
48+
bool random_,
4849
OutputLevel output_level) except +
4950
double get_computation_time()
5051
double get_entropy()

python/sample_entropy_calculator2d.pyx

+3-2
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ cdef class SampEn2DSamplingD:
6262
unsigned dilation_factor,
6363
unsigned sample_size, unsigned sample_num,
6464
double real_entropy, double real_a_norm, double real_b_norm,
65-
OutputLevel level):
65+
bool random_, OutputLevel level):
6666
self.c_ = new SampleEntropyCalculator2DSamplingDirect[int](
6767
data, r, m, width, height, moving_step_size, dilation_factor,
68-
sample_size, sample_num, real_entropy, real_a_norm, real_b_norm, level)
68+
sample_size, sample_num, real_entropy, real_a_norm, real_b_norm,
69+
random_, level)
6970

7071
def __dealloc__(self):
7172
if self.c_ != NULL:

python/test_sampen2d.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
import sys
13
import sampen2d
24
import numpy as np
35
from PIL import Image, ImageOps
@@ -8,7 +10,8 @@
810
n1 = 20
911

1012
if __name__ == '__main__':
11-
image_path = '../data2d/Original Brodatz/D1.gif'
13+
input_dir = os.path.join(os.environ['HOME'], 'workspace/entropy/2d')
14+
image_path = os.path.join(input_dir, 'Original_Brodatz/D1.gif')
1215
image = Image.open(image_path)
1316
image = ImageOps.grayscale(image)
1417
image = np.array(image)
@@ -24,6 +27,11 @@
2427

2528
n0 = n * sample_rate
2629
s = sampen2d.SampEn2DSamplingD(image.flatten(), r_scaled, m, w, h, 1, 1,
27-
n0, n1, r_e, r_a, r_b, 0)
30+
n0, n1, r_e, r_a, r_b, True, 0)
31+
print('time: ', s.time())
32+
print('entropy: ', s.entropy())
33+
34+
s = sampen2d.SampEn2DSamplingD(image.flatten(), r_scaled, m, w, h, 1, 1,
35+
n0, n1, r_e, r_a, r_b, True, 0)
2836
print('time: ', s.time())
2937
print('entropy: ', s.entropy())

script/python_experiments/exp_utils.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -84,31 +84,35 @@ def estimate_sampen2d_and_save_statistics(sig, r: float, m: int,
8484
r_e = s.entropy()
8585
r_a = s.a_norm()
8686
r_b = s.b_norm()
87+
t = s.time()
8788
else:
8889
r_e, r_a, r_b = groundtruth
90+
t = 0
8991
print(f'output_filename [{output_filename}]', file=f)
9092
print(f'n0 [{n0}] n1 [{n1}] m [{m}] r [{r}] n [{n}]', file=f)
91-
print(f'[Direct] sampen2d [{r_e:.6f}] a [{r_a:.6f}] b [{r_b:.6f}]', file=f)
93+
print(f'[Direct] sampen2d [{r_e:.6f}] a [{r_a:.6f}] b [{r_b:.6f}] t [{t:.4e}]', file=f)
9294
list_err_e = np.zeros(n_computations)
9395
list_err_a = np.zeros(n_computations)
9496
list_err_b = np.zeros(n_computations)
97+
list_time = np.zeros(n_computations)
9598
for i in range(n_computations):
9699
s = sampen2d.SampEn2DSamplingD(sig, r_scaled, m, width, height, 1, 1,
97-
n0, n1, r_e, r_a, r_b, 0)
100+
n0, n1, r_e, r_a, r_b, True, 0)
98101
err_e = s.entropy() - r_e
99102
err_a = s.a_norm() - r_a
100103
err_b = s.b_norm() - r_b
101104
list_err_e[i] = err_e
102105
list_err_a[i] = err_a
103106
list_err_b[i] = err_b
104-
print(f'[SWR] sampen2d [{s.entropy():.6f}] a [{s.a_norm():.6f}] b [{s.b_norm():.6f}]', file=f)
107+
list_time[i] = s.time()
108+
print(f'[SWR] sampen2d [{s.entropy():.6f}] a [{s.a_norm():.6f}] b [{s.b_norm():.6f}] t [{s.time():.4e}]', file=f)
105109
print(f'[SWR] err_sampen2d [{err_e :.4e}] err_a [{err_a:.4e}] err_b [{err_b:.4e}]', file=f)
106110
m_e, std_e, m_abs_err_e, r_m_e, r_std_e, r_m_abs_err_e = get_statistics(list_err_e, r_e)
107111
m_a, std_a, m_abs_err_a, r_m_a, r_std_a, r_m_abs_err_a = get_statistics(list_err_a, r_a)
108112
m_b, std_b, m_abs_err_b, r_m_b, r_std_b, r_m_abs_err_b = get_statistics(list_err_b, r_b)
109-
print(f'[SWR] m_e [{m_e:.4e}] std_e [{std_e:.4e}] m_abs_err_e [{m_abs_err_e:.4e}]', file=f)
113+
print(f'[SWR] m_e [{m_e:.4e}] std_e [{std_e:.4e}] m_abs_err_e [{m_abs_err_e:.4e}] m_t [{np.mean(list_time):.4e}]', file=f)
110114
print(f'[SWR] r_m_e [{r_m_e:.4e}] r_std_e [{r_std_e:.4e}] r_m_abs_err_e [{r_m_abs_err_e:.4e}]', file=f)
111115
print(f'[SWR] m_a [{m_a:.4e}] std_a [{std_a:.4e}] m_abs_err_a [{m_abs_err_a:.4e}]', file=f)
112116
print(f'[SWR] r_m_a [{r_m_a:.4e}] r_std_a [{r_std_a:.4e}] r_m_abs_err_a [{r_m_abs_err_a:.4e}]', file=f)
113117
print(f'[SWR] m_b [{m_b:.4e}] std_b [{std_b:.4e}] m_abs_err_b [{m_abs_err_b:.4e}]', file=f)
114-
print(f'[SWR] r_m_b [{r_m_b:.4e}] r_std_b [{r_std_b:.4e}] r_m_abs_err_b [{r_m_abs_err_b:.4e}]', file=f)
118+
print(f'[SWR] r_m_b [{r_m_b:.4e}] r_std_b [{r_std_b:.4e}] r_m_abs_err_b [{r_m_abs_err_b:.4e}]', file=f)

script/python_experiments/run_ex_2d.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
script_dir = os.path.dirname(sys.argv[0])
2222

2323
def estimate_sampen2d_and_save_task(db_name, record_name, r, m):
24-
output_dir = pjoin(script_dir, '../../result/2d_err', db_name)
24+
output_dir = pjoin(script_dir, '../../result/2d_err/m%d_r%.2f' % (m, r), db_name)
2525
output_filename = os.path.splitext(record_name)[0] + '.txt'
2626
input_path = pjoin(input_dir, db_name, record_name)
2727
image = Image.open(input_path)
2828
image = np.array(ImageOps.grayscale(image))
2929
height, width = image.shape
30-
print('start estimating...')
30+
print('start %s %s %.2f %d...' % (db_name, record_name, r, m))
3131
estimate_sampen2d_and_save_statistics(image.flatten(), r, m,
3232
width=width, height=height,
3333
n0=n0, n1=n1, outputdir=output_dir,

src/sampen2d.cpp

+15-13
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ struct Argument {
2727
unsigned height;
2828
unsigned moving_step_size;
2929
unsigned dilation_factor;
30-
bool sampling1;
31-
bool sampling2;
30+
bool sampling;
31+
bool random_;
3232
bool multiscale;
3333
unsigned multiscale_depth;
3434
double multiscale_factor;
@@ -72,13 +72,13 @@ char usage[] =
7272
" --multiscale-factor <FACTOR>\n"
7373
" The scaling factor of resizing when computing multiscale SampEn2D.\n\n"
7474
"Options:\n"
75-
" --sampling1\n"
76-
" Use sampling method (approach 1).\n"
77-
" --sampling2\n"
78-
" Use sampling method (approach 2).\n"
75+
" --sampling\n"
76+
" Use sampling method to estimate SampEn2D.\n"
7977
" --multiscale\n"
8078
" Compute multiscale SampEn2D.\n"
81-
" --help\n"
79+
" -r | --random\n"
80+
" Set seed randomly.\n"
81+
" -h | --help\n"
8282
" Display this message.\n";
8383
// clang-format on
8484

@@ -99,8 +99,7 @@ void ParseArgument(int argc, char *argv[]) {
9999
arg.image_filename = parser.getArg("--input");
100100
arg.output_level =
101101
static_cast<sampen::OutputLevel>(parser.getArgLong("--output-level", 0));
102-
arg.sampling1 = parser.isOption("--sampling1");
103-
arg.sampling2 = parser.isOption("--sampling2");
102+
arg.sampling = parser.isOption("--sampling");
104103
arg.multiscale = parser.isOption("--multiscale");
105104
arg.multiscale_depth = parser.getArgLong("--multiscale-depth", 1);
106105
arg.multiscale_factor = parser.getArgDouble("--multiscale-factor", 0.5);
@@ -113,9 +112,10 @@ void ParseArgument(int argc, char *argv[]) {
113112
std::cerr << "Usage: " << argv[0] << usage;
114113
exit(-1);
115114
}
116-
if (arg.sampling1 || arg.sampling2) {
115+
if (arg.sampling) {
117116
arg.sample_size = parser.getArgLong("--sample-size", 1024);
118117
arg.sample_num = parser.getArgLong("--sample-num", 20);
118+
arg.random_ = parser.isOption("--random") || parser.isOption("-r");
119119
}
120120
}
121121

@@ -149,7 +149,8 @@ std::vector<double> ComputeMultiscaleSampEn2D(Magick::Image image, double r,
149149
calculator =
150150
std::make_shared<SampleEntropyCalculator2DSamplingDirect<int>>(
151151
data.cbegin(), data.cend(), r, m, width, height, 1, 1,
152-
arg.sample_size, arg.sample_num, 0., 0., 0., arg.output_level);
152+
arg.sample_size, arg.sample_num, 0., 0., 0., arg.random_,
153+
arg.output_level);
153154
} else {
154155
calculator = std::make_shared<SampleEntropyCalculator2DDirect<int>>(
155156
data.cbegin(), data.cend(), r, m, width, height, 1, 1,
@@ -224,11 +225,12 @@ int main(int argc, char *argv[]) {
224225
double a_norm = sec2dd.get_a_norm();
225226
double b_norm = sec2dd.get_b_norm();
226227

227-
if (arg.sampling1) {
228+
if (arg.sampling) {
228229
sampen::SampleEntropyCalculator2DSamplingDirect<int> sec2dds(
229230
data.cbegin(), data.cend(), arg.r, arg.m, arg.width, arg.height,
230231
arg.moving_step_size, arg.dilation_factor, arg.sample_size,
231-
arg.sample_num, sampen2d, a_norm, b_norm, arg.output_level);
232+
arg.sample_num, sampen2d, a_norm, b_norm, arg.random_,
233+
arg.output_level);
232234
std::cout << sec2dds.get_result_str();
233235
}
234236
if (arg.multiscale) {

src/utils.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ void ReportVmPeak() {
2929
MSG_INFO("%s\n", buffer);
3030
}
3131
}
32+
ifs.close();
3233
}
3334
#endif
3435
}

0 commit comments

Comments
 (0)