static COMMAND_FUNC( equivalence ) { const char *obj_name; Data_Obj *dp; Precision * prec_p; Dimension_Set ds1, *dsp=(&ds1); long ns,nf,nr,nc,nd; obj_name=NAMEOF("name for equivalent image"); dp=pick_obj(PARENT_PROMPT); ns=(long) how_many("number of sequences"); nf=(long) how_many("number of frames"); nr=(long) how_many("number of rows"); nc=(long) how_many("number of columns"); nd=(long) how_many("number of components"); prec_p = get_precision(SINGLE_QSP_ARG); if( dp==NULL ) return; if( prec_p == NULL ) return; INSIST_POSITIVE_DIM(ns,"sequence","equivalence") INSIST_POSITIVE_DIM(nf,"frame","equivalence") INSIST_POSITIVE_DIM(nr,"row","equivalence") INSIST_POSITIVE_DIM(nc,"column","equivalence") INSIST_POSITIVE_DIM(nd,"component","equivalence") SET_DIMENSION(dsp,4,ns); SET_DIMENSION(dsp,3,nf); SET_DIMENSION(dsp,2,nr); SET_DIMENSION(dsp,1,nc); SET_DIMENSION(dsp,0,nd); if( COMPLEX_PRECISION(PREC_CODE(prec_p)) ){ if( DIMENSION(dsp,0) != 1 ){ warn("Sorry, can only have 1 complex component"); return; } //SET_DIMENSION(dsp,0,2); } else if( QUAT_PRECISION(PREC_CODE(prec_p)) ){ if( DIMENSION(dsp,0) != 1 ){ warn("Sorry, can only have 1 quaternion component"); return; } //SET_DIMENSION(dsp,0,2); } else if( COLOR_PRECISION(PREC_CODE(prec_p)) ){ if( DIMENSION(dsp,0) != 1 ){ warn("Sorry, can only have 1 color triple per pixel"); return; } advise("component dim 3 for color"); //SET_DIMENSION(dsp,0,3); } if( make_equivalence(obj_name,dp,dsp,prec_p) == NULL ) warn("error making equivalence"); }
void inner(QSP_ARG_DECL Data_Obj *dpto,Data_Obj *dpfr1,Data_Obj *dpfr2) { //dimension_t _n; /* dot prod len */ dimension_t i,j; Vec_Obj_Args oa1, *oap=&oa1; //Dimension_Set sizes={{1,1,1,1,1}}; Dimension_Set *sizes; index_t dst_indices[N_DIMENSIONS]={0,0,0,0,0}; index_t src1_indices[N_DIMENSIONS]={0,0,0,0,0}; index_t src2_indices[N_DIMENSIONS]={0,0,0,0,0}; Data_Obj *col_dp; sizes=NEW_DIMSET; for(i=0;i<N_DIMENSIONS;i++) SET_DIMENSION(sizes,i,1); #ifdef CAUTIOUS clear_obj_args(oap); #endif /* CAUTIOUS */ /* The types and precisions should be whatever is allowed by vdot, * which is float, double, real and complex... */ if( ! is_good_for_inner(dpto,"inner") ) return; if( ! is_good_for_inner(dpfr1,"inner") ) return; if( ! is_good_for_inner(dpfr2,"inner") ) return; /* we need to make sure that the types and precisions MATCH! */ if( ! prec_and_type_match(dpto,dpfr1,"inner") ) return; if( ! prec_and_type_match(dpto,dpfr2,"inner") ) return; if( OBJ_ROWS(dpto) != OBJ_ROWS(dpfr1) ){ sprintf(DEFAULT_ERROR_STRING, "inner: dpto %s (%d) and first operand %s (%d) must have same # rows", OBJ_NAME(dpto),OBJ_ROWS(dpto),OBJ_NAME(dpfr1),OBJ_ROWS(dpfr1)); NWARN(DEFAULT_ERROR_STRING); return; } if( OBJ_COLS(dpto) != OBJ_COLS(dpfr2) ){ sprintf(DEFAULT_ERROR_STRING, "inner: target %s (%d) and second operand %s (%d) must have same # columns", OBJ_NAME(dpto),OBJ_COLS(dpto),OBJ_NAME(dpfr2),OBJ_COLS(dpfr2)); NWARN(DEFAULT_ERROR_STRING); return; } if( OBJ_COLS(dpfr1) != OBJ_ROWS(dpfr2) ){ sprintf(DEFAULT_ERROR_STRING, "inner: # cols of operand %s (%d) must match # rows of operand %s (%d)", OBJ_NAME(dpfr1),OBJ_COLS(dpfr1),OBJ_NAME(dpfr2),OBJ_ROWS(dpfr2)); NWARN(DEFAULT_ERROR_STRING); return; } //_n=OBJ_COLS(dpfr1); /* the length of each dot product we will compute */ if( IS_COMPLEX(dpto) ) SET_OA_ARGSTYPE(oap,COMPLEX_ARGS); else SET_OA_ARGSTYPE(oap,REAL_ARGS); /* vdot things it's inputs have the same shape, so if we are taking the inner * product of a column vector with a row vector, we have to transpose one of * the inputs... */ if( OBJ_ROWS(dpfr1) > 1 ) SET_OA_SRC1(oap,d_subscript(QSP_ARG dpfr1,0) ); /* subscript first row */ else SET_OA_SRC1(oap,dpfr1); /* object is a row */ if( OBJ_COLS(dpto) > 1 ) col_dp=c_subscript(QSP_ARG dpfr2,0); else col_dp=dpfr2; SET_OA_DEST(oap,mk_subimg(QSP_ARG dpto,0,0,"target pixel",1,1) ); //[sizes setDimensionAtIndex : 1 withValue : OBJ_ROWS(col_dp) ]; SET_DIMENSION(sizes,1,OBJ_ROWS(col_dp)); SET_DIMENSION(sizes,0,OBJ_COMPS(col_dp)); SET_OA_SRC2(oap,make_equivalence(QSP_ARG "_transposed_column", col_dp,sizes,OBJ_PREC_PTR(col_dp)) ); for(i=0;i<OBJ_ROWS(dpto);i++){ src1_indices[2]=i; SET_OBJ_DATA_PTR( OA_SRC1(oap), multiply_indexed_data(dpfr1,src1_indices) ); for(j=0;j<OBJ_COLS(dpto);j++){ dst_indices[2]=i; /* k_th component */ dst_indices[1]=j; /* k_th component */ SET_OBJ_DATA_PTR( OA_DEST(oap), multiply_indexed_data(dpto,dst_indices) ); src2_indices[1]=j; SET_OBJ_DATA_PTR( OA_SRC2(oap), multiply_indexed_data(dpfr2,src2_indices) ); vdot(QSP_ARG oap); } } delvec(QSP_ARG OA_SRC2(oap) ); /* "_transposed_column" */ if( OA_SRC1(oap) != dpfr1 ) delvec(QSP_ARG OA_SRC1(oap) ); if( col_dp != dpfr2 ) delvec(QSP_ARG col_dp); delvec(QSP_ARG OA_DEST(oap) ); }