51 if (rows == 0 || cols == 0)
54 matd_t *m = calloc(1,
sizeof(
matd_t) + (rows*cols*
sizeof(
double)));
73 if (rows == 0 || cols == 0)
77 for (
int i = 0; i < rows * cols; i++)
85 if (rows == 0 || cols == 0)
89 for (
int i = 0; i < rows * cols; i++)
90 m->
data[i] = (
double)data[i];
101 for (
int i = 0; i < dim; i++)
113 assert(row < m->nrows);
115 assert(col < m->ncols);
131 assert(row < m->nrows);
133 assert(col < m->ncols);
171 assert(r0 >= 0 && r0 < a->nrows);
172 assert(c0 >= 0 && c0 < a->ncols);
174 int nrows = r1 - r0 + 1;
175 int ncols = c1 - c0 + 1;
179 for (
int row = r0; row <= r1; row++)
180 for (
int col = c0; col <= c1; col++)
195 for (
int i = 0; i < m->
nrows; i++) {
196 for (
int j = 0; j < m->
ncols; j++) {
213 for (
int j = 0; j < m->
ncols; j++) {
214 for (
int i = 0; i < m->
nrows; i++) {
244 for (
int i = 0; i < m->
nrows; i++) {
245 for (
int j = 0; j < m->
ncols; j++) {
247 for (
int k = 0; k < a->
ncols; k++) {
266 for (
int i = 0; i < m->
nrows; i++) {
267 for (
int j = 0; j < m->
ncols; j++) {
284 for (
int i = 0; i < a->
nrows; i++) {
285 for (
int j = 0; j < a->
ncols; j++) {
303 for (
int i = 0; i < m->
nrows; i++) {
304 for (
int j = 0; j < m->
ncols; j++) {
324 for (
int i = 0; i < a->
nrows; i++) {
325 for (
int j = 0; j < a->
ncols; j++) {
344 for (
int i = 0; i < m->
nrows; i++) {
345 for (
int j = 0; j < m->
ncols; j++) {
365 for (
int i = 0; i < a->
nrows; i++) {
366 for (
int j = 0; j < a->
ncols; j++) {
382 for (
int i = 0; i < a->
nrows; i++) {
383 for (
int j = 0; j < a->
ncols; j++) {
400 double detL = 1;
double detU = 1;
401 for (
int i = 0; i < a->
nrows; i++) {
411 double det = mlu->
pivsign * detL * detU;
429 assert(a->
nrows > 0);
451 double m00 =
MATD_EL(a,0,0), m01 =
MATD_EL(a,0,1), m02 =
MATD_EL(a,0,2), m03 =
MATD_EL(a,0,3);
452 double m10 =
MATD_EL(a,1,0), m11 =
MATD_EL(a,1,1), m12 =
MATD_EL(a,1,2), m13 =
MATD_EL(a,1,3);
453 double m20 =
MATD_EL(a,2,0), m21 =
MATD_EL(a,2,1), m22 =
MATD_EL(a,2,2), m23 =
MATD_EL(a,2,3);
454 double m30 =
MATD_EL(a,3,0), m31 =
MATD_EL(a,3,1), m32 =
MATD_EL(a,3,2), m33 =
MATD_EL(a,3,3);
456 return m00 * m11 * m22 * m33 - m00 * m11 * m23 * m32 -
457 m00 * m21 * m12 * m33 + m00 * m21 * m13 * m32 + m00 * m31 * m12 * m23 -
458 m00 * m31 * m13 * m22 - m10 * m01 * m22 * m33 +
459 m10 * m01 * m23 * m32 + m10 * m21 * m02 * m33 -
460 m10 * m21 * m03 * m32 - m10 * m31 * m02 * m23 +
461 m10 * m31 * m03 * m22 + m20 * m01 * m12 * m33 -
462 m20 * m01 * m13 * m32 - m20 * m11 * m02 * m33 +
463 m20 * m11 * m03 * m32 + m20 * m31 * m02 * m13 -
464 m20 * m31 * m03 * m12 - m30 * m01 * m12 * m23 +
465 m30 * m01 * m13 * m22 + m30 * m11 * m02 * m23 -
466 m30 * m11 * m03 * m22 - m30 * m21 * m02 * m13 +
467 m30 * m21 * m03 * m12;
497 double det = x->
data[0];
501 double invdet = 1.0 / det;
504 MATD_EL(m, 0, 0) = 1.0 * invdet;
513 double invdet = 1.0 / det;
554 while (expr[*pos] != 0) {
556 switch (expr[*pos]) {
561 garb[*garbpos] = res;
572 assert(expr[*pos+1] ==
'-');
573 assert(expr[*pos+2] ==
'1');
576 garb[*garbpos] = res;
595 matd_t **garb,
int *garbpos,
int oneterm)
597 while (expr[*pos] != 0) {
599 switch (expr[*pos]) {
602 if (oneterm && acc != NULL)
612 garb[*garbpos] = res;
638 garb[*garbpos] = res;
647 matd_t *rhs = args[*argpos];
648 garb[*garbpos] = rhs;
660 garb[*garbpos] = res;
669 matd_t *rhs = args[*argpos];
680 garb[*garbpos] = res;
710 const char *start = &expr[*pos];
712 double s = strtod(start, &end);
713 (*pos) += (end - start);
715 garb[*garbpos] = rhs;
724 garb[*garbpos] = res;
733 if (oneterm && acc != NULL)
744 garb[*garbpos] = res;
751 if (oneterm && acc != NULL)
761 garb[*garbpos] = res;
771 garb[*garbpos] = res;
785 debug_print(
"Unknown character: '%c'\n", expr[*pos]);
786 assert(expr[*pos] != expr[*pos]);
799 assert(expr != NULL);
801 for (
const char *p = expr; *p != 0; p++) {
802 if (*p ==
'M' || *p ==
'F')
816 for (
int i = 0; i < nargs; i++) {
817 args[i] = va_arg(ap,
matd_t*);
838 for (
int i = 0; i < garbpos; i++) {
853 for (
int i = 0; i < len; i++)
878 assert(n <= lena && n <= lenb);
881 for (
int i = 0; i < n; i++)
892 for (
int i = 0; i < maxcol; i++) {
895 double v = fabs(
MATD_EL(A, row, i));
912 assert(adim == bdim);
915 for (
int i = 0; i < adim; i++) {
933 for(
int i = 0; i < len; i++)
961 for (
int i = 0; i < a->
nrows; i++) {
962 for (
int j = 0; j < a->
ncols; j++) {
966 TYPE err = fabs(av - bv);
967 maxf = fmax(maxf, err);
1006 for (
int hhidx = 0; hhidx < A->
nrows; hhidx++) {
1008 if (hhidx < A->ncols) {
1026 int vlen = A->
nrows - hhidx;
1028 double *v = malloc(
sizeof(
double)*vlen);
1031 for (
int i = 0; i < vlen; i++) {
1032 v[i] =
MATD_EL(B, hhidx+i, hhidx);
1036 double oldv0 = v[0];
1042 mag2 += -oldv0*oldv0 + v[0]*v[0];
1045 double mag = sqrt(mag2);
1053 for (
int i = 0; i < vlen; i++)
1066 for (
int i = 0; i < LS->
nrows; i++) {
1068 for (
int j = 0; j < vlen; j++)
1069 dot +=
MATD_EL(LS, i, hhidx+j) * v[j];
1070 for (
int j = 0; j < vlen; j++)
1071 MATD_EL(LS, i, hhidx+j) -= 2*dot*v[j];
1075 for (
int i = 0; i < B->
ncols; i++) {
1077 for (
int j = 0; j < vlen; j++)
1078 dot +=
MATD_EL(B, hhidx+j, i) * v[j];
1079 for (
int j = 0; j < vlen; j++)
1080 MATD_EL(B, hhidx+j, i) -= 2*dot*v[j];
1086 if (hhidx+2 < A->
ncols) {
1087 int vlen = A->
ncols - hhidx - 1;
1089 double *v = malloc(
sizeof(
double)*vlen);
1092 for (
int i = 0; i < vlen; i++) {
1093 v[i] =
MATD_EL(B, hhidx, hhidx+i+1);
1097 double oldv0 = v[0];
1103 mag2 += -oldv0*oldv0 + v[0]*v[0];
1106 double mag = sqrt(mag2);
1114 for (
int i = 0; i < vlen; i++)
1124 for (
int i = 0; i < RS->
nrows; i++) {
1126 for (
int j = 0; j < vlen; j++)
1127 dot +=
MATD_EL(RS, i, hhidx+1+j) * v[j];
1128 for (
int j = 0; j < vlen; j++)
1129 MATD_EL(RS, i, hhidx+1+j) -= 2*dot*v[j];
1133 for (
int i = 0; i < B->
nrows; i++) {
1135 for (
int j = 0; j < vlen; j++)
1136 dot +=
MATD_EL(B, i, hhidx+1+j) * v[j];
1137 for (
int j = 0; j < vlen; j++)
1138 MATD_EL(B, i, hhidx+1+j) -= 2*dot*v[j];
1148 int maxiters = 200 + 2 * A->
nrows * A->
ncols;
1149 assert(maxiters > 0);
1158 const int find_max_method = 1;
1162 int *maxrowidx = malloc(
sizeof(
int)*B->
ncols);
1163 int lastmaxi, lastmaxj;
1165 if (find_max_method == 1) {
1166 for (
int i = 2; i < B->
ncols; i++)
1172 lastmaxi = 0, lastmaxj = 1;
1175 for (iter = 0; iter < maxiters; iter++) {
1185 if (find_max_method == 1) {
1199 for (
int rowi = 0; rowi < B->
ncols; rowi++) {
1207 if (rowi == lastmaxi || rowi == lastmaxj) {
1209 thismaxv = fabs(
MATD_EL(B, rowi, maxrowidx[rowi]));
1217 if (maxrowidx[rowi] == lastmaxi || maxrowidx[rowi] == lastmaxj) {
1219 thismaxv = fabs(
MATD_EL(B, rowi, maxrowidx[rowi]));
1229 thismaxv = fabs(
MATD_EL(B, rowi, maxrowidx[rowi]));
1232 if (lastmaxi != rowi) {
1233 double v = fabs(
MATD_EL(B, rowi, lastmaxi));
1236 maxrowidx[rowi] = lastmaxi;
1241 if (lastmaxj != rowi) {
1242 double v = fabs(
MATD_EL(B, rowi, lastmaxj));
1245 maxrowidx[rowi] = lastmaxj;
1251 if (thismaxv > maxv) {
1258 maxj = maxrowidx[maxi];
1267 }
else if (find_max_method == 2) {
1272 for (
int i = 0; i < B->
ncols; i++) {
1273 for (
int j = 0; j < B->
ncols; j++) {
1277 double v = fabs(
MATD_EL(B, i, j));
1299 double A0 =
MATD_EL(B, maxi, maxi);
1300 double A1 =
MATD_EL(B, maxi, maxj);
1301 double A2 =
MATD_EL(B, maxj, maxi);
1302 double A3 =
MATD_EL(B, maxj, maxj);
1311 double U[4], S[2], V[4];
1338 for (
int i = 0; i < LS->
nrows; i++) {
1339 double vi =
MATD_EL(LS, i, maxi);
1340 double vj =
MATD_EL(LS, i, maxj);
1342 MATD_EL(LS, i, maxi) = U[0]*vi + U[2]*vj;
1343 MATD_EL(LS, i, maxj) = U[1]*vi + U[3]*vj;
1347 for (
int i = 0; i < RS->
nrows; i++) {
1348 double vi =
MATD_EL(RS, i, maxi);
1349 double vj =
MATD_EL(RS, i, maxj);
1351 MATD_EL(RS, i, maxi) = V[0]*vi + V[2]*vj;
1352 MATD_EL(RS, i, maxj) = V[1]*vi + V[3]*vj;
1357 for (
int i = 0; i < B->
ncols; i++) {
1358 double vi =
MATD_EL(B, maxi, i);
1359 double vj =
MATD_EL(B, maxj, i);
1361 MATD_EL(B, maxi, i) = U[0]*vi + U[2]*vj;
1362 MATD_EL(B, maxj, i) = U[1]*vi + U[3]*vj;
1366 for (
int i = 0; i < B->
nrows; i++) {
1367 double vi =
MATD_EL(B, i, maxi);
1368 double vj =
MATD_EL(B, i, maxj);
1370 MATD_EL(B, i, maxi) = V[0]*vi + V[2]*vj;
1371 MATD_EL(B, i, maxj) = V[1]*vi + V[3]*vj;
1379 debug_print(
"WARNING: maximum iters (maximum = %d, matrix %d x %d, max=%.15f)\n",
1387 int *idxs = malloc(
sizeof(
int)*A->
ncols);
1388 double *vals = malloc(
sizeof(
double)*A->
ncols);
1389 for (
int i = 0; i < A->
ncols; i++) {
1399 for (
int i = 0; i + 1 < A->
ncols; i++) {
1400 if (fabs(vals[i+1]) > fabs(vals[i])) {
1402 idxs[i] = idxs[i+1];
1405 double tmpv = vals[i];
1406 vals[i] = vals[i+1];
1417 for (
int i = 0; i < A->
ncols; i++) {
1418 MATD_EL(LP, idxs[i], idxs[i]) = 0;
1419 MATD_EL(RP, idxs[i], idxs[i]) = 0;
1421 MATD_EL(LP, idxs[i], i) = vals[i] < 0 ? -1 : 1;
1431 B =
matd_op(
"M'*F*M", LP, B, RP);
1441 memset(&res, 0,
sizeof(res));
1445 for (
int i = 0; i < B->
nrows; i++) {
1446 for (
int j = 0; j < B->
ncols; j++) {
1478 memset(&res, 0,
sizeof(res));
1514 unsigned int *piv = calloc(a->
nrows,
sizeof(
unsigned int));
1523 for (
int i = 0; i < a->
nrows; i++)
1526 for (
int j = 0; j < a->
ncols; j++) {
1527 for (
int i = 0; i < a->
nrows; i++) {
1528 int kmax = i < j ? i : j;
1532 for (
int k = 0; k < kmax; k++)
1541 for (
int i = j+1; i < lu->
nrows; i++) {
1561 double LUjj =
MATD_EL(lu, j, j);
1578 if (j < lu->ncols && j < lu->nrows && LUjj != 0) {
1580 for (
int i = j+1; i < lu->
nrows; i++)
1606 for (
int i = 0; i < lu->
ncols; i++)
1618 for (
int i = 0; i < lu->
nrows; i++) {
1630 for (
int i = 0; i < lu->
nrows; i++) {
1633 for (
int j = 0; j < i; j++) {
1646 for (
int i = 0; i < lu->
ncols; i++) {
1647 for (
int j = 0; j < lu->
ncols; j++) {
1665 for (
int i = 0; i < mlu->
lu->
nrows; i++)
1669 for (
int k = 0; k < mlu->
lu->
nrows; k++) {
1670 for (
int i = k+1; i < mlu->
lu->
nrows; i++) {
1672 for (
int t = 0; t < b->
ncols; t++)
1678 for (
int k = mlu->
lu->
ncols-1; k >= 0; k--) {
1679 double LUkk = 1.0 /
MATD_EL(mlu->
lu, k, k);
1680 for (
int t = 0; t < b->
ncols; t++)
1683 for (
int i = 0; i < k; i++) {
1685 for (
int t = 0; t < b->
ncols; t++)
1706 int v = random()&31;
1711 static double randf()
1713 double v = 1.0 *random() / RAND_MAX;
1717 int main(
int argc,
char *argv[])
1723 for (
int iter = 0; 1; iter++) {
1726 if (iter % 1000 == 0)
1727 printf(
"%d\n", iter);
1729 int m = 1 + (random()%(maxdim-1));
1730 int n = 1 + (random()%(maxdim-1));
1732 for (
int i = 0; i < m*n; i++)
1733 A->
data[i] = randi();
1771 for (
int iter = 0; 1; iter++) {
1772 if (iter % 100000 == 0)
1773 printf(
"%d\n", iter);
1780 matd_svd22_impl(A->
data, &s);
1782 memcpy(U->
data, s.U, 4*
sizeof(
double));
1783 memcpy(V->
data, s.V, 4*
sizeof(
double));
1787 assert(s.S[0] >= s.S[1]);
1788 assert(s.S[0] >= 0);
1789 assert(s.S[1] >= 0);
1801 for (
int i = 0; i < 4; i++)
1802 maxerr = fmax(maxerr, fabs(USV->
data[i] - A->
data[i]));
1805 printf(
"------------------------------------\n");
1808 printf(
"\nUSV':\n");
1810 printf(
"maxerr: %.15f\n", maxerr);
1816 assert(maxerr < 0.00001);
1870 for (
int i = 0; i < N; i++) {
1878 for (
int j = i; j < N; j++)
1881 for (
int j = i+1; j < N; j++) {
1887 for (
int k = j; k < N; k++) {
1909 memcpy(x, b, n*
sizeof(
TYPE));
1910 for (
int i = 0; i < n; i++) {
1913 for (
int j = i+1; j < u->
ncols; j++) {
1914 x[j] -= x[i] *
MATD_EL(u, i, j);
1924 for (
int i = 0; i < n; i++) {
1927 for (
int j = 0; j < i; j++) {
1931 x[i] = acc /
MATD_EL(L, i, i);
1938 for (
int i = u->
ncols-1; i >= 0; i--) {
1941 double diag =
MATD_EL(u, i, i);
1943 for (
int j = i+1; j < u->
ncols; j++)
1960 for (
int i = 0; i < u->
nrows; i++) {
1961 for (
int j = 0; j < i; j++) {
1965 for (
int k = 0; k < b->
ncols; k++) {
1970 for (
int k = 0; k < b->
ncols; k++) {
1976 for (
int k = u->
ncols-1; k >= 0; k--) {
1977 double LUkk = 1.0 /
MATD_EL(u, k, k);
1978 for (
int t = 0; t < b->
ncols; t++)
1981 for (
int i = 0; i < k; i++) {
1982 double LUik = -
MATD_EL(u, i, k);
1983 for (
int t = 0; t < b->
ncols; t++)
2018 double d = -DBL_MAX;
2019 for(
int x=0; x<m->
nrows; x++) {
2020 for(
int y=0; y<m->
ncols; y++) {
matd_svd_t matd_svd_flags(matd_t *A, int flags)
matd_t * matd_plu_l(const matd_plu_t *mlu)
void svd22(const double A[4], double U[4], double S[2], double V[4])
matd_plu_t * matd_plu(const matd_t *a)
double matd_det(const matd_t *a)
matd_t * matd_select(const matd_t *a, int r0, int r1, int c0, int c1)
#define MATD_SVD_NO_WARNINGS
double matd_vec_dist_n(const matd_t *a, const matd_t *b, int n)
#define debug_print(fmt,...)
void matd_chol_destroy(matd_chol_t *chol)
void matd_utriangle_solve(matd_t *u, const TYPE *b, TYPE *x)
TYPE matd_get_scalar(const matd_t *m)
matd_t * matd_add(const matd_t *a, const matd_t *b)
void matd_ltriangle_solve(matd_t *L, const TYPE *b, TYPE *x)
matd_t * matd_chol_solve(const matd_chol_t *chol, const matd_t *b)
matd_t * matd_create_scalar(TYPE v)
void matd_put_scalar(matd_t *m, TYPE value)
#define MATD_EL(m, row, col)
matd_svd_t matd_svd(matd_t *A)
void matd_add_inplace(matd_t *a, const matd_t *b)
matd_chol_t * matd_chol(matd_t *A)
TYPE matd_get(const matd_t *m, int row, int col)
matd_t * matd_transpose(const matd_t *a)
static int matd_is_scalar(const matd_t *a)
matd_t * matd_vec_normalize(const matd_t *a)
matd_t * matd_solve(matd_t *A, matd_t *b)
static double sq(double v)
double matd_max(matd_t *m)
static int max_idx(const matd_t *A, int row, int maxcol)
matd_t * matd_create_data(int rows, int cols, const TYPE *data)
static int matd_is_vector(const matd_t *a)
static matd_t * matd_op_recurse(const char *expr, int *pos, matd_t *acc, matd_t **args, int *argpos, matd_t **garb, int *garbpos, int oneterm)
static double matd_det_general(const matd_t *a)
static matd_t * matd_op_gobble_right(const char *expr, int *pos, matd_t *acc, matd_t **garb, int *garbpos)
matd_t * matd_plu_u(const matd_plu_t *mlu)
void matd_scale_inplace(matd_t *a, double s)
matd_t * matd_scale(const matd_t *a, double s)
void matd_print_transpose(const matd_t *m, const char *fmt)
matd_t * matd_create_dataf(int rows, int cols, const float *data)
void matd_destroy(matd_t *m)
matd_t * matd_identity(int dim)
void matd_subtract_inplace(matd_t *a, const matd_t *b)
void matd_print(const matd_t *m, const char *fmt)
matd_t * matd_subtract(const matd_t *a, const matd_t *b)
matd_t * matd_create(int rows, int cols)
matd_t * matd_plu_solve(const matd_plu_t *mlu, const matd_t *b)
int main(int argc, char *argv[])
matd_t * matd_inverse(const matd_t *x)
void matd_put(matd_t *m, int row, int col, TYPE value)
matd_t * matd_plu_p(const matd_plu_t *mlu)
double matd_vec_dist(const matd_t *a, const matd_t *b)
double matd_vec_dot_product(const matd_t *a, const matd_t *b)
matd_t * matd_copy(const matd_t *m)
matd_t * matd_op(const char *expr,...)
void matd_ltransposetriangle_solve(matd_t *u, const TYPE *b, TYPE *x)
static matd_svd_t matd_svd_tall(matd_t *A, int flags)
matd_t * matd_multiply(const matd_t *a, const matd_t *b)
void matd_plu_destroy(matd_plu_t *mlu)
double matd_plu_det(const matd_plu_t *mlu)
matd_t * matd_crossproduct(const matd_t *a, const matd_t *b)
double matd_vec_mag(const matd_t *a)
static int matd_is_vector_len(const matd_t *a, int len)
matd_t * matd_chol_inverse(matd_t *a)
TYPE matd_err_inf(const matd_t *a, const matd_t *b)