예제 #1
0
파일: blocksort.c 프로젝트: kichik/nsis-1
static
void fallbackQSort3 ( UInt32* fmap, 
                      UInt32* eclass,
                      Int32   loSt, 
                      Int32   hiSt )
{
   Int32 unLo, unHi, ltLo, gtHi, n, m;
   Int32 sp, lo, hi;
   UInt32 med, r, r3;
   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];

   r = 0;

   sp = 0;
   fpush ( loSt, hiSt );

   while (sp > 0) {

      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );

      fpop ( lo, hi );
      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
         fallbackSimpleSort ( fmap, eclass, lo, hi );
         continue;
      }

      /* Random partitioning.  Median of 3 sometimes fails to
         avoid bad cases.  Median of 9 seems to help but 
         looks rather expensive.  This too seems to work but
         is cheaper.  Guidance for the magic constants 
         7621 and 32768 is taken from Sedgewick's algorithms
         book, chapter 35.
      */
      r = ((r * 7621) + 1) % 32768;
      r3 = r % 3;
      if (r3 == 0) med = eclass[fmap[lo]]; else
      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
                   med = eclass[fmap[hi]];

      unLo = ltLo = lo;
      unHi = gtHi = hi;

      while (1) {
         while (1) {
            if (unLo > unHi) break;
            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
            if (n == 0) { 
               fswap(fmap[unLo], fmap[ltLo]); 
               ltLo++; unLo++; 
               continue; 
            };
            if (n > 0) break;
            unLo++;
         }
         while (1) {
            if (unLo > unHi) break;
            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
            if (n == 0) { 
               fswap(fmap[unHi], fmap[gtHi]); 
               gtHi--; unHi--; 
               continue; 
            };
            if (n < 0) break;
            unHi--;
         }
         if (unLo > unHi) break;
         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
      }

      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );

      if (gtHi < ltLo) continue;

      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);

      n = lo + unLo - ltLo - 1;
      m = hi - (gtHi - unHi) + 1;

      if (n - lo > hi - m) {
         fpush ( lo, n );
         fpush ( m, hi );
      } else {
         fpush ( m, hi );
         fpush ( lo, n );
      }
   }
