Skip to content

Commit 689999f

Browse files
fix B matrix computation and add normalize vectors
1 parent 761a9da commit 689999f

File tree

3 files changed

+71
-24
lines changed

3 files changed

+71
-24
lines changed

imagery/i.cca/main.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,18 @@ int main(int argc, char *argv[])
192192
G_math_egvorder(eigval, eigmat, bands);
193193
G_math_d_AB(eigmat, w, q, bands, bands, bands);
194194

195+
/**Normalize each row (eigenvector) of the transformation matrix q */
196+
for (i = 0; i < bands; i++) {
197+
double norm = 0.0;
198+
for (j = 0; j < bands; j++)
199+
norm += q[i][j] * q[i][j];
200+
norm = sqrt(norm);
201+
if (norm > 0.0) {
202+
for (j = 0; j < bands; j++)
203+
q[i][j] /= norm;
204+
}
205+
}
206+
195207
for (i = 0; i < bands; i++) {
196208
G_verbose_message("%i. eigen value: %+6.5f", i, eigval[i]);
197209
G_verbose_message("eigen vector:");
@@ -207,7 +219,7 @@ int main(int argc, char *argv[])
207219
datafds[i] = Rast_open_old(refs.file[i].name, refs.file[i].mapset);
208220

209221
snprintf(tempname, sizeof(tempname), "%s.%d", out_opt->answer, i + 1);
210-
outfds[i] = Rast_open_c_new(tempname);
222+
outfds[i] = Rast_open_new(tempname, DCELL_TYPE);
211223
}
212224

213225
/* do the transform */

