/** * B returns the pseudoinverse of A (A with dimension N rows x 3 columns). * It is the matrix v.[diag(1/wi)].(u)t (cf. svdcmp()) * Function returns True if B has maximum rank, False otherwise * @param A * @param N * @param B * @return */ int pseudo_inverse(double **A, int N, double **B) { void svdcmp(); double **V, temp[3][3]; double W[3]; double WMAX; double TOL = 0.01; int i, j, k; int isMaxRank = 1;/* stays true if no singular value under tolerance level */ /*allocations*/ V = init_double_array(nbCoords, nbCoords); /*Singular value decomposition*/ if (debug_svd) print_matrix(A, N, nbCoords); svdcmp(A, N, nbCoords, W, V); if (debug_svd) { print_matrix(A, N, nbCoords); print_matrix(V, nbCoords, nbCoords); print_vector(W, nbCoords); } /*Getting largest singular value*/ WMAX = 0.0; for (i = 0; i < nbCoords; i++) { if (W[i] > WMAX) WMAX = W[i]; } /*Checking for signular values smaller than TOL times the largest one*/ for (i = 0; i < nbCoords; i++) { if (W[i] < TOL * WMAX) { W[i] = 0; isMaxRank = 0; return isMaxRank; } } if (isMaxRank) { /*Computing B*/ for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { temp[i][j] = V[i][j] / W[j]; } } for (i = 0; i < 3; i++) { for (j = 0; j < N; j++) { B[i][j] = 0.0; for (k = 0; k < 3; k++) { B[i][j] += temp[i][k] * A[j][k]; } } } if (debug_svd) print_matrix(B, nbCoords, N); /*deallocations*/ for (i = 0; i < nbCoords; i++) free(V[i]); return isMaxRank; } return isMaxRank; }
void allocate_globals (matrix *A) { int n,i,bs,bs2; int *my_offsets; int num; int global_index; TAU_ub = R_ub = Z_ub = 0; n = A->n; bs = A->max_block_size; bs2 = bs*bs; J = new_index_set(NULL,max_dim,"J"); I = new_index_set(NULL,max_dim,"I"); J_tilde = new_index_set(NULL,max_dim,"J_tilde"); I_tilde = new_index_set(NULL,max_dim,"I_tilde"); remote_buf = new_int_array(NULL,A->maxnz,"remote_buf"); remote_rbuf = new_int_array(NULL,A->maxnz,"remote_rbuf"); remote_abuf = new_double_array(NULL,bs2*(A->maxnz+1),"remote_abuf"); is = new_index_set(NULL,max_dim,"is"); isres = new_index_set(NULL,max_dim,"isres"); res = new_double_array(NULL,bs2*max_dim,"res"); resb = new_double_array(NULL,bs2*max_dim,"resb"); n1 = new_int_array(NULL,nbsteps+1,"n1"); n2 = new_int_array(NULL,nbsteps,"n2"); Ahat_size = max_dim*maxapi; Ahat = new_double_array(NULL,Ahat_size,"Ahat"); if (debug) init_double_array(Ahat,Ahat_size,init_val); TAU_ptr = (int *) new_int_array(NULL,nbsteps+1,"TAU_ptr"); TAU_size = 1000; TAU = new_double_array(NULL,TAU_size,"TAU"); if (debug) init_double_array(TAU,TAU_size,init_val); R_size = 1000; R = new_double_array(NULL,R_size,"R"); if (debug) init_double_array(R,R_size,init_val); Z_size = 1000; Z = new_double_array(NULL,Z_size,"Z"); if (debug) init_double_array(Z,Z_size,init_val); rw = new_double_array(NULL,bs2*max_dim,"rw"); rs = new_double_array(NULL,bs2*max_dim,"rs"); rz = new_double_array(NULL,bs2*max_dim,"rz"); x = new_double_array(NULL,bs2*max_dim,"x"); xb = new_double_array(NULL,bs2*max_dim,"xb"); Qlist = (double **) mmalloc(nbsteps*sizeof(double *)); for (i=0; i<nbsteps; i++) Qlist[i] = NULL; temp_block = new_double_array(NULL,bs2,"temp_block"); minus_Bj = new_double_array(NULL,bs2,"minus_Bj"); sum_block = new_double_array(NULL,bs2,"sum_block"); nbits_of_int = sizeof(int)*8; if (nbits_of_int == 32) { log_nbits_of_int = 5;} else if (nbits_of_int == 64) { log_nbits_of_int = 6;} else { if (A->myid == 0) fprintf(stderr,"unsupported word size: %d\n",nbits_of_int); exit(1); } bitvec = (unsigned int *) mmalloc(sizeof(unsigned int)*A->n); if (! bitvec) { fprintf(stderr,"failed to malloc bitvec\n"); exit(1); } len_all = (int *) mmalloc(A->n*sizeof(int)); rlen_all = (int *) mmalloc(A->n*sizeof(int)); slen_all = (int *) mmalloc(A->n*sizeof(int)); #ifdef MPI ptr_offsets = (int *) mmalloc(A->n*sizeof(int *)); rptr_offsets = (int *) mmalloc(A->n*sizeof(int *)); A_offsets = (int *) mmalloc(A->n*sizeof(int *)); MPI_Barrier(A->comm); MPI_Allgatherv ((void *) A->lines->len, A->mnl, MPI_INT, (void *) len_all, A->mnls, A->start_indices, MPI_INT, A->comm); MPI_Barrier(A->comm); MPI_Allgatherv ((void *) A->lines->rlen, A->mnl, MPI_INT, (void *) rlen_all, A->mnls, A->start_indices, MPI_INT, A->comm); MPI_Barrier(A->comm); MPI_Allgatherv ((void *) A->lines->slen, A->mnl, MPI_INT, (void *) slen_all, A->mnls, A->start_indices, MPI_INT, A->comm); /* offsets for ptrs */ my_offsets = (int *) mmalloc(A->mnl*sizeof(int *)); my_offsets[0] = 0; for (i=1; i<A->mnl; i++) { my_offsets[i] = my_offsets[i-1] + A->lines->len[i-1]; } MPI_Barrier(A->comm); MPI_Allgatherv ((void *) my_offsets, A->mnl, MPI_INT, (void *) ptr_offsets, A->mnls, A->start_indices, MPI_INT, A->comm); /* offsets for rptrs */ my_offsets[0] = 0; for (i=1; i<A->mnl; i++) { my_offsets[i] = my_offsets[i-1] + A->lines->rlen[i-1]; } MPI_Barrier(A->comm); MPI_Allgatherv ((void *) my_offsets, A->mnl, MPI_INT, (void *) rptr_offsets, A->mnls, A->start_indices, MPI_INT, A->comm); /* offsets for coefficients */ my_offsets[0] = 0; global_index = A->my_start_index; for (i=1; i<A->mnl; i++) { bs = A->block_sizes[global_index]; num = bs*A->lines->slen[i-1]; my_offsets[i] = my_offsets[i-1] + num; global_index++; } MPI_Barrier(A->comm); MPI_Allgatherv ((void *) my_offsets, A->mnl, MPI_INT, (void *) A_offsets, A->mnls, A->start_indices, MPI_INT, A->comm); free(my_offsets); #endif }