예제 #2
0
파일: drawing.cpp 프로젝트: yamamushi/bmfec
void plotCubicBezierSegAA(int x0, int y0, double x1, double y1,
                          double x2, double y2, int x3, int y3)
{                           /* plot limited anti-aliased cubic Bezier segment */
    int f, fx, fy, leg = 1;
    int sx = x0 < x3 ? 1 : -1, sy = y0 < y3 ? 1 : -1;        /* step direction */
    double xc = -fabs(x0+x1-x2-x3), xa = xc-4*sx*(x1-x2), xb = sx*(x0-x1-x2+x3);
    double yc = -fabs(y0+y1-y2-y3), ya = yc-4*sy*(y1-y2), yb = sy*(y0-y1-y2+y3);
    double ab, ac, bc, ba, xx, xy, yy, dx, dy, ex, px, py, ed, ip, EP = 0.01;
    
    /* check for curve restrains */
    /* slope P0-P1 == P2-P3     and  (P0-P3 == P1-P2      or  no slope change) */
    assert((x1-x0)*(x2-x3) < EP && ((x3-x0)*(x1-x2) < EP || xb*xb < xa*xc+EP));
    assert((y1-y0)*(y2-y3) < EP && ((y3-y0)*(y1-y2) < EP || yb*yb < ya*yc+EP));
    
    if (xa == 0 && ya == 0) {                              /* quadratic Bezier */
        sx = (int) floor((3*x1-x0+1)/2); sy = (int) floor((3*y1-y0+1)/2);   /* new midpoint */
        return plotQuadBezierSegAA(x0,y0, sx,sy, x3,y3);
    }
    x1 = (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)+1;                    /* line lengths */
    x2 = (x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)+1;
    do {                                                /* loop over both ends */
        ab = xa*yb-xb*ya; ac = xa*yc-xc*ya; bc = xb*yc-xc*yb;
        ip = 4*ab*bc-ac*ac;                   /* self intersection loop at all? */
        ex = ab*(ab+ac-3*bc)+ac*ac;       /* P0 part of self-intersection loop? */
        f = (int) (ex > 0 ? 1 : sqrt(1+1024/x1));               /* calculate resolution */
        ab *= f; ac *= f; bc *= f; ex *= f*f;            /* increase resolution */
        xy = 9*(ab+ac+bc)/8; ba = 8*(xa-ya);  /* init differences of 1st degree */
        dx = 27*(8*ab*(yb*yb-ya*yc)+ex*(ya+2*yb+yc))/64-ya*ya*(xy-ya);
        dy = 27*(8*ab*(xb*xb-xa*xc)-ex*(xa+2*xb+xc))/64-xa*xa*(xy+xa);
        /* init differences of 2nd degree */
        xx = 3*(3*ab*(3*yb*yb-ya*ya-2*ya*yc)-ya*(3*ac*(ya+yb)+ya*ba))/4;
        yy = 3*(3*ab*(3*xb*xb-xa*xa-2*xa*xc)-xa*(3*ac*(xa+xb)+xa*ba))/4;
        xy = xa*ya*(6*ab+6*ac-3*bc+ba); ac = ya*ya; ba = xa*xa;
        xy = 3*(xy+9*f*(ba*yb*yc-xb*xc*ac)-18*xb*yb*ab)/8;
        
        if (ex < 0) {         /* negate values if inside self-intersection loop */
            dx = -dx; dy = -dy; xx = -xx; yy = -yy; xy = -xy; ac = -ac; ba = -ba;
        }                                     /* init differences of 3rd degree */
        ab = 6*ya*ac; ac = -6*xa*ac; bc = 6*ya*ba; ba = -6*xa*ba;
        dx += xy; ex = dx+dy; dy += xy;                    /* error of 1st step */
        
        for (fx = fy = f; x0 != x3 && y0 != y3; ) {
            y1 = fmin(fabs(xy-dx),fabs(dy-xy));
            ed = fmax(fabs(xy-dx),fabs(dy-xy));    /* approximate error distance */
            ed = f*(ed+2*ed*y1*y1/(4*ed*ed+y1*y1));
            y1 = 255*fabs(ex-(f-fx+1)*dx-(f-fy+1)*dy+f*xy)/ed;
            if (y1 < 256)
                ;//setPixelAA(x0, y0, y1);                  /* plot curve */
            px = fabs(ex-(f-fx+1)*dx+(fy-1)*dy);       /* pixel intensity x move */
            py = fabs(ex+(fx-1)*dx-(f-fy+1)*dy);       /* pixel intensity y move */
            y2 = y0;
            do {                                  /* move sub-steps of one pixel */
                if (ip >= -EP)               /* intersection possible? -> check.. */
                    if (dx+xx > xy || dy+yy < xy) goto exit;   /* two x or y steps */
                y1 = 2*ex+dx;                    /* save value for test of y step */
                if (2*ex+dy > 0) {                                  /* x sub-step */
                    fx--; ex += dx += xx; dy += xy += ac; yy += bc; xx += ab;
                } else if (y1 > 0) goto exit;                 /* tiny nearly cusp */
                if (y1 <= 0) {                                      /* y sub-step */
                    fy--; ex += dy += yy; dx += xy += bc; xx += ac; yy += ba;
                }
            } while (fx > 0 && fy > 0);                       /* pixel complete? */
            if (2*fy <= f) {                           /* x+ anti-aliasing pixel */
                if (py < ed)
                    ;//setPixelAA(x0+sx, y0, 255*py/ed);      /* plot curve */
                y0 += sy; fy += f;                                      /* y step */
            }
            if (2*fx <= f) {                           /* y+ anti-aliasing pixel */
                if (px < ed)
                    ;//setPixelAA(x0, y2+sy, 255*px/ed);      /* plot curve */
                x0 += sx; fx += f;                                      /* x step */
            }
        }
        break;                                          /* finish curve by line */
    exit:
        if (2*ex < dy && 2*fy <= f+2) {         /* round x+ approximation pixel */
            if (py < ed)
                ;//setPixelAA(x0+sx, y0, 255*py/ed);         /* plot curve */
            y0 += sy;
        }
        if (2*ex > dx && 2*fx <= f+2) {         /* round y+ approximation pixel */
            if (px < ed)
                ;//setPixelAA(x0, y2+sy, 255*px/ed);         /* plot curve */
            x0 += sx;
        }
        xx = x0; x0 = x3; x3 = (int) xx; sx = -sx; xb = -xb;             /* swap legs */
        yy = y0; y0 = y3; y3 = (int) yy; sy = -sy; yb = -yb; x1 = x2;
    } while (leg--);                                          /* try other end */
    plotLineAA(x0,y0, x3,y3);     /* remaining part in case of cusp or crunode */
}
예제 #3
0
파일: Route.cpp 프로젝트: ekorel/OpenCPN
void Route::RenderSegment( ocpnDC& dc, int xa, int ya, int xb, int yb, ViewPort &VP,
        bool bdraw_arrow, int hilite_width )
{
    //    Get the dc boundary
    int sx, sy;
    dc.GetSize( &sx, &sy );

    //    Try to exit early if the segment is nowhere near the screen
    wxRect r( 0, 0, sx, sy );
    wxRect s( xa, ya, 1, 1 );
    wxRect t( xb, yb, 1, 1 );
    s.Union( t );
    if( !r.Intersects( s ) ) return;

    //    Clip the line segment to the dc boundary
    int x0 = xa;
    int y0 = ya;
    int x1 = xb;
    int y1 = yb;

    //    If hilite is desired, use a Native Graphics context to render alpha colours
    //    That is, if wxGraphicsContext is available.....

    if( hilite_width ) {
        if( Visible == cohen_sutherland_line_clip_i( &x0, &y0, &x1, &y1, 0, sx, 0, sy ) ) {
            wxPen psave = dc.GetPen();

            wxColour y = GetGlobalColor( _T ( "YELO1" ) );
            wxColour hilt( y.Red(), y.Green(), y.Blue(), 128 );

            wxPen HiPen( hilt, hilite_width, wxSOLID );

            dc.SetPen( HiPen );
            dc.StrokeLine( x0, y0, x1, y1 );

            dc.SetPen( psave );
            dc.StrokeLine( x0, y0, x1, y1 );
        }
    } else {
        if( Visible == cohen_sutherland_line_clip_i( &x0, &y0, &x1, &y1, 0, sx, 0, sy ) )
            dc.StrokeLine( x0, y0, x1, y1 );
    }

    if( bdraw_arrow ) {
        //    Draw a direction arrow

        double theta = atan2( (double) ( yb - ya ), (double) ( xb - xa ) );
        theta -= PI / 2.;

        wxPoint icon[10];
        double icon_scale_factor = 100 * VP.view_scale_ppm;
        icon_scale_factor = fmin ( icon_scale_factor, 1.5 );              // Sets the max size
        icon_scale_factor = fmax ( icon_scale_factor, .10 );

        //    Get the absolute line length
        //    and constrain the arrow to be no more than xx% of the line length
        double nom_arrow_size = 20.;
        double max_arrow_to_leg = .20;
        double lpp = sqrt( pow( (double) ( xa - xb ), 2 ) + pow( (double) ( ya - yb ), 2 ) );

        double icon_size = icon_scale_factor * nom_arrow_size;
        if( icon_size > ( lpp * max_arrow_to_leg ) ) icon_scale_factor = ( lpp * max_arrow_to_leg )
                / nom_arrow_size;

        for( int i = 0; i < 7; i++ ) {
            int j = i * 2;
            double pxa = (double) ( s_arrow_icon[j] );
            double pya = (double) ( s_arrow_icon[j + 1] );

            pya *= icon_scale_factor;
            pxa *= icon_scale_factor;

            double px = ( pxa * sin( theta ) ) + ( pya * cos( theta ) );
            double py = ( pya * sin( theta ) ) - ( pxa * cos( theta ) );

            icon[i].x = (int) ( px ) + xb;
            icon[i].y = (int) ( py ) + yb;
        }
        wxPen savePen = dc.GetPen();
        dc.SetPen( *wxTRANSPARENT_PEN );
        dc.StrokePolygon( 6, &icon[0], 0, 0 );
        dc.SetPen( savePen );
    }
}
예제 #4
0
파일: Synchronizer.cpp 프로젝트: Drakeo/ssr
void Synchronizer::ReadAudioSamples(unsigned int channels, unsigned int sample_rate, AVSampleFormat format, unsigned int sample_count, const uint8_t* data, int64_t timestamp) {
	assert(m_output_format->m_audio_enabled);

	// sanity check
	if(sample_count == 0)
		return;

	// add new block to sync diagram
	if(m_sync_diagram != NULL)
		m_sync_diagram->AddBlock(1, (double) timestamp * 1.0e-6, (double) timestamp * 1.0e-6 + (double) sample_count / (double) sample_rate, QColor(0, 255, 0));

	AudioLock audiolock(&m_audio_data);

	// check the timestamp
	if(timestamp < audiolock->m_last_timestamp) {
		if(timestamp < audiolock->m_last_timestamp - 10000)
			Logger::LogWarning("[Synchronizer::ReadAudioSamples] " + Logger::tr("Warning: Received audio samples with non-monotonic timestamp."));
		timestamp = audiolock->m_last_timestamp;
	}

	// update the timestamps
	int64_t previous_timestamp;
	if(audiolock->m_first_timestamp == (int64_t) AV_NOPTS_VALUE) {
		audiolock->m_filtered_timestamp = timestamp;
		audiolock->m_first_timestamp = timestamp;
		previous_timestamp = timestamp;
	} else {
		previous_timestamp = audiolock->m_last_timestamp;
	}
	audiolock->m_last_timestamp = timestamp;

	// filter the timestamp
	int64_t timestamp_delta = (int64_t) sample_count * (int64_t) 1000000 / (int64_t) sample_rate;
	audiolock->m_filtered_timestamp += (timestamp - audiolock->m_filtered_timestamp) / AUDIO_TIMESTAMP_FILTER;

	// calculate drift
	double current_drift = GetAudioDrift(audiolock.get());

	// if there are too many audio samples, drop some of them (unlikely unless you use PulseAudio)
	if(current_drift > DRIFT_ERROR_THRESHOLD && !audiolock->m_drop_samples) {
		audiolock->m_drop_samples = true;
		Logger::LogWarning("[Synchronizer::ReadAudioSamples] " + Logger::tr("Warning: Too many audio samples, dropping samples to keep the audio in sync with the video."));
	}

	// if there are not enough audio samples, insert zeros
	if(current_drift < -DRIFT_ERROR_THRESHOLD && !audiolock->m_insert_samples) {
		audiolock->m_insert_samples = true;
		Logger::LogWarning("[Synchronizer::ReadAudioSamples] " + Logger::tr("Warning: Not enough audio samples, inserting silence to keep the audio in sync with the video."));
	}

	// reset filter and recalculate drift if necessary
	if(audiolock->m_drop_samples || audiolock->m_insert_samples) {
		audiolock->m_filtered_timestamp = timestamp;
		current_drift = GetAudioDrift(audiolock.get());
	}

	// drop samples
	if(audiolock->m_drop_samples) {
		audiolock->m_drop_samples = false;

		// drop samples
		int n = (int) round(current_drift * (double) sample_rate);
		if(n > 0) {
			if(n >= (int) sample_count) {
				audiolock->m_drop_samples = true;
				return; // drop all samples
			}
			if(format == AV_SAMPLE_FMT_FLT) {
				data += n * channels * sizeof(float);
			} else if(format == AV_SAMPLE_FMT_S16) {
				data += n * channels * sizeof(int16_t);
			} else {
				assert(false);
			}
			sample_count -= n;
		}

	}

	// insert zeros
	unsigned int sample_count_out = 0;
	if(audiolock->m_insert_samples) {
		audiolock->m_insert_samples = false;

		// how many samples should be inserted?
		int n = (int) round(-current_drift * (double) sample_rate);
		if(n > 0) {

			// insert zeros
			audiolock->m_temp_input_buffer.Alloc(n * m_output_format->m_audio_channels);
			std::fill_n(audiolock->m_temp_input_buffer.GetData(), n * m_output_format->m_audio_channels, 0.0f);
			sample_count_out = audiolock->m_fast_resampler->Resample((double) sample_rate / (double) m_output_format->m_audio_sample_rate, 1.0,
																	 audiolock->m_temp_input_buffer.GetData(), n, &audiolock->m_temp_output_buffer, sample_count_out);

			// recalculate drift
			current_drift = GetAudioDrift(audiolock.get(), sample_count_out);

		}

	}

	// increase filtered timestamp
	audiolock->m_filtered_timestamp += timestamp_delta;

	// do drift correction
	// The point of drift correction is to keep video and audio in sync even when the clocks are not running at exactly the same speed.
	// This can happen because the sample rate of the sound card is not always 100% accurate. Even a 0.1% error will result in audio that is
	// seconds too early or too late at the end of a one hour video. This problem doesn't occur on all computers though (I'm not sure why).
	// Another cause of desynchronization is problems/glitches with PulseAudio (e.g. jumps in time when switching between sources).
	double drift_correction_dt = fmin((double) (timestamp - previous_timestamp) * 1.0e-6, DRIFT_MAX_BLOCK);
	audiolock->m_average_drift = clamp(audiolock->m_average_drift + DRIFT_CORRECTION_I * current_drift * drift_correction_dt, -0.5, 0.5);
	if(audiolock->m_average_drift < -0.02 && audiolock->m_warn_desync) {
		audiolock->m_warn_desync = false;
		Logger::LogWarning("[Synchronizer::ReadAudioSamples] " + Logger::tr("Warning: Audio input is more than 2% too slow!"));
	}
	if(audiolock->m_average_drift > 0.02 && audiolock->m_warn_desync) {
		audiolock->m_warn_desync = false;
		Logger::LogWarning("[Synchronizer::ReadAudioSamples] " + Logger::tr("Warning: Audio input is more than 2% too fast!"));
	}
	double length = (double) sample_count / (double) sample_rate;
	double drift_correction = clamp(DRIFT_CORRECTION_P * current_drift + audiolock->m_average_drift, -0.5, 0.5) * fmin(1.0, DRIFT_MAX_BLOCK / length);

	//qDebug() << "current_drift" << current_drift << "average_drift" << audiolock->m_average_drift << "drift_correction" << drift_correction;

	// convert the samples
	const float *data_float = NULL; // to keep GCC happy
	if(format == AV_SAMPLE_FMT_FLT) {
		if(channels == m_output_format->m_audio_channels) {
			data_float = (const float*) data;
		} else {
			audiolock->m_temp_input_buffer.Alloc(sample_count * m_output_format->m_audio_channels);
			data_float = audiolock->m_temp_input_buffer.GetData();
			SampleChannelRemap(sample_count, (const float*) data, channels, audiolock->m_temp_input_buffer.GetData(), m_output_format->m_audio_channels);
		}
	} else if(format == AV_SAMPLE_FMT_S16) {
		audiolock->m_temp_input_buffer.Alloc(sample_count * m_output_format->m_audio_channels);
		data_float = audiolock->m_temp_input_buffer.GetData();
		SampleChannelRemap(sample_count, (const int16_t*) data, channels, audiolock->m_temp_input_buffer.GetData(), m_output_format->m_audio_channels);
	} else {
		assert(false);
	}

	// resample
	sample_count_out = audiolock->m_fast_resampler->Resample((double) sample_rate / (double) m_output_format->m_audio_sample_rate, 1.0 / (1.0 - drift_correction),
															 data_float, sample_count, &audiolock->m_temp_output_buffer, sample_count_out);
	audiolock->m_samples_written += sample_count_out;

	SharedLock lock(&m_shared_data);

	// avoid memory problems by limiting the audio buffer size
	if(lock->m_audio_buffer.GetSize() / m_output_format->m_audio_channels >= MAX_AUDIO_SAMPLES_BUFFERED) {
		if(lock->m_segment_video_started) {
			Logger::LogWarning("[Synchronizer::ReadAudioSamples] " + Logger::tr("Warning: Audio buffer overflow, starting new segment to keep the audio in sync with the video "
																				"(some video and/or audio may be lost). The video input seems to be too slow."));
			NewSegment(lock.get());
		} else {
			// If the video hasn't started yet, it makes more sense to drop the oldest samples.
			// Shifting the start time like this isn't completely accurate, but this shouldn't happen often anyway.
			// The number of samples dropped is calculated so that the buffer will be 90% full after this.
			size_t n = lock->m_audio_buffer.GetSize() / m_output_format->m_audio_channels - MAX_AUDIO_SAMPLES_BUFFERED * 9 / 10;
			lock->m_audio_buffer.Pop(n * m_output_format->m_audio_channels);
			lock->m_segment_audio_start_time += (int64_t) round((double) n / (double) m_output_format->m_audio_sample_rate * 1.0e6);
		}
	}

	// start audio
	if(!lock->m_segment_audio_started) {
		lock->m_segment_audio_started = true;
		lock->m_segment_audio_start_time = timestamp;
		lock->m_segment_audio_stop_time = timestamp;
	}

	// store the samples
	lock->m_audio_buffer.Push(audiolock->m_temp_output_buffer.GetData(), sample_count_out * m_output_format->m_audio_channels);

	// increase segment stop time
	double new_sample_length = (double) (lock->m_segment_audio_samples_read + lock->m_audio_buffer.GetSize() / m_output_format->m_audio_channels) / (double) m_output_format->m_audio_sample_rate;
	lock->m_segment_audio_stop_time = lock->m_segment_audio_start_time + (int64_t) round(new_sample_length * 1.0e6);

}
예제 #5
0
파일: HWxcount.c 프로젝트: wrengels/HWxtest
double twoAlleleSpecialCase(int * m)  {
	unsigned ntables = fmin(m[0], m[1])/2 + 1;
	return (double)ntables;
}
예제 #6
0
SEXP call_rkAuto(SEXP Xstart, SEXP Times, SEXP Func, SEXP Initfunc,
  SEXP Parms, SEXP eventfunc, SEXP elist, SEXP Nout, SEXP Rho,
  SEXP Rtol, SEXP Atol, SEXP Tcrit, SEXP Verbose,
  SEXP Hmin, SEXP Hmax, SEXP Hini, SEXP Rpar, SEXP Ipar,
  SEXP Method, SEXP Maxsteps, SEXP Flist) {

  /**  Initialization **/
  long int old_N_Protect = save_N_Protected();

  double *tt = NULL, *xs = NULL;

  double *y,  *f,  *Fj, *tmp, *FF, *rr;
  SEXP  R_yout;
  double *y0,  *y1,  *y2,  *dy1,  *dy2, *out, *yout;

  double errold = 0.0, t, dt, tmax;

  SEXP R_FSAL, Alpha, Beta;
  int fsal = FALSE;       /* assume no FSAL */
  
  /* Use polynomial interpolation if not disabled by the method
     or when events come in to play (stop-and-go mode).
     Methods with dense output interpolate by default,
     all others do not.
  */
  int interpolate = TRUE;

  int i = 0, j = 0, it = 0, it_tot = 0, it_ext = 0, nt = 0, neq = 0, it_rej = 0;
  int isForcing, isEvent;

  /*------------------------------------------------------------------------*/
  /* Processing of Arguments                                                */
  /*------------------------------------------------------------------------*/
  int lAtol = LENGTH(Atol);
  double *atol = (double*) R_alloc((int) lAtol, sizeof(double));

  int lRtol = LENGTH(Rtol);
  double *rtol = (double*) R_alloc((int) lRtol, sizeof(double));

  for (j = 0; j < lRtol; j++) rtol[j] = REAL(Rtol)[j];
  for (j = 0; j < lAtol; j++) atol[j] = REAL(Atol)[j];

  double  tcrit = REAL(Tcrit)[0];
  double  hmin  = REAL(Hmin)[0];
  double  hmax  = REAL(Hmax)[0];
  double  hini  = REAL(Hini)[0];
  int  maxsteps = INTEGER(Maxsteps)[0];
  int  nout     = INTEGER(Nout)[0]; /* number of global outputs is func is in a DLL */
  int  verbose  = INTEGER(Verbose)[0];

  int stage     = (int)REAL(getListElement(Method, "stage"))[0];

  SEXP R_A, R_B1, R_B2, R_C, R_D, R_densetype;
  double  *A, *bb1, *bb2 = NULL, *cc = NULL, *dd = NULL;

  PROTECT(R_A = getListElement(Method, "A")); incr_N_Protect();
  A = REAL(R_A);

  PROTECT(R_B1 = getListElement(Method, "b1")); incr_N_Protect();
  bb1 = REAL(R_B1);

  PROTECT(R_B2 = getListElement(Method, "b2")); incr_N_Protect();
  if (length(R_B2)) bb2 = REAL(R_B2);

  PROTECT(R_C = getListElement(Method, "c")); incr_N_Protect();
  if (length(R_C)) cc = REAL(R_C);

  PROTECT(R_D = getListElement(Method, "d")); incr_N_Protect();
  if (length(R_D)) dd = REAL(R_D);

  /* dense output Cash-Karp: densetype = 2 */
  int densetype = 0;
  PROTECT(R_densetype = getListElement(Method, "densetype")); incr_N_Protect();
  if (length(R_densetype)) densetype = INTEGER(R_densetype)[0];

  double  qerr = REAL(getListElement(Method, "Qerr"))[0];
  double  beta = 0;      /* 0.4/qerr; */

  PROTECT(Beta = getListElement(Method, "beta")); incr_N_Protect();
  if (length(Beta)) beta = REAL(Beta)[0];

  double  alpha = 1/qerr - 0.75 * beta;
  PROTECT(Alpha = getListElement(Method, "alpha")); incr_N_Protect();
  if (length(Alpha)) alpha = REAL(Alpha)[0];

  PROTECT(R_FSAL = getListElement(Method, "FSAL")); incr_N_Protect();
  if (length(R_FSAL)) fsal = INTEGER(R_FSAL)[0];

  PROTECT(Times = AS_NUMERIC(Times)); incr_N_Protect();
  tt = NUMERIC_POINTER(Times);
  nt = length(Times);

  PROTECT(Xstart = AS_NUMERIC(Xstart)); incr_N_Protect();
  xs  = NUMERIC_POINTER(Xstart);
  neq = length(Xstart);
  /*------------------------------------------------------------------------*/
  /* timesteps (for advection computation in ReacTran)                      */
  /*------------------------------------------------------------------------*/
  for (i = 0; i < 2; i++) timesteps[i] = 0;

  /*------------------------------------------------------------------------*/
  /* DLL, ipar, rpar (for compatibility with lsoda)                         */
  /*------------------------------------------------------------------------*/
  int isDll = FALSE;
  int lrpar= 0, lipar = 0;
  int *ipar = NULL;

  /* code adapted from lsoda to improve compatibility */
  if (inherits(Func, "NativeSymbol")) { 
    /* function is a dll */
    isDll = TRUE;
    if (nout > 0) isOut = TRUE;
    //ntot  = neq + nout;           /* length of yout */
    lrpar = nout + LENGTH(Rpar);  /* length of rpar; LENGTH(Rpar) is always >0 */
    lipar = 3    + LENGTH(Ipar);  /* length of ipar */

  } else {
    /* function is not a dll */
    isDll = FALSE;
    isOut = FALSE;
    //ntot = neq;
    lipar = 3;    /* in lsoda = 1 */
    lrpar = nout; /* in lsoda = 1 */
  }
  out   = (double*) R_alloc(lrpar, sizeof(double)); 
  ipar  = (int *) R_alloc(lipar, sizeof(int));

  /* first 3 elements of ipar are special */
  ipar[0] = nout;              
  ipar[1] = lrpar;
  ipar[2] = lipar;
  if (isDll == 1) {
    /* other elements of ipar are set in R-function lsodx via argument "ipar" */
    for (j = 0; j < LENGTH(Ipar); j++) ipar[j+3] = INTEGER(Ipar)[j];
 
    /* out: first nout elements of out are reserved for output variables
       other elements are set via argument "rpar" */
    for (j = 0; j < nout; j++)         out[j] = 0.0;                
    for (j = 0; j < LENGTH(Rpar); j++) out[nout+j] = REAL(Rpar)[j];
  }

  /*------------------------------------------------------------------------*/
  /* Allocation of Workspace                                                */
  /*------------------------------------------------------------------------*/
  y0  =  (double*) R_alloc(neq, sizeof(double));
  y1  =  (double*) R_alloc(neq, sizeof(double));
  y2  =  (double*) R_alloc(neq, sizeof(double));
  dy1 =  (double*) R_alloc(neq, sizeof(double));
  dy2 =  (double*) R_alloc(neq, sizeof(double));
  f   =  (double*) R_alloc(neq, sizeof(double));
  y   =  (double*) R_alloc(neq, sizeof(double));
  Fj  =  (double*) R_alloc(neq, sizeof(double));
  tmp =  (double*) R_alloc(neq, sizeof(double));
  FF  =  (double*) R_alloc(neq * stage, sizeof(double));
  rr  =  (double*) R_alloc(neq * 5, sizeof(double));

  /* matrix for polynomial interpolation */
  SEXP R_nknots;
  int nknots = 6;  /* 6 = 5th order polynomials by default*/
  int iknots = 0;  /* counter for knots buffer */
  double *yknots;

  PROTECT(R_nknots = getListElement(Method, "nknots")); incr_N_Protect();
  if (length(R_nknots)) nknots = INTEGER(R_nknots)[0] + 1;
  if (nknots < 2) {nknots = 1; interpolate = FALSE;}
  if (densetype > 0) interpolate = TRUE;
  yknots = (double*) R_alloc((neq + 1) * (nknots + 1), sizeof(double));

  /* matrix for holding states and global outputs */
  PROTECT(R_yout = allocMatrix(REALSXP, nt, neq + nout + 1)); incr_N_Protect();
  yout = REAL(R_yout);
  /* initialize outputs with NA first */
  for (i = 0; i < nt * (neq + nout + 1); i++) yout[i] = NA_REAL;

  /* attribute that stores state information, similar to lsoda */
  SEXP R_istate;
  int *istate;
  PROTECT(R_istate = allocVector(INTSXP, 22)); incr_N_Protect();
  istate = INTEGER(R_istate);
  istate[0] = 0; /* assume succesful return */
  for (i = 0; i < 22; i++) istate[i] = 0;

  /*------------------------------------------------------------------------*/
  /* Initialization of Parameters (for DLL functions)                       */
  /*------------------------------------------------------------------------*/
  PROTECT(Y = allocVector(REALSXP,(neq)));        incr_N_Protect(); 
  
  initParms(Initfunc, Parms);
  isForcing = initForcings(Flist);
  isEvent = initEvents(elist, eventfunc, 0);
  if (isEvent) interpolate = FALSE;

  /*------------------------------------------------------------------------*/
  /* Initialization of Integration Loop                                     */
  /*------------------------------------------------------------------------*/
  yout[0]   = tt[0];              /* initial time                 */
  yknots[0] = tt[0];              /* for polynomial interpolation */
  for (i = 0; i < neq; i++) {
    y0[i]        = xs[i];         /* initial values               */
    yout[(i + 1) * nt] = y0[i];   /* output array                 */
    yknots[iknots + nknots * (i + 1)] = xs[i]; /* for polynomials */
  }
  iknots++;

  t = tt[0];
  tmax = fmax(tt[nt - 1], tcrit);
  dt   = fmin(hmax, hini);
  hmax = fmin(hmax, tmax - t);

  /* Initialize work arrays (to be on the safe side, remove this later) */
  for (i = 0; i < neq; i++)  {
    y1[i] = 0;
    y2[i] = 0;
    Fj[i] = 0;
    for (j= 0; j < stage; j++)  {
      FF[i + j * neq] = 0;
    }
  }

  /*------------------------------------------------------------------------*/
  /* Main Loop                                                              */
  /*------------------------------------------------------------------------*/
  it     = 1; /* step counter; zero element is initial state   */
  it_ext = 0; /* counter for external time step (dense output) */
  it_tot = 0; /* total number of time steps                    */
  it_rej = 0;
  
  if (interpolate) {
  /* integrate over the whole time step and interpolate internally */
    rk_auto(
      fsal, neq, stage, isDll, isForcing, verbose, nknots, interpolate, 
      densetype, maxsteps, nt,
      &iknots, &it, &it_ext, &it_tot, &it_rej,
      istate, ipar, 
      t, tmax, hmin, hmax, alpha, beta,
      &dt, &errold,
      tt, y0, y1, y2, dy1, dy2, f, y, Fj, tmp, FF, rr, A,
      out, bb1, bb2, cc, dd, atol, rtol, yknots, yout,
      Func, Parms, Rho
    );
  } else {  
     /* integrate separately between external time steps; do not interpolate */
     for (int j = 0; j < nt - 1; j++) {
       t = tt[j];
       tmax = fmin(tt[j + 1], tcrit);
       dt = tmax - t;
       if (isEvent) {
         updateevent(&t, y0, istate);
       }
       if (verbose) Rprintf("\n %d th time interval = %g ... %g", j, t, tmax);
       rk_auto(
          fsal, neq, stage, isDll, isForcing, verbose, nknots, interpolate, 
          densetype, maxsteps, nt,
          &iknots, &it, &it_ext, &it_tot, &it_rej,
          istate, ipar,
          t,  tmax, hmin, hmax, alpha, beta,
          &dt, &errold,
          tt, y0, y1, y2, dy1, dy2, f, y, Fj, tmp, FF, rr, A,
          out, bb1, bb2, cc, dd, atol, rtol, yknots, yout,
          Func, Parms, Rho
      );
      /* in this mode, internal interpolation is skipped,
         so we can simply store the results at the end of each call */
      yout[j + 1] = tmax;
      for (i = 0; i < neq; i++) yout[j + 1 + nt * (1 + i)] = y2[i];
    }
  }

  /*====================================================================*/
  /* call derivs again to get global outputs                            */
  /* j = -1 suppresses unnecessary internal copying                     */
  /*====================================================================*/
  if (nout > 0) {
    for (int j = 0; j < nt; j++) {
      t = yout[j];
      for (i = 0; i < neq; i++) tmp[i] = yout[j + nt * (1 + i)];
      derivs(Func, t, tmp, Parms, Rho, FF, out, -1, neq, ipar, isDll, isForcing);
      for (i = 0; i < nout; i++) {
        yout[j + nt * (1 + neq + i)] = out[i];
      }
    }
  }

  /* attach diagnostic information (codes are compatible to lsoda) */
  setIstate(R_yout, R_istate, istate, it_tot, stage, fsal, qerr, it_rej);
  if (densetype == 2)   istate[12] = it_tot * stage + 2; /* number of function evaluations */

  /* verbose printing in debugging mode*/
  if (verbose) 
    Rprintf("\nNumber of time steps it = %d, it_ext = %d, it_tot = %d it_rej %d\n", 
      it, it_ext, it_tot, it_rej);

  /* release R resources */
  timesteps[0] = 0;
  timesteps[1] = 0;
  
  restore_N_Protected(old_N_Protect);
  return(R_yout);
}
예제 #7
0
int main (int argc, char *argv[])
{
    char headerless;
    double obstime;

    char string[80];
    long seed=-1;

    float fval;
    unsigned char A,B,C,D;
    char help=0;
    uint_fast32_t i;


    /* set up default variables */
    strcpy(inpfile,"stdin");
    strcpy(outfile,"stdout");
    headerless=0;
    machine_id=telescope_id=0;
    machine_id=10;
    telescope_id=4;
    nchans=1024;
    nbits=2;
    tstart=56000.0;
    tsamp=64.0; // microseconds.. will be converted to seconds later
    fch1=1581.804688;
    foff=-0.390625;
    nifs=1;
    nbeams=1;
    ibeam=1;
    obstime=270.0;
    output=stdout;

    help=getB("--help","-h",argc,argv,0);
    obstime=getF("--tobs","-T",argc,argv,obstime);
    telescope_id=getI("--tid","",argc,argv,telescope_id);
    machine_id=getI("--bid","",argc,argv,machine_id);
    tsamp=getF("--tsamp","-t",argc,argv,tsamp);
    tstart=getF("--mjd","-m",argc,argv,tstart);
    fch1=getF("--fch1","-F",argc,argv,fch1);
    foff=getF("--foff","-f",argc,argv,foff);
    nbits=getI("--nbits","-b",argc,argv,nbits);
    nchans=getI("--nchans","-c",argc,argv,nchans);
    seed=getI("--seed","-S",argc,argv,seed);
    char test_mode=getB("--test","-0",argc,argv,0);
    strcpy(outfile,getS("--out","-o",argc,argv,"stdout"));
    strcpy(source_name,getS("--name","-s",argc,argv,"FAKE"));
    getArgs(&argc,argv);
    if (help || argc > 1){
        for(i=1; i < argc; i++)logerr("Unknown argument '%s'",argv[i]);
        fastfake_help();
    }

    logmsg("FASTFAKE - M.Keith 2014");


    time_t t0 = time(NULL);
    if (seed<0)seed=t0;

    mjk_rand_t *rnd = mjk_rand_init(seed);


    logmsg("tobs          = %lfs",obstime);
    logmsg("tsamp         = %lfus",tsamp);
    logmsg("mjdstart      = %lf",tstart);
    logmsg("freq chan 1   = %lfMHz",fch1);
    logmsg("freq offset   = %lfMHz",foff);
    logmsg("output nbits  = %d",nbits);
    logmsg("random seed   = %ld",seed);
    logmsg("output file   = '%s'",outfile);

    tsamp*=1e-6; // convert tsamp to us

    if(STREQ(outfile,"stdout")){
        output=stdout;
    } else{
        output=fopen(outfile,"w");
    }

    if (!headerless) {
        logmsg("write header");
        send_string("HEADER_START");
        send_string("source_name");
        send_string(source_name);
        send_int("machine_id",machine_id);
        send_int("telescope_id",telescope_id);
        send_int("data_type",1);
        send_double("fch1",fch1);
        send_double("foff",foff);
        send_int("nchans",nchans);
        send_int("nbits",nbits);
        send_int("nbeams",nbeams);
        send_int("ibeam",ibeam);
        send_double("tstart",tstart);
        send_double("tsamp",tsamp);
        send_int("nifs",nifs);
        if (nbits==8){
            send_char("signed",OSIGN);
        }
        send_string("HEADER_END");
    }

    int bits_per_sample = (nbits * nchans * nifs);
    if (bits_per_sample % 8 != 0){
        logerr("bits per sample is not a multiple of 8");
        exit(1);
    }


    int bytes_per_sample = bits_per_sample / 8.0;
    uint64_t nsamples = (uint64_t)(obstime/tsamp+0.5);

    logmsg("Generate %lld samples, %.3lf GiB",nsamples,nsamples*bytes_per_sample/pow(2,30));

    uint64_t onepercent = nsamples/100;
    int percent=0;
    unsigned char* buffer = (unsigned char*) malloc(sizeof(unsigned char)*bytes_per_sample);

    if (nbits==1 || nbits==2 || nbits==4 | nbits==8){
        // integer samples
        for(uint64_t samp = 0; samp < nsamples; samp++){
            if (samp%onepercent ==0){
                double t1=(double)(time(NULL)-t0)+1e-3;
                double bytespersec = samp*bytes_per_sample/t1;
                fprintf(stderr,"Complete: % 3d%%. Sample: % 9lld Real time % 6.1lfs, Sim time % 6.1lfs. Speed % 4.2lfMiB/s\r",percent,samp,t1,(double)samp*tsamp,bytespersec/pow(2,20));
                fflush(stderr);
                percent+=1;
            }
            mjk_rand_gauss_atleast(rnd,nchans);
            const int chanskip = 8/nbits;
            //#pragma omp parallel for schedule(dynamic,1)
            for(uint64_t chan = 0; chan < nchans; chan+=chanskip){
                switch(nbits){
                    case 1:
                        buffer[chan/8] = mjk_rand(rnd)&0xFF; 
                        break;
                    case 2:
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        A = (unsigned char)(fval)&0x3;
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        B = (unsigned char)(fval)&0x3 << 2;
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        C = (unsigned char)(fval)&0x3 << 4;
                        fval = (mjk_rand_gauss(rnd)+1.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,3.0);
                        D = (unsigned char)(fval)&0x3 << 6;
                        buffer[chan/4]=A|B|C|D;
                        break;
                    case 4:
                        fval = (mjk_rand_gauss(rnd)*3.0+7.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,15.0);
                        A = (unsigned char)(fval)&0xF;
                        fval = (mjk_rand_gauss(rnd)*3.0+7.5);
                        fval = fmax(fval,0);
                        fval = fmin(fval,15.0);
                        B = ((unsigned char)(fval)&0xF)<<4;
                        buffer[chan/2] = A|B;
                        break;
                    case 8:
                        fval = (mjk_rand_gauss(rnd)*24.0+96.0); // more headroom.
                        fval = fmax(fval,0);
                        fval = fmin(fval,255.0);
                        buffer[chan] = (unsigned char)fval;
                        break;
                }
            }
            if(!test_mode)fwrite(buffer,sizeof(unsigned char),bytes_per_sample,output);
        }
    } else if (nbits==32){
        // float samples
        float* fbuf = (float*)buffer;
        for(uint64_t samp = 0; samp < nsamples; samp++){
            if (samp%onepercent ==0){
                double t1=(double)(time(NULL)-t0)+1e-3;
                double bytespersec = samp*bytes_per_sample/t1;
                fprintf(stderr,"Complete: % 3d%%. Sample: % 9lld Real time % 6.1lfs, Sim time % 6.1lfs. Speed % 4.2lfMiB/s\r",percent,samp,t1,(double)samp*tsamp,bytespersec/pow(2,20));
                fflush(stderr);
                percent+=1;
            }
            for(uint64_t chan = 0; chan < nchans; chan++){
                fbuf[chan] = mjk_rand_gauss(rnd);
            }
            if(!test_mode)fwrite(buffer,sizeof(unsigned char),bytes_per_sample,output);
        }
    }


    fprintf(stderr,"\n");
    free(buffer);
    mjk_rand_free(rnd);
    logmsg("Done!");
    fclose(output);

    return 0;
}
int main(int argc, char ** argv)
{
	int nLevels = 10;
	int levelCube = 8;
	vmml::vector<3,int> offset(0,0,0);

	lunchbox::Clock clock;

	std::vector<std::string> parameters;
	parameters.push_back(std::string(argv[1]));
	parameters.push_back(std::string(argv[2]));

	if (argc == 4)
	{
		std::string n(argv[3]);
		mO = boost::lexical_cast<double>(n);
	}

	hdf5File.init(parameters);

	if (!ccc.initParameter(parameters, mO))
	{
		std::cerr<<"Error init control cube cpu cache"<<std::endl;
	}

	vmml::vector<3, int> dim = hdf5File.getRealDimension();

	std::cout<<"Checking errors........."<<std::endl;

	bool error = false;
	for(int i=0; i<10 && !error; i++)
	{
		vmml::vector<3,int> s;
		vmml::vector<3,int> e;
		int nLevels = 0;
		int dimA = 0;
		int dimV = 0;
		do
		{
			s.set(rand() % dim.x(), 0, rand() % dim.z());
			do
			{
				e.set(rand() % (dim.x() - s.x()) + s.x(), rand() % (dim.y() - s.y()) + s.y(), rand() % (dim.z() - s.z()) + s.z());
			}
			while(s.x() >= e.x() || s.y() >= e.y() || s.z() >= e.z());
			 
			/* Calcular dimension del árbol*/
			dimA = fmin(e.x()-s.x(), fmin(e.y() - s.y(), e.z() - s.z()));
			float aux = logf(dimA)/logf(2.0);
			float aux2 = aux - floorf(aux);
			nLevels = aux2>0.0 ? aux+1 : aux;
			dimV = exp2(nLevels);
		}
		while(nLevels <= 1 || s.x()+dimV >= dim.x() || s.y()+dimV >= dim.y() || s.z()+dimV >= dim.z());

		int levelCube = rand() % (nLevels - 1) + 1;

		std::cout<<"Test "<<i<<" nLevels "<<nLevels<<" levelCube "<<levelCube<<" dimension "<<exp2(nLevels - levelCube)<<" offset "<<s<<" : "<<std::endl;

		error = test(nLevels, levelCube, s);
		if (error)
			std::cout<<"Test Fail!"<<std::endl;
		else
		{
			std::cout<<"Test OK"<<std::endl;
		}
	}

	std::cout<<"Checking performance........."<<std::endl;

	for(int i=0; i<10 && !error; i++)
	{
		vmml::vector<3,int> s;
		vmml::vector<3,int> e;
		int nLevels = 0;
		int dimA = 0;
		int dimV = 0;
		do
		{
			s.set(rand() % dim.x(), 0, rand() % dim.z());
			do
			{
				e.set(rand() % (dim.x() - s.x()) + s.x(), rand() % (dim.y() - s.y()) + s.y(), rand() % (dim.z() - s.z()) + s.z());
			}
			while(s.x() >= e.x() || s.y() >= e.y() || s.z() >= e.z());
			 
			dimA = fmin(e.x()-s.x(), fmin(e.y() - s.y(), e.z() - s.z()));;
			/* Calcular dimension del árbol*/
			float aux = logf(dimA)/logf(2.0);
			float aux2 = aux - floorf(aux);
			nLevels = aux2>0.0 ? aux+1 : aux;
			dimV = exp2(nLevels);
		}
		while(nLevels <= 1 || s.x()+dimV >= dim.x() || s.y()+dimV >= dim.y() || s.z()+dimV >= dim.z());

		int levelCube = rand() % (nLevels - 1) + 1;

		std::cout<<"Test "<<i<<" nLevels "<<nLevels<<" levelCube "<<levelCube<<" dimension "<<exp2(nLevels - levelCube)<<" offset "<<s<<" : "<<std::endl;

		double time = 0.0;
		clock.reset();
		testPerf(nLevels, levelCube, s);
		time = clock.getTimed()/1000.0;
		double bw = ((((dimV-s.x())*(dimV-s.y())*(dimV-s.z()))*sizeof(float))/1204.0/1024.0)/time;

		std::cout<<"Test "<<s<<" "<<e<<": "<<time<<" seconds ~ "<<bw<<" MB/s"<<std::endl;
	}

	if (!error)
	{
		int dimA = fmax(dim.x(), fmaxf(dim.y(), dim.z()));
		nLevels = 0;
		/* Calcular dimension del árbol*/
		float aux = logf(dimA)/logf(2.0);
		float aux2 = aux - floorf(aux);
		nLevels = aux2>0.0 ? aux+1 : aux;

		levelCube = rand() % (nLevels - 4) + 4;
		std::cout<<"Test reading complete volume"<<std::endl;
		if (test(nLevels, levelCube, vmml::vector<3,int>(0,0,0)))
		{
			std::cerr<<"Test Fail!!"<<std::endl;	
		}
		else
		{
			double time = 0.0;
			clock.reset();
			testPerf(nLevels, levelCube, vmml::vector<3,int>(0,0,0));
			time = clock.getTimed()/1000.0;
			double bw = (((dim.x()*dim.y()*dim.z())*sizeof(float))/1204.0/1024.0)/time;

			std::cout<<"Read complete volume "<<dim<<" : "<<time<<" seconds ~ "<<bw<<" MB/s"<<std::endl; 
		}
	}

	ccc.stopCache();
	hdf5File.close();

	return 0;
}
예제 #9
0
float2 fmin(float2 p, float2 q)
{
	return float2(fmin(p.x, q.x), fmin(p.y, q.y));
}
예제 #10
0
void AdvectionManager::advance(double dt, const TimeLevelIndex<2> &newTimeIdx,
                               const VelocityField &velocity) {
    TimeLevelIndex<2> oldTimeIdx = newTimeIdx-1;
    TimeLevelIndex<2> halfTimeIdx = newTimeIdx-0.5;
    const double eps = 1.0e-80;
    const double R = domain->getRadius();
    for (int s = 0; s < Q.size(); ++s) {
        ScalarField &q = *Q[s];
        double dQ;
        int J;
//#define ONLY_LAX_WENDROFF
//#define ONLY_UPWIND
#ifndef ONLY_UPWIND
        // ---------------------------------------------------------------------
        // Lax-Wendroff pass
        for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, HALF); ++i) {
                double f1 = dt/(R*dlon[i]);
                double f2 = f1/cosLatFull[j];
                double u = velocity(0)(halfTimeIdx, i, j);
                double q1 = q(oldTimeIdx, i,   j);
                double q2 = q(oldTimeIdx, i+1, j);
                FX(i, j) = 0.5*f1*(u*(q2+q1)-u*u*f2*(q2-q1));
            }
        }
        FX.applyBndCond();
        for (int j = 0; j < mesh->getNumGrid(1, HALF); ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
                double f1 = dt/(R*dlat[j]);
                double f2 = f1/cosLatHalf[j];
                double v = velocity(1)(halfTimeIdx, i, j)*cosLatHalf[j];
                double q1 = q(oldTimeIdx, i, j  );
                double q2 = q(oldTimeIdx, i, j+1);
                FY(i, j) = 0.5*f1*(v*(q2+q1)-v*v*f2*(q2-q1));
            }
        }
        FY.applyBndCond();
