⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 approx.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 2 页
字号:
   unsigned	 size 	  = size_of_level (range->level);    /*    *  Initialize domain pool and inner product arrays    */   domain_blocks = domain_pool->generate (range->level, y_state, wfa,					  domain_pool->model);   for (domain = 0; domain_blocks [domain] >= 0; domain++)   {      used [domain] = NO;      rem_denominator [domain]		/* norm of domain */	 = get_ip_state_state (domain_blocks [domain], domain_blocks [domain],			       range->level, c);      if (rem_denominator [domain] / size < min_norm)	 used [domain] = YES;		/* don't use domains with small norm */      else	 rem_numerator [domain]		/* inner product <s_domain, b> */	    = get_ip_image_state (range->image, range->address,				  range->level, domain_blocks [domain], c);      if (!used [domain] && fabs (rem_numerator [domain]) < min_norm)	 used [domain] = YES;   }   /*    *  Exclude all domain blocks given in array 'mp->exclude'    */   for (n = 0; isdomain (mp->exclude [n]); n++)      used [mp->exclude [n]] = YES;   /*    *  Compute the approximation costs if 'range' is approximated with    *  no linear combination, i.e. the error is equal to the square    *  of the image norm and the size of the automaton is determined by    *  storing only zero elements in the current matrix row    */   for (norm = 0, n = 0; n < size; n++)      norm += square (c->pixels [range->address * size + n]);   additional_bits = range->tree_bits + range->mv_tree_bits		     + range->mv_coord_bits + range->nd_tree_bits		     + range->nd_weights_bits;   mp->err          = norm;   mp->weights_bits = 0;   mp->matrix_bits  = domain_pool->bits (domain_blocks, NULL, range->level,					 y_state, wfa, domain_pool->model);   mp->costs        = (mp->matrix_bits + mp->weights_bits		       + additional_bits) * price + mp->err;   n = 0;   do    {      /*       *  Current approximation is: b = d_0 o_0 + ... + d_(n-1) o_(n-1)       *  with corresponding costs 'range->err + range->bits * p'.       *  For all remaining state images s_i (used[s_i] == NO) set       *  o_n :	= s_i - \sum(k = 0, ... , n-1) {(<s_i, o_k> / ||o_k||^2) o_k}       *  and try to beat current costs.       *  Choose that vector for the next orthogonalization step,       *  which has minimal costs: s_index.       *  (No progress is indicated by index == -1)       */            real_t min_matrix_bits  = 0;      real_t min_weights_bits = 0;      real_t min_error 	      = 0;      real_t min_weight [MAXEDGES];      real_t min_costs = full_search ? MAXCOSTS : mp->costs;            for (index = -1, domain = 0; domain_blocks [domain] >= 0; domain++) 	 if (!used [domain]) 	 {	    real_t    matrix_bits, weights_bits;	    /*	     *  To speed up the search through the domain images,	     *  the costs of using domain image 'domain' as next vector	     *  can be approximated in a first step:	     *  improvement of image quality	     *	  <= square (rem_numerator[domain]) / rem_denominator[domain]	     */	    {		  word_t   vectors [MAXEDGES + 1];		  word_t   states [MAXEDGES + 1];		  real_t   weights [MAXEDGES + 1];		  unsigned i, k;		  		  for (i = 0, k = 0; k < n; k++)		     if (mp->weight [k] != 0)		     {			vectors [i] = mp->indices [k];			states [i]  = domain_blocks [vectors [i]];			weights [i] = mp->weight [k];			i++;		     }		  vectors [i] 	  = domain;		  states [i]  	  = domain_blocks [domain];		  weights [i] 	  = 0.5;		  vectors [i + 1] = -1;		  states [i + 1]  = -1;		  weights_bits = coeff->bits (weights, states, range->level,					      coeff);		  matrix_bits = domain_pool->bits (domain_blocks, vectors,						   range->level, y_state,						   wfa, domain_pool->model);	    }	    if (((matrix_bits + weights_bits + additional_bits) * price +		 mp->err -		 square (rem_numerator [domain]) / rem_denominator [domain])		< min_costs)	    {	       /*		*  1.) Compute the weights (linear factors) c_i of the		*  linear combination		*  b = c_0 v_0 + ... + c_(n-1) v_(n-1) + c_n v_'domain'		*  Use backward substitution to obtain c_i from the linear		*  factors of the lin. comb. b = d_0 o_0 + ... + d_n o_n		*  of the corresponding orthogonal vectors {o_0, ..., o_n}.		*  Vector o_n of the orthogonal basis is obtained by using		*  vector 'v_domain' in step n of the Gram Schmidt		*  orthogonalization (see above for definition of o_n).		*  Recursive formula for the coefficients c_i:		*  c_n := <b, o_n> / ||o_n||^2		*  for i = n - 1, ... , 0:		*  c_i := <b, o_i> / ||o_i||^2 +		*          \sum (k = i + 1, ... , n){ c_k <v_k, o_i>		*					/ ||o_i||^2 }		*  2.) Because linear factors are stored with reduced precision		*  factor c_i is rounded with the given precision in step i		*  of the recursive formula. 		*/	       unsigned k;		/* counter */	       int    	l;		/* counter */	       real_t 	m_bits;		/* number of matrix bits to store */	       real_t 	w_bits;		/* number of weights bits to store */	       real_t 	r [MAXEDGES];	/* rounded linear factors */	       real_t 	f [MAXEDGES];	/* linear factors */	       int    	v [MAXEDGES];	/* mapping of domains to vectors */	       real_t 	costs;		/* current approximation costs */	       real_t 	m_err;		/* current approximation error */	       f [n] = rem_numerator [domain] / rem_denominator [domain];	       v [n] = domain;		/* corresponding mapping */	       for (k = 0; k < n; k++)	       {		  f [k] = ip_image_ortho_vector [k] / norm_ortho_vector [k];		  v [k] = mp->indices [k];	       }	    	       for (l = n; l >= 0; l--) 	       {		  rpf_t *rpf = domain_blocks [v [l]]			       ? coeff->rpf : coeff->dc_rpf;		  r [l] = f [l] = btor (rtob (f [l], rpf), rpf);		     		  for (k = 0; k < (unsigned) l; k++)		     f [k] -= f [l] * ip_domain_ortho_vector [v [l]][k]			      / norm_ortho_vector [k] ;	       } 	       /*		*  Compute the number of output bits of the linear combination		*  and store the weights with reduced precision. The		*  resulting linear combination is		*  b = r_0 v_0 + ... + r_(n-1) v_(n-1) + r_n v_'domain'		*/	       {		  word_t vectors [MAXEDGES + 1];		  word_t states [MAXEDGES + 1];		  real_t weights [MAXEDGES + 1];		  int	 i;		  		  for (i = 0, k = 0; k <= n; k++)		     if (f [k] != 0)		     {			vectors [i] = v [k];			states [i]  = domain_blocks [v [k]];			weights [i] = f [k];			i++;		     }		  vectors [i] = -1;		  states [i]  = -1;		  w_bits = coeff->bits (weights, states, range->level, coeff);		  m_bits = domain_pool->bits (domain_blocks, vectors,					      range->level, y_state,					      wfa, domain_pool->model);	       }	       	       /*		*  To compute the approximation error, the corresponding		*  linear factors of the linear combination 		*  b = r_0 o_0 + ... + r_(n-1) o_(n-1) + r_n o_'domain'		*  with orthogonal vectors must be computed with following		*  formula:		*  r_i := r_i +		*          \sum (k = i + 1, ... , n) { r_k <v_k, o_i>		*					/ ||o_i||^2 }		*/	       for (l = 0; (unsigned) l <= n; l++)	       {		  /*		   *  compute <v_n, o_n>		   */		  real_t a;		  a = get_ip_state_state (domain_blocks [v [l]],					  domain_blocks [domain],					  range->level, c);		  for (k = 0; k < n; k++) 		     a -= ip_domain_ortho_vector [v [l]][k]			  / norm_ortho_vector [k]			  * ip_domain_ortho_vector [domain][k];		  ip_domain_ortho_vector [v [l]][n] = a;	       }	       norm_ortho_vector [n]     = rem_denominator [domain];	       ip_image_ortho_vector [n] = rem_numerator [domain]; 	    	       for (k = 0; k <= n; k++)		  for (l = k + 1; (unsigned) l <= n; l++)		     r [k] += ip_domain_ortho_vector [v [l]][k] * r [l]			      / norm_ortho_vector [k];	       /*		*  Compute approximation error:		*  error := ||b||^2 +		*  \sum (k = 0, ... , n){r_k^2 ||o_k||^2 - 2 r_k <b, o_k>}		*/	       m_err = norm;	       for (k = 0; k <= n; k++)		  m_err += square (r [k]) * norm_ortho_vector [k]			 - 2 * r [k] * ip_image_ortho_vector [k];	       if (m_err < 0)		/* TODO: return MAXCOSTS */		  warning ("Negative image norm: %f"			   " (current domain: %d, level = %d)",			   (double) m_err, domain, range->level);	       costs = (m_bits + w_bits + additional_bits) * price + m_err;	       if (costs < min_costs)	/* found a better approximation */	       {		  index            = domain;		  min_costs        = costs;		  min_matrix_bits  = m_bits;		  min_weights_bits = w_bits;		  min_error        = m_err;		  for (k = 0; k <= n; k++)		     min_weight [k] = f [k];	       }	    }	 }            if (index >= 0)			/* found a better approximation */      {	 if (min_costs < mp->costs)	 {	    unsigned k;	    	    mp->costs        = min_costs;	    mp->err          = min_error;	    mp->matrix_bits  = min_matrix_bits;	    mp->weights_bits = min_weights_bits;	    	    for (k = 0; k <= n; k++)	       mp->weight [k] = min_weight [k];	    best_n = n + 1;	 }	 	 mp->indices [n] = index;	 mp->into [n]    = domain_blocks [index];	 used [index] = YES;	 /* 	  *  Gram-Schmidt orthogonalization step n 	  */	 orthogonalize (index, n, range->level, min_norm, domain_blocks, c);	 n++;      }	   }    while (n < max_edges && index >= 0);   mp->indices [best_n] = NO_EDGE;      mp->costs = (mp->matrix_bits + mp->weights_bits + additional_bits) * price	       + mp->err;   Free (domain_blocks);}static voidorthogonalize (unsigned index, unsigned n, unsigned level, real_t min_norm,	       const word_t *domain_blocks, const coding_t *c)/* *  Step 'n' of the Gram-Schmidt orthogonalization procedure: *  vector 'index' is orthogonalized with respect to the set *  {u_[0], ... , u_['n' - 1]}. The size of the image blocks is given by *  'level'. If the denominator gets smaller than 'min_norm' then *  the corresponding domain is excluded from the list of available *  domain blocks. * *  No return value. * *  Side effects: *	The remainder values (numerator and denominator) of *	all 'domain_blocks' are updated.  */{   unsigned domain;      ip_image_ortho_vector [n] = rem_numerator [index];   norm_ortho_vector [n]     = rem_denominator [index];   /*    *  Compute inner products between all domain images and     *  vector n of the orthogonal basis:    *  for (i = 0, ... , wfa->states)      *  <s_i, o_n> := <s_i, v_n> -    *      \sum (k = 0, ... , n - 1){ <v_n, o_k> <s_i, o_k> / ||o_k||^2}    *  Moreover the denominator and numerator parts of the comparitive    *  value are updated.    */   for (domain = 0; domain_blocks [domain] >= 0; domain++)       if (!used [domain])       {	 unsigned k;	 real_t   tmp = get_ip_state_state (domain_blocks [index],					    domain_blocks [domain], level, c);	 	 for (k = 0; k < n; k++) 	    tmp -= ip_domain_ortho_vector [domain][k] / norm_ortho_vector [k]		   * ip_domain_ortho_vector [index][k];	 ip_domain_ortho_vector [domain][n] = tmp;	 rem_denominator [domain] -= square (tmp) / norm_ortho_vector [n];	 rem_numerator [domain]   -= ip_image_ortho_vector [n]				     / norm_ortho_vector [n]				     * ip_domain_ortho_vector [domain][n] ;	 /*	  *  Exclude vectors with small denominator	  */	 if (!used [domain]) 	    if (rem_denominator [domain] / size_of_level (level) < min_norm) 	       used [domain] = YES;      }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -