-
Notifications
You must be signed in to change notification settings - Fork 165
/
nrmse.c
executable file
·117 lines (80 loc) · 2.47 KB
/
nrmse.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* Copyright 2015. The Regents of the University of California.
* Copyright 2015-2016. Martin Uecker.
* All rights reserved. Use of this source code is governed by
* a BSD-style license which can be found in the LICENSE file.
*
* Authors:
* 2013 Dara Bahri <[email protected]>
* 2014 Frank Ong
* 2014 Jonathan Tamir
* 2015-2016 Martin Uecker
*/
#include <complex.h>
#include <stdbool.h>
#include <assert.h>
#include "misc/mmio.h"
#include "misc/misc.h"
#include "misc/opts.h"
#include "misc/debug.h"
#include "num/multind.h"
#include "num/flpmath.h"
#include "num/init.h"
#ifndef DIMS
#define DIMS 16
#endif
static const char help_str[] =
"Output normalized root mean square error (NRMSE),\n"
"i.e. norm(input - ref) / norm(ref)";
int main_nrmse(int argc, char* argv[argc])
{
const char* ref_file = NULL;
const char* in_file = NULL;
struct arg_s args[] = {
ARG_INFILE(true, &ref_file, "reference"),
ARG_INFILE(true, &in_file, "input"),
};
float test = -1.;
bool auto_scale = false;
bool scientific = false;
const struct opt_s opts[] = {
OPT_FLOAT('t', &test, "eps", "compare to eps"),
OPT_SET('s', &auto_scale, "automatic (complex) scaling"),
OPTL_SET('S', "scientific", &scientific, "use scientific notation in output"),
};
cmdline(&argc, argv, ARRAY_SIZE(args), args, help_str, ARRAY_SIZE(opts), opts);
num_init();
long ref_dims[DIMS];
long in_dims[DIMS];
complex float* ref = load_cfl(ref_file, DIMS, ref_dims);
complex float* in = load_cfl(in_file, DIMS, in_dims);
assert(md_check_compat(DIMS, 0u, in_dims, ref_dims));
if (auto_scale) {
complex float sc = md_zscalar(DIMS, ref_dims, in, ref);
float n = md_znorm(DIMS, ref_dims, ref);
if (0. == n)
error("Reference has zero norm\n");
sc /= n * n;
debug_printf(DP_INFO, "Scaled by: %f%+fi\n", crealf(sc), cimagf(sc));
md_zsmul(DIMS, ref_dims, ref, ref, sc);
}
float err = md_znrmse(DIMS, ref_dims, ref, in);
// automatically switch to scientific output if the regular output
// might show all zeros for a non-zero error
if ((0 != err) && (1e-6 >= err))
scientific = true;
if (scientific)
bart_printf("%e\n", err);
else
bart_printf("%f\n", err);
unmap_cfl(DIMS, ref_dims, ref);
unmap_cfl(DIMS, in_dims, in);
if (test == -1.)
test = err;
if (err < test * 0.1) {
if (scientific)
debug_printf(DP_DEBUG2, "Loose test: %e <= 0.1 x %e\n", err, test);
else
debug_printf(DP_DEBUG2, "Loose test: %f <= 0.1 x %f\n", err, test);
}
return (err <= test) ? 0 : 1;
}