void RBFVectorFieldGenerator2D::process() {
    if (samples_.size() != static_cast<size_t>(seeds_.get())) {
        createSamples();
    }

    Eigen::MatrixXd A(seeds_.get(), seeds_.get());
    Eigen::VectorXd bx(seeds_.get()), by(seeds_.get());
    Eigen::VectorXd xx(seeds_.get()), xy(seeds_.get());

    int row = 0;
    for (auto &a : samples_) {
        int col = 0;
        for (auto &b : samples_) {
            auto r = glm::distance(a.first, b.first);
            A(row, col++) = shape_.get() + gaussian_.evaluate(r);
        }
        bx(row) = a.second.x;
        by(row++) = a.second.y;
    }

    auto solverX = A.llt();
    auto solverY = A.llt();

    xx = solverX.solve(bx);
    xy = solverY.solve(by);

    auto img = std::make_shared<Image>(size_.get(), DataVec4Float32::get());

    vec4 *data =
        static_cast<vec4 *>(img->getColorLayer()->getEditableRepresentation<LayerRAM>()->getData());

    int i = 0;
    for (int y = 0; y < size_.get().y; y++) {
        for (int x = 0; x < size_.get().x; x++) {
            dvec2 p(x, y);
            p /= size_.get();
            p *= 2;
            p -= 1;

            vec3 v(0, 0, 0);
            int s = 0;
            for (; s < seeds_.get(); s++) {
                double r = glm::distance(p, samples_[s].first);
                auto w = gaussian_.evaluate(r);
                v.x += static_cast<float>(xx(s) * w);
                v.y += static_cast<float>(xy(s) * w);
            }
            data[i++] = vec4(v, 1.0f);
        }
    }
    vectorField_.setData(img);
}
Exemple #2
0
void bu_hci::_set_hci_filter()
{
    TRACE(__FUNCTION__);

    struct  _PAACK8
    {
        uint32_t    filter0;
        uint32_t    filter1;
        uint32_t    filter2;
        uint16_t    filter3;
    }  filter =
    {
        btohl((1 << HCI_EVENT_PKT)| (1 << HCI_ACLDATA_PKT)),
#ifdef ACL_MTU_FRAG
        btohl( (1 << EVT_NUM_COMP_PKTS)|
               (1 << EVT_DISCONN_COMPLETE) |
               (1 << EVT_ENCRYPT_CHANGE) |
               (1 << EVT_CMD_COMPLETE) |
               (1 << EVT_CMD_STATUS)),
#else
        btohl( (1 << EVT_DISCONN_COMPLETE) |
               (1 << EVT_ENCRYPT_CHANGE) |
               (1 << EVT_CMD_COMPLETE) |
               (1 << EVT_CMD_STATUS)),
#endif
        btohs(1 << (EVT_LE_META_EVENT - 32)),
        0
    };
#ifdef DEBUG
    bybuff by((const uint8_t*)&filter, sizeof(filter));
    TRACE("[]<=" << by.to_string());
#endif
    _socket->set_filter((const uint8_t*)&filter, sizeof(filter));
}
Exemple #3
0
	Vec3q SATSampler::operator()(const Vec2q &uv,const Vec2q &diff) const {
		f32x4b fullMask=diff.x>=0.5f||diff.x>= 0.5f;
		if(ForAll(fullMask)) return Vec3q(avg.x,avg.y,avg.z);

		Vec2q tDiff=diff*floatq(0.5f);
		Vec2q a=(uv-tDiff),b=(uv+tDiff);
		a*=Vec2q(floatq(w),floatq(h));
		b*=Vec2q(floatq(w),floatq(h));

		i32x4 ax(a.x),ay(a.y);
		i32x4 bx(b.x),by(b.y);
		ax&=wMask; ay&=hMask;
		bx&=wMask; by&=hMask;

		union { __m128 count; float countf[4]; };
		TSample sum[4];
		i32x4 one(1);

		if(ForAll(ax<=bx&&ay<=by)) {
			count = (f32x4(by-ay+one)*f32x4(bx-ax+one)).m;
			ComputeRect(ax,ay,bx,by,sum);
		}
		else for(int k=0;k<4;k++) {
			if(ax[k]>bx[k]) {
				if(ay[k]>by[k]) {
					countf[k]=(bx[k]+1)*(by[k]+1)+(w-ax[k])*(h-ay[k]);
					sum[k]=ComputeRect(0,0,bx[k],by[k])+ComputeRect(ax[k],ay[k],w-1,h-1);
				}
				else {
					countf[k]=(bx[k]+1+w-ax[k])*(by[k]-ay[k]+1);
					sum[k]=ComputeRect(0,ay[k],bx[k],by[k])+ComputeRect(ax[k],ay[k],w-1,by[k]);
				}
			}
			else {
				if(ay[k]>by[k]) {
					countf[k]=(bx[k]-ax[k]+1)*(by[k]+h+1-ay[k]);
					sum[k]=ComputeRect(ax[k],0,bx[k],by[k])+ComputeRect(ax[k],ay[k],bx[k],h-1);
				}
				else {
					countf[k]=(by[k]-ay[k]+1)*(bx[k]-ax[k]+1);
					sum[k]=ComputeRect(ax[k],ay[k],bx[k],by[k]);
				}
			}
		}

		union {
			__m128 out[3];
			struct { float ox[4]; float oy[4]; float oz[4]; } o;
		};
		o.ox[0]=sum[0].R(); o.oy[0]=sum[0].G(); o.oz[0]=sum[0].B();
		o.ox[1]=sum[1].R(); o.oy[1]=sum[1].G(); o.oz[1]=sum[1].B();
		o.ox[2]=sum[2].R(); o.oy[2]=sum[2].G(); o.oz[2]=sum[2].B();
		o.ox[3]=sum[3].R(); o.oy[3]=sum[3].G(); o.oz[3]=sum[3].B();

		return Condition(fullMask,Vec3q(avg.x,avg.y,avg.z),
				Vec3q(out[0], out[1], out[2]) * Inv(floatq(count) * 255.0f));
	}
Exemple #4
0
	bool KL2Map_Base::_InsertJointToBlock(const _Node_Lite * pNode)
	{	PERF_COUNTER(KL2Map_Base__InsertJointToBlock);

		ASSERT_RETURN(pNode, false);
		int_r bx(-1), by(-1);
		GetJointBlockPos(pNode->x, pNode->y, bx, by);
		ASSERT_RETURN(bx >= 0, false);
		ASSERT_RETURN(by >= 0, false);
		return m_L2MapByBlock[bx][by].insert_unique(pNode) > -1;
	}
