17 const unsigned int n = A.
columns();
22 const unsigned int m = A.
rows();
37 std::memset(ata[0], 0, n * n *
sizeof ata[0][0]);
38 for (
unsigned int k = 0; k <
m; ++k)
39 for (
unsigned int i = 0; i < n; ++i) {
40 const double aki = a[k][i];
41 double const* arow = a[k] + i;
42 double* atarow = ata[i] + i;
43 double const* arowend = a[k] + n;
44 while (arow != arowend)
45 *atarow++ += aki * *arow++;
47 for (
unsigned int i = 0; i < n; ++i)
48 for (
unsigned int j = i+1; j < n; ++j)
49 ata[j][i] = ata[i][j];
55 const unsigned int na = A.
columns();
56 const unsigned int mb = B.
rows();
60 std::cerr <<
"vnl_fastops::AB: argument sizes do not match: " << na <<
" != " << mb <<
'\n';
64 const unsigned int ma = A.
rows();
65 const unsigned int nb = B.
columns();
75 for (
unsigned int i = 0; i < ma; ++i)
76 for (
unsigned int j = 0; j < nb; ++j) {
78 for (
unsigned int k = 0; k < na; ++k)
79 accum += a[i][k] * b[k][j];
80 outdata[i][j] = accum;
87 const unsigned int ma = A.
rows();
88 const unsigned int mb = B.
rows();
92 std::cerr <<
"vnl_fastops::AtB: argument sizes do not match: " << ma <<
" != " << mb <<
'\n';
96 const unsigned int na = A.
columns();
97 const unsigned int nb = B.
columns();
107 for (
unsigned int i = 0; i < na; ++i)
108 for (
unsigned int j = 0; j < nb; ++j) {
110 for (
unsigned int k = 0; k < ma; ++k)
111 accum += a[k][i] * b[k][j];
112 outdata[i][j] = accum;
119 const unsigned int m = A.
rows();
120 const unsigned int l = B.
size();
124 std::cerr <<
"vnl_fastops::AtB: argument sizes do not match: " <<
m <<
" != " << l <<
'\n';
128 const unsigned int n = A.
columns();
138 for (
unsigned int i = 0; i < n; ++i) {
140 for (
unsigned int k = 0; k < l; ++k)
141 accum += a[k][i] * b[k];
149 const unsigned int m = A.
cols();
150 const unsigned int l = b.
size();
154 std::cerr <<
"vnl_fastops::Ab: argument sizes do not match: " <<
m <<
" != " << l <<
'\n';
158 const unsigned int n = A.
rows();
168 for (
unsigned int i = 0; i < n; ++i) {
170 for (
unsigned int k = 0; k < l; ++k)
171 accum += a[i][k] * bb[k];
179 const unsigned int na = A.
columns();
180 const unsigned int nb = B.
columns();
184 std::cerr <<
"vnl_fastops::ABt: argument sizes do not match: " << na <<
" != " << nb <<
'\n';
188 const unsigned int ma = A.
rows();
189 const unsigned int mb = B.
rows();
199 for (
unsigned int i = 0; i < ma; ++i)
200 for (
unsigned int j = 0; j < mb; ++j) {
202 for (
unsigned int k = 0; k < na; ++k)
203 accum += a[i][k] * b[j][k];
204 outdata[i][j] = accum;
211 const unsigned int na = A.
columns();
212 const unsigned int mb = B.
rows();
216 std::cerr <<
"vnl_fastops::ABAt: argument sizes do not match: " << na <<
" != " << mb <<
'\n';
220 const unsigned int ma = A.
rows();
221 const unsigned int nb = B.
columns();
225 std::cerr <<
"vnl_fastops::ABAt: argument sizes do not match: " << na <<
" != " << nb <<
'\n';
239 for (
unsigned int i = 0; i < ma; ++i)
240 for (
unsigned int w = 0; w < ma; ++w)
243 for (
unsigned int i = 0; i < ma; ++i)
244 for (
unsigned int j = 0; j < nb; ++j) {
246 for (
unsigned int k = 0; k < na; ++k)
247 accum += a[i][k] * b[k][j];
248 for (
unsigned int w = 0; w < ma; ++w)
249 outdata[i][w] += accum * a[w][j];
256 const unsigned int m = A.
rows();
257 const unsigned int n = A.
cols();
258 const unsigned int l = b.
size();
262 std::cerr <<
"vnl_fastops::btAb: argument sizes do not match: " <<
m <<
" != " << l <<
'\n';
266 std::cerr <<
"vnl_fastops::btAb: not a square matrix: " <<
m <<
" != " << n <<
'\n';
275 for (
unsigned int i = 0; i < n; ++i)
276 for (
unsigned int j = 0; j < n; ++j) {
277 accum += bb[j] * a[i][j] * bb[i];
285 const unsigned int m = X.
rows();
286 const unsigned int n = X.
columns();
290 std::cerr <<
"vnl_fastops::inc_X_by_AtA: argument sizes do not match\n";
294 const unsigned int l = A.
rows();
300 for (
unsigned int i = 0; i < n; ++i) {
301 x[i][i] += (a[0][i] * a[0][i] + a[1][i] * a[1][i]);
302 for (
unsigned int j = i+1; j < n; ++j) {
303 double accum = (a[0][i] * a[0][j] + a[1][i] * a[1][j]);
309 for (
unsigned int i = 0; i < n; ++i)
310 for (
unsigned int j = i; j < n; ++j) {
312 for (
unsigned int k = 0; k < l; ++k)
313 accum += a[k][i] * a[k][j];
324 const unsigned int na = A.
columns();
325 const unsigned int mb = B.
rows();
329 std::cerr <<
"vnl_fastops::inc_X_by_AB: argument sizes do not match: " << na <<
" != " << mb <<
'\n';
333 const unsigned int ma = A.
rows();
334 const unsigned int nb = B.
columns();
335 const unsigned int mx = X.
rows();
336 const unsigned int nx = X.
columns();
339 if (mx != ma || nx != nb) {
340 std::cerr <<
"vnl_fastops::inc_X_by_AB: argument sizes do not match\n";
348 for (
unsigned int i = 0; i < ma; ++i)
349 for (
unsigned int j = 0; j < nb; ++j)
350 for (
unsigned int k = 0; k < na; ++k)
351 x[i][j] += a[i][k] * b[k][j];
357 const unsigned int na = A.
columns();
358 const unsigned int mb = B.
rows();
362 std::cerr <<
"vnl_fastops::dec_X_by_AB: argument sizes do not match: " << na <<
" != " << mb <<
'\n';
366 const unsigned int ma = A.
rows();
367 const unsigned int nb = B.
columns();
368 const unsigned int mx = X.
rows();
369 const unsigned int nx = X.
columns();
372 if (mx != ma || nx != nb) {
373 std::cerr <<
"vnl_fastops::dec_X_by_AB: argument sizes do not match\n";
381 for (
unsigned int i = 0; i < ma; ++i)
382 for (
unsigned int j = 0; j < nb; ++j)
383 for (
unsigned int k = 0; k < na; ++k)
384 x[i][j] -= a[i][k] * b[k][j];
390 const unsigned int ma = A.
rows();
391 const unsigned int mb = B.
rows();
395 std::cerr <<
"vnl_fastops::inc_X_by_AtB: argument sizes do not match: " << ma <<
" != " << mb <<
'\n';
399 const unsigned int na = A.
columns();
400 const unsigned int nb = B.
columns();
401 const unsigned int mx = X.
rows();
402 const unsigned int nx = X.
columns();
405 if (mx != na || nx != nb) {
406 std::cerr <<
"vnl_fastops::inc_X_by_AtB: argument sizes do not match\n";
414 for (
unsigned int i = 0; i < na; ++i)
415 for (
unsigned int j = 0; j < nb; ++j) {
417 for (
unsigned int k = 0; k < ma; ++k)
418 accum += a[k][i] * b[k][j];
426 const unsigned int ma = A.
rows();
427 const unsigned int mb = B.
rows();
431 std::cerr <<
"vnl_fastops::dec_X_by_AtB: argument sizes do not match: " << ma <<
" != " << mb <<
'\n';
435 const unsigned int na = A.
columns();
436 const unsigned int nb = B.
columns();
437 const unsigned int mx = X.
rows();
438 const unsigned int nx = X.
columns();
441 if (mx != na || nx != nb) {
442 std::cerr <<
"vnl_fastops::dec_X_by_AtB: argument sizes do not match\n";
450 for (
unsigned int i = 0; i < na; ++i)
451 for (
unsigned int j = 0; j < nb; ++j) {
453 for (
unsigned int k = 0; k < ma; ++k)
454 accum += a[k][i] * b[k][j];
462 const unsigned int ma = A.
rows();
463 const unsigned int mb = B.
size();
467 std::cerr <<
"vnl_fastops::inc_X_by_AtB: argument sizes do not match: " << ma <<
" != " << mb <<
'\n';
471 const unsigned int mx = X.
size();
472 const unsigned int na = A.
columns();
476 std::cerr <<
"vnl_fastops::inc_X_by_AtB: argument sizes do not match\n";
484 for (
unsigned int i = 0; i < na; ++i) {
486 for (
unsigned int k = 0; k < ma; ++k)
487 accum += a[k][i] * b[k];
495 const unsigned int ma = A.
rows();
496 const unsigned int mb = B.
size();
500 std::cerr <<
"vnl_fastops::dec_X_by_AtB: argument sizes do not match: " << ma <<
" != " << mb <<
'\n';
504 const unsigned int mx = X.
size();
505 const unsigned int na = A.
columns();
509 std::cerr <<
"vnl_fastops::dec_X_by_AtB: argument sizes do not match\n";
517 for (
unsigned int i = 0; i < na; ++i) {
519 for (
unsigned int k = 0; k < ma; ++k)
520 accum += a[k][i] * b[k];
528 const unsigned int m = X.
rows();
529 const unsigned int n = X.
columns();
533 std::cerr <<
"vnl_fastops::dec_X_by_AtA: argument sizes do not match\n";
537 const unsigned int l = A.
rows();
543 for (
unsigned int i = 0; i < n; ++i) {
544 x[i][i] -= (a[0][i] * a[0][i] + a[1][i] * a[1][i]);
545 for (
unsigned int j = i+1; j < n; ++j) {
546 double accum = (a[0][i] * a[0][j] + a[1][i] * a[1][j]);
552 for (
unsigned int i = 0; i < n; ++i)
553 for (
unsigned int j = i; j < n; ++j) {
555 for (
unsigned int k = 0; k < l; ++k)
556 accum += a[k][i] * a[k][j];
567 #define METHOD 3 // Method 2 is fastest on the u170 -- weird. 570 const double* aend = a + n;
572 accum += *a++ * *b++;
575 for (
unsigned int k = 0; k < n; ++k)
576 accum += a[k] * b[k];
580 accum += a[n] * b[n];
585 --k, accum += a[k] * b[k];
594 const unsigned int na = A.
columns();
595 const unsigned int nb = B.
columns();
599 std::cerr <<
"vnl_fastops::inc_X_by_ABt: argument sizes do not match: " << na <<
" != " << nb <<
'\n';
603 const unsigned int mx = X.
rows();
604 const unsigned int nx = X.
columns();
605 const unsigned int ma = A.
rows();
606 const unsigned int mb = B.
rows();
609 if (mx != ma || nx != mb) {
610 std::cerr <<
"vnl_fastops::inc_X_by_ABt: argument sizes do not match\n";
619 for (
unsigned int i = 0; i < mb; ++i)
620 for (
unsigned int j = 0; j < ma; ++j)
621 x[j][i] += (a[j][0] * b[i][0] +
624 }
else if (na == 2) {
625 for (
unsigned int i = 0; i < mb; ++i)
626 for (
unsigned int j = 0; j < ma; ++j)
627 x[j][i] += (a[j][0] * b[i][0] +
629 }
else if (na == 1) {
630 for (
unsigned int i = 0; i < mb; ++i)
631 for (
unsigned int j = 0; j < ma; ++j)
632 x[j][i] += a[j][0] * b[i][0];
634 for (
unsigned int i = 0; i < mb; ++i)
635 for (
unsigned int j = 0; j < ma; ++j)
636 x[j][i] +=
dot(a[j], b[i], na);
643 const unsigned int na = A.
columns();
644 const unsigned int nb = B.
columns();
648 std::cerr <<
"vnl_fastops::dec_X_by_ABt: argument sizes do not match: " << na <<
" != " << nb <<
'\n';
652 const unsigned int mx = X.
rows();
653 const unsigned int nx = X.
columns();
654 const unsigned int ma = A.
rows();
655 const unsigned int mb = B.
rows();
658 if (mx != ma || nx != mb) {
659 std::cerr <<
"vnl_fastops::dec_X_by_ABt: argument sizes do not match\n";
668 for (
unsigned int i = 0; i < mb; ++i)
669 for (
unsigned int j = 0; j < ma; ++j)
670 x[j][i] -= (a[j][0] * b[i][0] +
673 }
else if (na == 2) {
674 for (
unsigned int i = 0; i < mb; ++i)
675 for (
unsigned int j = 0; j < ma; ++j)
676 x[j][i] -= (a[j][0] * b[i][0] +
678 }
else if (na == 1) {
679 for (
unsigned int i = 0; i < mb; ++i)
680 for (
unsigned int j = 0; j < ma; ++j)
681 x[j][i] -= a[j][0] * b[i][0];
683 for (
unsigned int i = 0; i < mb; ++i)
684 for (
unsigned int j = 0; j < ma; ++j)
685 x[j][i] -=
dot(a[j], b[i], na);
693 const unsigned int na = A.
columns();
694 const unsigned int mb = B.
rows();
698 std::cerr <<
"vnl_fastops::ABAt: argument sizes do not match: " << na <<
" != " << mb <<
'\n';
702 const unsigned int ma = A.
rows();
703 const unsigned int nb = B.
columns();
707 std::cerr <<
"vnl_fastops::ABAt: argument sizes do not match: " << na <<
" != " << nb <<
'\n';
720 for (
unsigned int i = 0; i < ma; ++i)
721 for (
unsigned int j = 0; j < nb; ++j) {
723 for (
unsigned int k = 0; k < na; ++k)
724 accum += a[i][k] * b[k][j];
725 for (
unsigned int w = 0; w < ma; ++w)
726 Xdata[i][w] += accum * a[w][j];
unsigned int cols() const
Return the number of columns.
static double dot(const double *a, const double *b, unsigned int n)
Compute dot product of a and b.
static void dec_X_by_AB(vnl_matrix< double > &X, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $X -= A B$.
bool set_size(size_t n)
Resize to n elements.
static void AB(vnl_matrix< double > &out, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute AxB.
static void inc_X_by_AtB(vnl_matrix< double > &X, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $X += A^\top B$.
size_t size() const
Return the length, number of elements, dimension of this vector.
T const * data_block() const
Access the contiguous block storing the elements in the vector. O(1).
static double btAb(const vnl_matrix< double > &A, const vnl_vector< double > &b)
Compute $b^\top A b$ for vector b and matrix A.
static void inc_X_by_ABt(vnl_matrix< double > &X, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $X += A B^\top$.
static void AtA(vnl_matrix< double > &out, const vnl_matrix< double > &A)
Compute $A^\top A$.
static void AtB(vnl_matrix< double > &out, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $A^\top B$.
Collection of C-style matrix functions.
static void dec_X_by_AtA(vnl_matrix< double > &X, const vnl_matrix< double > &A)
Compute $ X -= A^\top A$.
static void inc_X_by_AB(vnl_matrix< double > &X, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $X += A B$.
static void Ab(vnl_vector< double > &out, const vnl_matrix< double > &A, const vnl_vector< double > &b)
Compute $A b$ for vector b. out may not be b.
static void dec_X_by_AtB(vnl_matrix< double > &X, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $X -= A^\top B$.
static void inc_X_by_ABAt(vnl_matrix< double > &X, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $X += A B A^\top$.
static void ABAt(vnl_matrix< double > &out, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $A B A^\top$.
T const *const * data_array() const
Access the 2D array, so that elements can be accessed with array[row][col] directly.
unsigned int rows() const
Return the number of rows.
bool set_size(unsigned r, unsigned c)
Resize to r rows by c columns. Old data lost.
static void inc_X_by_AtA(vnl_matrix< double > &X, const vnl_matrix< double > &A)
Compute $ X += A^\top A$.
unsigned int columns() const
Return the number of columns.
static void ABt(vnl_matrix< double > &out, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $A B^\top$.
static void dec_X_by_ABt(vnl_matrix< double > &X, const vnl_matrix< double > &A, const vnl_matrix< double > &B)
Compute $X -= A B^\top$.