// Use SVD to solve linear least squares problem // result is statically allocated void polyfit_reuse( double *y, int n, int degree, double *coeffs, double *workspace ) { int ncoeffs = degree + 1; double *u = workspace, *w = u + n*ncoeffs, *v = w + ncoeffs; #ifdef DEBUG_POLYFIT_REUSE printf("\n---Got---\n"); printf("\nU:\n"); mat_print( u, n, ncoeffs); printf("\nS:\n"); mat_print( w, ncoeffs, 1); printf("\nV:\n"); mat_print( v, ncoeffs, ncoeffs); printf("\nU S V':\n"); mat_print( matmul_right_transpose_static( matmul_right_vec_as_diag_static( u, n, ncoeffs, w, ncoeffs), n, ncoeffs, v, ncoeffs, ncoeffs), n, ncoeffs); #endif svd_backsub( u, w, v, n, ncoeffs, y, coeffs ); }
int main(int argc, char* argv[]) { double v[4], s[2]; double **ia = mat_index(A,NROWS,NCOLS), **iv = mat_index(v,NROWS,NCOLS); printf("Input\n"); mat_print( A, NROWS, NCOLS); assert( svd(ia, NROWS, NCOLS, s, iv) ); free(ia); free(iv); printf("\n---Got---\n"); printf("\nU:\n"); mat_print( A, NROWS, NCOLS); printf("\nS:\n"); mat_print( s, NCOLS, 1); printf("\nV:\n"); mat_print( v, NCOLS, NCOLS); printf("\nU S V':\n"); mat_print( matmul_right_transpose_static( matmul_right_vec_as_diag_static( A, NROWS, NCOLS, s, NCOLS), NROWS, NCOLS, v, NCOLS, NCOLS), NROWS, NCOLS); printf("\n---Expected---\n"); printf("\nU:\n"); mat_print( U, NROWS, NCOLS); printf("\nS:\n"); mat_print( S, NCOLS, 1); printf("\nV:\n"); mat_print( V, NCOLS, NCOLS); printf("\nU S V':\n"); mat_print( matmul_right_transpose_static( matmul_right_vec_as_diag_static( U, NROWS, NCOLS, S, NCOLS), NROWS, NCOLS, V, NCOLS, NCOLS), NROWS, NCOLS); return 0; }
void polyfit( double *x, double *y, int n, int degree, double *coeffs, double *workspace ) { int ncoeffs = degree + 1; double *u = workspace, *w = u + n*ncoeffs, *v = w + ncoeffs; double **iu = mat_index(u, n,ncoeffs), **iv = mat_index(v,ncoeffs,ncoeffs); Vandermonde_Build(x,n,ncoeffs,u); #ifdef DEBUG_POLYFIT printf("\nV:\n"); mat_print( u, n, ncoeffs); #endif svd( iu, n, ncoeffs, w, iv ); free(iu); free(iv); svd_threshold( POLYFIT_SINGULAR_THRESHOLD, w, ncoeffs ); #ifdef DEBUG_POLYFIT printf("\n---Got---\n"); printf("\nU:\n"); mat_print( u, n, ncoeffs); printf("\nS:\n"); mat_print( w, ncoeffs, 1); printf("\nV:\n"); mat_print( v, ncoeffs, ncoeffs); printf("\nU S V':\n"); mat_print( matmul_right_transpose_static( matmul_right_vec_as_diag_static( u, n, ncoeffs, w, ncoeffs), n, ncoeffs, v, ncoeffs, ncoeffs), n, ncoeffs); #endif polyfit_reuse( y, n, degree, coeffs, workspace ); }