Exemple #5
0
int main(){
	bint a, start, end, mid, temp;
	type i, j, len;
	int s[200];
	while(input(a)){
		give(a,end);
		end.len = a.len/3  + 2;
		end.dig[end.len-1] = 0;
		end.dig[end.len] = 1;
		shift(end,10);
		give(a,start);
		start.len = a.len/3 - 1;
		if(start.len<0)start.len = 0;
		start.dig[start.len] = 1;
		shift(start,10);
		shift(a,30);
		while(cmp(end,start)>=0){
			add(end,start,mid);
			move(mid);
			by(mid,mid,temp);
			by(mid,temp,temp);
			if(cmp(temp,a)<=0)add(mid,type(1), start);
			else sub(mid,type(1),end);
		}
		for(i=0;i<30;i++)div(end,10,end,j);
		j = 0, len = 0;
		give(end,temp);
		while( !(temp.dig[0]==0&&temp.len==0) ){
			j += temp.dig[0]%10;
			s[len++] = temp.dig[0]%10;
			j %= 10;
			div(temp,10,temp,i);
		}
		printf("%d ",j);
		len--;
		while(len>=10)printf("%d",s[len--]);
		printf(".");
		while(len>=0)printf("%d",s[len--]);
		printf("\n");
	}
	return 0;
}
int main()
{
  Delaunay_triangulation T;

  Point_value_map value_function;
  Point_vector_map gradient_function;

  //parameters for spherical function:
  Coord_type a(0.25), bx(1.3), by(-0.7), c(0.2);
  for (int y=0; y<4; y++) {
    for (int x=0; x<4; x++) {
      K::Point_2 p(x,y);
      T.insert(p);
      value_function.insert(std::make_pair(p,a + bx* x+ by*y + c*(x*x+y*y)));
    }
  }

  sibson_gradient_fitting_nn_2(T, std::inserter(gradient_function,
                                                gradient_function.begin()),
                               CGAL:: Data_access<Point_value_map>(value_function),
                               Traits());

  for(Point_vector_map::iterator it = gradient_function.begin(); it != gradient_function.end(); ++it)
  {
    std::cout << it->first << "  "  << it->second << std::endl;
  }
  // coordinate computation
  K::Point_2 p(1.6, 1.4);
  std::vector< std::pair< Point, Coord_type > > coords;
  Coord_type norm = CGAL::natural_neighbor_coordinates_2(T, p, std::back_inserter(coords)).second;


  //Sibson interpolant: version without sqrt:
  std::pair<Coord_type, bool> res =
    CGAL::sibson_c1_interpolation_square(coords.begin(),
                                         coords.end(), norm, p,
                                         CGAL::Data_access<Point_value_map>(value_function),
                                         CGAL::Data_access<Point_vector_map>(gradient_function),
                                         Traits());

  if(res.second)
    std::cout << "Tested interpolation on " << p
              << " interpolation: " << res.first << " exact: "
              << a + bx*p.x() + by*p.y() + c*(p.x()*p.x()+p.y()*p.y())
              << std::endl;
  else
    std::cout << "C^1 Interpolation not successful." << std::endl
              << " not all gradients are provided." << std::endl
              << " You may resort to linear interpolation." << std::endl;

  return EXIT_SUCCESS;
}
Exemple #7
0
void boolbvt::post_process_quantifiers()
{
  std::set<exprt> instances;
  
  if(quantifier_list.empty()) return;
  
  for(quantifier_listt::const_iterator q_it=quantifier_list.begin();
      q_it!=quantifier_list.end();
      q_it++)
    forall_operands(o_it, q_it->expr.op1())
      instances.insert(*o_it);

  if(instances.empty())
    throw "post_process_quantifiers: no instances";

  for(quantifier_listt::const_iterator q_it=quantifier_list.begin();
      q_it!=quantifier_list.end();
      q_it++)
  {
    const exprt &expr=q_it->expr;
    
    bvt inst_bv;
    inst_bv.reserve(instances.size());
    
    for(std::set<exprt>::const_iterator it=instances.begin();
        it!=instances.end();
        it++)
    {
      exprt dest(expr.op2());

      exprt by(*it);
      if(expr.op0().type()!=by.type())
        by.make_typecast(expr.op0().type());

      replace_expr(expr.op0(), by, dest);
      inst_bv.push_back(convert(dest));
    }

    if(expr.id()=="forall")
      prop.set_equal(prop.land(inst_bv), q_it->l);
    else if(expr.id()=="exists")
      prop.set_equal(prop.lor(inst_bv), q_it->l);
    else
      assert(false);
  }
}
Joint Filter::Filter_LeastSquare(Joint joint)
{
	LS_count++;
	LS_List.push_back(joint);
	while (LS_count > LS_n)
	{
		LS_count--;
		LS_List.erase(LS_List.begin());
	}
	if (LS_count < LS_n)
	{
		return joint;
	}
	//Generate b
	Mat bx(LS_m, 1, CV_64FC1);
	Mat by(LS_m, 1, CV_64FC1);
	for (int i = 0; i < LS_m; i++)
	{
		bx.at<double>(i, 0) = 0;
		by.at<double>(i, 0) = 0;
		for (int j = 0; j < LS_n; j++)
		{
			double t = LS_t0 + j*LS_delta;

			double xt = LS_List[j].Position.X * pow(t, i);
			bx.at<double>(i, 0) += xt;

			double yt = LS_List[j].Position.Y * pow(t, i);
			by.at<double>(i, 0) += yt;
		}
	}
	Mat ax = LS_A.inv()*bx;
	Mat ay = LS_A.inv()*by;
	double x = 0; double y = 0;
	double t = LS_t0 + LS_n*LS_delta;
	for (int i = 0; i < LS_m; i++)
	{
		x += ax.at<double>(i, 0)*pow(t, i);
		y += ay.at<double>(i, 0)*pow(t, i);
	}
	Joint result;
	result = joint;
	result.Position.X = x;
	result.Position.Y = y;
	return result;
}
int main()
{
  Delaunay_triangulation T;
  std::map<Point, Coord_type, K::Less_xy_2> function_values;
  typedef CGAL::Data_access< std::map<Point, Coord_type, K::Less_xy_2 > >
                                            Value_access;

  Coord_type a(0.25), bx(1.3), by(-0.7);

  for (int y=0 ; y<3 ; y++)
    for (int x=0 ; x<3 ; x++){
      K::Point_2 p(x,y);
      T.insert(p);
      function_values.insert(std::make_pair(p,a + bx* x+ by*y));
    }
  //coordinate computation
  K::Point_2 p(1.3,0.34);
  std::vector< std::pair< Point, Coord_type > > coords;
  Coord_type norm =
    CGAL::natural_neighbor_coordinates_2
    (T, p,std::back_inserter(coords)).second;

  Coord_type res =  CGAL::linear_interpolation(coords.begin(), coords.end(),
                                               norm,
                                               Value_access(function_values));

  std::cout << "   Tested interpolation on " << p << " interpolation: "
            << res << " exact: " << a + bx* p.x()+ by* p.y()<< std::endl;

  std::cout << "done" << std::endl;

//////////////////////////////////////////////////////////////////////
// own version
  
  
  



  return 0;
}
Exemple #10
0
//(15)
void div(bint a, bint b, bint& c, bint& d){
	type x, k;
	bint temp;
	give(a, d);
	c.len = c.dig[0] = 0;
	while( cmp(d,b)>0 ){
		k = d.len - b.len;
		if( d.dig[d.len] > b.dig[b.len] )
			x = d.dig[d.len] / (b.dig[b.len] + 1);
		else if( k )
			k--, x =  ( d.dig[d.len]*mod + d.dig[d.len-1])/(b.dig[b.len] + 1);
		else break;
		by( b, x, temp);
		shift( temp, k );
		sub(d, temp, d);
		give( x, temp );
		shift(temp, k);
		add(c, temp, c);
	}
	if(cmp(d,b)>=0) sub(d,b,d), add(c,(type)1, c); 	
}
Exemple #11
0
// This blocks the current thread.  This releases the given mutex (which
// must be held when BlockThread() is called).  To reduce contention, it
// does not reclaim the mutex on return.
zx_status_t FutexNode::BlockThread(Guard<fbl::Mutex>&& adopt_guard, const Deadline& deadline) {
    // Adopt the guarded lock from the caller. This could happen before or after
    // the following locks because the underlying lock is held from the caller's
    // frame. The runtime validator state is not affected by the adoption.
    Guard<fbl::Mutex> guard{AdoptLock, ktl::move(adopt_guard)};

    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
    ThreadDispatcher::AutoBlocked by(ThreadDispatcher::Blocked::FUTEX);

    // We specifically want reschedule=MutexPolicy::NoReschedule here, otherwise
    // the combination of releasing the mutex and enqueuing the current thread
    // would not be atomic, which would mean that we could miss wakeups.
    guard.Release(MutexPolicy::ThreadLockHeld, MutexPolicy::NoReschedule);

    thread_t* current_thread = get_current_thread();
    zx_status_t result;
    current_thread->interruptable = true;
    result = wait_queue_.Block(deadline);
    current_thread->interruptable = false;

    return result;
}
Exemple #12
0
void cover()
{
 s=18;sp=6;
 w9=w8=w4=w6=w5=w2=w3=w7=w0=wk=we=wf=wj=wl=wp=wr=ws=s/2;//1/2
 w1=wi=s/4;
 wg=wc=wh=wn=wb=wu=wt=wv=wx=wy=2*s/3;//2/3
 ww=wm=wa=wd=wo=wq=wz=3*s/4;//3/4
 h=s;//1

///////////////////

 xnxt=-52;ynxt=370;
 computer();
 xnxt+=s/2;
 graphics();

 xnxt=0;ynxt-=2*s-4;
 mini();
 xnxt+=s/2;
 project();

 /////////////////

 s=28;sp=8;
 w9=w8=w4=w6=w5=w2=w3=w7=w0=wk=we=wf=wj=wl=wp=wr=ws=s/2;//1/2
 w1=wi=s/4;
 wg=wc=wh=wn=wb=wu=wt=wv=wx=wy=2*s/3;//2/3
 ww=wm=wa=wd=wo=wq=wz=3*s/4;//3/4
 h=s;//1

///////////////////
 glPointSize(3.0);
 xnxt=-100;ynxt-=2*s;
 balloon1();
 xnxt+=s/2;
 shooting();

////////////////

 s=16;sp=4;
 w9=w8=w4=w6=w5=w2=w3=w7=w0=wk=we=wf=wj=wl=wp=wr=ws=s/2;//1/2
 w1=wi=s/4;
 wg=wc=wh=wn=wb=wu=wt=wv=wx=wy=2*s/3;//2/3
 ww=wm=wa=wd=wo=wq=wz=3*s/4;//3/4
 h=s;//1

//////////////
 glPointSize(2.0);
 xnxt=320;ynxt-=4*s;
 glPointSize(1.5);
 by();

////////////////

 s=16;sp=6;
 w9=w8=w4=w6=w5=w2=w3=w7=w0=wk=we=wf=wj=wl=wp=wr=ws=s/2;//1/2
 w1=wi=s/4;
 wg=wc=wh=wn=wb=wu=wt=wv=wx=wy=2*s/3;//2/3
 ww=wm=wa=wd=wo=wq=wz=3*s/4;//3/4
 h=s;//1

 xnxt=170;ynxt-=3*s;
 arahant();

 xnxt=160;ynxt-=2*s;
 ashrith();

 xnxt=170;ynxt-=2*s;
 dhanush();

 xnxt=138;ynxt-=2*s;
 harsha();
 
 xnxt=184;ynxt-=2*s;
 shreeman();
///////////////////////////
 
 xnxt=-190;ynxt=124;
 guidance();

 xnxt=-190;ynxt-=3*s;
 sir();

 xnxt=-190;ynxt-=2*s;
 madam();
}
Exemple #13
0
box
pager_rep::pages_format (pagelet pg) {
  // cout << "Formatting pagelet " << (N(pages)+1)
  //      << " stretch " << pg->stretch
  //      << " height " << stretch_space (pg->ht, pg->stretch) << LF << INDENT;
  if (N (pg->ins) == 0) {
    if (N(pages) == 0) return dummy_box (decorate_middle (ip));
    return dummy_box (decorate_middle (pages [N(pages)-1] -> find_rip ()));
  }
  else if (N (pg->ins) == 1) {
    insertion ins= pg->ins[0];
    // cout << ins << " stretch " << ins->stretch
    //      << " height " << stretch_space (ins->ht, ins->stretch) << LF;
    //      << UNINDENT << "Formatted pagelet " << (N(pages)+1) << LF << LF;
    return pages_format (ins);
  }
  else {
    int i, n= N(pg->ins);
    array<box> bs (n);
    array<SI>  bx (n);
    array<SI>  by (n);
    SI y= 0, fnote_y= MAX_SI;
    for (i=0; i<n; i++) {
      insertion ins= pg->ins[i];
      // cout << ins << " at " << y << " stretch " << ins->stretch
      //      << " height " << stretch_space (ins->ht, ins->stretch) << LF;
      bs[i]= pages_format (ins);
      bx[i]= 0;
      by[i]= y;
      y -= bs[i]->h();
      if (i < n-1) {
	insertion next= pg->ins[i+1];
	if (ins->type != next->type) {
	  if (is_tuple (next->type, "footnote")) {
	    // cout << "sep " << stretch_space (fnote_sep, ins->stretch) << LF;
	    y -= stretch_space (fnote_sep, ins->stretch);
	    fnote_y= y;
	  }
	  else if (is_tuple (ins->type, "float")) {
	    if (!is_tuple (next->type, "float")) {
	      // cout << "sep " << stretch_space(float_sep, ins->stretch) << LF;
	      y -= stretch_space (float_sep, ins->stretch);
	    }
	  }
	  else if (is_tuple (ins->type, "multi-column") ||
		   is_tuple (next->type, "multi-column")) {
	    page_item item= access (l, path_dec (ins->end));
	    // cout << "sep " << stretch_space (item->spc, ins->stretch) << LF;
	    y -= stretch_space (item->spc, ins->stretch);
	  }
	}
	if (is_tuple (ins->type, "footnote"))
	  if (is_tuple (next->type, "footnote")) {
	    page_item item= access (l, path_dec (ins->end));
	    SI sep= stretch_space (item->spc + fn_sep, ins->stretch);
	    // cout << "sep " << sep << LF;
	    y -= sep;
	  }
	if (is_tuple (next->type, "float")) {
	  // cout << "sep " << stretch_space (float_sep, ins->stretch) << LF;
	  y -= stretch_space (float_sep, ins->stretch);
	}
      }
    }
    if (fnote_y != MAX_SI) {
      pencil pen= env->pen->set_width (env->fn->wline);
      bs << line_box (decorate(), 0, 0, fnote_bl, 0, pen);
      bx << 0;
      by << (fnote_y + env->fn->sep);
    }
    // cout << UNINDENT << "Formatted pagelet " << (N(pages)+1) << LF << LF;
    return scatter_box (ip, bs, bx, by);
  }
}
Exemple #14
0
visit_handle Simulation:: get_curve( const string &name ) const
{
    visit_handle h = VISIT_INVALID_HANDLE;
    
    if( strncmp(name.c_str(),"bubble",6) == 0 )
    {
        const size_t  id = strconv::to_size( name.c_str()+6, "bubble id");
        assert(id>0);
        assert(id<=bubbles.count());
        const Bubble *b  = bubbles.first();
        for(size_t iter=1;iter<id;++iter) b=b->next;
        assert(b);
        if( VisIt_CurveData_alloc(&h) == VISIT_OKAY )
        {
            // copy bubble spots coordinates
            const size_t bn = b->size+1;
            vector<Real> bx(bn,0);
            vector<Real> by(bn,0);
            const Tracer *p = b->root;
            
            
            for( size_t i=1; i <= bn; ++i,p=p->next)
            {
                bx[i] = p->vertex.x;
                by[i] = p->vertex.y;
            }
            
            
            // make a curve
            visit_handle hcx,hcy;
            VisIt_VariableData_alloc( &hcx );
            VisIt_VariableData_alloc( &hcy );
            VisIt_VariableData_setDataD(hcx, VISIT_OWNER_COPY, 1, bn, bx());
            VisIt_VariableData_setDataD(hcy, VISIT_OWNER_COPY, 1, bn, by());
            VisIt_CurveData_setCoordsXY(h, hcx, hcy);
            
        }
    }
    
    if( name == "junctions" )
    {
        if( VisIt_CurveData_alloc(&h) == VISIT_OKAY )
        {
            // copy juntions coordinates
            const size_t nj = segmenter.num_junctions();
            vector<Real> jx(nj,0);
            vector<Real> jy(nj,0);
            const Segments &segments = segmenter();
            for( size_t i=segments.size(),j=1;i>0;--i)
            {
                const Segment &seg = *segments[i];
                for( const Junction *J = seg.head;J;J=J->next)
                {
                    assert(j<=nj);
                    jx[j] = J->vertex.x;
                    jy[j] = J->vertex.y;
                    ++j;
                }
            }
            
            // make a curve
            visit_handle hcx,hcy;
            VisIt_VariableData_alloc( &hcx );
            VisIt_VariableData_alloc( &hcy );
            VisIt_VariableData_setDataD(hcx, VISIT_OWNER_COPY, 1, nj, jx());
            VisIt_VariableData_setDataD(hcy, VISIT_OWNER_COPY, 1, nj, jy());
            VisIt_CurveData_setCoordsXY(h, hcx, hcy);

        }

    }
    
    return h;
}
/*************************************************************************
Weighted  fitting  by  Chebyshev  polynomial  in  barycentric  form,  with
constraints on function values or first derivatives.

Small regularizing term is used when solving constrained tasks (to improve
stability).

Task is linear, so linear least squares solver is used. Complexity of this
computational scheme is O(N*M^2), mostly dominated by least squares solver

SEE ALSO:
    PolynomialFit()

INPUT PARAMETERS:
    X   -   points, array[0..N-1].
    Y   -   function values, array[0..N-1].
    W   -   weights, array[0..N-1]
            Each summand in square  sum  of  approximation deviations from
            given  values  is  multiplied  by  the square of corresponding
            weight. Fill it by 1's if you don't  want  to  solve  weighted
            task.
    N   -   number of points, N>0.
    XC  -   points where polynomial values/derivatives are constrained,
            array[0..K-1].
    YC  -   values of constraints, array[0..K-1]
    DC  -   array[0..K-1], types of constraints:
            * DC[i]=0   means that P(XC[i])=YC[i]
            * DC[i]=1   means that P'(XC[i])=YC[i]
            SEE BELOW FOR IMPORTANT INFORMATION ON CONSTRAINTS
    K   -   number of constraints, 0<=K<M.
            K=0 means no constraints (XC/YC/DC are not used in such cases)
    M   -   number of basis functions (= polynomial_degree + 1), M>=1

OUTPUT PARAMETERS:
    Info-   same format as in LSFitLinearW() subroutine:
            * Info>0    task is solved
            * Info<=0   an error occured:
                        -4 means inconvergence of internal SVD
                        -3 means inconsistent constraints
                        -1 means another errors in parameters passed
                           (N<=0, for example)
    P   -   interpolant in barycentric form.
    Rep -   report, same format as in LSFitLinearW() subroutine.
            Following fields are set:
            * RMSError      rms error on the (X,Y).
            * AvgError      average error on the (X,Y).
            * AvgRelError   average relative error on the non-zero Y
            * MaxError      maximum error
                            NON-WEIGHTED ERRORS ARE CALCULATED

IMPORTANT:
    this subroitine doesn't calculate task's condition number for K<>0.

SETTING CONSTRAINTS - DANGERS AND OPPORTUNITIES:

Setting constraints can lead  to undesired  results,  like ill-conditioned
behavior, or inconsistency being detected. From the other side,  it allows
us to improve quality of the fit. Here we summarize  our  experience  with
constrained regression splines:
* even simple constraints can be inconsistent, see  Wikipedia  article  on
  this subject: http://en.wikipedia.org/wiki/Birkhoff_interpolation
* the  greater  is  M (given  fixed  constraints),  the  more chances that
  constraints will be consistent
* in the general case, consistency of constraints is NOT GUARANTEED.
* in the one special cases, however, we can  guarantee  consistency.  This
  case  is:  M>1  and constraints on the function values (NOT DERIVATIVES)

Our final recommendation is to use constraints  WHEN  AND  ONLY  when  you
can't solve your task without them. Anything beyond  special  cases  given
above is not guaranteed and may result in inconsistency.

  -- ALGLIB PROJECT --
     Copyright 10.12.2009 by Bochkanov Sergey
*************************************************************************/
void polynomialfitwc(ap::real_1d_array x,
     ap::real_1d_array y,
     const ap::real_1d_array& w,
     int n,
     ap::real_1d_array xc,
     ap::real_1d_array yc,
     const ap::integer_1d_array& dc,
     int k,
     int m,
     int& info,
     barycentricinterpolant& p,
     polynomialfitreport& rep)
{
    double xa;
    double xb;
    double sa;
    double sb;
    ap::real_1d_array xoriginal;
    ap::real_1d_array yoriginal;
    ap::real_1d_array y2;
    ap::real_1d_array w2;
    ap::real_1d_array tmp;
    ap::real_1d_array tmp2;
    ap::real_1d_array tmpdiff;
    ap::real_1d_array bx;
    ap::real_1d_array by;
    ap::real_1d_array bw;
    ap::real_2d_array fmatrix;
    ap::real_2d_array cmatrix;
    int i;
    int j;
    double mx;
    double decay;
    double u;
    double v;
    double s;
    int relcnt;
    lsfitreport lrep;

    if( m<1||n<1||k<0||k>=m )
    {
        info = -1;
        return;
    }
    for(i = 0; i <= k-1; i++)
    {
        info = 0;
        if( dc(i)<0 )
        {
            info = -1;
        }
        if( dc(i)>1 )
        {
            info = -1;
        }
        if( info<0 )
        {
            return;
        }
    }
    
    //
    // weight decay for correct handling of task which becomes
    // degenerate after constraints are applied
    //
    decay = 10000*ap::machineepsilon;
    
    //
    // Scale X, Y, XC, YC
    //
    lsfitscalexy(x, y, n, xc, yc, dc, k, xa, xb, sa, sb, xoriginal, yoriginal);
    
    //
    // allocate space, initialize/fill:
    // * FMatrix-   values of basis functions at X[]
    // * CMatrix-   values (derivatives) of basis functions at XC[]
    // * fill constraints matrix
    // * fill first N rows of design matrix with values
    // * fill next M rows of design matrix with regularizing term
    // * append M zeros to Y
    // * append M elements, mean(abs(W)) each, to W
    //
    y2.setlength(n+m);
    w2.setlength(n+m);
    tmp.setlength(m);
    tmpdiff.setlength(m);
    fmatrix.setlength(n+m, m);
    if( k>0 )
    {
        cmatrix.setlength(k, m+1);
    }
    
    //
    // Fill design matrix, Y2, W2:
    // * first N rows with basis functions for original points
    // * next M rows with decay terms
    //
    for(i = 0; i <= n-1; i++)
    {
        
        //
        // prepare Ith row
        // use Tmp for calculations to avoid multidimensional arrays overhead
        //
        for(j = 0; j <= m-1; j++)
        {
            if( j==0 )
            {
                tmp(j) = 1;
            }
            else
            {
                if( j==1 )
                {
                    tmp(j) = x(i);
                }
                else
                {
                    tmp(j) = 2*x(i)*tmp(j-1)-tmp(j-2);
                }
            }
        }
        ap::vmove(&fmatrix(i, 0), &tmp(0), ap::vlen(0,m-1));
    }
    for(i = 0; i <= m-1; i++)
    {
        for(j = 0; j <= m-1; j++)
        {
            if( i==j )
            {
                fmatrix(n+i,j) = decay;
            }
            else
            {
                fmatrix(n+i,j) = 0;
            }
        }
    }
    ap::vmove(&y2(0), &y(0), ap::vlen(0,n-1));
    ap::vmove(&w2(0), &w(0), ap::vlen(0,n-1));
    mx = 0;
    for(i = 0; i <= n-1; i++)
    {
        mx = mx+fabs(w(i));
    }
    mx = mx/n;
    for(i = 0; i <= m-1; i++)
    {
        y2(n+i) = 0;
        w2(n+i) = mx;
    }
    
    //
    // fill constraints matrix
    //
    for(i = 0; i <= k-1; i++)
    {
        
        //
        // prepare Ith row
        // use Tmp for basis function values,
        // TmpDiff for basos function derivatives
        //
        for(j = 0; j <= m-1; j++)
        {
            if( j==0 )
            {
                tmp(j) = 1;
                tmpdiff(j) = 0;
            }
            else
            {
                if( j==1 )
                {
                    tmp(j) = xc(i);
                    tmpdiff(j) = 1;
                }
                else
                {
                    tmp(j) = 2*xc(i)*tmp(j-1)-tmp(j-2);
                    tmpdiff(j) = 2*(tmp(j-1)+xc(i)*tmpdiff(j-1))-tmpdiff(j-2);
                }
            }
        }
        if( dc(i)==0 )
        {
            ap::vmove(&cmatrix(i, 0), &tmp(0), ap::vlen(0,m-1));
        }
        if( dc(i)==1 )
        {
            ap::vmove(&cmatrix(i, 0), &tmpdiff(0), ap::vlen(0,m-1));
        }
        cmatrix(i,m) = yc(i);
    }
    
    //
    // Solve constrained task
    //
    if( k>0 )
    {
        
        //
        // solve using regularization
        //
        lsfitlinearwc(y2, w2, fmatrix, cmatrix, n+m, m, k, info, tmp, lrep);
    }
    else
    {
        
        //
        // no constraints, no regularization needed
        //
        lsfitlinearwc(y, w, fmatrix, cmatrix, n, m, 0, info, tmp, lrep);
    }
    if( info<0 )
    {
        return;
    }
    
    //
    // Generate barycentric model and scale it
    // * BX, BY store barycentric model nodes
    // * FMatrix is reused (remember - it is at least MxM, what we need)
    //
    // Model intialization is done in O(M^2). In principle, it can be
    // done in O(M*log(M)), but before it we solved task with O(N*M^2)
    // complexity, so it is only a small amount of total time spent.
    //
    bx.setlength(m);
    by.setlength(m);
    bw.setlength(m);
    tmp2.setlength(m);
    s = 1;
    for(i = 0; i <= m-1; i++)
    {
        if( m!=1 )
        {
            u = cos(ap::pi()*i/(m-1));
        }
        else
        {
            u = 0;
        }
        v = 0;
        for(j = 0; j <= m-1; j++)
        {
            if( j==0 )
            {
                tmp2(j) = 1;
            }
            else
            {
                if( j==1 )
                {
                    tmp2(j) = u;
                }
                else
                {
                    tmp2(j) = 2*u*tmp2(j-1)-tmp2(j-2);
                }
            }
            v = v+tmp(j)*tmp2(j);
        }
        bx(i) = u;
        by(i) = v;
        bw(i) = s;
        if( i==0||i==m-1 )
        {
            bw(i) = 0.5*bw(i);
        }
        s = -s;
    }
    barycentricbuildxyw(bx, by, bw, m, p);
    barycentriclintransx(p, 2/(xb-xa), -(xa+xb)/(xb-xa));
    barycentriclintransy(p, sb-sa, sa);
    
    //
    // Scale absolute errors obtained from LSFitLinearW.
    // Relative error should be calculated separately
    // (because of shifting/scaling of the task)
    //
    rep.taskrcond = lrep.taskrcond;
    rep.rmserror = lrep.rmserror*(sb-sa);
    rep.avgerror = lrep.avgerror*(sb-sa);
    rep.maxerror = lrep.maxerror*(sb-sa);
    rep.avgrelerror = 0;
    relcnt = 0;
    for(i = 0; i <= n-1; i++)
    {
        if( ap::fp_neq(yoriginal(i),0) )
        {
            rep.avgrelerror = rep.avgrelerror+fabs(barycentriccalc(p, xoriginal(i))-yoriginal(i))/fabs(yoriginal(i));
            relcnt = relcnt+1;
        }
    }
    if( relcnt!=0 )
    {
        rep.avgrelerror = rep.avgrelerror/relcnt;
    }
}
void initialize_new_objects(mpi::communicator& world,
			    parameter_t const& P,  directory_structure_t const& ds,
			    geometric_info_t const& gi, object_info_t& oi,
			    vector<std::vector<std::string> > const &seq, int tt,
			    vector<CImg<unsigned char> > const& images,
			    vector<matrix<float> > const& grd,
			    vector<matrix<float> >& detected_rects)
{
    int Ncam = seq.size();
    vector<object_trj_t> & trlet_list=oi.trlet_list;
    int nobj = trlet_list.size();
    int num_new_obj = detected_rects(0).size1();
    int T = seq[0].size();
    int np = oi.model.size();

    int num_scales = P.scales.size();

    //std::cout<<"detected_rects="<<detected_rects<<std::endl;

    for(int oo=0; oo<num_new_obj; ++oo)
    {
	int nn = oi.curr_num_obj + oo;

	trlet_list(nn).startt = tt;
	trlet_list(nn).endt = tt;
	trlet_list(nn).state = 1;
	trlet_list(nn).trj = vector<matrix<float> >(Ncam);
	for(int cam=0; cam<Ncam; ++cam)
	{
	    trlet_list(nn).trj(cam) = scalar_matrix<float>(T, 4, 0);
	}
	trlet_list(nn).trj_3d = scalar_matrix<float>(T, 2, 0);

	trlet_list(nn).hist_p = vector<matrix<float> >(Ncam);
	trlet_list(nn).hist_q = vector<matrix<float> >(Ncam);

	trlet_list(nn).fscores = vector<matrix<float> >(Ncam);
	trlet_list(nn).scores = scalar_matrix<float>(Ncam, T, 0);

	vector<candidate_array<Float> > cand_array(Ncam);
	for(int cam=0; cam<Ncam; ++cam)
	{

	    trlet_list(nn).fscores(cam) = scalar_matrix<float>(np*2, T, 0);

	    float w = detected_rects(cam)(oo, 2)-detected_rects(cam)(oo, 0);
	    float h = detected_rects(cam)(oo, 3)-detected_rects(cam)(oo, 1);
	    row(trlet_list(nn).trj(cam), tt) = row(detected_rects(cam), oo);

	    matrix<float> rects;
	    compute_part_rects(detected_rects(cam)(oo, 0), detected_rects(cam)(oo, 1),
			  w, h, oi.model, rects);

	    pmodel_t pmodel;

	    vector<float> br(row(detected_rects(cam), oo));
	    rects_to_pmodel_geom(br, gi.horiz_mean, pmodel);
	    oi.pmodel_list(cam, nn) = pmodel;

	    //collect_sift(grd(cam), );
	    matrix<float> hist_p, hist_q;
	    collect_hist(images(cam), rects, hist_p, hist_q);
	    trlet_list(nn).hist_p(cam) = hist_p;
	    trlet_list(nn).hist_q(cam) = hist_q;

	    matrix<Float> cand_rects;
	    vector<Float> cand_scale;
	    matrix<int> cand_ijs;

	    if(0==world.rank())
	    {

		std::vector<float> sxr, syr;
		for(float v=-P.xrange/2; v<=P.xrange/2; v+=P.xstep)
		{
		    sxr.push_back(v);
		}
		for(float v=-P.yrange/2; v<=P.yrange/2; v+=P.ystep)
		{
		    syr.push_back(v);
		}
		vector<float> xr(sxr.size()), yr(syr.size());
		std::copy(sxr.begin(), sxr.end(), xr.begin());
		std::copy(syr.begin(), syr.end(), yr.begin());

		float feetx = (trlet_list(nn).trj(cam)(tt, 0)
			       +trlet_list(nn).trj(cam)(tt, 2))/2;
		float feety = trlet_list(nn).trj(cam)(tt, 3);


		enumerate_rects_inpoly(images(cam), oi.pmodel_list(cam, nn),
				       feetx, feety,
				       xr, yr, P.scales, gi.horiz_mean, gi.horiz_sig,
				       gi.polys_im(tt, cam),
				       cand_rects, cand_scale,
				       cand_ijs, cand_array(cam));

	    }

	    mpi::broadcast(world, cand_rects, 0);

	    real_timer_t timer;
	    vector<Float> cand_hist_score(cand_rects.size1());
	    matrix<Float> hist_fscores;

	    range rrank(world.rank()*cand_rects.size1()/world.size(), 
			(world.rank()+1)*cand_rects.size1()/world.size());
	    matrix<Float> cand_rects_rank(project(cand_rects, rrank, range(0, 4)));
	    vector<Float> cand_hist_score_rank;
	    matrix<Float> hist_fscores_rank;
	    get_cand_hist_score(images(cam), oi.model, P.logp1, P.logp2,
				trlet_list(nn).hist_p(cam),
				trlet_list(nn).hist_q(cam),
				cand_rects_rank,
				cand_hist_score_rank, hist_fscores_rank);
	    if(world.rank()==0)
	    {
		std::vector<vector<Float> > v1;
		std::vector<matrix<Float> > v2;
		mpi::gather(world, cand_hist_score_rank, v1, 0);
		mpi::gather(world, hist_fscores_rank, v2, 0);
		hist_fscores = matrix<Float>(cand_rects.size1(),
					     hist_fscores_rank.size2());
		for(int r=0; r<world.size(); ++r)
		{
		    int start = r*cand_rects.size1()/world.size();
		    for(int vv=0; vv<v1[r].size(); ++vv)
		    {
			cand_hist_score(start+vv) = v1[r](vv);
		    }
		    for(int vv=0; vv<v2[r].size1(); ++vv)
		    {
			row(hist_fscores, start+vv) = row(v2[r], vv);
		    }
		}
	    }
	    else
	    {
		mpi::gather(world, cand_hist_score_rank, 0);
		mpi::gather(world, hist_fscores_rank, 0);
	    }

	    mpi::broadcast(world, cand_hist_score, 0);
	    mpi::broadcast(world, hist_fscores, 0);


	    vector<Float> cand_score=cand_hist_score;
	    if(0==world.rank())
	    std::cout<<"\t\t"<<cand_rects.size1()<<" rects, \tget_cand_hist_score time:"
		     <<timer.elapsed()/1000.0f<<"s."<<std::endl;

	    if(0==world.rank())
	    {
		int idx_max = std::max_element(cand_score.begin(), cand_score.end())
		    - cand_score.begin();

		column(trlet_list(nn).fscores(cam), tt) = row(hist_fscores, idx_max);
		trlet_list(nn).scores(cam, tt) = cand_score(idx_max);
		cand_array(cam).fill_score(cand_score, cand_ijs);
	    }
	    mpi::broadcast(world, cand_array(cam), 0);
	    mpi::broadcast(world, trlet_list(nn).scores(cam, tt), 0);
	    vector<Float> fscore_col;
	    if(0==world.rank())
	    {
		fscore_col = column(trlet_list(nn).fscores(cam), tt);
	    }
	    mpi::broadcast(world, fscore_col, 0);
	    if(0!=world.rank())
	    {
		column(trlet_list(nn).fscores(cam), tt) = fscore_col;
	    }


	}//end for cam

	int best_y, best_x, best_s;
	if(0==world.rank())
	{
	    ground_scoremap_t<Float> grd_scoremap;
	    combine_ground_score(tt, cand_array, grd_scoremap, gi);
	    grd_scoremap.peak(best_y, best_x, best_s);	
	}
	mpi::broadcast(world, best_y, 0);
	mpi::broadcast(world, best_x, 0);

	trlet_list(nn).trj_3d(tt, 0) = best_x;
	trlet_list(nn).trj_3d(tt, 1) = best_y;

	for(int cam=0; cam<Ncam; ++cam)
	{
	    vector<Float> trj_row(4);

	    if(0==world.rank())
	    {
		vector<double> bx(1), by(1), ix, iy;
		bx <<= best_x; by <<= best_y;
		apply_homography(gi.grd2img(tt, cam), bx, by, ix, iy);
		float hpre = oi.pmodel_list(cam, nn).hpre;
		float cur_fy = iy(0);
		float cur_fx = ix(0);
		float cur_hy = gi.horiz_mean+hpre*(cur_fy-gi.horiz_mean);
		float ds = P.scales(best_s)*(cur_fy-cur_hy)/oi.pmodel_list(cam, nn).bh;
		float ww = ds*oi.pmodel_list(cam, nn).bw;
		float hh = cur_fy - cur_hy;

		trj_row <<= (cur_fx-ww/2), cur_hy, (cur_fx+ww/2), cur_fy;
	    }
	    mpi::broadcast(world, trj_row, 0);
	    row(trlet_list(nn).trj(cam), tt) = trj_row;


	}//endfor cam

    }//endfor oo

    oi.curr_num_obj += num_new_obj;
}
Exemple #17
0
  void System::Problem_generate_IC(const int param)
  {
    if (thisIndex == 0)
    {
      CkPrintf(" ********* Cloud capture ************* \n");
      CkPrintf(" **** MAGNETISATION=%g     \n", MAGNETISATION);
      CkPrintf(" **** H/R          =%g     \n", HoR  );
      CkPrintf(" **** GRAVITY_MASS= %g     \n", GM);
      CkPrintf(" **** GRAVITY_EPS=  %g     \n", GM_EPS);
      CkPrintf(" ---  \n");	
    }

    gamma_gas  = 1.0;
    courant_no = 0.8;

    t_global  = 0;
    iteration = 0;

    const real xcl = XCL;
    const real ycl = YCL;

    const real vx_cl = VX0/VUNIT;
    const real vy_cl = VY0/VUNIT;

    const real vorb  = std::sqrt(sqr(vx_cl) + sqr(vy_cl));
    const real Rinit = std::sqrt(sqr(xcl)   + sqr(ycl)  );

    const real tinfall = Rinit/vorb;

    const real dcl = (DCLOUD/DUNIT);
    const real cs2 = get_cs2(vec3(xcl, ycl, 0.0)); //TCLOUD*Tunit/sqr(vunit);

    if (thisIndex == 0)
    {
      CkPrintf("Ro= %g pc, x= %g  y= %g; vx= %g vy= %g vt= %g  tinfall= %g Myr [%g]\n",
          Rinit,
          xcl, ycl,
          vx_cl, vy_cl,
          vorb,
          tinfall * TIMEUNIT, tinfall);
    }


    for (int i = 0; i < local_n; i++) 
    {
      const Particle &pi = ptcl_list[i];

      const vec3 &pos = pi.get_pos();

      if (pos.abs() < BND_RADIUS || pos.abs() > RoutBND)
        mesh_pnts[i].boundary = MeshPoint::DIOD;
      else  
        mesh_pnts[i].boundary = MeshPoint::NO_BOUNDARY;

      const real Rdist = (pos - vec3(xcl, ycl, 0.0)).abs();
      const real inv_beta = MAGNETISATION;

      real dens = dcl;
      real pres = dcl * cs2;
      real b0   = std::sqrt(2.0*pres * inv_beta);

      real bx(0), by(0), bz(0);

#if 0
      bx = by = b0/sqrt(2.0);
#else
      bx = by = bz = b0/sqrt(3.0);
#endif

      real vx(vx_cl), vy(vy_cl), vz(0.0);

      real scalar = 1.0;
      if (Rdist > RCLOUD)
      {
        dens = DENSvac/DUNIT;
        const real csig = std::sqrt(get_cs2(pos));
        vx = (1 - 2.0*drand48()) * csig;
        vy = (1 - 2.0*drand48()) * csig;
        vz = (1 - 2.0*drand48()) * csig;
        scalar = -1.0;
      }
      Fluid m;

      m[Fluid::DENS] = dens;
      m[Fluid::ETHM] = get_cs2(pos)*dens;
      m[Fluid::VELX] = vx;
      m[Fluid::VELY] = vy;
      m[Fluid::VELZ] = vz;
      m[Fluid::BX  ] = bx;
      m[Fluid::BY  ] = by;
      m[Fluid::BZ  ] = bz;
      m[Fluid::PSI ] = 0.0;
      m[Fluid::ENTR] = 1.0;

      Wrec_list[i] = Fluid_rec(m);

      mesh_pnts[i].idx  = thisIndex*1000000 + i+1;

    }
  }
