/** * Check histogram data. */ INT16 CGEN_PROTECTED CHistogram::CheckHisto() { INT16 mode; if (data_empty (m_hist) == TRUE) return IERROR(this,HIS_EMPTY,0,0,0); if (data_chtype (m_hist, T_DOUBLE) != TRUE) return IERROR(this,HIS_TYPE,0,0,0); m_bins = (INT32) data_descr(m_hist,DESCR2); if (m_bins < 0 || m_bins > data_nrec(m_hist)) return IERROR(this,HIS_HISTO,0,0,0); m_hdim = data_ndim(m_hist); m_nhist = data_nblock(m_hist); if (m_nhist == 0) m_nhist = data_nrec(m_hist) / m_bins; set_data_nblock(m_hist, m_nhist); if (m_nhist == 0) return IERROR(this,HIS_HISTO,0,0,0); mode = (INT16) data_descr(m_hist,DESCR1); if (mode >= 1 && mode <= 3) m_hmode = mode; else set_data_descr (m_hist,mode,DESCR1); return (O_K); }
/** * Check minmax data, return mode. */ INT16 CGEN_PROTECTED CHistogram::CheckMinmax() { if (data_empty (m_minmax) == TRUE) return IERROR(this,HIS_EMPTY,0,0,0); if (data_chtype (m_minmax, T_DOUBLE) != TRUE) return IERROR(this,HIS_TYPE,0,0,0); if (data_nrec(m_minmax) == 2 && data_dim(m_minmax) == 1) return (1); if (data_nrec(m_minmax) == 2) return (2); if (data_nrec(m_minmax) > 2) return (3); return (-1); }
/** * Check consistency between histogram and minmax data. */ INT16 CGEN_PROTECTED CHistogram::CheckConsist() { INT16 ierr, mode; INT32 nhist; mode = HIS_MODE; nhist = data_nblock(m_hist); mode = CheckMinmax(); if (mode == -1) return (NOT_EXEC); if ((ierr = CheckHisto()) != O_K) return (ierr); switch (mode) { case 1: if (data_nrec(m_minmax) != 2 || data_dim (m_minmax) != 1) return IERROR(this,HIS_INCONS,0,0,0); break; case 2: if (data_nrec(m_minmax) != 2) return IERROR(this,HIS_INCONS,0,0,0); if (data_dim(m_minmax) != data_dim(m_hist)) return IERROR(this,HIS_INCONS,0,0,0); break; case 3: if (data_nrec(m_minmax) < 2 * nhist) return IERROR(this,HIS_INCONS,0,0,0); if (data_dim(m_minmax) != data_dim(m_hist)) return IERROR(this,HIS_INCONS,0,0,0); break; default: return IERROR(this,HIS_INCONS,0,0,0); } return (O_K); }
/** * Compute minmax data of pooled histogram. The blocks of hist are added. * * @param minmax minmax data * @param mm pooled minmax data * @return O_K if ok, NOT_EXEC if not executed */ static INT16 CHistogram_minmax_poole(CData* minmax, CData* mm) { FLOAT64 d, dmi, dmx; INT16 i, j; if (mm == NULL) return (NOT_EXEC); if (data_empty(minmax) == TRUE) return (NOT_EXEC); if (data_nrec(minmax) == 2) { data_copy (minmax,mm); return (O_K); } data_reset (mm); data_scopy (minmax, mm); data_arr_alloc (mm, 2); for (j = 0; j < data_dim(minmax); j++) { dmi = dfetch(minmax,0,j); dmx = dfetch(minmax,1,j); for (i = 1; i < data_nrec(minmax) / 2; i++) { d = dfetch(minmax,2*i,j); if (d < dmi) dmi = d; d = dfetch(minmax,2*i+1,j); if (d > dmx) dmx = d; } dstore (dmi, mm, 0, j); dstore (dmx, mm, 1, j); } return (O_K); }
/** * Search index maximum * * @param ind index sequence * @param i component containing index * @return max. index value or -1, if ind empty */ static INT32 CHistogram_max_index(CData* ind, INT32 i) { INT32 j, n; FLOAT64 j1, jmax; if (data_empty(ind) == TRUE) return (-1); jmax = (INT32) dfetch(ind,0,i); n = data_nrec(ind); for (j = 1; j < n; j++) if ((j1 = dfetch(ind,j,i)) > jmax) jmax = j1; return ((INT32) jmax); }
/** * Reorganize histogram. * * <p>Remarks</p> * <ul> * <li>If (exist == NULL), the number of histogram blocks is set to nind, * by adding empty blocks or removing blocks from the end.</li> * <li>If (exist != NULL), histogram blocks may selected as follows: * exist(i,0) == 0: block i is deleted; * exist(i,0) > 0: block i is preserved</li> * <li> Only preserved blocks will be available after reorganization! The * index correspondence may be changed by this operation!nind is not used * in this case.</li> * </ul> * * @param exist - index existing flag sequence (may be NULL) * @param nind - index number * @return O_K if ok, NOT_EXEC if not executed */ INT16 CGEN_PUBLIC CHistogram::ReorgEx(CData* exist, INT32 nind) { INT32 n, ifree, i, imax, rl; CData* h; if (CheckHisto() != O_K) return (NOT_EXEC); /* --- change only histogram number */ if (exist == NULL) { if (nind > 0 && nind != data_nblock(m_hist)) { data_realloc (m_hist, nind * m_bins); set_data_nblock(m_hist, nind); set_data_nrec (m_hist, nind * m_bins); return (O_K); } else return (NOT_EXEC); } /* --- reorganize according to exist */ if (exist != NULL) { imax = data_nrec(exist); n = 0; for (i = 0; i < imax; i++) { if (dfetch (exist,i,0) > 0.0) n++; } if (n == imax) return (O_K); h = data_create("h"); data_copy (m_hist,h); rl = BytesPerBlock(); data_realloc (m_hist, n * m_bins); ifree = 0; for (i = 0; i < imax; i++) { if (dfetch (exist,i,0) > 0.0) { dl_memmove ( xaddr(m_hist,ifree,0),xaddr(h,i*m_bins,0), rl); ifree += m_bins; } } if (m_hmode == 3) { data_copy (m_hist,h); rl = 2 * data_reclen(m_minmax); data_realloc (m_minmax, n * 2); ifree = 0; for (i = 0; i < imax; i++) { if (dfetch (exist,i,0) > 0.0) { dl_memmove ( xaddr(m_minmax,ifree,0),xaddr(h,2*i,0), rl); ifree += 2; } } } data_destroy(h); set_data_nblock(m_hist, n); return (O_K); } return (O_K); }
/** * Update histogram data st by data records from x * * Uses the followong fields of class CVh: * hist - histogram data (must be double, may be empty) * minp - minima-maxima (must be double) * icomp - index component (may be -1, if not index in data x) * nind - index number (only for initialization required) * m_bins - histogram resolution (only for initialization required) * indexlist - index list of vectors * * if index list cannot be created, index indep. histogram is made: * - no label, no index comp. or no label file * - label, but no ltab * mode - 1 constant data interval (minm->dim == 1, * minm->nvec == 1) * 2 component spec. quantization (minm->nvec == 2) * 3 index - comp. spec. quantization (minm->nvec > 2) * * @param x Feature vector sequence * @param wv Weighting vector sequence (may be NULL) * @return O_K if ok or NOT_EXEC if not executed */ INT16 CGEN_PUBLIC CHistogram::UpdateHist(CData* x, CData* wv) { INT32 t, il, wdim, T; FLOAT64 cw; FLOAT64 *xp, *wvp, *p_mm; INT16 lflag, flag_w, mflag; INT32 *qx; INT16 ierr; IDENTIFY ("CVh::UpdateHist"); /* Check input data */ if (data_empty(x) == TRUE) return IERROR(this,HIS_NOINP,0,0,0); if (data_ndim(x) == 0) return IERROR(this,HIS_NODAT,0,0,0); T = data_nrec(x); m_count = 0; /* Check index list data */ lflag = 0; if (data_empty(m_indexlist) != TRUE) lflag = 1; /* Use minp data */ SetupHmode(); if (m_hmode <= 0) return NOT_EXEC; p_mm = (FLOAT64*) data_ptr(m_minmax); /* Prepare histogram array */ Prepare(x, wv); if ((ierr = CheckConsist()) != O_K) return NOT_EXEC; /* Check weight data */ flag_w = 0; wvp = NULL; wdim = data_ndim(wv); if (data_empty(wv) != TRUE && lflag == 0) { if (wdim < m_nhist) return (NOT_EXEC); flag_w = 1; wvp = (FLOAT64*) dl_calloc (wdim,sizeof(FLOAT64),"UpdateHist"); } mflag = 0; if (data_empty(wv) != TRUE && lflag == 1) { if (wdim == 1) mflag = 1; } if (flag_w == 1 || mflag == 1) if (data_nrec(wv) < T) { T = data_nrec(wv); printf("histogram update: less weights than data ... only %d records", T); } /* Aux. arrays */ qx = (INT32*) dl_calloc(m_hdim+2, sizeof(INT32), "UpdateHist"); xp = (FLOAT64*) dl_calloc(m_hdim+2, sizeof(FLOAT64),"UpdateHist"); /* Hard update, index driven */ cw = 1.; if (flag_w == 0) { il = 0; for (t = 0; t < T; t++) { dvec_fetch(xp, x, t, m_hdim, m_icomp); if (lflag != 0) il = (INT32) dfetch(m_indexlist,t,0); if (il > -1 && il < m_nhist) { m_count++; if (mflag == 1) cw = dfetch(wv,t,0); QuantVec(xp, qx, p_mm, il); IncrementHisto(qx, cw, il); } } } /* Soft updating weighted by w-array */ if (flag_w == 1) { for (t = 0; t < T; t++) { dvec_fetch(wvp,wv,t,wdim,-1); dvec_fetch(xp,x,t,m_hdim,m_icomp); for (il = 0; il < m_nhist; il++) { m_count++; QuantVec(xp, qx, p_mm, il); IncrementHisto(qx, wvp[il], il); } } } /* Ending activities */dl_free(qx); dl_free(xp); if (flag_w == 1) dl_free (wvp); return O_K; }