void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ int i, j, NS, NZB, count, bdim, match, domain, bindex, sindex, nzCounts=0; int *observed, *bsubv, *ssubv, *bir, *sir, *bjc, *sjc, *mask, *ssize, *bcumprod, *scumprod; double *pDomain, *pSize, *bpr, *spr; mxArray *pTemp; pTemp = mxGetField(prhs[0], 0, "CPT"); bpr = mxGetPr(pTemp); bir = mxGetIr(pTemp); bjc = mxGetJc(pTemp); NZB = bjc[1]; pTemp = mxGetField(prhs[0], 0, "sizes"); pSize = mxGetPr(pTemp); pDomain = mxGetPr(prhs[1]); bdim = mxGetNumberOfElements(prhs[1]); mask = malloc(bdim * sizeof(int)); ssize = malloc(bdim * sizeof(int)); observed = malloc(bdim * sizeof(int)); for(i=0; i<bdim; i++){ ssize[i] = (int)pSize[i]; } count = 0; for(i=0; i<bdim; i++){ domain = (int)pDomain[i] - 1; pTemp = mxGetCell(prhs[2], domain); if(pTemp){ mask[count] = i; ssize[i] = 1; observed[count] = (int)mxGetScalar(pTemp) - 1; count++; } } if(count == 0){ pTemp = mxGetField(prhs[0], 0, "CPT"); plhs[0] = mxDuplicateArray(pTemp); free(mask); free(ssize); free(observed); return; } bsubv = malloc(bdim * sizeof(int)); ssubv = malloc(count * sizeof(int)); bcumprod = malloc(bdim * sizeof(int)); scumprod = malloc(bdim * sizeof(int)); NS = 1; for(i=0; i<bdim; i++){ NS *= ssize[i]; } plhs[0] = mxCreateSparse(NS, 1, NS, mxREAL); spr = mxGetPr(plhs[0]); sir = mxGetIr(plhs[0]); sjc = mxGetJc(plhs[0]); sjc[0] = 0; sjc[1] = NS; bcumprod[0] = 1; scumprod[0] = 1; for(i=0; i<bdim-1; i++){ bcumprod[i+1] = bcumprod[i] * (int)pSize[i]; scumprod[i+1] = scumprod[i] * ssize[i]; } nzCounts = 0; for(i=0; i<NZB; i++){ bindex = bir[i]; ind_subv(bindex, bcumprod, bdim, bsubv); for(j=0; j<count; j++){ ssubv[j] = bsubv[mask[j]]; } match = 1; for(j=0; j<count; j++){ if((ssubv[j]) != observed[j]){ match = 0; break; } } if(match){ spr[nzCounts] = bpr[i]; sindex = subv_ind(bdim, scumprod, bsubv); sir[nzCounts] = sindex; nzCounts++; } } reset_nzmax(plhs[0], NS, nzCounts); free(mask); free(ssize); free(observed); free(bsubv); free(ssubv); free(bcumprod); free(scumprod); }
void multiply_null_by_fuPot(mxArray *bigPot, const mxArray *smallPot){ int i, j, count, NB, NS, siz_b, siz_s, ndim, nzCounts=0; int *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2, *bir, *bjc; double *pbDomain, *psDomain, *pbSize, *psSize, *spr, *bpr, value; mxArray *pTemp, *pTemp1; pTemp = mxGetField(bigPot, 0, "domain"); pbDomain = mxGetPr(pTemp); siz_b = mxGetNumberOfElements(pTemp); pTemp = mxGetField(smallPot, 0, "domain"); psDomain = mxGetPr(pTemp); siz_s = mxGetNumberOfElements(pTemp); pTemp = mxGetField(bigPot, 0, "sizes"); pbSize = mxGetPr(pTemp); pTemp = mxGetField(smallPot, 0, "sizes"); psSize = mxGetPr(pTemp); NB = 1; for(i=0; i<siz_b; i++){ NB *= (int)pbSize[i]; } NS = 1; for(i=0; i<siz_s; i++){ NS *= (int)psSize[i]; } pTemp = mxGetField(smallPot, 0, "T"); spr = mxGetPr(pTemp); pTemp1 = mxCreateSparse(NB, 1, NB, mxREAL); bpr = mxGetPr(pTemp1); bir = mxGetIr(pTemp1); bjc = mxGetJc(pTemp1); bjc[0] = 0; bjc[1] = NB; if(NS == 1){ value = *spr; for(i=0; i<NB; i++){ bpr[i] = value; bir[i] = i; } nzCounts = NB; pTemp = mxGetField(bigPot, 0, "T"); if(pTemp)mxDestroyArray(pTemp); reset_nzmax(pTemp1, NB, nzCounts); mxSetField(bigPot, 0, "T", pTemp1); return; } if(NS == NB){ for(i=0; i<NB; i++){ if(spr[i] != 0){ bpr[nzCounts] = spr[i]; bir[nzCounts] = i; nzCounts++; } } pTemp = mxGetField(bigPot, 0, "T"); if(pTemp)mxDestroyArray(pTemp); reset_nzmax(pTemp1, NB, nzCounts); mxSetField(bigPot, 0, "T", pTemp1); return; } mask = malloc(siz_s * sizeof(int)); count = 0; for(i=0; i<siz_s; i++){ for(j=0; j<siz_b; j++){ if(psDomain[i] == pbDomain[j]){ mask[count] = j; count++; break; } } } ndim = siz_b; sx = (int *)malloc(sizeof(int)*ndim); sy = (int *)malloc(sizeof(int)*ndim); for(i=0; i<ndim; i++){ sx[i] = (int)pbSize[i]; sy[i] = 1; } for(i=0; i<count; i++){ sy[mask[i]] = sx[mask[i]]; } s = (int *)malloc(sizeof(int)*ndim); *(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1; subs = (int *)malloc(sizeof(int)*ndim); cpsy2 = (int *)malloc(sizeof(int)*ndim); for(i = 0; i < ndim; i++){ subs[i] = 0; s[i] = sx[i] - 1; } for(i = 0; i < ndim-1; i++){ cpsy[i+1] = cpsy[i]*sy[i]--; cpsy2[i] = cpsy[i]*sy[i]; } cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]); for(j=0; j<NB; j++){ if(*spr != 0){ bpr[nzCounts] = *spr; bir[nzCounts] = j; nzCounts++; } for(i = 0; i < ndim; i++){ if(subs[i] == s[i]){ subs[i] = 0; if(sy[i]) spr -= cpsy2[i]; } else{ subs[i]++; if(sy[i]) spr += cpsy[i]; break; } } } pTemp = mxGetField(bigPot, 0, "T"); if(pTemp)mxDestroyArray(pTemp); reset_nzmax(pTemp1, NB, nzCounts); mxSetField(bigPot, 0, "T", pTemp1); free(sx); free(sy); free(s); free(cpsy); free(subs); free(cpsy2); free(mask); }
void multiply_spPot_by_spPot(mxArray *bigPot, const mxArray *smallPot){ int i, j, count, bdim, sdim, NB, NZB, NZS, position, bindex, sindex, nzCounts=0; int *mask, *result, *bir, *sir, *rir, *bjc, *sjc, *rjc, *bCumprod, *sCumprod, *bsubv, *ssubv; double *pbDomain, *psDomain, *pbSize, *psSize, *bpr, *spr, *rpr; mxArray *pTemp, *pTemp1; pTemp = mxGetField(bigPot, 0, "domain"); pbDomain = mxGetPr(pTemp); bdim = mxGetNumberOfElements(pTemp); pTemp = mxGetField(smallPot, 0, "domain"); psDomain = mxGetPr(pTemp); sdim = mxGetNumberOfElements(pTemp); pTemp = mxGetField(bigPot, 0, "sizes"); pbSize = mxGetPr(pTemp); pTemp = mxGetField(smallPot, 0, "sizes"); psSize = mxGetPr(pTemp); NB = 1; for(i=0; i<bdim; i++){ NB *= (int)pbSize[i]; } pTemp = mxGetField(bigPot, 0, "T"); bpr = mxGetPr(pTemp); bir = mxGetIr(pTemp); bjc = mxGetJc(pTemp); NZB = bjc[1]; pTemp = mxGetField(smallPot, 0, "T"); spr = mxGetPr(pTemp); sir = mxGetIr(pTemp); sjc = mxGetJc(pTemp); NZS = sjc[1]; pTemp1 = mxCreateSparse(NB, 1, NZB, mxREAL); rpr = mxGetPr(pTemp1); rir = mxGetIr(pTemp1); rjc = mxGetJc(pTemp1); rjc[0] = 0; rjc[1] = NZB; mask = malloc(sdim * sizeof(int)); bCumprod = malloc(bdim * sizeof(int)); sCumprod = malloc(sdim * sizeof(int)); bsubv = malloc(bdim * sizeof(int)); ssubv = malloc(sdim * sizeof(int)); count = 0; for(i=0; i<sdim; i++){ for(j=0; j<bdim; j++){ if(psDomain[i] == pbDomain[j]){ mask[count] = j; count++; break; } } } bCumprod[0] = 1; for(i=0; i<bdim-1; i++){ bCumprod[i+1] = bCumprod[i] * (int)pbSize[i]; } sCumprod[0] = 1; for(i=0; i<sdim-1; i++){ sCumprod[i+1] = sCumprod[i] * (int)psSize[i]; } for(i=0; i<NZB; i++){ bindex = bir[i]; ind_subv(bindex, bCumprod, bdim, bsubv); for(j=0; j<sdim; j++){ ssubv[j] = bsubv[mask[j]]; } sindex = subv_ind(sdim, sCumprod, ssubv); result = (int *) bsearch(&sindex, sir, NZS, sizeof(int), compare); if(result){ position = result - sir; rpr[nzCounts] = bpr[i] * spr[position]; rir[nzCounts] = bindex; nzCounts++; } } pTemp = mxGetField(bigPot, 0, "T"); if(pTemp)mxDestroyArray(pTemp); reset_nzmax(pTemp1, NZB, nzCounts); mxSetField(bigPot, 0, "T", pTemp1); free(mask); free(bCumprod); free(sCumprod); free(bsubv); free(ssubv); }