#endif
#if (!defined ONLY_LAX_WENDROFF && !defined ONLY_UPWIND)
        // ---------------------------------------------------------------------
        // calculate intermediate Qstar
        for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
                double fx1 = dt/(R*dlon[i]*cosLatFull[i]); // TODO: Should we support irregular lon grids?
                double fx2 = dt/(R*dlon[i]*cosLatFull[i]);
                double fy1 = dt/(R*dlat[j-1]*cosLatHalf[j-1]);
                double fy2 = dt/(R*dlat[j  ]*cosLatHalf[j  ]);
                double u1 = velocity(0)(halfTimeIdx, i-1, j);
                double u2 = velocity(0)(halfTimeIdx, i,   j);
                double v1 = velocity(1)(halfTimeIdx, i, j-1);
                double v2 = velocity(1)(halfTimeIdx, i, j  );
                double tmp1 = fabs(u1*fx1)*(1-fabs(u1*fx1));
                double tmp2 = fabs(u2*fx2)*(1-fabs(u2*fx2));
                double tmp3 = fabs(v1*fy1)*(1-fabs(v1*fy1));
                double tmp4 = fabs(v2*fy2)*(1-fabs(v2*fy2));
                double gamma = fmax(fmax(tmp1, tmp2), fmax(tmp3, tmp4));
                B(i, j) = 2/(2-2*gamma);
            }
        }
        for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
                Qstar(i, j) = q(oldTimeIdx, i, j)-B(i, j)/cosLatFull[j]*
                    (FX(i, j)-FX(i-1, j)+FY(i, j)-FY(i, j-1));
            }
        }
        // handle poles
        // south pole
        dQ = 0; J = 0;
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            dQ += B(i, J+1)*FY(i, J);
        }
        dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J];
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            Qstar(i, J) = q(oldTimeIdx, i, J)-dQ;
        }
        // north pole
        dQ = 0; J = mesh->getNumGrid(1, FULL)-1;
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            dQ += B(i, J-1)*FY(i, J-1);
        }
        dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J-1];
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            Qstar(i, J) = q(oldTimeIdx, i, J)+dQ;
        }
        // ---------------------------------------------------------------------
        // shape-preserving rule (A <= 0 is good)
        for (int j = 0; j < mesh->getNumGrid(1, FULL); ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
                double Qmin =  1.0e+15;
                double Qmax = -1.0e+15;
                if (j == 0) {
                    Qmin = fmin(fmin(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j+1)), Qmin);
                    Qmax = fmax(fmax(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j+1)), Qmax);
                } else if (j == mesh->getNumGrid(1, FULL)-1) {
                    Qmin = fmin(fmin(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j-1)), Qmin);
                    Qmax = fmax(fmax(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j-1)), Qmax);
                } else {
                    Qmin = fmin(fmin(fmin(q(oldTimeIdx, i-1, j), q(oldTimeIdx, i+1, j)),
                                     fmin(q(oldTimeIdx, i, j-1), q(oldTimeIdx, i, j+1))),
                                fmin(q(oldTimeIdx, i, j), Qmin));
                    Qmax = fmax(fmax(fmax(q(oldTimeIdx, i-1, j), q(oldTimeIdx, i+1, j)),
                                     fmax(q(oldTimeIdx, i, j-1), q(oldTimeIdx, i, j+1))),
                                fmax(q(oldTimeIdx, i, j), Qmax));
                }
                A(i, j) = (Qstar(i, j)-Qmax)*(Qstar(i, j)-Qmin);
            }
        }
        A.applyBndCond();