void
generate_texture_patches(UniGraph const & graph, std::vector<TextureView> const & texture_views,
    mve::TriangleMesh::ConstPtr mesh, mve::VertexInfoList::ConstPtr vertex_infos,
    std::vector<std::vector<VertexProjectionInfo> > * vertex_projection_infos,
    std::vector<TexturePatch> * texture_patches) {

    util::WallTimer timer;

    mve::TriangleMesh::FaceList const & mesh_faces = mesh->get_faces();
    mve::TriangleMesh::VertexList const & vertices = mesh->get_vertices();
    vertex_projection_infos->resize(vertices.size());

    std::size_t num_patches = 0;

    std::cout << "\tRunning... " << std::flush;
    #pragma omp parallel for schedule(dynamic)
    for (std::size_t i = 0; i < texture_views.size(); ++i) {

        std::vector<std::vector<std::size_t> > subgraphs;
        int const label = i + 1;
        graph.get_subgraphs(label, &subgraphs);

        std::list<TexturePatchCandidate> candidates;
        for (std::size_t j = 0; j < subgraphs.size(); ++j) {
            candidates.push_back(generate_candidate(label, texture_views[i], subgraphs[j], mesh));
        }

        /* Merge candidates which contain the same image content. */
        std::list<TexturePatchCandidate>::iterator it, sit;
        for (it = candidates.begin(); it != candidates.end(); ++it) {
            for (sit = candidates.begin(); sit != candidates.end();) {
                Rect<int> bounding_box = sit->bounding_box;
                if (it != sit && bounding_box.is_inside(&it->bounding_box)) {
                    TexturePatch::Faces & faces = it->texture_patch.get_faces();
                    TexturePatch::Faces & ofaces = sit->texture_patch.get_faces();
                    faces.insert(faces.end(), ofaces.begin(), ofaces.end());

                    TexturePatch::Texcoords & texcoords = it->texture_patch.get_texcoords();
                    TexturePatch::Texcoords & otexcoords = sit->texture_patch.get_texcoords();
                    math::Vec2f offset;
                    offset[0] = sit->bounding_box.min_x - it->bounding_box.min_x;
                    offset[1] = sit->bounding_box.min_y - it->bounding_box.min_y;
                    for (std::size_t i = 0; i < otexcoords.size(); ++i) {
                        texcoords.push_back(otexcoords[i] + offset);
                    }

                    sit = candidates.erase(sit);
                } else {
                    ++sit;
                }
            }
        }

        it = candidates.begin();
        for (; it != candidates.end(); ++it) {
            std::size_t texture_patch_id;

            #pragma omp critical
            {
                texture_patches->push_back(it->texture_patch);
                texture_patch_id = num_patches++;
            }

            std::vector<std::size_t> const & faces = it->texture_patch.get_faces();
            std::vector<math::Vec2f> const & texcoords = it->texture_patch.get_texcoords();
            for (std::size_t i = 0; i < faces.size(); ++i) {
                std::size_t const face_id = faces[i];
                std::size_t const face_pos = face_id * 3;
                for (std::size_t j = 0; j < 3; ++j) {
                    std::size_t const vertex_id = mesh_faces[face_pos  + j];
                    math::Vec2f const projection = texcoords[i * 3 + j];

                    VertexProjectionInfo info = {texture_patch_id, projection, {face_id}};

                    #pragma omp critical
                    vertex_projection_infos->at(vertex_id).push_back(info);
                }
            }
        }
    }

    merge_vertex_projection_infos(vertex_projection_infos);

    std::size_t num_holes = 0;
    std::size_t num_hole_faces = 0;

    //if (!settings.skip_hole_filling) {
    {
        std::vector<std::vector<std::size_t> > subgraphs;
        graph.get_subgraphs(0, &subgraphs);

        #pragma omp parallel for schedule(dynamic)
        for (std::size_t i = 0; i < subgraphs.size(); ++i) {
            std::vector<std::size_t> const & subgraph = subgraphs[i];

            std::map<std::size_t, std::set<std::size_t> > tmp;
            for (std::size_t const face_id : subgraph) {
                std::size_t const v0 = mesh_faces[face_id * 3];
                std::size_t const v1 = mesh_faces[face_id * 3 + 1];
                std::size_t const v2 = mesh_faces[face_id * 3 + 2];
                tmp[v0].insert(face_id);
                tmp[v1].insert(face_id);
                tmp[v2].insert(face_id);
            }

            std::size_t const num_vertices = tmp.size();
            /* Only fill small holes. */
            if (num_vertices > 100) {
                //std::cerr << "Hole to large" << std::endl;
                continue;
            }


            /* Calculate 2D parameterization using the technique from libremesh/patch2d,
             * which was published as sourcecode accompanying the following paper:
             *
             * Isotropic Surface Remeshing
             * Simon Fuhrmann, Jens Ackermann, Thomas Kalbe, Michael Goesele
             */

            std::size_t seed = -1;
            std::vector<bool> is_border(num_vertices, false);
            std::vector<std::vector<std::size_t> > adj_verts_via_border(num_vertices);
            /* Index structures to map from local <-> global vertex id. */
            std::map<std::size_t, std::size_t> g2l;
            std::vector<std::size_t> l2g(num_vertices);
            /* Index structure to determine column in matrix/vector. */
            std::vector<std::size_t> idx(num_vertices);

            std::size_t num_border_vertices = 0;

            bool disk_topology = true;
            std::map<std::size_t, std::set<std::size_t> >::iterator it = tmp.begin();
            for (std::size_t j = 0; j < num_vertices; ++j, ++it) {
                std::size_t vertex_id = it->first;
                g2l[vertex_id] = j;
                l2g[j] = vertex_id;

                /* Check topology in original mesh. */
                if (vertex_infos->at(vertex_id).vclass != mve::VERTEX_CLASS_SIMPLE) {
                    //std::cerr << "Complex/Border vertex in original mesh" << std::endl;
                    disk_topology = false;
                    break;
                }

                /* Check new topology and determine if vertex is now at the border. */
                std::vector<std::size_t> const & adj_faces = vertex_infos->at(vertex_id).faces;
                std::set<std::size_t> const & adj_hole_faces = it->second;
                std::vector<std::pair<std::size_t, std::size_t> > fan;
                for (std::size_t k = 0; k < adj_faces.size(); ++k) {
                    std::size_t adj_face = adj_faces[k];
                    if (graph.get_label(adj_faces[k]) == 0 &&
                        adj_hole_faces.find(adj_face) != adj_hole_faces.end()) {
                        std::size_t curr = adj_faces[k];
                        std::size_t next = adj_faces[(k + 1) % adj_faces.size()];
                        std::pair<std::size_t, std::size_t> pair(curr, next);
                        fan.push_back(pair);
                    }
                }

                std::size_t gaps = 0;
                for (std::size_t k = 0; k < fan.size(); k++) {
                    std::size_t curr = fan[k].first;
                    std::size_t next = fan[(k + 1) % fan.size()].first;
                    if (fan[k].second != next) {
                        ++gaps;

                        for (std::size_t l = 0; l < 3; ++l) {
                            if(mesh_faces[curr * 3 + l] == vertex_id) {
                                std::size_t second = mesh_faces[curr * 3 + (l + 2) % 3];
                                adj_verts_via_border[j].push_back(second);
                            }
                            if(mesh_faces[next * 3 + l] == vertex_id) {
                                std::size_t first = mesh_faces[next * 3 + (l + 1) % 3];
                                adj_verts_via_border[j].push_back(first);
                            }
                        }
                    }
                }

                is_border[j] = gaps == 1;

                /* Check if vertex is now complex. */
                if (gaps > 1) {
                    //std::cerr << "Complex vertex in hole" << std::endl;
                    disk_topology = false;
                    break;
                }

                if (is_border[j]) {
                    idx[j] = num_border_vertices++;
                    seed = vertex_id;
                } else {
                    idx[j] = j - num_border_vertices;
                }
            }
            tmp.clear();

            if (!disk_topology) continue;
            if (num_border_vertices == 0) {
                //std::cerr << "Genus zero topology" << std::endl;
                continue;
            }

            std::vector<std::size_t> border; border.reserve(num_border_vertices);
            std::size_t prev = seed;
            std::size_t curr = seed;
            while (prev == seed || curr != seed) {
                std::size_t next = std::numeric_limits<std::size_t>::max();
                std::vector<std::size_t> const & adj_verts = adj_verts_via_border[g2l[curr]];
                for (std::size_t adj_vert : adj_verts) {
                    assert(is_border[g2l[adj_vert]]);
                    if (adj_vert != prev && adj_vert != curr) {
                        next = adj_vert;
                        break;
                    }
                }
                if (next != std::numeric_limits<std::size_t>::max()) {
                    prev = curr;
                    curr = next;
                    border.push_back(next);
                } else {
                    //std::cerr << "No new border vertex" << std::endl;
                    border.clear();
                    break;
                }

                if (border.size() > num_border_vertices) {
                    //std::cerr << "Loop within border" << std::endl;
                    break;
                }
            }

            if (border.size() != num_border_vertices) {
                continue;
            }

            float total_length = 0.0f;
            float total_projection_length = 0.0f;
            for (std::size_t j = 0; j < border.size(); ++j) {
                std::size_t vi0 = border[j];
                std::size_t vi1 = border[(j + 1) % border.size()];
                std::vector<VertexProjectionInfo> const & vpi0 = vertex_projection_infos->at(vi0);
                std::vector<VertexProjectionInfo> const & vpi1 = vertex_projection_infos->at(vi0);
                /* According to the previous checks (vertex class within the origial
                 * mesh and boundary) there already has to be at least one projection
                 * of each border vertex. */
                assert(!vpi0.empty() && !vpi1.empty());
                math::Vec2f vp0(0.0f), vp1(0.0f);
                for (VertexProjectionInfo const & info0 : vpi0) {
                    for (VertexProjectionInfo const & info1 : vpi1) {
                        if (info0.texture_patch_id == info1.texture_patch_id) {
                            vp0 = info0.projection;
                            vp1 = info1.projection;
                            break;
                        }
                    }
                }
                total_projection_length += (vp0 - vp1).norm();
                math::Vec3f const & v0 = vertices[vi0];
                math::Vec3f const & v1 = vertices[vi1];
                total_length += (v0 - v1).norm();
            }
            float radius = total_projection_length / (2.0f * MATH_PI);

            float length = 0.0f;
            std::vector<math::Vec2f> projections(num_vertices);
            for (std::size_t j = 0; j < border.size(); ++j) {
                float angle = 2.0f * MATH_PI * (length / total_length);
                projections[g2l[border[j]]] = math::Vec2f(std::cos(angle), std::sin(angle));
                math::Vec3f const & v0 = vertices[border[j]];
                math::Vec3f const & v1 = vertices[border[(j + 1) % border.size()]];
                length += (v0 - v1).norm();
            }

            typedef Eigen::Triplet<float, int> Triplet;
            std::vector<Triplet> coeff;
            std::size_t matrix_size = num_vertices - border.size();

            Eigen::VectorXf xx(matrix_size), xy(matrix_size);

            if (matrix_size != 0) {
                Eigen::VectorXf bx(matrix_size);
                Eigen::VectorXf by(matrix_size);
                for (std::size_t j = 0; j < num_vertices; ++j) {
                    if (is_border[j]) continue;

                    std::size_t const vertex_id = l2g[j];

                    /* Calculate "Mean Value Coordinates" as proposed by Michael S. Floater */
                    std::map<std::size_t, float> weights;
                    std::vector<std::size_t> const & adj_faces = vertex_infos->at(vertex_id).faces;
                    for (std::size_t adj_face : adj_faces) {
                        std::size_t v0 = mesh_faces[adj_face * 3];
                        std::size_t v1 = mesh_faces[adj_face * 3 + 1];
                        std::size_t v2 = mesh_faces[adj_face * 3 + 2];
                        if (v1 == vertex_id) std::swap(v1, v0);
                        if (v2 == vertex_id) std::swap(v2, v0);

                        math::Vec3f v01 = vertices[v1] - vertices[v0];
                        float v01n = v01.norm();
                        math::Vec3f v02 = vertices[v2] - vertices[v0];
                        float v02n = v02.norm();
                        float alpha = std::acos(v01.dot(v02) / (v01n * v02n));
                        weights[g2l[v1]] += std::tan(alpha / 2.0f) / v01n;
                        weights[g2l[v2]] += std::tan(alpha / 2.0f) / v02n;
                    }

                    std::map<std::size_t, float>::iterator it;
                    float sum = 0.0f;
                    for (it = weights.begin(); it != weights.end(); ++it)
                        sum += it->second;
                    for (it = weights.begin(); it != weights.end(); ++it)
                        it->second /= sum;

                    bx[idx[j]] = 0.0f;
                    by[idx[j]] = 0.0f;
                    for (it = weights.begin(); it != weights.end(); ++it) {
                        if (is_border[it->first]) {
                            std::size_t border_vertex_id = border[idx[it->first]];
                            bx[idx[j]] += projections[g2l[border_vertex_id]][0] * it->second;
                            by[idx[j]] += projections[g2l[border_vertex_id]][1] * it->second;
                        } else {
                            coeff.push_back(Triplet(idx[j], idx[it->first], -it->second));
                        }
                    }
                }
                for (std::size_t j = 0; j < matrix_size; ++j) {
                    coeff.push_back(Triplet(j, j, 1.0f));
                }

                typedef Eigen::SparseMatrix<float> SpMat;
                SpMat A(matrix_size, matrix_size);
                A.setFromTriplets(coeff.begin(), coeff.end());

                Eigen::SparseLU<SpMat> solver;
                solver.analyzePattern(A);
                solver.factorize(A);
                xx = solver.solve(bx);
                xy = solver.solve(by);
            }

            int image_size = std::floor(radius * 1.1f) * 2 + 4;
            int scale = image_size / 2 - texture_patch_border;
            for (std::size_t j = 0, k = 0; j < num_vertices; ++j) {
                if (!is_border[j]) {
                    projections[j] = math::Vec2f(xx[k], xy[k]) * scale + image_size / 2;
                    ++k;
                } else {
                    projections[j] = projections[j] * scale + image_size / 2;
                }
            }

            mve::ByteImage::Ptr image = mve::ByteImage::create(image_size, image_size, 3);
            //DEBUG image->fill_color(*math::Vec4uc(0, 255, 0, 255));
            std::vector<math::Vec2f> texcoords; texcoords.reserve(subgraph.size());
            for (std::size_t const face_id : subgraph) {
                for (std::size_t j = 0; j < 3; ++j) {
                    std::size_t const vertex_id = mesh_faces[face_id * 3 + j];
                    math::Vec2f const & projection = projections[g2l[vertex_id]];
                    texcoords.push_back(projection);
                }
            }
            TexturePatch texture_patch(0, subgraph, texcoords, image);
            std::size_t texture_patch_id;
            #pragma omp critical
            {
                texture_patches->push_back(texture_patch);
                texture_patch_id = num_patches++;

                num_hole_faces += subgraph.size();
                ++num_holes;
            }

            for (std::size_t j = 0; j < num_vertices; ++j) {
                std::size_t const vertex_id = l2g[j];
                std::vector<std::size_t> const & adj_faces = vertex_infos->at(vertex_id).faces;
                std::vector<std::size_t> faces; faces.reserve(adj_faces.size());
                for (std::size_t adj_face : adj_faces) {
                    if (graph.get_label(adj_face) == 0) {
                        faces.push_back(adj_face);
                    }
                }
                VertexProjectionInfo info = {texture_patch_id, projections[j], faces};
                #pragma omp critical
                vertex_projection_infos->at(vertex_id).push_back(info);
            }
        }
    }

    merge_vertex_projection_infos(vertex_projection_infos);

    std::cout << "done. (Took " << timer.get_elapsed_sec() << "s)" << std::endl;
    std::cout << "\t" << num_patches << " texture patches." << std::endl;
    std::cout << "\t" << num_holes << " holes (" << num_hole_faces << " faces)." << std::endl;
}
Exemple #19
0
void AcIndex::Search(const AcRequest &req, AcResult &resp) {
    Watch watch;
    ByAlphabet by(this->data);
    auto rewrite = this->queryRewrite(req.q);
    auto q = rewrite.first;
    auto low = indexes.begin(), hi = indexes.end();
    bool check = rewrite.second;

    if (q.size() > 0) {
        low = std::lower_bound(indexes.begin(), indexes.end(), q.data(), by);
        hi = std::lower_bound(indexes.begin(), indexes.end(), one_greater(q).data(), by);
    } else {
        check = false;
    }

    bool accurate = hi - low < 200000;
    dense_int_set counter(accurate ? hi - low : 10);
    size_t how_many = req.limit + req.offset;
    hit_queue<AcIndexItem> pq(how_many);

    for (auto it = low; it != hi; it++) {
        if (pq.Replace(*it)) {   // save value, but with a higher score
            continue;
        }

        if (check && strstr(data.Get(it->check), req.q.data()) == NULL) {
            continue;
        }

        if (accurate) { counter.insert(it->show); }
        resp.hits += 1;
        pq.UpdateTop(*it);
    }

    // pop all the sentinel elements (there are pq.size() - totalHits).
    for (int i = how_many - resp.hits; i > 0; i--) {
        pq.Pop();
    }

    if (how_many > resp.hits) {
        how_many = resp.hits;
    }

    std::vector<AcIndexItem> tmp(how_many);
    for (int i = how_many - 1; i >= 0; i--) {
        tmp[i] = pq.Pop();
    }
    // printf("total hits %ld, fast: %d, how_many: %d\n", total_hits, fast, how_many);
    size_t skip = 0;
    for (size_t i = 0; i < how_many; i++) {
        auto it = tmp[i];

        skip += 1;
        if (req.offset >= skip) {
            continue;
        }

        auto data = this->data.Get(it.show);
        resp.items.emplace_back(data, it.score, this->highlight(data, q));
        if (resp.items.size() >= req.limit) {
            break;
        }
    }

    if (accurate) {
        resp.hits = counter.size();
    } else {
        resp.hits /= 6;         // not accurate, just estimation
    }

    log_info("%s %d/%d %s=>a%d/c%d/%s, hit %d/%d/%d, %.1fms",
            name.data(), req.limit, req.offset,
            req.q.data(), accurate, check, q.data(),
            how_many, resp.hits, hi - low,
            watch.Tick());
}
zx_status_t PagerSource::WaitOnEvent(event_t* event) {
    ThreadDispatcher::AutoBlocked by(ThreadDispatcher::Blocked::PAGER);
    return event_wait_deadline(event, ZX_TIME_INFINITE, true);
}
bool fill_hole(std::vector<std::size_t> const & hole, UniGraph const & graph,
    mve::TriangleMesh::ConstPtr mesh, mve::MeshInfo const & mesh_info,
    std::vector<std::vector<VertexProjectionInfo> > * vertex_projection_infos,
    std::vector<TexturePatch::Ptr> * texture_patches) {

    mve::TriangleMesh::FaceList const & mesh_faces = mesh->get_faces();
    mve::TriangleMesh::VertexList const & vertices = mesh->get_vertices();

    std::map<std::size_t, std::set<std::size_t> > tmp;
    for (std::size_t const face_id : hole) {
        std::size_t const v0 = mesh_faces[face_id * 3];
        std::size_t const v1 = mesh_faces[face_id * 3 + 1];
        std::size_t const v2 = mesh_faces[face_id * 3 + 2];

        tmp[v0].insert(face_id);
        tmp[v1].insert(face_id);
        tmp[v2].insert(face_id);
    }

    std::size_t const num_vertices = tmp.size();
    /* Only fill small holes. */
    if (num_vertices > MAX_HOLE_NUM_FACES) return false;

    /* Calculate 2D parameterization using the technique from libremesh/patch2d,
     * which was published as sourcecode accompanying the following paper:
     *
     * Isotropic Surface Remeshing
     * Simon Fuhrmann, Jens Ackermann, Thomas Kalbe, Michael Goesele
     */

    std::size_t seed = -1;
    std::vector<bool> is_border(num_vertices, false);
    std::vector<std::vector<std::size_t> > adj_verts_via_border(num_vertices);
    /* Index structures to map from local <-> global vertex id. */
    std::map<std::size_t, std::size_t> g2l;
    std::vector<std::size_t> l2g(num_vertices);
    /* Index structure to determine column in matrix/vector. */
    std::vector<std::size_t> idx(num_vertices);

    std::size_t num_border_vertices = 0;

    bool disk_topology = true;
    std::map<std::size_t, std::set<std::size_t> >::iterator it = tmp.begin();
    for (std::size_t j = 0; j < num_vertices; ++j, ++it) {
        std::size_t vertex_id = it->first;
        g2l[vertex_id] = j;
        l2g[j] = vertex_id;

        /* Check topology in original mesh. */
        if (mesh_info[vertex_id].vclass != mve::MeshInfo::VERTEX_CLASS_SIMPLE) {
            /* Complex/Border vertex in original mesh */
            disk_topology = false;
            break;
        }

        /* Check new topology and determine if vertex is now at the border. */
        std::vector<std::size_t> const & adj_faces = mesh_info[vertex_id].faces;
        std::set<std::size_t> const & adj_hole_faces = it->second;
        std::vector<std::pair<std::size_t, std::size_t> > fan;
        for (std::size_t k = 0; k < adj_faces.size(); ++k) {
            std::size_t adj_face = adj_faces[k];
            if (graph.get_label(adj_faces[k]) == 0 &&
                adj_hole_faces.find(adj_face) != adj_hole_faces.end()) {
                std::size_t curr = adj_faces[k];
                std::size_t next = adj_faces[(k + 1) % adj_faces.size()];
                std::pair<std::size_t, std::size_t> pair(curr, next);
                fan.push_back(pair);
            }
        }

        std::size_t gaps = 0;
        for (std::size_t k = 0; k < fan.size(); k++) {
            std::size_t curr = fan[k].first;
            std::size_t next = fan[(k + 1) % fan.size()].first;
            if (fan[k].second != next) {
                ++gaps;

                for (std::size_t l = 0; l < 3; ++l) {
                    if(mesh_faces[curr * 3 + l] == vertex_id) {
                        std::size_t second = mesh_faces[curr * 3 + (l + 2) % 3];
                        adj_verts_via_border[j].push_back(second);
                    }
                    if(mesh_faces[next * 3 + l] == vertex_id) {
                        std::size_t first = mesh_faces[next * 3 + (l + 1) % 3];
                        adj_verts_via_border[j].push_back(first);
                    }
                }
            }
        }

        is_border[j] = gaps == 1;

        /* Check if vertex is now complex. */
        if (gaps > 1) {
            /* Complex vertex in hole */
            disk_topology = false;
            break;
        }

        if (is_border[j]) {
            idx[j] = num_border_vertices++;
            seed = vertex_id;
        } else {
            idx[j] = j - num_border_vertices;
        }
    }
    tmp.clear();

    /* No disk or genus zero topology */
    if (!disk_topology || num_border_vertices == 0) return false;

    std::vector<std::size_t> border; border.reserve(num_border_vertices);
    std::size_t prev = seed;
    std::size_t curr = seed;
    while (prev == seed || curr != seed) {
        std::size_t next = std::numeric_limits<std::size_t>::max();
        std::vector<std::size_t> const & adj_verts = adj_verts_via_border[g2l[curr]];
        for (std::size_t adj_vert : adj_verts) {
            assert(is_border[g2l[adj_vert]]);
            if (adj_vert != prev && adj_vert != curr) {
                next = adj_vert;
                break;
            }
        }
        if (next != std::numeric_limits<std::size_t>::max()) {
            prev = curr;
            curr = next;
            border.push_back(next);
        } else {
            /* No new border vertex */
            border.clear();
            break;
        }

        /* Loop within border */
        if (border.size() > num_border_vertices) break;
    }

    if (border.size() != num_border_vertices) return false;

    float total_length = 0.0f;
    float total_projection_length = 0.0f;
    for (std::size_t j = 0; j < border.size(); ++j) {
        std::size_t vi0 = border[j];
        std::size_t vi1 = border[(j + 1) % border.size()];
        std::vector<VertexProjectionInfo> const & vpi0 = vertex_projection_infos->at(vi0);
        std::vector<VertexProjectionInfo> const & vpi1 = vertex_projection_infos->at(vi0);
        /* According to the previous checks (vertex class within the origial
         * mesh and boundary) there already has to be at least one projection
         * of each border vertex. */
        assert(!vpi0.empty() && !vpi1.empty());
        math::Vec2f vp0(0.0f), vp1(0.0f);
        for (VertexProjectionInfo const & info0 : vpi0) {
            for (VertexProjectionInfo const & info1 : vpi1) {
                if (info0.texture_patch_id == info1.texture_patch_id) {
                    vp0 = info0.projection;
                    vp1 = info1.projection;
                    break;
                }
            }
        }
        total_projection_length += (vp0 - vp1).norm();
        math::Vec3f const & v0 = vertices[vi0];
        math::Vec3f const & v1 = vertices[vi1];
        total_length += (v0 - v1).norm();
    }
    float radius = total_projection_length / (2.0f * MATH_PI);

    if (total_length < std::numeric_limits<float>::epsilon()) return false;

    float length = 0.0f;
    std::vector<math::Vec2f> projections(num_vertices);
    for (std::size_t j = 0; j < border.size(); ++j) {
        float angle = 2.0f * MATH_PI * (length / total_length);
        projections[g2l[border[j]]] = math::Vec2f(std::cos(angle), std::sin(angle));
        math::Vec3f const & v0 = vertices[border[j]];
        math::Vec3f const & v1 = vertices[border[(j + 1) % border.size()]];
        length += (v0 - v1).norm();
    }

    typedef Eigen::Triplet<float, int> Triplet;
    std::vector<Triplet> coeff;
    std::size_t matrix_size = num_vertices - border.size();

    Eigen::VectorXf xx(matrix_size), xy(matrix_size);

    if (matrix_size != 0) {
        Eigen::VectorXf bx(matrix_size);
        Eigen::VectorXf by(matrix_size);
        for (std::size_t j = 0; j < num_vertices; ++j) {
            if (is_border[j]) continue;

            std::size_t const vertex_id = l2g[j];

            /* Calculate "Mean Value Coordinates" as proposed by Michael S. Floater */
            std::map<std::size_t, float> weights;
            std::vector<std::size_t> const & adj_faces = mesh_info[vertex_id].faces;
            for (std::size_t adj_face : adj_faces) {
                std::size_t v0 = mesh_faces[adj_face * 3];
                std::size_t v1 = mesh_faces[adj_face * 3 + 1];
                std::size_t v2 = mesh_faces[adj_face * 3 + 2];
                if (v1 == vertex_id) std::swap(v1, v0);
                if (v2 == vertex_id) std::swap(v2, v0);

                math::Vec3f v01 = vertices[v1] - vertices[v0];
                float v01n = v01.norm();
                math::Vec3f v02 = vertices[v2] - vertices[v0];
                float v02n = v02.norm();

                /* Ensure numerical stability */
                if (v01n * v02n < std::numeric_limits<float>::epsilon()) return false;

                float alpha = std::acos(v01.dot(v02) / (v01n * v02n));
                weights[g2l[v1]] += std::tan(alpha / 2.0f) / v01n;
                weights[g2l[v2]] += std::tan(alpha / 2.0f) / v02n;
            }

            std::map<std::size_t, float>::iterator it;
            float sum = 0.0f;
            for (it = weights.begin(); it != weights.end(); ++it)
                sum += it->second;
            assert(sum > 0.0f);
            for (it = weights.begin(); it != weights.end(); ++it)
                it->second /= sum;

            bx[idx[j]] = 0.0f;
            by[idx[j]] = 0.0f;
            for (it = weights.begin(); it != weights.end(); ++it) {
                if (is_border[it->first]) {
                    std::size_t border_vertex_id = border[idx[it->first]];
                    bx[idx[j]] += projections[g2l[border_vertex_id]][0] * it->second;
                    by[idx[j]] += projections[g2l[border_vertex_id]][1] * it->second;
                } else {
                    coeff.push_back(Triplet(idx[j], idx[it->first], -it->second));
                }
            }
        }

        for (std::size_t j = 0; j < matrix_size; ++j) {
            coeff.push_back(Triplet(j, j, 1.0f));
        }

        typedef Eigen::SparseMatrix<float> SpMat;
        SpMat A(matrix_size, matrix_size);
        A.setFromTriplets(coeff.begin(), coeff.end());

        Eigen::SparseLU<SpMat> solver;
        solver.analyzePattern(A);
        solver.factorize(A);
        xx = solver.solve(bx);
        xy = solver.solve(by);
    }

    float const max_hole_patch_size = MAX_HOLE_PATCH_SIZE;
    int image_size = std::min(std::floor(radius * 1.1f) * 2.0f, max_hole_patch_size);
    /* Ensure a minimum scale of one */
    image_size += 2 * (1 + texture_patch_border);
    int scale = image_size / 2 - texture_patch_border;
    for (std::size_t j = 0, k = 0; j < num_vertices; ++j) {
        if (is_border[j]) {
            projections[j] = projections[j] * scale + image_size / 2;
        } else {
            projections[j] = math::Vec2f(xx[k], xy[k]) * scale + image_size / 2;
            ++k;
        }
    }

    mve::ByteImage::Ptr image = mve::ByteImage::create(image_size, image_size, 3);
    //DEBUG image->fill_color(*math::Vec4uc(0, 255, 0, 255));
    std::vector<math::Vec2f> texcoords; texcoords.reserve(hole.size());
    for (std::size_t const face_id : hole) {
        for (std::size_t j = 0; j < 3; ++j) {
            std::size_t const vertex_id = mesh_faces[face_id * 3 + j];
            math::Vec2f const & projection = projections[g2l[vertex_id]];
            texcoords.push_back(projection);
        }
    }
    TexturePatch::Ptr texture_patch = TexturePatch::create(0, hole, texcoords, image);
    std::size_t texture_patch_id;
    #pragma omp critical
    {
        texture_patches->push_back(texture_patch);
        texture_patch_id = texture_patches->size() - 1;
    }

    for (std::size_t j = 0; j < num_vertices; ++j) {
        std::size_t const vertex_id = l2g[j];
        std::vector<std::size_t> const & adj_faces = mesh_info[vertex_id].faces;
        std::vector<std::size_t> faces; faces.reserve(adj_faces.size());
        for (std::size_t adj_face : adj_faces) {
            if (graph.get_label(adj_face) == 0) {
                faces.push_back(adj_face);
            }
        }
        VertexProjectionInfo info = {texture_patch_id, projections[j], faces};
        #pragma omp critical
        vertex_projection_infos->at(vertex_id).push_back(info);
    }

    return true;
}
void initialize_new_objects(parameter_t const& P,  directory_structure_t const& ds,
			    geometric_info_t const& gi, object_info_t& oi,
			    vector<std::vector<std::string> > const &seq, int tt,
			    vector<CImg<unsigned char> > const& images,
			    vector<matrix<float> > const& grd,
			    vector<matrix<float> >& detected_rects)
{
    int Ncam = seq.size();
    vector<object_trj_t> & trlet_list=oi.trlet_list;
    int nobj = trlet_list.size();
    int num_new_obj = detected_rects(0).size1();
    int T = seq[0].size();
    int np = oi.model.size();

    int num_scales = P.scales.size();

    for(int oo=0; oo<num_new_obj; ++oo)
    {
	int nn = oi.curr_num_obj + oo;


	trlet_list(nn).startt = tt;
	trlet_list(nn).endt = tt;
	trlet_list(nn).state = 1;
	trlet_list(nn).trj = vector<matrix<float> >(Ncam);
	for(int cam=0; cam<Ncam; ++cam)
	{
	    trlet_list(nn).trj(cam) = scalar_matrix<float>(T, 4, 0);
	}
	trlet_list(nn).trj_3d = scalar_matrix<float>(T, 2, 0);

	trlet_list(nn).hist_p = vector<matrix<float> >(Ncam);
	trlet_list(nn).hist_q = vector<matrix<float> >(Ncam);

	trlet_list(nn).fscores = vector<matrix<float> >(Ncam);
	trlet_list(nn).scores = scalar_matrix<float>(Ncam, T, 0);

	vector<candidate_array<Float> > cand_array(Ncam);

	for(int cam=0; cam<Ncam; ++cam)
	{

	    trlet_list(nn).fscores(cam) = scalar_matrix<float>(np*2, T, 0);

	    float w = detected_rects(cam)(oo, 2)-detected_rects(cam)(oo, 0);
	    float h = detected_rects(cam)(oo, 3)-detected_rects(cam)(oo, 1);
	    row(trlet_list(nn).trj(cam), tt) = row(detected_rects(cam), oo);

	    matrix<float> rects;
	    compute_part_rects(detected_rects(cam)(oo, 0), detected_rects(cam)(oo, 1),
			  w, h, oi.model, rects);

	    pmodel_t pmodel;

	    vector<float> br(row(detected_rects(cam), oo));
	    rects_to_pmodel_geom(br, gi.horiz_mean, pmodel);
	    oi.pmodel_list(cam, nn) = pmodel;

	    //collect_sift(grd(cam), );
	    matrix<float> hist_p, hist_q;
	    collect_hist(images(cam), rects, hist_p, hist_q);
	    trlet_list(nn).hist_p(cam) = hist_p;
	    trlet_list(nn).hist_q(cam) = hist_q;


	    std::vector<float> sxr, syr;
	    for(float v=-P.xrange/2; v<=P.xrange/2; v+=P.xstep)
	    {
		sxr.push_back(v);
	    }
	    for(float v=-P.yrange/2; v<=P.yrange/2; v+=P.ystep)
	    {
		syr.push_back(v);
	    }
	    vector<float> xr(sxr.size()), yr(syr.size());
	    std::copy(sxr.begin(), sxr.end(), xr.begin());
	    std::copy(syr.begin(), syr.end(), yr.begin());

	    float feetx = (trlet_list(nn).trj(cam)(tt, 0)
			   +trlet_list(nn).trj(cam)(tt, 2))/2;
	    float feety = trlet_list(nn).trj(cam)(tt, 3);

	    matrix<Float> cand_rects;
	    vector<Float> cand_scale;
	    matrix<int> cand_ijs;

	    enumerate_rects_inpoly(images(cam), oi.pmodel_list(cam, nn),
				   feetx, feety,
				   xr, yr, P.scales, gi.horiz_mean, gi.horiz_sig,
				   gi.polys_im(cam),
				   cand_rects, cand_scale,
				   cand_ijs, cand_array(cam));


	    vector<Float> cand_hist_score;
	    matrix<Float> hist_fscores;

	    real_timer_t timer;
	    get_cand_hist_score(images(cam), oi.model, P.logp1, P.logp2,
				trlet_list(nn).hist_p(cam),
				trlet_list(nn).hist_q(cam),
				cand_rects,
				cand_hist_score, hist_fscores);

	    vector<Float> cand_score=cand_hist_score;
	    std::cout<<"\t\t"<<cand_rects.size1()<<" rects, \tget_cand_hist_score time:"
		     <<timer.elapsed()/1000.0f<<"s."<<std::endl;

	    int idx_max = std::max_element(cand_score.begin(), cand_score.end())
		- cand_score.begin();

	    column(trlet_list(nn).fscores(cam), tt) = row(hist_fscores, idx_max);
	    trlet_list(nn).scores(cam, tt) = cand_score(idx_max);
	    cand_array(cam).fill_score(cand_score, cand_ijs);


	}//end for cam

	real_timer_t timer;

	ground_scoremap_t<Float> grd_scoremap;
	combine_ground_score(cand_array, grd_scoremap, gi);
	int best_y, best_x, best_s;

	grd_scoremap.peak(best_y, best_x, best_s);	


	for(int cam=0; cam<Ncam; ++cam)
	{
	    vector<double> bx(1), by(1), ix, iy;
	    bx <<= best_x; by <<= best_y;
	    apply_homography(gi.grd2img(cam), bx, by, ix, iy);
	    float hpre = oi.pmodel_list(cam, nn).hpre;
	    float cur_fy = iy(0);
	    float cur_fx = ix(0);
	    float cur_hy = gi.horiz_mean+hpre*(cur_fy-gi.horiz_mean);
	    float ds = P.scales(best_s)*(cur_fy-cur_hy)/oi.pmodel_list(cam, nn).bh;
	    float ww = ds*oi.pmodel_list(cam, nn).bw;
	    float hh = cur_fy - cur_hy;

	    vector<Float> tmp(4);
	    tmp <<= (cur_fx-ww/2), cur_hy, (cur_fx+ww/2), cur_fy;
	    row(trlet_list(nn).trj(cam), tt) = tmp;

	    //std::cout<<"trlet_list(nn).trj(cam)(tt, :)="
	    //     <<row(trlet_list(nn).trj(cam), tt)<<std::endl;

	}//endfor cam

    }//endfor oo

    oi.curr_num_obj += num_new_obj;
}
Exemple #23
0
	/**
	 * Record performance measures
	 */
	void record(uint time, const Model& model, double control = 1){
		//uint year = IOSKJ::year(time);
		uint quarter = IOSKJ::quarter(time);

		times.append();

		// Catch magnitude
		auto catch_total = model.catches_taken(sum);
		catches_total.append(catch_total);
		auto catches_by_method = model.catches_taken(sum,by(methods));
		catches_ps.append(catches_by_method(PS));
		catches_pl.append(catches_by_method(PL));
		catches_gn.append(catches_by_method(GN));

		// Years catch goes below baseline
		catches_lower.append(catch_total < 425000/4.0);

		// Catch variability
		if(quarter == 0 and catch_total>0){
			catches_var.append(catch_total);
			catches_mapc.append(catch_total);
		}
		// Shutdown defined as quarterly catches <10% of recent average
		// catches of about 400000t
		catches_shut.append(catch_total<1000);

		// Changes in MP control e.g. catch or effort limit
		if (quarter == 0) {
			if (std::isfinite(control_last_)) {
				control_ups.append(control>control_last_);
				control_downs.append(control<control_last_);
			}
			control_last_ = control;
		}

		// Stock status relative to unfished
		auto status = model.biomass_status();
		status_mean.append(status);
		status_b10.append(status<0.1);
		status_b20.append(status<0.2);

		// Biomass relative to B40
		auto b = model.biomass_spawners(sum)/model.biomass_spawners_40;
		b_ratio.append(b);
		// F relative to F40
		auto f = model.fishing_mortality_get()/model.f_40;
		f_ratio.append(f);

		// Kobe plot
		// Determine quadrant
		char quadrant;
		if(b>=1){
			if(f<=1) quadrant = 'a';
			else quadrant = 'b';
		} else {
			if(f<=1) quadrant = 'c';
			else quadrant = 'd';
		}
		// Update performance measures for proportion of time spent in each quadrant
		kobe_a.append(quadrant=='a');
		kobe_b.append(quadrant=='b');
		kobe_c.append(quadrant=='c');
		kobe_d.append(quadrant=='d');
		// Update performance measure for time taken to get back into quadrant A
		if(quadrant=='a'){
			// If previously outside of A then append the time that 
			// have been outside to the mean and reset time counter to zero.
			if(kobe_out_a>0){
				kobe_to_a.append(kobe_out_a);
				kobe_out_a = 0;
			}
		} else {
			// Outside of A so increment time counter.
			kobe_out_a++;
		}

		// Catch rates 
		// Use vulnerable (i.e. selected) biomass for the three main regions/gears
		// relative to the start year as a measure of catch rates (CPUE)
		if(times==1){
			// Record baselines
			for(auto region : regions){
				for(auto method : methods){
					cpue_baseline(region,method) = model.biomass_vulnerable(region,method);
				}
			}
		} else {
			// Record relative to baseline
			for(auto region : regions){
				for(auto method : methods){
					cpue_mean(region,method).append(
						model.biomass_vulnerable(region,method)/cpue_baseline(region,method)
					);
				}
			}
		}
	}