$search
00001 #include "cs.h" 00002 /* x=A\b where A can be rectangular; b overwritten with solution */ 00003 int cs_qrsol (int order, const cs *A, double *b) 00004 { 00005 double *x ; 00006 css *S ; 00007 csn *N ; 00008 cs *AT = NULL ; 00009 int k, m, n, ok ; 00010 if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ 00011 n = A->n ; 00012 m = A->m ; 00013 if (m >= n) 00014 { 00015 S = cs_sqr (order, A, 1) ; /* ordering and symbolic analysis */ 00016 N = cs_qr (A, S) ; /* numeric QR factorization */ 00017 x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; /* get workspace */ 00018 ok = (S && N && x) ; 00019 if (ok) 00020 { 00021 cs_ipvec (S->pinv, b, x, m) ; /* x(0:m-1) = b(p(0:m-1) */ 00022 for (k = 0 ; k < n ; k++) /* apply Householder refl. to x */ 00023 { 00024 cs_happly (N->L, k, N->B [k], x) ; 00025 } 00026 cs_usolve (N->U, x) ; /* x = R\x */ 00027 cs_ipvec (S->q, x, b, n) ; /* b(q(0:n-1)) = x(0:n-1) */ 00028 } 00029 } 00030 else 00031 { 00032 AT = cs_transpose (A, 1) ; /* Ax=b is underdetermined */ 00033 S = cs_sqr (order, AT, 1) ; /* ordering and symbolic analysis */ 00034 N = cs_qr (AT, S) ; /* numeric QR factorization of A' */ 00035 x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; /* get workspace */ 00036 ok = (AT && S && N && x) ; 00037 if (ok) 00038 { 00039 cs_pvec (S->q, b, x, m) ; /* x(q(0:m-1)) = b(0:m-1) */ 00040 cs_utsolve (N->U, x) ; /* x = R'\x */ 00041 for (k = m-1 ; k >= 0 ; k--) /* apply Householder refl. to x */ 00042 { 00043 cs_happly (N->L, k, N->B [k], x) ; 00044 } 00045 cs_pvec (S->pinv, x, b, n) ; /* b(0:n-1) = x(p(0:n-1)) */ 00046 } 00047 } 00048 cs_free (x) ; 00049 cs_sfree (S) ; 00050 cs_nfree (N) ; 00051 cs_spfree (AT) ; 00052 return (ok) ; 00053 }