#endif
#ifndef ONLY_LAX_WENDROFF
        // ---------------------------------------------------------------------
        // upwind pass
        for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, HALF); ++i) {
#ifndef ONLY_UPWIND
                double tmp1 = (fabs(A(i,   j))+A(i,   j))/(fabs(A(i,   j))+eps);
                double tmp2 = (fabs(A(i+1, j))+A(i+1, j))/(fabs(A(i+1, j))+eps);
                double tmp3 = (fabs(A(i+1, j))+A(i+1, j))*(fabs(A(i, j))+A(i, j));
                double tmp4 = fabs(A(i, j))*fabs(A(i+1, j))+eps;
                double cxstar = 0.5*(tmp1+tmp2)-0.25*tmp3/tmp4;
#else
                double cxstar = 1;
#endif
                double f = dt/(R*dlon[i]);
                double u = velocity(0)(halfTimeIdx, i, j);
                double q1 = q(oldTimeIdx, i,   j);
                double q2 = q(oldTimeIdx, i+1, j);
                double cx = cxstar+(1-cxstar)*fabs(u*f/cosLatFull[j]);
                FX(i, j) = 0.5*f*(u*(q2+q1)-fabs(cx*u)*(q2-q1));
            }
        }
        FX.applyBndCond();
        for (int j = 0; j < mesh->getNumGrid(1, HALF); ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
#ifndef ONLY_UPWIND
                double tmp1 = (fabs(A(i, j  ))+A(i, j  ))/(fabs(A(i, j  ))+eps);
                double tmp2 = (fabs(A(i, j+1))+A(i, j+1))/(fabs(A(i, j+1))+eps);
                double tmp3 = (fabs(A(i, j+1))+A(i, j+1))*(fabs(A(i, j))+A(i, j));
                double tmp4 = fabs(A(i, j))*fabs(A(i, j+1))+eps;
                double cystar = 0.5*(tmp1+tmp2)-0.25*tmp3/tmp4;
#else
                double cystar = 1;
#endif
                double f = dt/(R*dlat[j]);
                double v = velocity(1)(halfTimeIdx, i, j)*cosLatHalf[j];
                double q1 = q(oldTimeIdx, i, j  );
                double q2 = q(oldTimeIdx, i, j+1);
                double cy = cystar+(1-cystar)*fabs(v*f/cosLatHalf[j]);
                FY(i, j) = 0.5*f*(v*(q2+q1)-fabs(cy*v)*(q2-q1));
            }
        }
        FY.applyBndCond();
#endif
        // ---------------------------------------------------------------------
        // calculate final Q
        for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) {
            for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
                q(newTimeIdx, i, j) = q(oldTimeIdx, i, j)-
                    (FX(i, j)-FX(i-1, j)+FY(i, j)-FY(i, j-1))/cosLatFull[j];
            }
        }
        // handle poles
        // south pole
        dQ = 0; J = 0;
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            dQ += FY(i, J);
        }
        dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J];
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            q(newTimeIdx, i, J) = q(oldTimeIdx, i, J)-dQ;
        }
        // north pole
        dQ = 0; J = mesh->getNumGrid(1, FULL)-1;
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            dQ += FY(i, J-1);
        }
        dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J-1];
        for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) {
            q(newTimeIdx, i, J) = q(oldTimeIdx, i, J)+dQ;
        }
        q.applyBndCond(newTimeIdx);
    }

    diagnose(newTimeIdx);
}
예제 #11
0
void drawClock(NVGcontext* vg, int screenWidth, int screenHeight) {
	int clockRadius = (fmin(screenWidth, screenHeight) - 10) / 2;

	NVGcolor baseColor = nvgRGB(145, 100, 0);
	NVGcolor lighterColor = nvgRGB(200, 140, 0);
	NVGcolor dblLighterColor = nvgRGB(255, 177, 0);
	NVGcolor lightestColor = nvgRGB(255, 195, 60);

	int widthLight = fmax(clockRadius * 0.0075, 1);
	int widthMedium = fmax(clockRadius * 0.013, 1);
	int widthHeavy = fmax(clockRadius * 0.025, 1);


	time_t t = time(NULL);
	struct tm localTime = *localtime(&t);

	nvgTranslate(vg, screenWidth / 2, screenHeight / 2);
	nvgStrokeColor(vg, baseColor);

	// Frame
	nvgSave(vg);
	nvgBeginPath(vg);
	nvgCircle(vg, 0, 0, clockRadius);
	nvgStrokeWidth(vg, widthMedium);
	nvgStroke(vg);
	nvgBeginPath(vg);
	nvgStrokeColor(vg, lighterColor);
	for (int i = 0; i < 12; i++) {
		nvgMoveTo(vg, 0, -clockRadius * 0.98);
		nvgLineTo(vg, 0, -clockRadius * 0.90);
		for (int j = 0; j < 5; j++) {
			nvgRotate(vg, 2 * M_PI / 12 / 5);
			nvgMoveTo(vg, 0, -clockRadius * 0.98);
			nvgLineTo(vg, 0, -clockRadius * 0.95);
		}
	}
	nvgStroke(vg);

	nvgBeginPath(vg);
	nvgFontFace(vg, "bold");

	int digitsRadius = clockRadius * 0.79;
	int digitLargeSize = clockRadius * 0.29;
	int digitSmallSize = clockRadius * 0.2;

	int clockTitleSize = clockRadius * 0.06;

	nvgFillColor(vg, dblLighterColor);

	char* nineTitle = "9";
	nvgFontSize(vg, digitLargeSize);
	nvgTranslate(vg, -digitsRadius, 0);
	nvgRotate(vg, - 3 * 2 * M_PI / 12);
	//nvgTranslate(vg, 0, -digitsRadius);
	drawTextCenter(vg, nineTitle, 0, 0);
	nvgFill(vg);

	nvgFillColor(vg, lighterColor);

	char* tenTitle = "10";
	nvgFontSize(vg, digitSmallSize);
	nvgTranslate(vg, 0, digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, -digitsRadius);
	drawTextCenter(vg, tenTitle, 0, 0);
	nvgFill(vg);

	char* elevenTitle = "11";
	nvgTranslate(vg, 0, digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, -digitsRadius);
	drawTextCenter(vg, elevenTitle, 0, 0);
	nvgFill(vg);

	nvgFillColor(vg, dblLighterColor);

	char* twelveTitle = "12";
	nvgFontSize(vg, digitLargeSize);
	nvgTranslate(vg, 0, digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, -digitsRadius);
	drawTextCenter(vg, twelveTitle, 0, 0);
	nvgFill(vg);

	nvgFillColor(vg, lighterColor);

	char* oneTitle = "1";
	nvgFontSize(vg, digitSmallSize);
	nvgTranslate(vg, 0, digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, -digitsRadius);
	drawTextCenter(vg, oneTitle, 0, 0);
	nvgFill(vg);

	char* twoTitle = "2";
	nvgTranslate(vg, 0, digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, -digitsRadius);
	drawTextCenter(vg, twoTitle, 0, 0);
	nvgFill(vg);

	nvgFillColor(vg, dblLighterColor);

	char* threeTitle = "3";
	nvgFontSize(vg, digitLargeSize);
	nvgTranslate(vg, 0, digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, -digitsRadius);
	drawTextCenter(vg, threeTitle, 0, 0);
	nvgFill(vg);

	nvgFillColor(vg, lighterColor);

	char* fourTitle = "4";
	nvgFontSize(vg, digitSmallSize);
	nvgTranslate(vg, 0, digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12 - M_PI);
	nvgTranslate(vg, 0, digitsRadius);
	drawTextCenter(vg, fourTitle, 0, 0);
	nvgFill(vg);

	char* fiveTitle = "5";
	nvgTranslate(vg, 0, -digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, digitsRadius);
	drawTextCenter(vg, fiveTitle, 0, 0);
	nvgFill(vg);

	nvgFillColor(vg, dblLighterColor);

	char* sixTitle = "6";
	nvgFontSize(vg, digitLargeSize);
	nvgTranslate(vg, 0, -digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, digitsRadius);
	drawTextCenter(vg, sixTitle, 0, 0);
	nvgFill(vg);

	nvgFillColor(vg, lighterColor);

	char* sevenTitle = "7";
	nvgFontSize(vg, digitSmallSize);
	nvgTranslate(vg, 0, -digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, digitsRadius);
	drawTextCenter(vg, sevenTitle, 0, 0);
	nvgFill(vg);

	char* eightTitle = "8";
	nvgTranslate(vg, 0, -digitsRadius);
	nvgRotate(vg, 2 * M_PI / 12);
	nvgTranslate(vg, 0, digitsRadius);
	drawTextCenter(vg, eightTitle, 0, 0);
	nvgFill(vg);

	nvgRestore(vg);

	nvgSave(vg);
	nvgFontFace(vg, "black");
	char* clockTitle = "ALPHA";
	nvgFontSize(vg, clockTitleSize);
	nvgFillColor(vg, baseColor);
	nvgTranslate(vg, 0, clockTitleSize);
	nvgTextLetterSpacing(vg, clockTitleSize);
	drawTextCenter(vg, clockTitle, 0, -2 * clockTitleSize);
	nvgFill(vg);
	nvgRestore(vg);

	double secAngle = 2 * M_PI / 60 * localTime.tm_sec;
	double minAngle = 2 * M_PI / 60 * localTime.tm_min + secAngle / 60;
	double hrAngle = 2 * M_PI / 12 * localTime.tm_hour + minAngle / 60;

	// Hour hand
	nvgStrokeColor(vg, lighterColor);
	nvgSave(vg);
	nvgRotate(vg, hrAngle);
	nvgBeginPath(vg);
	nvgMoveTo(vg, 0, clockRadius * 0.02);
	nvgLineTo(vg, 0, -clockRadius * 0.5);
	nvgStrokeWidth(vg, widthHeavy);
	nvgStroke(vg);
	nvgRestore(vg);

	// Minute hand
	nvgStrokeColor(vg, lighterColor);
	nvgSave(vg);
	nvgRotate(vg, minAngle);
	nvgBeginPath(vg);
	nvgMoveTo(vg, 0, clockRadius * 0.04);
	nvgLineTo(vg, 0, -clockRadius * 0.8);
	nvgStrokeWidth(vg, widthMedium);
	nvgStroke(vg);
	nvgRestore(vg);

	// Second hand
	nvgStrokeColor(vg, lightestColor);
	nvgSave(vg);
	nvgRotate(vg, secAngle);
	nvgBeginPath(vg);
	nvgMoveTo(vg, 0, clockRadius * 0.05);
	nvgLineTo(vg, 0, -clockRadius * 0.9);
	nvgStrokeWidth(vg, widthLight);
	nvgStroke(vg);
	nvgRestore(vg);
}
예제 #12
0
/*	Calculate change in momentum when there is contact. Return true or false if an adjustment was calculated
	If BC at the node, the delta momemtum should be zero in fixed direction
	Only called if both verified are verified and have 1 or more particles
	This method should ignore material that are ignoring cracks
*/
bool CrackSurfaceContact::GetDeltaMomentum(NodalPoint *np,Vector *delPa,CrackVelocityField *cva,CrackVelocityField *cvb,
											Vector *normin,int number,bool postUpdate,double deltime,int *inContact)
{
	// first determine if there is contact
	*inContact=IN_CONTACT;
	
	// velocities above and below
	bool hasParticles;
	double massa,massb;
	Vector pka=cva->GetCMatMomentum(hasParticles,&massa);
	Vector pkb=cvb->GetCMatMomentum(hasParticles,&massb);
	double mnode=1./(massa+massb);
	
	// screen low masses
	double aratio=massa*mnode;
	if(aratio<1.e-6 || aratio>0.999999) return false;
	//if(aratio<1.e-3 || aratio>0.999) return FALSE;
	
	// find Delta p_a (see notes)
	CopyScaleVector(delPa,&pkb,massa*mnode);
	AddScaledVector(delPa,&pka,-massb*mnode);
	
	// get normalized normal vector and find Delta p_a . n (actual (vb-va).n = dotn*(ma+mb)/(ma*mb))
	Vector norm;
	CopyScaleVector(&norm,normin,1./sqrt(DotVectors2D(normin,normin)));
	double dotn=DotVectors2D(delPa,&norm);
	
	// With the first check, any movement apart will be taken as noncontact
	// Also, frictional contact assume dvel<0.
	if(dotn>=0.)
		*inContact=SEPARATED;
	else
	{	// if approaching, check displacements
        // (Note: to use only velocity, skip the following displacement check)
		Vector dispa=cva->GetCMDisplacement(np,true);
		dispa.x/=massa;
		dispa.y/=massa;
		Vector dispb=cvb->GetCMDisplacement(np,true);
		dispb.x/=massb;
		dispb.y/=massb;
		
		// normal cod
		double dnorm=(dispb.x-dispa.x)*norm.x + (dispb.y-dispa.y)*norm.y
                        - mpmgrid.GetNormalCODAdjust(&norm,NULL,0);
		if(postUpdate)
		{	double dvel=(massa+massb)*dotn/(massa*massb);
			dnorm+=dvel*deltime;
		}
		
		// if current displacement positive then no contact
		if(dnorm >= 0.) *inContact=SEPARATED;
	}
	
	// if separated, then no contact unless possibly needed for an imperfect interface
	if(crackContactLaw[number]->ContactIsDone(*inContact==IN_CONTACT)) return false;
	
	// Now need to change momentum. For imperfect interface, change only for perfect directions
	double mredDE;
	if(crackContactLaw[number]->IsFrictionalContact())
	{	bool getHeating = postUpdate && ConductionTask::crackContactHeating;
		double mred = (massa*massb)/(massa+massb);
		double contactArea = 1.;
		if(crackContactLaw[number]->FrictionLawNeedsContactArea())
		{	// Angled path correction (2D only)
			double dist = mpmgrid.GetPerpendicularDistance(&norm, NULL, 0.);
			
			// Area correction method (new): sqrt(2*vmin/vtot)*vtot/dist = sqrt(2*vmin*vtot)/dist
			double vola = cva->GetVolumeNonrigid(true),volb = cvb->GetVolumeNonrigid(true),voltot=vola+volb;
			contactArea = sqrt(2.0*fmin(vola,volb)*voltot)/dist;
			if(fmobj->IsAxisymmetric()) contactArea *= np->x;
		}
		if(!crackContactLaw[number]->GetFrictionalDeltaMomentum(delPa,&norm,dotn,&mredDE,mred,
										getHeating,contactArea,*inContact==IN_CONTACT,deltime,NULL))
		{	return false;
		}
		if(mredDE>0.)
		{	double qrate = mredDE/mred;
			NodalPoint::frictionWork += qrate;
		
			// As heat source need nJ/sec or multiply by 1/timestep
			// Note that this is after transport rates are calculated (by true in last parameter)
			conduction->AddFluxCondition(np,fabs(qrate/deltime),true);
		}
	}
	else
	{
		// Contact handled here only perfect interface (Dt or Dn < 0)
		// Imperfect interfaces are handled as forces later
		if(crackContactLaw[number]->IsPerfectTangentialInterface())
		{	if(!crackContactLaw[number]->IsPerfectNormalInterface(*inContact==IN_CONTACT))
			{	// prefect in tangential, but imperfect in normal direction
				// make stick in tangential direction only
				AddScaledVector(delPa,&norm,-dotn);
			}
			// else perfect in both so return with the stick conditions already in delPa
		}
		else if(crackContactLaw[number]->IsPerfectNormalInterface(*inContact==IN_CONTACT))
		{	// perfect in normal direction, but imperfect in tangential direction
			// make stick in normal direction only
			CopyScaleVector(delPa,&norm,dotn);
		}
		else
		{	// no change in momentum, just imperfect interface forces later and nothing changed here
			return false;
		}
		
	}
	
	return true;
}
예제 #13
0
   sd->val = from;
   pd->intvl_to = to;

   if (pd->intvl_from < sd->val_min) {
        pd->intvl_from = sd->val_min;
        sd->val = sd->val_min;
   }
   if (pd->intvl_to > sd->val_max) pd->intvl_to = sd->val_max;

   efl_ui_slider_val_set(obj);
}

