add matrix_row to get a row of a matrix

fix a bit of error handling.
This commit is contained in:
Vitor Santos Costa 2008-10-31 09:47:58 +00:00
parent aca06e16fc
commit 9c1ee7ba34
3 changed files with 91 additions and 7 deletions

View File

@ -9151,13 +9151,21 @@ Expand @var{Matrix} to occupy new dimensions. The elements in
positive integer with the size of the new dimension.
@item matrix_select(+@var{Matrix},+@var{Dimension},+@var{Index},-@var{New})
@findex matrix_select/3
@snindex matrix_select/3
@cnindex matrix_select/3
@findex matrix_select/4
@snindex matrix_select/4
@cnindex matrix_select/4
Select from @var{Matrix} the elements who have @var{Index} at
@var{Dimension}.
@item matrix_row(+@var{Matrix},+@var{Column},-@var{NewMatrix})
@findex matrix_row/3
@snindex matrix_row/3
@cnindex matrix_row/3
Select from @var{Matrix} the row matching @var{Column} as new matrix @var{NewMatrix}. @var{Column} must have one less dimension than the original matrix.
@var{Dimension}.
@end table
@node MATLAB, Non-Backtrackable Data Structures, matrix, Library

View File

@ -81,7 +81,8 @@ typedef enum {
matrix_transpose/2,
matrix_set_all_that_disagree/5,
matrix_expand/3,
matrix_select/4
matrix_select/4,
matrix_row/3
]).
:- load_foreign_files([matrix], [], init_matrix).

View File

@ -139,8 +139,9 @@ new_int_matrix(int ndims, int dims[], long int data[])
}
sz = ((MAT_DIMS+1)*sizeof(int)+ndims*sizeof(int)+nelems*sizeof(long int))/sizeof(YAP_CELL);
blob = YAP_MkBlobTerm(sz);
if (blob == YAP_TermNil())
return FALSE;
if (blob == YAP_TermNil()) {
return blob;
}
mat = (int *)YAP_BlobOfTerm(blob);
mat[MAT_TYPE] = INT_MATRIX;
mat[MAT_NDIMS] = ndims;
@ -173,7 +174,7 @@ new_float_matrix(int ndims, int dims[], double data[])
sz = ((MAT_DIMS+1)*sizeof(int)+ndims*sizeof(int)+(nelems+1)*sizeof(double)+(sizeof(YAP_CELL)-1))/sizeof(YAP_CELL);
blob = YAP_MkBlobTerm(sz);
if (blob == YAP_TermNil())
return FALSE;
return blob;
mat = YAP_BlobOfTerm(blob);
mat[MAT_TYPE] = FLOAT_MATRIX;
mat[MAT_NDIMS] = ndims;
@ -319,6 +320,8 @@ new_ints_matrix(void)
if (!scan_dims(ndims, tl, dims))
return FALSE;
out = new_int_matrix(ndims, dims, NULL);
if (out == YAP_TermNil())
return FALSE;
if (!cp_int_matrix(YAP_ARG3,out))
return FALSE;
return YAP_Unify(YAP_ARG4, out);
@ -353,6 +356,8 @@ new_floats_matrix(void)
if (!scan_dims(ndims, tl, dims))
return FALSE;
out = new_float_matrix(ndims, dims, NULL);
if (out == YAP_TermNil())
return FALSE;
if (!cp_float_matrix(YAP_ARG3,out))
return FALSE;
return YAP_Unify(YAP_ARG4, out);
@ -2291,6 +2296,75 @@ matrix_select(void)
return YAP_Unify(YAP_ARG4, tf);
}
/* given a matrix M and a set of N-1 dims, get the first dimension
*/
static int
matrix_row(void)
{
int size, i, ndims, newdims[1];
int indx[MAX_DIMS];
int *mat = (int *)YAP_BlobOfTerm(YAP_ARG1), *nmat;
YAP_Term tconv, tf;
if (!mat) {
/* Error */
return FALSE;
}
ndims = mat[MAT_NDIMS];
/* we now have our target matrix, let us grab our conversion arguments */
tconv = YAP_ARG2;
for (i=1; i < ndims; i++) {
YAP_Term th;
if (!YAP_IsPairTerm(tconv))
return FALSE;
th = YAP_HeadOfTerm(tconv);
if (!YAP_IsIntTerm(th))
return FALSE;
indx[i] = YAP_IntOfTerm(th);
tconv = YAP_TailOfTerm(tconv);
}
if (tconv != YAP_TermNil())
return FALSE;
newdims[0] = size = mat[MAT_DIMS];
if (mat[MAT_TYPE] == INT_MATRIX) {
long int *data, *ndata;
/* create a new matrix with the same size */
tf = new_int_matrix(1, newdims, NULL);
if (tf == YAP_TermNil())
return FALSE;
/* in case the matrix moved */
mat = (int *)YAP_BlobOfTerm(YAP_ARG1);
nmat = (int *)YAP_BlobOfTerm(tf);
data = matrix_long_data(mat,ndims);
ndata = matrix_long_data(nmat,1);
/* create a new matrix with smaller size */
for (i=0; i< size; i++) {
indx[0]=i;
ndata[i] = data[matrix_get_offset(mat, indx)];
}
} else {
double *data, *ndata;
/* create a new matrix with the same size */
tf = new_float_matrix(1,newdims,NULL);
if (tf == YAP_TermNil())
return FALSE;
/* in case the matrix moved */
mat = (int *)YAP_BlobOfTerm(YAP_ARG1);
nmat = (int *)YAP_BlobOfTerm(tf);
data = matrix_double_data(mat,ndims);
ndata = matrix_double_data(nmat,1);
/* create a new matrix with smaller size */
for (i=0; i< size; i++) {
indx[0]=i;
ndata[i] = data[matrix_get_offset(mat, indx)];
}
}
return YAP_Unify(YAP_ARG3, tf);
}
/* given a matrix M and a set of dims, sum out one of the dimensions
*/
static int
@ -2882,6 +2956,7 @@ init_matrix(void)
YAP_UserCPredicate("matrix_shuffle", matrix_transpose, 3);
YAP_UserCPredicate("matrix_expand", matrix_expand, 3);
YAP_UserCPredicate("matrix_select", matrix_select, 4);
YAP_UserCPredicate("matrix_row", matrix_row, 3);
YAP_UserCPredicate("matrix_to_logs", matrix_log_all,1);
YAP_UserCPredicate("matrix_to_exps", matrix_exp_all, 1);
YAP_UserCPredicate("matrix_to_logs", matrix_log_all2,2);