a3939547c53f1ccb39910e61bfa90a0c54310273 kent Tue Jan 5 00:40:36 2021 -0800 First cut of vRowMatrix to stream through a variety of matrices semi-transparently I hope. FOr now just handles tsv though. diff --git src/lib/sparseMatrix.c src/lib/sparseMatrix.c new file mode 100644 index 0000000..7a1e817 --- /dev/null +++ src/lib/sparseMatrix.c @@ -0,0 +1,100 @@ +#include "common.h" +#include "linefile.h" +#include "hash.h" +#include "localmem.h" +#include "sparseMatrix.h" + + +struct sparseRowMatrix *sparseRowMatrixNew(int xSize, int ySize) +/* Make up a new sparseRowMatrix structure */ +{ +struct sparseRowMatrix *matrix; +AllocVar(matrix); +matrix->xSize = xSize; +matrix->ySize = ySize; +matrix->lm = lmInit(0); +lmAllocArray(matrix->lm, matrix->rows, ySize); +return matrix; +} + +void sparseRowMatrixFree(struct sparseRowMatrix **pMatrix) +/* Free up resources associated with sparse matrix */ +{ +struct sparseRowMatrix *matrix = *pMatrix; +if (matrix != NULL) + { + lmCleanup(&matrix->lm); + freez(pMatrix); + } +} + +void sparseRowMatrixAdd(struct sparseRowMatrix *matrix, int x, int y, float val) +/* Add data to our sparse matrix */ +{ +struct sparseRowVal *fv; +lmAllocVar(matrix->lm, fv); +fv->x = x; +fv->val = val; +slAddHead(&matrix->rows[y], fv); +} + +void sparseRowMatrixUnpackRow(struct sparseRowMatrix *matrix, int y, double *row, int rowSize) +/* Unpack sparse matrix into buf that should be matrix->xSize long */ +{ +if (matrix->xSize != rowSize) + errAbort("sparseRowMatrixUnpackRow size mismatch %d vs %d", matrix->xSize, rowSize); +int bufSize = matrix->xSize * sizeof(double); +zeroBytes(row, bufSize); +struct sparseRowVal *fv; +for (fv = matrix->rows[y]; fv != NULL; fv = fv->next) + row[fv->x] = fv->val; +} + +static void sparseRowMatrixTsvBody(struct sparseRowMatrix *matrix, char **rowLabels, FILE *f) +/* Write body (but not header) of matrix to tsv file */ +{ +int xSize = matrix->xSize; +int ySize = matrix->ySize; +int x,y; +double row[xSize]; +for (y=0; y<ySize; ++y) + { + sparseRowMatrixUnpackRow(matrix, y, row, xSize); + fprintf(f, "%s", rowLabels[y]); + for (x=0; x<xSize; ++x) + { + double val = row[x]; + if (val == 0.0) + fprintf(f, "\t0"); // so much zero in the world + else + fprintf(f, "\t%g", row[x]); + } + fprintf(f, "\n"); + } +} + +static void writeTsvRow(FILE *f, int rowSize, char **row) +/* Write out row of strings to a line in tab-sep file */ +{ +if (rowSize > 0) + { + fprintf(f, "%s", row[0]); + int i; + for (i=1; i<rowSize; ++i) + fprintf(f, "\t%s", row[i]); + } +fprintf(f, "\n"); +} + +void sparseRowMatrixSaveAsTsv(struct sparseRowMatrix *matrix, + char **columnLabels, char **rowLabels, char *fileName) +/* Save sparseRowMatrix to tab-sep-file as expanded non-sparse */ +{ +FILE *f = mustOpen(fileName, "w"); +verbose(1, "outputting %d row matrix, a dot every 100 rows\n", matrix->ySize); +fprintf(f, "gene\t"); +writeTsvRow(f, matrix->xSize, columnLabels); +sparseRowMatrixTsvBody(matrix, rowLabels, f); +carefulClose(&f); +} +