EOLIAN static void
_efl_ui_slider_interval_interval_value_get(const Eo *obj EINA_UNUSED, Efl_Ui_Slider_Interval_Data *pd, double *from, double *to)
{
   if (from) *from = fmin(pd->intvl_from, pd->intvl_to);
   if (to) *to = fmax(pd->intvl_from, pd->intvl_to);
}

EOLIAN static Efl_Object *
_efl_ui_slider_interval_efl_object_constructor(Eo *obj, Efl_Ui_Slider_Interval_Data *pd EINA_UNUSED)
{
   ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);

   if (!elm_widget_theme_klass_get(obj))
     elm_widget_theme_klass_set(obj, "slider_interval");
   obj = efl_constructor(efl_super(obj, MY_CLASS));

   return obj;
}
/*
 * Core function for computing the ROM waveform.
 * Interpolate projection coefficient data and evaluate coefficients at desired (q, chi).
 * Construct 1D splines for amplitude and phase.
 * Compute strain waveform from amplitude and phase.
*/
static int SEOBNRv1ROMDoubleSpinCore(
  COMPLEX16FrequencySeries **hptilde,
  COMPLEX16FrequencySeries **hctilde,
  double phiRef,
  double fRef,
  double distance,
  double inclination,
  double Mtot_sec,
  double q,
  double chi1,
  double chi2,
  const REAL8Sequence *freqs_in, /* Frequency points at which to evaluate the waveform (Hz) */
  double deltaF
  /* If deltaF > 0, the frequency points given in freqs are uniformly spaced with
   * spacing deltaF. Otherwise, the frequency points are spaced non-uniformly.
   * Then we will use deltaF = 0 to create the frequency series we return. */
  )
{
  /* Check output arrays */
  if(!hptilde || !hctilde)
    XLAL_ERROR(XLAL_EFAULT);
  SEOBNRROMdataDS *romdata=&__lalsim_SEOBNRv1ROMDS_data;
  if(*hptilde || *hctilde) {
    XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p",(*hptilde),(*hctilde));
    XLAL_ERROR(XLAL_EFAULT);
  }
  int retcode=0;

  // 'Nudge' parameter values to allowed boundary values if close by
  if (q < 1.0)     nudge(&q, 1.0, 1e-6);
  if (q > 10.0)    nudge(&q, 10.0, 1e-6);
  if (chi1 < -1.0) nudge(&chi1, -1.0, 1e-6);
  if (chi1 > 0.6)  nudge(&chi1, 0.6, 1e-6);
  if (chi2 < -1.0) nudge(&chi2, -1.0, 1e-6);
  if (chi2 > 0.6)  nudge(&chi2, 0.6, 1e-6);

  /* If either spin > 0.6, model not available, exit */
  if ( chi1 < -1.0 || chi2 < -1.0 || chi1 > 0.6 || chi2 > 0.6 ) {
    XLALPrintError( "XLAL Error - %s: chi1 or chi2 smaller than -1 or larger than 0.6!\nSEOBNRv1ROMDoubleSpin is only available for spins in the range -1 <= a/M <= 0.6.\n", __func__);
    XLAL_ERROR( XLAL_EDOM );
  }

  if (q > 10) {
    XLALPrintError( "XLAL Error - %s: q=%lf larger than 10!\nSEOBNRv1ROMDoubleSpin is only available for q in the range 1 <= q <= 10.\n", __func__, q);
    XLAL_ERROR( XLAL_EDOM );
  }

  /* Find frequency bounds */
  if (!freqs_in) XLAL_ERROR(XLAL_EFAULT);
  double fLow  = freqs_in->data[0];
  double fHigh = freqs_in->data[freqs_in->length - 1];

  if(fRef==0.0)
    fRef=fLow;

  /* Convert to geometric units for frequency */
  double Mf_ROM_min = fmax(gA[0], gPhi[0]);               // lowest allowed geometric frequency for ROM
  double Mf_ROM_max = fmin(gA[nk_amp-1], gPhi[nk_phi-1]); // highest allowed geometric frequency for ROM
  double fLow_geom = fLow * Mtot_sec;
  double fHigh_geom = fHigh * Mtot_sec;
  double fRef_geom = fRef * Mtot_sec;
  double deltaF_geom = deltaF * Mtot_sec;

  // Enforce allowed geometric frequency range
  if (fLow_geom < Mf_ROM_min)
    XLAL_ERROR(XLAL_EDOM, "Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g.\n", fLow_geom, Mf_ROM_min);
  if (fHigh_geom == 0)
    fHigh_geom = Mf_ROM_max;
  else if (fHigh_geom > Mf_ROM_max) {
    XLALPrintWarning("Maximal frequency Mf_high=%g is greater than highest ROM frequency Mf_ROM_Max=%g. Using Mf_high=Mf_ROM_Max.", fHigh_geom, Mf_ROM_max);
    fHigh_geom = Mf_ROM_max;
  }
  else if (fHigh_geom < Mf_ROM_min)
    XLAL_ERROR(XLAL_EDOM, "End frequency %g is smaller than starting frequency %g!\n", fHigh_geom, fLow_geom);
  if (fRef_geom > Mf_ROM_max) {
    XLALPrintWarning("Reference frequency Mf_ref=%g is greater than maximal frequency in ROM Mf=%g. Starting at maximal frequency in ROM.\n", fRef_geom, Mf_ROM_max);
    fRef_geom = Mf_ROM_max; // If fref > fhigh we reset fref to default value of cutoff frequency.
  }
  if (fRef_geom < Mf_ROM_min) {
    XLALPrintWarning("Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fRef_geom, Mf_ROM_min);
    fRef_geom = Mf_ROM_min;
  }

  /* Internal storage for w.f. coefficiencts */
  SEOBNRROMdataDS_coeff *romdata_coeff=NULL;
  SEOBNRROMdataDS_coeff_Init(&romdata_coeff);
  REAL8 amp_pre;

  /* Interpolate projection coefficients and evaluate them at (q,chi1,chi2) */
  retcode=TP_Spline_interpolation_3d(
    q,                         // Input: q-value for which projection coefficients should be evaluated
    chi1,                      // Input: chi1-value for which projection coefficients should be evaluated
    chi2,                      // Input: chi2-value for which projection coefficients should be evaluated
    romdata->cvec_amp,         // Input: data for spline coefficients for amplitude
    romdata->cvec_phi,         // Input: data for spline coefficients for phase
    romdata->cvec_amp_pre,     // Input: data for spline coefficients for amplitude prefactor
    romdata_coeff->c_amp,      // Output: interpolated projection coefficients for amplitude
    romdata_coeff->c_phi,      // Output: interpolated projection coefficients for phase
    &amp_pre                   // Output: interpolated amplitude prefactor
  );

  if(retcode!=0) {
    SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);
    XLAL_ERROR(retcode, "Parameter-space interpolation failed.");
  }

  // Compute function values of amplitude an phase on sparse frequency points by evaluating matrix vector products
  // amp_pts = B_A^T . c_A
  // phi_pts = B_phi^T . c_phi
  gsl_vector* amp_f = gsl_vector_alloc(nk_amp);
  gsl_vector* phi_f = gsl_vector_alloc(nk_phi);
  gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bamp, romdata_coeff->c_amp, 0.0, amp_f);
  gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bphi, romdata_coeff->c_phi, 0.0, phi_f);

  // Setup 1d splines in frequency
  gsl_interp_accel *acc_amp = gsl_interp_accel_alloc();
  gsl_spline *spline_amp = gsl_spline_alloc(gsl_interp_cspline, nk_amp);
  gsl_spline_init(spline_amp, gA, gsl_vector_const_ptr(amp_f,0), nk_amp);

  gsl_interp_accel *acc_phi = gsl_interp_accel_alloc();
  gsl_spline *spline_phi = gsl_spline_alloc(gsl_interp_cspline, nk_phi);
  gsl_spline_init(spline_phi, gPhi, gsl_vector_const_ptr(phi_f,0), nk_phi);


  size_t npts = 0;
  LIGOTimeGPS tC = {0, 0};
  UINT4 offset = 0; // Index shift between freqs and the frequency series
  REAL8Sequence *freqs = NULL;
  if (deltaF > 0)  { // freqs contains uniform frequency grid with spacing deltaF; we start at frequency 0
    /* Set up output array with size closest power of 2 */
    npts = NextPow2(fHigh_geom / deltaF_geom) + 1;
    if (fHigh_geom < fHigh * Mtot_sec) /* Resize waveform if user wants f_max larger than cutoff frequency */
      npts = NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1;

    XLALGPSAdd(&tC, -1. / deltaF);  /* coalesce at t=0 */
    *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts);
    *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts);

    // Recreate freqs using only the lower and upper bounds
    // Use fLow, fHigh and deltaF rather than geometric frequencies for numerical accuracy
    double fHigh_temp = fHigh_geom / Mtot_sec;
    UINT4 iStart = (UINT4) ceil(fLow / deltaF);
    UINT4 iStop = (UINT4) ceil(fHigh_temp / deltaF);
    freqs = XLALCreateREAL8Sequence(iStop - iStart);
    if (!freqs) {
      XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
    }
    for (UINT4 i=iStart; i<iStop; i++)
      freqs->data[i-iStart] = i*deltaF_geom;

    offset = iStart;
  } else { // freqs contains frequencies with non-uniform spacing; we start at lowest given frequency
    npts = freqs_in->length;
    *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts);
    *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts);
    offset = 0;

    freqs = XLALCreateREAL8Sequence(freqs_in->length);
    if (!freqs) {
      XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
    }
    for (UINT4 i=0; i<freqs_in->length; i++)
      freqs->data[i] = freqs_in->data[i] * Mtot_sec;
  }


  if (!(*hptilde) || !(*hctilde))
  {
      XLALDestroyREAL8Sequence(freqs);

      gsl_spline_free(spline_amp);
      gsl_spline_free(spline_phi);
      gsl_interp_accel_free(acc_amp);
      gsl_interp_accel_free(acc_phi);
      gsl_vector_free(amp_f);
      gsl_vector_free(phi_f);
      SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);
      XLAL_ERROR(XLAL_EFUNC, "Waveform allocation failed.");
  }
  memset((*hptilde)->data->data, 0, npts * sizeof(COMPLEX16));
  memset((*hctilde)->data->data, 0, npts * sizeof(COMPLEX16));

  XLALUnitMultiply(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit);
  XLALUnitMultiply(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit);

  COMPLEX16 *pdata=(*hptilde)->data->data;
  COMPLEX16 *cdata=(*hctilde)->data->data;

  REAL8 cosi = cos(inclination);
  REAL8 pcoef = 0.5*(1.0 + cosi*cosi);
  REAL8 ccoef = cosi;

  REAL8 s = 0.5; // Scale polarization amplitude so that strain agrees with FFT of SEOBNRv1
  double Mtot = Mtot_sec / LAL_MTSUN_SI;
  double amp0 = Mtot * amp_pre * Mtot_sec * LAL_MRSUN_SI / (distance); // Correct overall amplitude to undo mass-dependent scaling used in ROM

  // Evaluate reference phase for setting phiRef correctly
  double phase_change = gsl_spline_eval(spline_phi, fRef_geom, acc_phi) - 2*phiRef;

  // Assemble waveform from aplitude and phase
  for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence
    double f = freqs->data[i];
    if (f > Mf_ROM_max) continue; // We're beyond the highest allowed frequency; since freqs may not be ordered, we'll just skip the current frequency and leave zero in the buffer
    int j = i + offset; // shift index for frequency series if needed
    double A = gsl_spline_eval(spline_amp, f, acc_amp);
    double phase = gsl_spline_eval(spline_phi, f, acc_phi) - phase_change;
    COMPLEX16 htilde = s*amp0*A * cexp(I*phase);
    pdata[j] =      pcoef * htilde;
    cdata[j] = -I * ccoef * htilde;
  }

  /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */

  // Get SEOBNRv1 ringdown frequency for 22 mode
  double Mf_final = SEOBNRROM_Ringdown_Mf_From_Mtot_q(Mtot_sec, q, chi1, chi2, SEOBNRv1);

  UINT4 L = freqs->length;
  // prevent gsl interpolation errors
  if (Mf_final > freqs->data[L-1])
    Mf_final = freqs->data[L-1];
  if (Mf_final < freqs->data[0])
  {
      XLALDestroyREAL8Sequence(freqs);

      gsl_spline_free(spline_amp);
      gsl_spline_free(spline_phi);
      gsl_interp_accel_free(acc_amp);
      gsl_interp_accel_free(acc_phi);
      gsl_vector_free(amp_f);
      gsl_vector_free(phi_f);
      SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);
      XLAL_ERROR(XLAL_EDOM, "f_ringdown < f_min");
  }

  // Time correction is t(f_final) = 1/(2pi) dphi/df (f_final)
  // We compute the dimensionless time correction t/M since we use geometric units.
  REAL8 t_corr = gsl_spline_eval_deriv(spline_phi, Mf_final, acc_phi) / (2*LAL_PI);

  // Now correct phase
  for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence
    double f = freqs->data[i] - fRef_geom;
    int j = i + offset; // shift index for frequency series if needed
    pdata[j] *= cexp(-2*LAL_PI * I * f * t_corr);
    cdata[j] *= cexp(-2*LAL_PI * I * f * t_corr);
  }

  XLALDestroyREAL8Sequence(freqs);

  gsl_spline_free(spline_amp);
  gsl_spline_free(spline_phi);
  gsl_interp_accel_free(acc_amp);
  gsl_interp_accel_free(acc_phi);
  gsl_vector_free(amp_f);
  gsl_vector_free(phi_f);
  SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);

  return(XLAL_SUCCESS);
}
예제 #15
0
zarray_t *apriltag_quad_thresh(apriltag_detector_t *td, image_u8_t *im)
{
    ////////////////////////////////////////////////////////
    // step 1. threshold the image, creating the edge image.

    int w = im->width, h = im->height, s = im->stride;

    image_u8_t *threshim = threshold(td, im);
    assert(threshim->stride == s);

    image_u8_t *edgeim = image_u8_create(w, h);

    if (1) {
        image_u8_t *sumim = image_u8_create(w, h);

        // apply a horizontal sum kernel of width 3
        for (int y = 0; y < h; y++) {
            for (int x = 1; x+1 < w; x++) {

                sumim->buf[y*s + x] =
                    threshim->buf[y*s + x - 1] +
                    threshim->buf[y*s + x + 0] +
                    threshim->buf[y*s + x + 1];
            }
        }
        timeprofile_stamp(td->tp, "sumim");

        // deglitch
        if (td->qtp.deglitch) {
            for (int y = 1; y+1 < h; y++) {
                for (int x = 1; x+1 < w; x++) {
                    // edge: black pixel next to white pixel
                    if (threshim->buf[y*s + x] == 0 &&
                        sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] == 8) {
                        threshim->buf[y*s + x] = 1;
                        sumim->buf[y*s + x - 1]++;
                        sumim->buf[y*s + x + 0]++;
                        sumim->buf[y*s + x + 1]++;
                    }

                    if (threshim->buf[y*s + x] == 1 &&
                        sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] == 1) {
                        threshim->buf[y*s + x] = 0;
                        sumim->buf[y*s + x - 1]--;
                        sumim->buf[y*s + x + 0]--;
                        sumim->buf[y*s + x + 1]--;
                   }
                }
            }

            timeprofile_stamp(td->tp, "deglitch");
        }

        // apply a vertical sum kernel of width 3; check if any
        // over-threshold pixels are adjacent to an under-threshold
        // pixel.
        //
        // There are two types of edges: white pixels neighboring a
        // black pixel, and black pixels neighboring a white pixel. We
        // label these separately.  (Values 0xc0 and 0x3f are picked
        // such that they add to 255 (see below) and so that they can be
        // viewed as pixel intensities for visualization purposes.)
        //
        // symmetry of detection. We don't want to use JUST "black
        // near white" (or JUST "white near black"), because that
        // biases the detection towards one side of the edge. This
        // measurably reduces detection performance.
        //
        // On large tags, we could treat "neighbor" pixels the same
        // way. But on very small tags, there may be other edges very
        // near the tag edge. Since each of these edges is effectively
        // two pixels thick (the white pixel near the black pixel, and
        // the black pixel near the white pixel), it becomes likely
        // that these two nearby edges will actually touch.
        //
        // A partial solution to this problem is to define edges to be
        // adjacent white-near-black and black-near-white pixels.
        //

        for (int y = 1; y+1 < h; y++) {
            for (int x = 1; x+1 < w; x++) {
                if (threshim->buf[y*s + x] == 0) {
                    // edge: black pixel next to white pixel
                    if (sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] > 0)
                        edgeim->buf[y*s + x] = 0xc0;
                } else {
                    // edge: white pixel next to black pixel when both
                    // edge types are on, we get less bias towards one
                    // side of the edge.
                    if (sumim->buf[y*s + x - s] + sumim->buf[y*s + x] + sumim->buf[y*s + x + s] < 9)
                        edgeim->buf[y*s + x] = 0x3f;
                }
            }
        }

        if (td->debug) {
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    threshim->buf[y*s + x] *= 255;
                }
            }

            image_u8_write_pnm(threshim, "debug_threshold.pnm");
            image_u8_write_pnm(edgeim, "debug_edge.pnm");
