/** * Do several things here: * 1. Compute lambda from the texcoords, if needed * 2. Determine if we're minifying or magnifying * 3. If minifying, choose mipmap levels * 4. Return image filter to use within mipmap images * \param level0 Returns first mipmap level to sample from * \param level1 Returns second mipmap level to sample from * \param levelBlend Returns blend factor between levels, in [0,1] * \param imgFilter Returns either the min or mag filter, depending on lambda */ static void choose_mipmap_levels(const struct pipe_texture *texture, const struct pipe_sampler_state *sampler, const float s[QUAD_SIZE], const float t[QUAD_SIZE], const float p[QUAD_SIZE], boolean computeLambda, float lodbias, unsigned *level0, unsigned *level1, float *levelBlend, unsigned *imgFilter) { if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { /* no mipmap selection needed */ *level0 = *level1 = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level); if (sampler->min_img_filter != sampler->mag_img_filter) { /* non-mipmapped texture, but still need to determine if doing * minification or magnification. */ float lambda = compute_lambda(texture, sampler, s, t, p, lodbias); if (lambda <= 0.0) { *imgFilter = sampler->mag_img_filter; } else { *imgFilter = sampler->min_img_filter; } } else { *imgFilter = sampler->mag_img_filter; } } else { float lambda; if (computeLambda) /* fragment shader */ lambda = compute_lambda(texture, sampler, s, t, p, lodbias); else /* vertex shader */ lambda = lodbias; /* not really a bias, but absolute LOD */ if (lambda <= 0.0) { /* XXX threshold depends on the filter */ /* magnifying */ *imgFilter = sampler->mag_img_filter; *level0 = *level1 = 0; } else { /* minifying */ *imgFilter = sampler->min_img_filter; /* choose mipmap level(s) and compute the blend factor between them */ if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { /* Nearest mipmap level */ const int lvl = (int) (lambda + 0.5); *level0 = *level1 = CLAMP(lvl, 0, (int) texture->last_level); } else { /* Linear interpolation between mipmap levels */ const int lvl = (int) lambda; *level0 = CLAMP(lvl, 0, (int) texture->last_level); *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level); *levelBlend = FRAC(lambda); /* blending weight between levels */ } } } }
void ICM_iteration(int N, int n, int K, int nlast, int first[], int m[], int **freq, int **ind, double **y, double **F, double **F_new, double **cumw, double **cs, double **v, double **w, double **nabla, double *lambda1, double *alpha1) { int i,j,k; double a,lambda,alpha; lambda=*lambda1; for (k=1;k<=K;k++) { for (i=1;i<=m[k];i++) v[k][i]=w[k][i]=0; } for (k=1;k<=K;k++) { j=0; for (i=first[k];i<=n;i++) { if (freq[k][i]>0) { j++; v[k][j] = freq[k][i]/(N*F[k][i]); w[k][j] = freq[k][i]/(N*SQR(F[k][i])); } if (freq[0][i]>0) { v[k][j] -= freq[0][i]/(N*(1-F[K+1][i])); w[k][j] += freq[0][i]/(N*SQR(1-F[K+1][i])); } } if (nlast<n) v[k][m[k]] -=lambda; for (i=1;i<=m[k];i++) v[k][i] += w[k][i]*F[k][ind[k][i]]; } cumsum(K,m,v,cs); convexmin(K,m,cumw,cs,w,y); Compute_F(K,n,freq,first,y,F_new); if (F_new[K+1][nlast]>=1) { a=(1-F[K+1][nlast])/(F_new[K+1][nlast]-F[K+1][nlast]); for (k=1;k<=K;k++) { for (i=first[k];i<=n;i++) F_new[k][i]=F[k][i]+a*(F_new[k][i]-F[k][i]); } compute_Fplus(n,K,F_new); for (k=1;k<=K;k++) { j=0; for (i=first[k];i<=n;i++) { if (freq[k][i]>0) { j++; y[k][j]=F_new[k][i]; } } } } if (f_alpha_prime(N,n,K,freq,1.0,F,F_new,lambda)<=0) alpha=1; else alpha=golden(N,n,K,freq,F,F_new,0.1,1,f_alpha,lambda); for (k=1;k<=K;k++) { for (i=first[k];i<=n;i++) F[k][i] += alpha*(F_new[k][i]-F[k][i]); } compute_Fplus(n,K,F); if (nlast<n) lambda=compute_lambda(N,n,K,freq,F); else lambda=0; compute_nabla(N,n,K,first,m,freq,F,lambda,nabla); *lambda1=lambda; *alpha1=alpha; }
void CG::solve_lp(double epsilon){ bool no_delete = valid_solution(); if (no_delete) { // if there is no need to delete nodes cout << "CG::solve_lp() no need to delete nodes" << endl; return; } cout << "problem size: " << n_vertex_ << endl; double max_weight = 0; for (int ii = 0; ii < n_vertex_; ii++) { if (g_[ii].weight > max_weight) { max_weight = g_[ii].weight; } } // find the initial solution, which is the longest path in terms of the weights assigned for (int ii = 0; ii < n_vertex_; ii++) { g_[ii].dual_val = 1 + max_weight - g_[ii].weight; } double dummy1; vector<int> initial_path; find_shortest_path(dummy1, initial_path); for (vector<int>::iterator iter1 = initial_path.begin(); iter1 != initial_path.end(); ++iter1) { g_[*iter1].total_flow = 1; } double lambda = compute_lambda(); double alpha = (4 / (lambda * epsilon)) * log(2 * n_vertex_ / epsilon); double delta = epsilon / (4 * alpha); double crt_left = 0.0; double crt_lambda = lambda; int iteration = -1; while (true) { iteration++; compute_dual_vals(alpha); double middle = 0; // middle corresponds to \vec{z}^tA\vec{y} for (int ii = 0; ii < n_vertex_; ii++) { middle = middle + g_[ii].dual_val * g_[ii].total_flow; } double right = 0; // right corresponds to \lambda\vec{z}^t\vec{b} for (int ii = 0; ii < n_vertex_; ii++) { right = right + crt_lambda * g_[ii].dual_val * g_[ii].weight; } vector<int> opt_path; double left; // left corresponds to \vec{z}^tA\vec{y} find_shortest_path(left, opt_path); crt_left = left; if (iteration % 1000 == 0) { cout << "iteration " << iteration << " left:" << left << " middle:" << middle << " right:" << right << " sol:" << 1 / crt_lambda << endl; } // check if the following condition is met or not // \vec{z}^tA\vec{y} - C(\vec{z}) \le \epsilon(\vec{z}^tA\vec{y} + \lambda\vec{z}^t\vec{b}) if ((middle - left) < epsilon * (middle + right) ) { cout << "converged!" << endl; cout << "iteration " << iteration << " left:" << left << " middle:" << middle << " right:" << right << " sol:" << 1 / crt_lambda << endl; break; } else { update_solution(delta, opt_path); crt_lambda = compute_lambda(); if (crt_lambda < 0.5 * lambda) { lambda = crt_lambda; alpha = 4 / (lambda * epsilon) * log(2 * n_vertex_ / epsilon); delta = epsilon / (4 * alpha); } } } // compute the normalized dual solution for (int ii = 0; ii < n_vertex_; ii++) { g_[ii].nor_dual_val = g_[ii].dual_val / crt_left; if (g_[ii].nor_dual_val > 1) { g_[ii].nor_dual_val = 1; } } // as the last step, round the fractional solution to integral solutions round_lp(); }
void ICM(int N, int n, int **freq, int K, int **ind, double **F, int n_It, double *phi1, int *iteration) { int *first,nlast,i,j,k,iteration1,*m,*n1,m_total; double **cumw,**cs,**v,**w,**nabla,**F_new; double **y; double sum,alpha,lambda,inprod,partialsum,eta=1.0e-10; y= new double *[K+2]; F_new=new double *[K+2]; cumw=new double *[K+2]; cs=new double *[K+2]; v=new double *[K+2]; w=new double *[K+2]; nabla=new double *[K+2]; first= new int[K+2]; m = new int[K+2]; n1 = new int[K+2]; for (i=0;i<K+2;i++) { y[i]= new double[N+1]; F_new[i]= new double[N+1]; cumw[i]= new double[N+1]; cs[i]= new double[N+1]; v[i]= new double[N+1]; w[i]= new double[N+1]; nabla[i]= new double[N+1]; } j=n; while (freq[0][j]==0) j--; nlast=j; for (k=1;k<=K;k++) { j=1; while (freq[k][j]==0) j++; first[k]=j; } for (k=0;k<=K;k++) m[k]=n1[k]=0; for (k=1;k<=K;k++) { j=0; for (i=first[k];i<=n;i++) { if (freq[k][i]>0) { j++; ind[k][j]=i; n1[k] += freq[k][i]; } } m[k]=j; } for (k=1;k<=K;k++) { for (i=0;i<first[k];i++) F[k][i]=F_new[k][i]=0; } m_total=0; for (k=1;k<=K;k++) m_total += n1[k]; for (k=1;k<=K;k++) { for (i=first[k];i<=n;i++) { if (freq[k][i]>0) F[k][i]=F[k][i-1]+freq[k][i]*1.0/(m_total+K); else F[k][i]=F[k][i-1]; } } for (i=1;i<=n;i++) { sum=0; for (k=1;k<=K;k++) sum += F[k][i]; F[K+1][i]=sum; } for (k=1;k<=K;k++) { j=0; for (i=first[k];i<=n;i++) { if (freq[k][i]>0) { j++; y[k][j]=F[k][i]; } } } if (nlast<n) lambda=compute_lambda(N,n,K,freq,F); else lambda=0; for (k=1;k<=K;k++) { for (i=first[k];i<=n;i++) F_new[k][i]=F[k][i]; } compute_Fplus(n,K,F_new); compute_nabla(N,n,K,first,m,freq,F,lambda,nabla); iteration1=0; while (iteration1<=n_It && fenchelviol(K,m,ind,y,nabla,eta,&partialsum,&inprod)) { iteration1++; ICM_iteration(N,n,K,nlast,first,m,freq,ind,y,F,F_new,cumw,cs,v,w,nabla,&lambda,&alpha); } *phi1=phi_ICM(n,K,nlast,freq,F); *iteration=iteration1; for (i=0;i<K+2;i++){ delete[] y[i], delete[] F_new[i], delete[] cumw[i], delete[] cs[i], delete[] v[i], delete[] w[i], delete[] nabla[i]; } delete[] y, delete[] cumw, delete[] cs, delete[] v, delete[] w, delete[] nabla; delete[] m, delete[] n1, delete[] first; }