imagery/i.cca/stats.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ int within(int samptot, int nclass, double *nsamp, double ***cov, double **w,
2020

2121
for (i = 0; i < bands; i++)
2222
for (j = 0; j < bands; j++)
23-
w[i][j] = (1.0 / ((double)(samptot - nclass))) * w[i][j];
23+
w[i][j] /= (samptot - nclass);
2424

2525
return 0;
2626
}
@@ -37,20 +37,43 @@ int between(int samptot, int nclass, double *nsamp, double **mu, double **p,
3737
tmp2 = G_alloc_matrix(bands, bands);
3838
newvec = G_alloc_vector(bands);
3939

40+
/* Initialize to zero */
41+
for (i = 0; i < bands; i++) {
42+
newvec[i] = 0.0;
43+
for (j = 0; j < bands; j++) {
44+
tmp1[i][j] = 0.0;
45+
tmp2[i][j] = 0.0;
46+
}
47+
}
48+
49+
/* Compute weighted sum for overall mean vector */
4050
for (i = 0; i < nclass; i++)
4151
for (j = 0; j < bands; j++)
4252
newvec[j] += nsamp[i] * mu[i][j];
43-
for (i = 0; i < bands; i++)
44-
for (j = 0; j < bands; j++)
45-
tmp1[i][j] = (newvec[i] * newvec[j]) / samptot;
4653

54+
/* Compute N * mu_bar * mu_bar^T */
55+
for (i = 0; i < bands; i++) {
56+
double mu_bar_i = newvec[i] / samptot;
57+
for (j = 0; j < bands; j++) {
58+
double mu_bar_j = newvec[j] / samptot;
59+
tmp1[i][j] = samptot * mu_bar_i * mu_bar_j;
60+
}
61+
}
62+
63+
/* Compute sum of n_i * mu_i * mu_i^T */
4764
for (k = 0; k < nclass; k++) {
4865
product(mu[k], nsamp[k], tmp0, bands);
4966
for (i = 0; i < bands; i++)
5067
for (j = 0; j < bands; j++)
51-
tmp2[i][j] += tmp0[i][j] - tmp1[i][j];
68+
tmp2[i][j] += tmp0[i][j];
5269
}
5370

71+
/* Subtract overall mean component */
72+
for (i = 0; i < bands; i++)
73+
for (j = 0; j < bands; j++)
74+
tmp2[i][j] -= tmp1[i][j];
75+
76+
/* Normalize */
5477
for (i = 0; i < bands; i++)
5578
for (j = 0; j < bands; j++)
5679
p[i][j] = tmp2[i][j] / (nclass - 1);

imagery/i.cca/transform.c

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <stdlib.h>
2+
#include <limits.h>
23

34
#include <grass/gis.h>
45
#include <grass/gmath.h>
@@ -11,49 +12,60 @@ int transform(int *datafds, int *outfds, int rows, int cols, double **eigmat,
1112
{
1213
int i, j, k, l;
1314
double *sum;
14-
CELL **rowbufs;
15+
DCELL **rowbufs;
1516

1617
sum = G_alloc_vector(bands);
17-
rowbufs = (CELL **)G_calloc(bands, sizeof(CELL *));
18+
rowbufs = (DCELL **)G_calloc(bands, sizeof(DCELL *));
1819

1920
/* allocate row buffers for each band */
20-
for (i = 0; i < bands; i++)
21-
if ((rowbufs[i] = Rast_allocate_c_buf()) == NULL)
22-
G_fatal_error(_("Unable to allocate cell buffers."));
21+
for (i = 0; i < bands; i++) {
22+
rowbufs[i] = Rast_allocate_d_buf();
23+
if (!rowbufs[i])
24+
G_fatal_error(_("Unable to allocate DCELL buffers."));
25+
mins[i] = INT_MAX;
26+
maxs[i] = INT_MIN;
27+
}
2328

2429
for (i = 0; i < rows; i++) {
25-
/* get one row of data */
26-
for (j = 0; j < bands; j++)
27-
Rast_get_c_row(datafds[j], rowbufs[j], i);
30+
/* read each input band as CELL, convert to DCELL */
31+
for (j = 0; j < bands; j++) {
32+
CELL *tmp = Rast_allocate_c_buf();
33+
Rast_get_c_row(datafds[j], tmp, i);
34+
for (l = 0; l < cols; l++)
35+
rowbufs[j][l] = (DCELL)tmp[l];
36+
G_free(tmp);
37+
}
2838

29-
/* transform each cell in the row */
39+
/* apply canonical transform */
3040
for (l = 0; l < cols; l++) {
3141
for (j = 0; j < bands; j++) {
3242
sum[j] = 0.0;
3343
for (k = 0; k < bands; k++) {
34-
sum[j] += eigmat[j][k] * (double)rowbufs[k][l];
44+
sum[j] += eigmat[j][k] * rowbufs[k][l];
3545
}
3646
}
3747
for (j = 0; j < bands; j++) {
38-
rowbufs[j][l] = (CELL)(sum[j] + 0.5);
39-
if (rowbufs[j][l] > maxs[j])
40-
maxs[j] = rowbufs[j][l];
41-
if (rowbufs[j][l] < mins[j])
42-
mins[j] = rowbufs[j][l];
48+
rowbufs[j][l] = sum[j];
49+
/*min/max are tracked as integer CELL */
50+
if ((CELL)rowbufs[j][l] > maxs[j])
51+
maxs[j] = (CELL)rowbufs[j][l];
52+
if ((CELL)rowbufs[j][l] < mins[j])
53+
mins[j] = (CELL)rowbufs[j][l];
4354
}
4455
}
4556

46-
/* output the row of data */
57+
/* write each output band row as DCELL */
4758
for (j = 0; j < bands; j++)
48-
Rast_put_row(outfds[j], rowbufs[j], CELL_TYPE);
59+
Rast_put_d_row(outfds[j], rowbufs[j]);
4960
}
61+
5062
for (i = 0; i < bands; i++)
5163
G_free(rowbufs[i]);
5264

5365
G_free(rowbufs);
5466
G_free_vector(sum);
5567

56-
G_message(_("Transform completed.\n"));
68+
G_message(_("Canonical transform completed."));
5769

5870
return 0;
5971
}

0 commit comments

Comments
 (0)