//            image_u8_destroy(edgeim2);
        }

        image_u8_destroy(threshim);
        image_u8_destroy(sumim);
    }

    timeprofile_stamp(td->tp, "edges");

    ////////////////////////////////////////////////////////
    // step 2. find connected components.

    unionfind_t *uf = unionfind_create(w * h);

    for (int y = 1; y < h - 1; y++) {
        for (int x = 1; x < w -1; x++) {
            uint8_t v = edgeim->buf[y*s + x];
            if (v==0)
                continue;

            // (dx,dy) pairs for 8 connectivity:
            //          (REFERENCE) (1, 0)
            // (-1, 1)    (0, 1)    (1, 1)
            //
            // i.e., the minimum value of dx should be:
            //   y=0:   1
            //   y=1:  -1
            for (int dy = 0; dy <= 1; dy++) {
                for (int dx = 1-2*dy; dx <= 1; dx++) {
                    if (edgeim->buf[(y+dy)*s + (x+dx)] == v) {
                        unionfind_connect(uf, y*w + x, (y+dy)*w + x + dx);
                    }
                }
            }
        }
    }

    timeprofile_stamp(td->tp, "unionfind");

    zhash_t *clustermap = zhash_create(sizeof(uint64_t), sizeof(zarray_t*),
                                       zhash_uint64_hash, zhash_uint64_equals);

    for (int y = 1; y < h-1; y++) {
        for (int x = 1; x < w-1; x++) {

            uint8_t v0 = edgeim->buf[y*s + x];
            if (v0 == 0)
                continue;

            uint64_t rep0 = unionfind_get_representative(uf, y*w + x);

            // 8 connectivity. (4 neighbors to check).
//            for (int dy = 0; dy <= 1; dy++) {
//                for (int dx = 1-2*dy; dx <= 1; dx++) {

            // 4 connectivity. (2 neighbors to check)
            for (int n = 1; n <= 2; n++) {
                int dy = n & 1;
                int dx = (n & 2) >> 1;

                uint8_t v1 = edgeim->buf[(y+dy)*s + x + dx];
                if (v0 + v1 != 255)
                    continue;
                uint64_t rep1 = unionfind_get_representative(uf, (y+dy)*w + x+dx);

                uint64_t clusterid;
                if (rep0 < rep1)
                    clusterid = (rep1 << 32) + rep0;
                else
                    clusterid = (rep0 << 32) + rep1;

                zarray_t *cluster = NULL;
                if (!zhash_get(clustermap, &clusterid, &cluster)) {
                    cluster = zarray_create(sizeof(struct pt));
                    zhash_put(clustermap, &clusterid, &cluster, NULL, NULL);
                }

                // NB: We will add some points multiple times to a
                // given cluster.  I don't know an efficient way to
                // avoid that here; we remove them later on when we
                // sort points by pt_compare_theta.
                if (1) {
                    struct pt p = { .x = x, .y = y};
                    zarray_add(cluster, &p);
                }
                if (1) {
                    struct pt p = { .x = x+dx, .y = y+dy};
                    zarray_add(cluster, &p);
                }
            }
        }
    }

    // make segmentation image.
    if (td->debug) {
        image_u8_t *d = image_u8_create(w, h);
        assert(d->stride == s);

        uint8_t *colors = (uint8_t*) calloc(w*h, 1);

        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                uint32_t v = unionfind_get_representative(uf, y*w+x);
                uint32_t sz = unionfind_get_set_size(uf, y*w+x);
                if (sz < td->qtp.min_cluster_pixels)
                    continue;

                uint8_t color = colors[v];

                if (color == 0) {
                    const int bias = 20;
                    color = bias + (random() % (255-bias));
                    colors[v] = color;
                }

                float mix = 0.7;
                mix = 1.0;
                d->buf[y*d->stride + x] = mix*color + (1-mix)*im->buf[y*im->stride + x];
            }
        }

        free(colors);

        image_u8_write_pnm(d, "debug_segmentation.pnm");
        image_u8_destroy(d);
    }

    timeprofile_stamp(td->tp, "make clusters");


    ////////////////////////////////////////////////////////
    // step 3. process each connected component.

    zarray_t *clusters = zhash_values(clustermap);
    zhash_destroy(clustermap);

    zarray_t *quads = zarray_create(sizeof(struct quad));

    int sz = zarray_size(clusters);
    int chunksize = 1 + sz / (APRILTAG_TASKS_PER_THREAD_TARGET * td->nthreads);
    struct quad_task tasks[sz / chunksize + 1];

    int ntasks = 0;
    for (int i = 0; i < sz; i += chunksize) {
        tasks[ntasks].td = td;
        tasks[ntasks].cidx0 = i;
        tasks[ntasks].cidx1 = imin(sz, i + chunksize);
        tasks[ntasks].h = h;
        tasks[ntasks].w = w;
        tasks[ntasks].quads = quads;
        tasks[ntasks].clusters = clusters;
        tasks[ntasks].im = im;

        workerpool_add_task(td->wp, do_quad_task, &tasks[ntasks]);
        ntasks++;
    }

    workerpool_run(td->wp);

    timeprofile_stamp(td->tp, "fit quads to clusters");

    if (td->debug) {
        FILE *f = fopen("debug_lines.ps", "w");
        fprintf(f, "%%!PS\n\n");

        image_u8_t *im2 = image_u8_copy(im);
        image_u8_darken(im2);
        image_u8_darken(im2);

        // assume letter, which is 612x792 points.
        double scale = fmin(612.0/im->width, 792.0/im2->height);
        fprintf(f, "%.15f %.15f scale\n", scale, scale);
        fprintf(f, "0 %d translate\n", im2->height);
        fprintf(f, "1 -1 scale\n");

        postscript_image(f, im);

        for (int i = 0; i < zarray_size(quads); i++) {
            struct quad *q;
            zarray_get_volatile(quads, i, &q);

            float rgb[3];
            int bias = 100;

            for (int i = 0; i < 3; i++)
                rgb[i] = bias + (random() % (255-bias));

            fprintf(f, "%f %f %f setrgbcolor\n", rgb[0]/255.0f, rgb[1]/255.0f, rgb[2]/255.0f);
            fprintf(f, "%.15f %.15f moveto %.15f %.15f lineto %.15f %.15f lineto %.15f %.15f lineto %.15f %.15f lineto stroke\n",
                    q->p[0][0], q->p[0][1],
                    q->p[1][0], q->p[1][1],
                    q->p[2][0], q->p[2][1],
                    q->p[3][0], q->p[3][1],
                    q->p[0][0], q->p[0][1]);
        }

        fclose(f);
    }

//        printf("  %d %d %d %d\n", indices[0], indices[1], indices[2], indices[3]);

/*
        if (td->debug) {
            for (int i = 0; i < 4; i++) {
            int i0 = indices[i];
                int i1 = indices[(i+1)&3];

                if (i1 < i0)
                    i1 += zarray_size(cluster);

                for (int j = i0; j <= i1; j++) {
                    struct pt *p;
                    zarray_get_volatile(cluster, j % zarray_size(cluster), &p);

                    edgeim->buf[p->y*edgeim->stride + p->x] = 30+64*i;
                }
            }
            } */

    unionfind_destroy(uf);

    for (int i = 0; i < zarray_size(clusters); i++) {
        zarray_t *cluster;
        zarray_get(clusters, i, &cluster);
        zarray_destroy(cluster);
    }

    zarray_destroy(clusters);

    image_u8_destroy(edgeim);

    return quads;
}
예제 #16
0
float3 fmin(float3 p, float3 q)
{
	return float3(fmin(p.x, q.x), fmin(p.y, q.y), fmin(p.z, q.z));
}
예제 #17
0
void evolve(double *G, double *h, double *u, double g, double dx, double dt, int nBC, int n,double *nG, double *nh)
{
    //modifies nh and nG to give the new values of h and G after a single time step
    double idx = 1.0 / dx;
    double ithree = 1.0 / 3.0;
    int i = nBC - 1;

    //calculate values at right of i cell
    double hir = h[i];
    double Gir = G[i];
    double uir = u[i];

    //calculate values at left of i+1 cell
    double hip1l = h[i+1];
    double Gip1l = G[i+1];
    double uip1l = u[i+1];

    //right force

    double duer = idx*(u[i+2] - u[i+1]);
    double duel = idx*(u[i] - u[i-1]);

    double sqrtghel = sqrt(g* hir);
    double sqrtgher = sqrt(g* hip1l);

    double sl = fmin(0,fmin(uir - sqrtghel, uip1l - sqrtgher));
    double sr = fmax(0,fmax(uir + sqrtghel, uip1l + sqrtgher));

    double felh = uir*hir;
    double felG = Gir*uir + 0.5*g*hir*hir - 2*ithree*hir*hir*hir*duel*duel;
    double ferh = uip1l*hip1l;
    double ferG = Gip1l*uip1l + 0.5*g*hip1l*hip1l -2*ithree*hip1l*hip1l*hip1l*duer*duer;

    double isrmsl = 0.0;

    if(sr != sl) isrmsl = 1.0 / (sr - sl);
   
    double foh = isrmsl*(sr*felh - sl*ferh + sl*sr*(hip1l - hir));

    double foG = isrmsl*(sr*felG - sl*ferG + sl*sr*(Gip1l - Gir));

    double fih = foh;
    double fiG = foG;
    for (i = nBC ; i < n +nBC;i++)
    {
        //i right

        hir = h[i];
        Gir = G[i];
        uir = u[i];

        //i+1 left

        hip1l = h[i+1];
        Gip1l = G[i+1];
        uip1l = u[i+1];


        duer = idx*(u[i+2] - u[i+1]);
        duel = idx*(u[i] - u[i-1]);

        sqrtghel = sqrt(g*hir);
        sqrtgher = sqrt(g*hip1l);

        sl = fmin(0,fmin(uir - sqrtghel, uip1l - sqrtgher));
        sr = fmax(0,fmax(uir + sqrtghel, uip1l + sqrtgher));

        felh = uir*hir;
        felG = Gir*uir + 0.5*g*hir*hir - 2*ithree*hir*hir*hir*duel*duel;
        ferh = uip1l*hip1l;
        ferG = Gip1l*uip1l + 0.5*g*hip1l*hip1l -2*ithree*hip1l*hip1l*hip1l*duer*duer;

        isrmsl = 0.0;

        if(sr != sl) isrmsl = 1.0 / (sr - sl);
   
        foh = isrmsl*(sr*felh - sl*ferh + sl*sr*(hip1l - hir));
        foG = isrmsl*(sr*felG - sl*ferG + sl*sr*(Gip1l - Gir));

        //source term
        nh[i -nBC] = h[i] -dt*idx*(foh - fih);
        nG[i -nBC] = G[i] -dt*idx*(foG -fiG);

        fih = foh;
        fiG = foG;  
 
    }
    
   
}
예제 #18
0
float4 fmin(float4 p, float4 q)
{
	return float4(fmin(p.x, q.x), fmin(p.y, q.y), fmin(p.z, q.z), fmin(p.w, q.w));
}
예제 #19
0
    /**
     *  \brief Callback for the joystick topic.
     */
    void joyCb(const sensor_msgs::Joy::ConstPtr& msg)
    {
        last_recv_ = ros::Time::now();

        deadman_ = msg->buttons[deadman_button_];
        deadman_head_ = msg->buttons[deadman_head_button_];
        deadman_arm_angular_ = msg->buttons[deadman_arm_angular_button_];
        deadman_arm_linear_ = msg->buttons[deadman_arm_linear_button_];

        if (!deadman_)
        {
            controller_.stop();
            return;
        }

        controller_.start();

        if (deadman_arm_angular_ || deadman_arm_linear_)
        {
            // Stop moving base
            vx = 0.0;
            vw = 0.0;

            // Stop head
            pan = 0.0;
            tilt = 0.0;

            // Stop moving torso
            torso = 0.0;

            if (deadman_arm_linear_)
            {
                // Linear takes precedence over angular
                arm_lx = msg->axes[arm_lx_axis_]*arm_linear_scale_;
                arm_ly = msg->axes[arm_ly_axis_]*arm_linear_scale_;
                arm_lz = msg->axes[arm_lz_axis_]*arm_linear_scale_;
                arm_ax = 0.0;
                arm_ay = 0.0;
                arm_az = 0.0;
            }
            else
            {
                arm_lx = 0.0;
                arm_ly = 0.0;
                arm_lz = 0.0;
                arm_ax = -msg->axes[arm_ax_axis_]*arm_angular_scale_;
                arm_ay = msg->axes[arm_ay_axis_]*arm_angular_scale_;
                arm_az = msg->axes[arm_az_axis_]*arm_angular_scale_;
            }

            controller_.setArmTwist(arm_lx, arm_ly, arm_lz, arm_ax, arm_ay, arm_az);
        }
        else if (deadman_head_)
        {
            // Stop moving base
            vx = 0.0;
            vw = 0.0;

            // Get head
            pan = msg->axes[head_pan_axis_]*head_pan_step_;
            tilt = msg->axes[head_tilt_axis_]*head_tilt_step_;

            // Stop moving torso
            torso = 0.0;

            // Stop moving arm
            controller_.disableArm();
        }
        else
        {
            // Get base velocities
            vx = msg->axes[base_vx_axis_] * base_max_vel_x_;
            vw = msg->axes[base_vw_axis_] * base_max_vel_w_;

            // Limit velocities
            vx = fmax(fmin(vx, base_max_vel_x_), -base_max_vel_x_);
            vw = fmax(fmin(vw, base_max_vel_w_), -base_max_vel_w_);

            // Stop moving head
            pan = 0.0;
            tilt = 0.0;

            // Get torso
            if (msg->buttons[torso_down_button_])
                torso = -torso_step_;
            else if (msg->buttons[torso_up_button_])
                torso = torso_step_;
            else
                torso = 0.0;

            // Get Gripper
            if (msg->buttons[gripper_open_button_])
                controller_.openGripper();
            else if (msg->buttons[gripper_close_button_])
                controller_.closeGripper();

            // Stop moving arm
            controller_.disableArm();
        }
    }
예제 #20
0
void psi_rtree_split(psi_rtree_node* newnodes[2], psi_rtree_data* entries) {

	psi_int lohi, splitind, group, i, j, c;
	psi_real mtmp, atmp[2];
	psi_real sortdata[NODE_MAX+1];
	psi_int sortinds[NODE_MAX+1];
	psi_rvec splitboxes[2][2]; 

	// for keeping track of the best possible split
	psi_int axis, best_axis;
	psi_real margin, overlap, area, best_margin, best_overlap, best_area;
	psi_int best_sorts[PSI_NDIM][NODE_MAX+1];
	psi_int best_split_inds[PSI_NDIM];

	psi_rtree_sort_helper_data = sortdata; 
	best_margin = 1.0e30;
	best_axis = -1;
	for(axis = 0; axis < PSI_NDIM; ++axis) {
		margin = 0.0;
		best_overlap = 1.0e30;
		best_area = 1.0e30;
		for(lohi = 0; lohi < 1; ++ lohi) {

			// sort by the low or hi box bounds
			for(c = 0; c < NODE_MAX+1; ++c) {
				sortdata[c] = entries[c].rbox[lohi].xyz[axis];
				sortinds[c] = c;
			}
			qsort(sortinds, NODE_MAX+1, sizeof(psi_int), psi_rtree_sort_helper);
	
			// divide into several distributions based on the sort
			// splitind determines the split within the sorted group
			for(splitind = NODE_MIN; splitind < (NODE_MAX-NODE_MIN+1); ++splitind) {

				// get the two bounding boxes for this split
				for(group = 0; group < 2; ++group)
					for(i = 0; i < PSI_NDIM; ++i) {
						splitboxes[group][0].xyz[i] = 1.0e30;
						splitboxes[group][1].xyz[i] = -1.0e30;
					}
				for(c = 0; c < NODE_MAX+1; ++c) {
					group = (c >= splitind);
					for(i = 0; i < PSI_NDIM; ++i) {
						if(entries[sortinds[c]].rbox[0].xyz[i] < splitboxes[group][0].xyz[i]) 
							splitboxes[group][0].xyz[i] = entries[sortinds[c]].rbox[0].xyz[i];
						if(entries[sortinds[c]].rbox[1].xyz[i] > splitboxes[group][1].xyz[i]) 
							splitboxes[group][1].xyz[i] = entries[sortinds[c]].rbox[1].xyz[i];
					}
				}

				// sum the margin-values for each box
				// TODO: This is wrong for dimensions higher than 3
				for(group = 0; group < 2; ++group)
					for(i = 0; i < PSI_NDIM; ++i) {
						mtmp = 1.0;
						for(j = 0; j < PSI_NDIM-1; ++j)
							mtmp *= splitboxes[group][1].xyz[(i+j)%PSI_NDIM]-splitboxes[group][0].xyz[(i+j)%PSI_NDIM];
						margin += 2.0*mtmp;
					}

				// get the area value
				for(group = 0; group < 2; ++group) {
					atmp[group] = 1.0;
					for(i = 0; i < PSI_NDIM; ++i)
						atmp[group] *= splitboxes[group][1].xyz[i]-splitboxes[group][0].xyz[i];
				}
				area = atmp[0] + atmp[1];

				// get the overlap between the two boxes
				overlap = 1.0;
				for(i = 0; i < PSI_NDIM; ++i) {
					if(splitboxes[0][0].xyz[i] > splitboxes[1][1].xyz[i] ||
							splitboxes[0][1].xyz[i] < splitboxes[1][0].xyz[i]) {
						overlap = 0.0;
						break;
					}
					overlap *= fmin(splitboxes[0][1].xyz[i], splitboxes[1][1].xyz[i])
								- fmax(splitboxes[0][0].xyz[i], splitboxes[1][0].xyz[i]);
				}

				if(overlap < best_overlap || (overlap == best_overlap && area < best_area)) {
					best_overlap = overlap;
					best_area = area;
					memcpy(best_sorts[axis], sortinds, (NODE_MAX+1)*sizeof(psi_int));
					best_split_inds[axis] = splitind;
				}
			}
		}
		if(margin < best_margin) {
			best_margin = margin;
			best_axis = axis;
		}
	}

	// now, we have information on the best split in hand
	// use the indices we saved to redistribute the entries
	newnodes[0]->nchildren = 0;
	newnodes[1]->nchildren = 0;
	for(c = 0; c < NODE_MAX+1; ++c) {
		group = (c >= best_split_inds[best_axis]);
		newnodes[group]->children[newnodes[group]->nchildren++] = entries[best_sorts[best_axis][c]];
	}
}
예제 #21
0
void compute_tangents_C(double *tangents, double *y, double *energies,
                        int n_dofs_image, int n_images
                        ) {

    /* Compute the tangents for every degree of freedom of a NEBM band,
     * following the rules from Henkelman and Jonsson [Henkelman et al.,
     * Journal of Chemical Physics 113, 22 (2000)]
     *
     * We assume we have n_images images in the band, which is represented by
     * the *y array. the *y array has the structure

     *      y = [ theta0_0 phi0_0 theta0_1, phi0_1  ... phi0_(n_dofs_images),
     *            theta1_0 phi1_0 theta1_1, phi1_1  ... phi1_(n_dofs_images),
     *            ...
     *            theta(n_images -1)_0 phi(n_images -1)_0  ... phi(n_images - 1)_(n_dofs_images)]

     * where (theta(i)_j, phi(i)_j) are the spherical coordinates of the j-th
     * spin in the i-th image of the band. Thus we have n_dofs_image spins per
     * image. Images at the extremes, i=0,(n_images-1), are kept fixed, thus we
     * do not compute the tangents for them.
     *
     * The *energies array contains the energy of every image, thus its length
     * is n_images.
     *
     * The tangents have the same length of an image, thus the *tangents array
     * has length (n_images * n_dofs_image), just as the *y array, and we keep
     * the first and last n_dofs_image components as zero (they correspond to
     * the extreme images)
     *
     * To compute the tangents, we use the t+ and t- vectors. Denoting the i-th
     * image by Y_i, these vectors are defined by

     *      t+_i = Y_(i+1) - Y_i          t-_i = Y_i - Y_(i-1)

     * Then, when an image is at a saddle point, we have, using the energies
     * of the neighbouring images,:

     *               __
     *      t_i  =   |   t+_i    if  E_(i+1) > E_i > E_(i-1)
     *              <
     *               |_  t-_i    if  E_(i+1) < E_i < E_(i-1)

     * Otherwise, if we have a maximum or a minimum  (E_(i+1) < E_i > E_(i-1)
     * or E_(i+1) > E_i < E_(i-1) respectively), we use an average of the
     * vectors:
     *
                     __
     *      t_i  =   |   t+_i * dE_max + t-_i * dE_min  if  E_(i+1) > E_(i-1)
     *              <
     *               |_  t+_i * dE_min + t-_i * dE_max  if  E_(i+1) < E_(i-1)

     * where dE_max = max( |E_(i+1) - E_i|, |E_i - E_(i-1)|) and
     *       dE_min = min( |E_(i+1) - E_i|, |E_i - E_(i-1)|)
     *
     */

    int i, j;

    // Index where the components of an image start in the *y array,
    int im_idx;
    // And also the previous and next images:
    int next_im_idx, prev_im_idx;

    double *t_plus;
    double *t_minus;
    t_plus  = malloc(n_dofs_image * sizeof(double));
    t_minus = malloc(n_dofs_image * sizeof(double));

    double deltaE_plus, deltaE_minus;
    double deltaE_MAX, deltaE_MIN;

    for(i = 1; i < n_images - 1; i++){

        im_idx = i * (n_dofs_image);
        next_im_idx = (i + 1) * (n_dofs_image);
        prev_im_idx = (i - 1) * (n_dofs_image);

        // Tangents of the i-th image
        double * t = &tangents[im_idx];

        // Compute the t+ and t- vectors for the i-th image of the band, which
        // is given by the difference of the Y_i image with its neighbours
        for(j = 0; j < n_dofs_image; j++){
            t_plus[j]  = y[next_im_idx + j] - y[im_idx + j];
            t_minus[j] = y[im_idx + j]      - y[prev_im_idx + j];
        }

        // Similarly, compute the energy differences
        deltaE_plus  = energies[i + 1] - energies[i];
        deltaE_minus = energies[i]     - energies[i - 1];

        /* Now we follow Henkelman and Jonsson rules [Henkelman et al., Journal
         * of Chemical Physics 113, 22 (2000)] for the tangent directions
         * (remember that there is a tangent for every spin (degree of
         * freedom))
         *
         * The first two cases are straightforward: If the energy has a
         * positive (negative) slope, just make the difference between the spin
         * directions with respect to the right (left) image.
         *
         * The other case is when the image is an energy maximum, or minimum
         */

        /* ----------------------------------------------------------------- */

        if(deltaE_plus > 0 && deltaE_minus > 0) {
            for(j = 0; j < n_dofs_image; j++) t[j] = t_plus[j];
        }

        /* ----------------------------------------------------------------- */

        else if(deltaE_plus < 0 && deltaE_minus < 0) {
            for(j = 0; j < n_dofs_image; j++) t[j] = t_minus[j];
        }

        /* ----------------------------------------------------------------- */

        else {

            /* According to the energy of the neighbouring images, the tangent
             * of the i-th image will be a combination of the differences wrt
             * to the left and right images components weighted according to
             * the neighbours energies
             */
            deltaE_MAX = fmax(fabs(deltaE_plus), fabs(deltaE_minus));
            deltaE_MIN = fmin(fabs(deltaE_plus), fabs(deltaE_minus));

            if (energies[i + 1] > energies[i - 1]) {
                for(j = 0; j < n_dofs_image; j++) {
                    t[j] = t_plus[j] * deltaE_MAX + t_minus[j] * deltaE_MIN;
                }
            }

            else {
                for(j = 0; j < n_dofs_image; j++) {
                    t[j] = t_plus[j] * deltaE_MIN + t_minus[j] * deltaE_MAX;
                }
            }

        }

        /* ----------------------------------------------------------------- */

    } // Close loop in images
    free(t_plus);
    free(t_minus);
} // Close main function
예제 #22
0
struct flow_interpolation_line_contributions *
flow_interpolation_line_contributions_create(flow_c * context, const uint32_t output_line_size,
                                             const uint32_t input_line_size,
                                             const struct flow_interpolation_details * details)
{
    const double sharpen_ratio = flow_interpolation_details_percent_negative_weight(details);
    const double desired_sharpen_ratio = details->sharpen_percent_goal / 100.0;

    const double scale_factor = (double)output_line_size / (double)input_line_size;
    const double downscale_factor = fmin(1.0, scale_factor);
    const double half_source_window = (details->window + 0.5) / downscale_factor;

    const uint32_t allocated_window_size = (int)ceil(2 * (half_source_window - TONY)) + 1;
    uint32_t u, ix;
    struct flow_interpolation_line_contributions * res
        = LineContributions_alloc(context, output_line_size, allocated_window_size);
    if (res == NULL) {
        FLOW_add_to_callstack(context);
        return NULL;
    }
    double negative_area = 0;
    double positive_area = 0;

    for (u = 0; u < output_line_size; u++) {
        const double center_src_pixel = ((double)u + 0.5) / scale_factor - 0.5;

        const int left_edge = (int)floor(center_src_pixel) - ((allocated_window_size - 1) / 2);
        const int right_edge = left_edge + allocated_window_size - 1;

        const uint32_t left_src_pixel = (uint32_t)int_max(0, left_edge);
        const uint32_t right_src_pixel = (uint32_t)int_min(right_edge, (int)input_line_size - 1);

        double total_weight = 0.0;
        double total_negative_weight = 0.0;

        const uint32_t source_pixel_count = right_src_pixel - left_src_pixel + 1;

        if (source_pixel_count > allocated_window_size) {
            flow_interpolation_line_contributions_destroy(context, res);
            FLOW_error(context, flow_status_Invalid_internal_state);
            return NULL;
        }

        res->ContribRow[u].Left = left_src_pixel;
        res->ContribRow[u].Right = right_src_pixel;

        float * weights = res->ContribRow[u].Weights;

        // commented: additional weight for edges (doesn't seem to be too effective)
        // for (ix = left_edge; ix <= right_edge; ix++) {
        for (ix = left_src_pixel; ix <= right_src_pixel; ix++) {
            int tx = ix - left_src_pixel;
            // int tx = min(max(ix, left_src_pixel), right_src_pixel) - left_src_pixel;
            double add = (*details->filter)(details, downscale_factor *((double)ix - center_src_pixel));
            if (fabs(add) <= 0.00000002){
                add = 0.0;
                // Weights below a certain threshold make consistent x-plat
                // integration test results impossible. pos/neg zero, etc.
                // They should be rounded down to zero at the threshold at which results are consistent.
            }
            weights[tx] = (float)add;
            total_weight += add;
            total_negative_weight -= fmin(0,add);
        }

        float neg_factor, pos_factor;
        if (total_weight <= 0 || desired_sharpen_ratio > sharpen_ratio){
            float total_positive_weight = total_weight + total_negative_weight;
            float target_negative_weight = desired_sharpen_ratio * total_positive_weight;
            pos_factor = 1;
            neg_factor = target_negative_weight / total_negative_weight;
        }else{
            neg_factor = pos_factor = (float)(1.0f / total_weight);
        }
        for (ix = 0; ix < source_pixel_count; ix++) {
            if (weights[ix] < 0) {
                weights[ix] *= neg_factor;
                negative_area -= weights[ix];
            } else {
                weights[ix] *= pos_factor;
                positive_area += weights[ix];
            }
        }

        //Shrink to improve perf & result consistency
        int32_t iix;
        //Shrink region from the right
        for (iix = source_pixel_count - 1; iix >= 0; iix--){
            if (weights[iix] != 0) break;
            res->ContribRow[u].Right--;
        }
        //Shrink region from the left
        for (iix = 0; iix < (int32_t)source_pixel_count; iix++){
            if (weights[0] != 0) break;
            res->ContribRow[u].Weights++;
            weights++;
            res->ContribRow[u].Left++;
        }
    }
    res->percent_negative = negative_area / positive_area;
    return res;
}
예제 #23
0
파일: HWxcount.c 프로젝트: wrengels/HWxtest
void heterozygote (unsigned r, unsigned c, COUNTTYPE * R)
{
    if(tableCount < 0) return;  // aborted because of time limit
	COUNTTYPE *res, *resn;
	int lower, upper;
	unsigned ntables;
	unsigned i, arc, ar1, ar2, a32, a31;
	COUNTTYPE * Rnew = R + nAlleles;
	double countsSoFar;
    unsigned long long hash;
    //	NSNumber * n;
	
    res = R-1; // to make res a 1-based version of R
    resn = Rnew-1; // so resn is 1-based for Rnew
	lower = res[r];
	for (i = 1; i < c; i++) lower -= res[i];
    lower = fmax(0, lower);
    upper = fmin(res[r], res[c]);
    if(c > 2) for (arc = lower; arc <= upper; arc++) {
        memcpy(Rnew, R, Rbytes); // Put a fresh set of residuals from R into Rnew
        
        // decrement residuals for the current value of arc.
        resn[r] -= arc;
        resn[c] -= arc;
        heterozygote(r, c-1, Rnew);
    }
	if(c==2){
		if(r > 3) for (ar2= lower; ar2 <= upper; ar2++) {
            memcpy(Rnew, R, Rbytes); // Put a fresh set of residuals from R into Rnew
    // decrement residuals for the current value of arc.
			resn[r] -= ar2;
			resn[c] -= ar2;
			// The value of ar1 is now fixed, so no need for any more calls to heterozygote in this row
			ar1 = fmin(resn[r], resn[1]);
			resn[1] -= ar1;
			resn[r] -= ar1;
            // Before calling homozygote, see if we have visited this node before by comparing its hash tag.
            hash = makeHash(r-1, Rnew);
            i = 0;
            // Search list of old nodes
            while (hash != nodez[i].hash && i < nextNode) i++;
            if(i < nextNode) {
				// old node was found, no need to go any further.
				tableCount += nodez[i].count;
			} else {
				// new node
				countsSoFar =  tableCount;
                homozygote(r-1, Rnew);
                if (nextNode < MAXNODE) {
                    // Make a new node
                    nodez[i].hash = hash;
                    nodez[i].count = tableCount - countsSoFar;
                    nextNode++;
                }
  			} // new node
        }
		if(r==3) // and c = 2, then we can handle a series of two-allele cases with no deeper recursion
		{
			for(a32 = lower; a32 <= upper; a32++) {
				a31 = fmin(res[1], res[3]-a32); //Value of a31 is now fixed for each a32
				ntables = (fmin(res[1] - a31, res[2]-a32))/2 + 1;
				tableCount += ntables;
			}
		} // if r == 3
	} // if c == 2
} // heterozygote
예제 #24
0
	/**
	 * Converts a ratio with ideal value of 1 to a score. The resulting function is piecewise
	 * linear going from (0,0) to (1,100) to (2,0) and is 0 for all inputs outside the range 0-2
	 */
	double ratioToScore(double ratio)
	{
		return (fmax(0, fmin(100*(1-fabs(1-ratio)), 100)));
	}
예제 #25
0
void mcmc(tree *tr, analdef *adef)
{
  int i=0;

  tr->startLH = tr->likelihood;
  printBothOpen("start minimalistic search with LH %f\n", tr->likelihood);
  printBothOpen("tr LH %f, startLH %f\n", tr->likelihood, tr->startLH);
  
  int insert_id;
  int j;

  int maxradius = 30;
  int accepted_spr = 0, accepted_nni = 0, accepted_bl = 0, accepted_model = 0, accepted_gamma = 0, inserts = 0;
  int rejected_spr = 0, rejected_nni = 0, rejected_bl = 0, rejected_model = 0, rejected_gamma = 0;
  int num_moves = 10000;
  boolean proposalAccepted;
  boolean proposalSuccess;
  prop which_proposal;
  double testr;
  double acceptance;

  srand (440);
  double totalTime = 0.0, proposalTime = 0.0, blTime = 0.0, printTime = 0.0;
  double t_start = gettime();
  double t;


  //allocate states
  double bl_prior_exp_lambda = 0.1;
  double bl_sliding_window_w = 0.005;
  double gm_sliding_window_w = 0.75;
  double rt_sliding_window_w = 0.5;
  state *curstate = state_init(tr, adef, maxradius, bl_sliding_window_w, rt_sliding_window_w, gm_sliding_window_w, bl_prior_exp_lambda);
  printStateFileHeader(curstate);
  set_start_bl(curstate);
  printf("start bl_prior: %f\n",curstate->bl_prior);
  set_start_prior(curstate);
  curstate->hastings = 1;//needs to be set by the proposal when necessary

  /* Set the starting LH with a full traversal */
  evaluateGeneric(tr, tr->start, TRUE);	 
  tr->startLH = tr->likelihood;
  printBothOpen("Starting with tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);

  /* Set reasonable model parameters */
  evaluateGeneric(curstate->tr, curstate->tr->start, FALSE); // just for validation 
  printBothOpen("tr LH before modOpt %f\n",curstate->tr->likelihood);
  printSubsRates(curstate->tr, curstate->model, curstate->numSubsRates);

  /* optimize the model with Brents method for reasonable starting points */
  modOpt(curstate->tr, curstate->adef, 5.0); /* not by proposal, just using std raxml machinery... */
  evaluateGeneric(curstate->tr, curstate->tr->start, FALSE); // just for validation 
  printBothOpen("tr LH after modOpt %f\n",curstate->tr->likelihood);
  printSubsRates(curstate->tr, curstate->model, curstate->numSubsRates);
  recordSubsRates(curstate->tr, curstate->model, curstate->numSubsRates, curstate->curSubsRates);

  int first = 1;
  /* beginning of the MCMC chain */
  for(j=0; j<num_moves; j++)
  {
    //printBothOpen("iter %d, tr LH %f, startLH %f\n",j, tr->likelihood, tr->startLH);
    //printRecomTree(tr, TRUE, "startiter");
    proposalAccepted = FALSE;
    t = gettime(); 

    /*
      evaluateGeneric(tr, tr->start); // just for validation 
      printBothOpen("before proposal, iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
    */

    which_proposal = proposal(curstate);
    if (first == 1)
    {
      first = 0;
      curstate->curprior = curstate->newprior;
    }
   //printBothOpen("proposal done, iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
    assert(which_proposal == SPR || which_proposal == stNNI ||
           which_proposal == UPDATE_ALL_BL || 
           which_proposal == UPDATE_MODEL || which_proposal == UPDATE_GAMMA);
    proposalTime += gettime() - t;
    /* decide upon acceptance */
    testr = (double)rand()/(double)RAND_MAX;
    //should look something like 
    acceptance = fmin(1,(curstate->hastings) * 
		      (exp(curstate->newprior-curstate->curprior)) * (exp(curstate->tr->likelihood-curstate->tr->startLH)));
    
    /*
      //printRecomTree(tr, FALSE, "after proposal");
      printBothOpen("after proposal, iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
    */
    if(testr < acceptance)
    {
      proposalAccepted = TRUE;

      switch(which_proposal)
	{
	case SPR:      
	  //printRecomTree(tr, TRUE, "after accepted");
	  // printBothOpen("SPR new topology , iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
	   accepted_spr++;
	  break;
	case stNNI:	  
	  printBothOpen("NNI new topology , iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
	  accepted_nni++;
	  break;
	case UPDATE_ALL_BL:	  
	  //      printBothOpen("BL new , iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
	  accepted_bl++;
	  break;
	case UPDATE_MODEL:      
	  //	printBothOpen("Model new, iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
	  accepted_model++;
	  break;
	case UPDATE_GAMMA:      
	  //	printBothOpen("Gamma new, iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
	  accepted_gamma++;
	  break;
	default:
	  assert(0);
	}

      curstate->tr->startLH = curstate->tr->likelihood;  //new LH
      curstate->curprior = curstate->newprior;          
    }
    else
    {
      //printBothOpen("rejected , iter %d tr LH %f, startLH %f, %i \n", j, tr->likelihood, tr->startLH, which_proposal);
      resetState(which_proposal,curstate);
      
      switch(which_proposal)
	{
	case SPR:
	  rejected_spr++;
	  break;
	case stNNI:
	  rejected_nni++;
	  break;
	case UPDATE_ALL_BL:
	  rejected_bl++;
	  break;
	case UPDATE_MODEL:
	  rejected_model++;
	  break;
	case UPDATE_GAMMA:
	  rejected_gamma++;
	  break;
	default:
	  assert(0);
	}
      
      evaluateGeneric(tr, tr->start, FALSE); 
      
      // just for validation 

      if(fabs(curstate->tr->startLH - tr->likelihood) > 1.0E-10)
      {
        printBothOpen("WARNING: LH diff %.10f\n", curstate->tr->startLH - tr->likelihood);
      }
      //printRecomTree(tr, TRUE, "after reset");
      //printBothOpen("after reset, iter %d tr LH %f, startLH %f\n", j, tr->likelihood, tr->startLH);
      assert(fabs(curstate->tr->startLH - tr->likelihood) < 1.0E-10);
    }       
    inserts++;
    
    /* need to print status */
    if (j % 50 == 0)
    {
      t = gettime(); 
      printBothOpen("sampled at iter %d, tr LH %f, startLH %f, prior %f, incr %f\n",j, tr->likelihood, tr->startLH, curstate->curprior, tr->likelihood - tr->startLH);
      boolean printBranchLengths = TRUE;
      /*printSimpleTree(tr, printBranchLengths, adef);*/
      //TODO: print some parameters to a file 
      printStateFile(j,curstate);
      printTime += gettime() - t;
    }
  }

  t = gettime(); 
  treeEvaluate(tr, 1);
  blTime += gettime() - t;
  printBothOpen("accepted SPR %d, accepted stNNI %d, accepted BL %d, accepted model %d, accepted gamma %d, num moves tried %d, SPRs with max radius %d\n", 
		accepted_spr, accepted_nni, accepted_bl, accepted_model, accepted_gamma, num_moves, maxradius);
  printBothOpen("rejected SPR %d, rejected stNNI %d, rejected BL %d, rejected model %d, rejected gamma %d\n",
		rejected_spr, rejected_nni, rejected_bl, rejected_model, rejected_gamma);
  printBothOpen("ratio SPR %f, ratio stNNI %f,  ratio BL %f, ratio model %f, ratio gamma %f\n",
		accepted_spr/(double)(rejected_spr+accepted_spr), accepted_nni/(double)(rejected_nni+accepted_nni), accepted_bl/(double)(rejected_bl+accepted_bl), 
		accepted_model/(double)(rejected_model+accepted_model), accepted_gamma/(double)(rejected_gamma+accepted_gamma));
  printBothOpen("total  %f, BL %f, printing %f, proposal %f\n", gettime()- t_start, blTime, printTime, proposalTime);
  assert(inserts == num_moves);
  state_free(curstate);
}
int
DjVuPalette::compute_palette(int maxcolors, int minboxsize)
{
  if (!hist)
    G_THROW( ERR_MSG("DjVuPalette.no_color") );
  if (maxcolors<1 || maxcolors>MAXPALETTESIZE)
    G_THROW( ERR_MSG("DjVuPalette.many_colors") );
  
  // Paul Heckbert: "Color Image Quantization for Frame Buffer Display", 
  // SIGGRAPH '82 Proceedings, page 297.  (also in ppmquant)
  
  // Collect histogram colors
  int sum = 0;
  int ncolors = 0;
  GTArray<PData> pdata;
  { // extra nesting for windows
    for (GPosition p = *hist; p; ++p)
    {
      pdata.touch(ncolors);
      PData &data = pdata[ncolors++];
      int k = hist->key(p);
      data.p[0] = (k>>16) & 0xff;
      data.p[1] = (k>>8) & 0xff;
      data.p[2] = (k) & 0xff;
      data.w = (*hist)[p];
      sum += data.w;
    }
  }
  // Create first box
  GList<PBox> boxes;
  PBox newbox;
  newbox.data = pdata;
  newbox.colors = ncolors;
  newbox.boxsize = 256;
  newbox.sum = sum;
  boxes.append(newbox);
  // Repeat spliting boxes
  while (boxes.size() < maxcolors)
    {
      // Find suitable box
      GPosition p;
      for (p=boxes; p; ++p)
        if (boxes[p].colors>=2 && boxes[p].boxsize>minboxsize) 
          break;
      if (! p)
        break;
      // Find box boundaries
      PBox &splitbox = boxes[p];
      unsigned char pmax[3];
      unsigned char pmin[3];
      pmax[0] = pmin[0] = splitbox.data->p[0];
      pmax[1] = pmin[1] = splitbox.data->p[1];
      pmax[2] = pmin[2] = splitbox.data->p[2];
      { // extra nesting for windows
        for (int j=1; j<splitbox.colors; j++)
        {
          pmax[0] = umax(pmax[0], splitbox.data[j].p[0]);
          pmax[1] = umax(pmax[1], splitbox.data[j].p[1]);
          pmax[2] = umax(pmax[2], splitbox.data[j].p[2]);
          pmin[0] = umin(pmin[0], splitbox.data[j].p[0]);
          pmin[1] = umin(pmin[1], splitbox.data[j].p[1]);
          pmin[2] = umin(pmin[2], splitbox.data[j].p[2]);
        }
      }
      // Determine split direction and sort
      int bl = pmax[0]-pmin[0]; 
      int gl = pmax[1]-pmin[1];
      int rl = pmax[2]-pmin[2];
      splitbox.boxsize = (bl>gl ? (rl>bl ? rl : bl) : (rl>gl ? rl : gl));
      if (splitbox.boxsize <= minboxsize)
        continue;
      if (gl == splitbox.boxsize)
        qsort(splitbox.data, splitbox.colors, sizeof(PData), gcomp);
      else if (rl == splitbox.boxsize)
        qsort(splitbox.data, splitbox.colors, sizeof(PData), rcomp);
      else
        qsort(splitbox.data, splitbox.colors, sizeof(PData), bcomp);
      // Find median
      int lowercolors = 0;
      int lowersum = 0;
      while (lowercolors<splitbox.colors-1 && lowersum+lowersum<splitbox.sum)
        lowersum += splitbox.data[lowercolors++].w;
      // Compute new boxes
      newbox.data = splitbox.data + lowercolors;
      newbox.colors = splitbox.colors - lowercolors;
      newbox.sum = splitbox.sum - lowersum;
      splitbox.colors = lowercolors;
      splitbox.sum = lowersum;
      // Insert boxes at proper location
      GPosition q;
      for (q=p; q; ++q)
        if (boxes[q].sum < newbox.sum)
          break;
      boxes.insert_before(q, newbox);
      for (q=p; q; ++q)
        if (boxes[q].sum < splitbox.sum)
          break;
      boxes.insert_before(q, boxes, p);
    }
  // Fill palette array
  ncolors = 0;
  palette.empty();
  palette.resize(0,boxes.size()-1);
  { // extra nesting for windows
    for (GPosition p=boxes; p; ++p)
    {
      PBox &box = boxes[p];
      // Compute box representative color
      float bsum = 0;
      float gsum = 0;
      float rsum = 0;
      for (int j=0; j<box.colors; j++)
        {
          float w = (float)box.data[j].w;
          bsum += box.data[j].p[0] * w;
          gsum += box.data[j].p[1] * w;
          rsum += box.data[j].p[2] * w;
        }
      PColor &color = palette[ncolors++];
      color.p[0] = (unsigned char) fmin(255, bsum/box.sum);
      color.p[1] = (unsigned char) fmin(255, gsum/box.sum);
      color.p[2] = (unsigned char) fmin(255, rsum/box.sum);
      color.p[3] = ( color.p[0]*BMUL + color.p[1]*GMUL + color.p[2]*RMUL) / SMUL;
    }
  }
  // Save dominant color
  PColor dcolor = palette[0];
  // Sort palette colors in luminance order
  qsort((PColor*)palette, ncolors, sizeof(PColor), lcomp);
  // Clear invalid data
  colordata.empty();
  delete pmap;
  pmap = 0;
  // Return dominant color
  return color_to_index_slow(dcolor.p);
}
예제 #27
0
/** Compare two REAL4 vectors using various different comparison metrics
 */
int
XLALCompareREAL4Vectors ( VectorComparison *result,	///< [out] return comparison results
                          const REAL4Vector *x,		///< [in] first input vector
                          const REAL4Vector *y,		///< [in] second input vector
                          const VectorComparison *tol	///< [in] accepted tolerances on comparisons, or NULL for no check
                          )
{
  XLAL_CHECK ( result != NULL, XLAL_EINVAL );
  XLAL_CHECK ( x != NULL, XLAL_EINVAL );
  XLAL_CHECK ( y != NULL, XLAL_EINVAL );
  XLAL_CHECK ( x->data != NULL, XLAL_EINVAL );
  XLAL_CHECK ( y->data != NULL, XLAL_EINVAL );
  XLAL_CHECK ( x->length > 0, XLAL_EINVAL );
  XLAL_CHECK ( x->length == y->length, XLAL_EINVAL );

  REAL8 x_L1 = 0, x_L2 = 0;
  REAL8 y_L1 = 0, y_L2 = 0;
  REAL8 diff_L1 = 0, diff_L2 = 0;
  REAL8 scalar = 0;

  REAL4 maxAbsx = 0, maxAbsy = 0;
  REAL4 x_atMaxAbsx = 0, y_atMaxAbsx = 0;
  REAL4 x_atMaxAbsy = 0, y_atMaxAbsy = 0;

  UINT4 numSamples = x->length;
  for ( UINT4 i = 0; i < numSamples; i ++ )
    {
      REAL4 x_i = x->data[i];
      REAL4 y_i = y->data[i];
      XLAL_CHECK ( isfinite ( x_i ), XLAL_EFPINVAL, "non-finite element: x(%d) = %g\n", i, x_i );
      XLAL_CHECK ( isfinite ( y_i ), XLAL_EFPINVAL, "non-finite element: y(%d) = %g\n", i, y_i );
      REAL4 xAbs_i = fabs ( x_i );
      REAL4 yAbs_i = fabs ( y_i );

      REAL8 absdiff = fabs ( x_i - y_i );
      diff_L1 += absdiff;
      diff_L2 += SQ(absdiff);

      x_L1 += xAbs_i;
      y_L1 += yAbs_i;
      x_L2 += SQ(xAbs_i);
      y_L2 += SQ(yAbs_i);

      scalar += x_i * y_i;

      if ( xAbs_i > maxAbsx ) {
        maxAbsx = xAbs_i;
        x_atMaxAbsx = x_i;
        y_atMaxAbsx = y_i;
      }
      if ( yAbs_i > maxAbsy ) {
        maxAbsy = yAbs_i;
        x_atMaxAbsy = x_i;
        y_atMaxAbsy = y_i;
      }

    } // for i < numSamples

  // complete L2 norms by taking sqrt
  x_L2 = sqrt ( x_L2 );
  y_L2 = sqrt ( y_L2 );
  diff_L2 = sqrt ( diff_L2 );

  // compute and return comparison results
  result->relErr_L1 = diff_L1 / ( 0.5 * (x_L1 + y_L1 ) );
  result->relErr_L2 = diff_L2 / ( 0.5 * (x_L2 + y_L2 ) );
  REAL8 cosTheta = fmin ( 1, scalar / (x_L2 * y_L2) );
  result->angleV = acos ( cosTheta );
  result->relErr_atMaxAbsx = fRELERR ( x_atMaxAbsx, y_atMaxAbsx );
  result->relErr_atMaxAbsy = fRELERR ( x_atMaxAbsy, y_atMaxAbsy );;

  XLAL_CHECK ( XLALCheckVectorComparisonTolerances ( result, tol ) == XLAL_SUCCESS, XLAL_EFUNC );

  return XLAL_SUCCESS;

} // XLALCompareREAL4Vectors()
예제 #28
0
void character_addStatus(character_t* c, int s, float q)
{
	float max = character_maxOfStatus(c, s);
	float n = c->statuses[s] + q;
	c->statuses[s] = fmin(fmax(n, 0), max);
}
예제 #29
0
float fminf (float x, float y)
{
	return (float) fmin( (double)x, (double)y );
}
extern float4 __attribute__((overloadable)) min(float4 v1, float v2) {
    return fmin(v1, v2);
}