예제 #1
0
void
surface_randomize(GwySurface *surface,
                  GRand *rng)
{
    GwyXYZ *d = surface->data;
    for (guint n = surface->n; n; n--, d++) {
        d->x = g_rand_double(rng);
        d->y = g_rand_double(rng);
        d->z = g_rand_double(rng);
    }
}
예제 #2
0
/**
 * random_int_poisson:
 * @lambda: Lambda parameter for the distribution function, which must be
 * non-zero
 *
 * Generate a random variable from a Poisson distribution with parameter
 * @lambda. This consumes one %gdouble’s worth of randomness from the global
 * @prng.
 *
 * This is implemented using the inverse transform of the Poisson CDF, and is
 * guaranteed to return in time linearly proportional to @lambda.
 *
 * Returns: Poisson-distributed pseudo-random variable
 */
static guint32
random_int_poisson (guint lambda)
{
  gdouble U;
  guint32 i;
  gdouble p, F;

  g_return_val_if_fail (lambda > 0, 0);

  /*
   * Reference: http://www.cs.bgu.ac.il/~mps042/invtransnote.htm,
   * §Simulating a Poisson random variable.
   */
  U = g_rand_double (prng);  /* step 1 */
  i = 0;
  p = exp (0.0 - (gdouble) lambda);
  F = p;  /* step 2 */

  while (U >= F) {  /* step 3 */
    p = (lambda * p) / (i + 1);
    F += p;
    i += 1;  /* step 4 and 5 */
  }

  return i;
}
예제 #3
0
void dp_evaluation_individ_prepare(DpEvaluationCtrl*hevalctrl, DpIndivid*individ)
{
	int i;
	double y;
	for ( i = 0; i < hevalctrl->eval->size; i++) {
		if ( hevalctrl->eval->points[i]->limited ) {
			if ( hevalctrl->eval_strategy == sin_trans_flag ) {
				y = hevalctrl->eval->points[i]->alpha + hevalctrl->eval->points[i]->beta * sin(hevalctrl->eval->points[i]->gamma * individ->x[i]);
				y /= hevalctrl->eval->points[i]->scale;
				individ->z[i] = y;
			} else if ( hevalctrl->eval_strategy == tanh_trans_flag ) {
				y = hevalctrl->eval->points[i]->alpha + hevalctrl->eval->points[i]->beta * tanh(hevalctrl->eval->points[i]->gamma * individ->x[i]);
				y /= hevalctrl->eval->points[i]->scale;
				individ->z[i] = y;
			} else if ( hevalctrl->eval_strategy == alg_trans_flag ) {
				if ( individ->x[i] > hevalctrl->eval->points[i]->lower && individ->x[i] < hevalctrl->eval->points[i]->upper ) {
					individ->z[i] = individ->x[i] / hevalctrl->eval->points[i]->scale;
				} else {
					individ->x[i] = hevalctrl->eval->points[i]->lower + 2.0 * g_rand_double(individ->hrand) * hevalctrl->eval->points[i]->beta;
					individ->z[i] = individ->x[i] / hevalctrl->eval->points[i]->scale;
				}
			} else if ( hevalctrl->eval_strategy == rand_trans_flag ) {
				while ( individ->x[i] < hevalctrl->eval->points[i]->lower || individ->x[i] > hevalctrl->eval->points[i]->upper ) {
					individ->x[i] = hevalctrl->eval->points[i]->alpha + dp_rand_gauss(individ->hrand, 0, 1) * hevalctrl->eval->points[i]->beta;
				}
				individ->z[i] = individ->x[i] / hevalctrl->eval->points[i]->scale;
			}
		} else {
			individ->z[i] = individ->x[i] / hevalctrl->eval->points[i]->scale;
		}
	}
}
예제 #4
0
int dp_evaluation_individ_compare(const void *p1, const void *p2, void *user_data)
{
	int i, need_swap;
	DpIndivid**i1 = (DpIndivid**)p1;
	DpIndivid**i2 = (DpIndivid**)p2;
	DpIndivid*individ = *i1;
	DpIndivid*trial = *i2;
	DpEvaluationCtrl*hevalctrl = (DpEvaluationCtrl*)user_data;
	int ignore_cost = hevalctrl->eval_target->ignore_cost;
	double use_crdist = hevalctrl->eval_target->use_crdist;
	need_swap = 0;
	if ( individ->invalid == 1 && trial->invalid == 0 ) {
		need_swap = 1;
	} else if ( ignore_cost == 0 && trial->cost < individ->cost ) {
		need_swap = 1;
	} else if ( use_crdist > 0 && ( trial->pareto_front < individ->pareto_front || (( trial->pareto_front == individ->pareto_front ) && trial->crdist > individ->crdist) ) && g_rand_double(individ->hrand) < use_crdist ) {
		need_swap = 1;
	} else {
		need_swap = -1;
		for ( i = 0; i < hevalctrl->eval_target->size; i++ ) {
			if ( trial->targets[i] < individ->targets[i] && g_rand_double(individ->hrand) < hevalctrl->eval_target->penalty[i]->rank ) {
				need_swap = 1;
				break;
			}
		}
	}
	return need_swap;
}
예제 #5
0
static int semi_uniform (RLearner *rl, const unsigned int state)
{
	double rand_value = 0.0; 
	int    action     = 0;
	
    if (rl == NULL)
    {
        fprintf(stderr, "RLearner-WARNING **: RLearner *rl is NULL\n");
    }
    else
    {
        rand_value = g_rand_double(rl->random);
        
        if (rand_value > (1.0 - EXPLORATION_THRESHOLD))
        {
            /* Random action */
            action = g_rand_int_range(rl->random, 0, rl->num_actions);
        }
        else
        {
            action = best_action(rl, state);
        }
    }
    
    return action;
} 
예제 #6
0
파일: test-server.c 프로젝트: IMCG/kiro
static void
print_current_frame (gchar *buffer, guint number, guint width, guint height, GRand *rand)
{
    guint divisor = 10000000;
    int x = 1;

    while (divisor > 0) {
        print_number (buffer, number / divisor, x, 1, width);
        number = number % divisor;
        divisor = divisor / 10;
        x += DIGIT_WIDTH + 1;
    }

    //Grayscale pattern is the same for every row. Just calculate one single
    //Scanline, so we can reuse it and dont have to do the whole calculation
    //for every row again.
    char default_line[width];

    for (guint p = 0; p < width; p++) {
        default_line[p] = (char) ((p * 256) / (width));
    }

    //Use memcpy to quickly fill every row with the precalculated grayscale
    //pattern
    for (guint y = 16; y < height; y++) {
        guint index = y * width;
        memcpy (buffer + index, &default_line[0], width);
    }

    //This block will fill a square at the center of the image with normal
    //distributed random data
    const double mean = 128.0;
    const double std = 32.0;

    for (guint y = (height / 3); y < ((height * 2) / 3); y++) {
        guint row_start = y * width;

        for (guint i = (width / 3); i < ((width * 2) / 3); i++) {
            int index = row_start + i;
            double u1 = g_rand_double (rand);
            double u2 = g_rand_double (rand);
            double r = sqrt (-2 * log (u1)) * cos (2 * G_PI * u2);
            buffer[index] = (guint8) (r * std + mean);
        }
    }
}
예제 #7
0
static gint
random_integer(GRand *rng)
{
    gdouble x = -5.0*log(g_rand_double(rng));
    if (g_rand_boolean(rng))
        x = -x;

    return (gint)gwy_round(x);
}
void
swfdec_as_math_random (SwfdecAsContext *cx, SwfdecAsObject *object, 
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  double unused, unused2;

  *ret = swfdec_as_value_from_number (cx, NAN);
  SWFDEC_AS_CHECK (0, NULL, "|nn", &unused, &unused2);

  *ret = swfdec_as_value_from_number (cx, g_rand_double (cx->rand));
}
예제 #9
0
파일: nova.c 프로젝트: AjayRamanathan/gimp
static gdouble
gauss (GRand *gr)
{
  gdouble sum = 0.0;
  gint    i;

  for (i = 0; i < 6; i++)
    sum += g_rand_double (gr);

  return sum / 6.0;
}
예제 #10
0
void
swfdec_as_math_random (SwfdecAsContext *cx, SwfdecAsObject *object, 
    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
{
  double unused, unused2;

  SWFDEC_AS_VALUE_SET_NUMBER (ret, NAN);
  SWFDEC_AS_CHECK (0, NULL, "|nn", &unused, &unused2);

  SWFDEC_AS_VALUE_SET_NUMBER (ret, g_rand_double (cx->rand));
}
예제 #11
0
/**
 * crank_bench_run_rand_double_array: (skip)
 * @run: A benchmark run.
 * @length: Length of required random array.
 *
 * Constructs random double array of given @length.
 *
 * Returns: (array) (transfer container): A random double array.
 */
gdouble*
crank_bench_run_rand_double_array (CrankBenchRun *run,
                                  const guint    length)
{
  gdouble *result = g_new (gdouble, length);
  guint i;
  for (i = 0;i < length; i++)
    result[i] = g_rand_double (run->random);

  return result;
}
예제 #12
0
double dp_rand_gauss(GRand*hrand, double mean, double dev)
{
	static double V2, fac;
	static int phase = 0;
	double S, Z, U1, U2, V1;
	if ( phase == 1 ) {
		Z = V2 * fac;
	} else {
		do {
			U1 = g_rand_double(hrand);
			U2 = g_rand_double(hrand);
			V1 = 2 * U1 - 1;
			V2 = 2 * U2 - 1;
			S = V1 * V1 + V2 * V2;
		} while ( S >= 1 || S == 0.0 );
		fac = sqrt (-2 * log(S) / S);
		Z = V1 * fac;
	}
	phase = 1 - phase;
	Z = mean + dev*Z;
	return Z;
}
예제 #13
0
static void
randomize(GwyMaskField *field, GRand *rng, gdouble p)
{

    for (guint i = 0; i < field->yres; i++) {
        GwyMaskIter iter;
        gwy_mask_field_iter_init(field, iter, 0, i);
        for (guint j = 0; j < field->xres; j++) {
            gboolean v = (g_rand_double(rng) <= p);
            gwy_mask_iter_set(iter, v);
            gwy_mask_iter_next(iter);
        }
    }
    gwy_mask_field_invalidate(field);
}
static void
random_test (void)
{
	/*
	 * outline:
	 * 1. create new tree and empty list of intervals
	 * 2. insert some intervals into tree and list
	 * 3. do various searches, compare results of both structures
	 * 4. delete some intervals 
	 * 5. do various searches, compare results of both structures
	 * 6. free memory
	 */
	gint i, start, end;
	EInterval *interval = NULL;
	EIntervalTree *tree;
	GList *l1, *l2, *next;
	gint num_deleted = 0;

	tree = e_intervaltree_new ();

	for (i = 0; i < NUM_INTERVALS_CLOSED; i++)
	{
		ECalComponent *comp;
		start = g_rand_int_range (myrand, 0, 1000);
		end = g_rand_int_range (myrand, start, 2000);
		comp = create_test_component (start, end);
		if (!comp)
		{
			g_message (G_STRLOC ": error");
			exit (-1);
		}

		interval = g_new (EInterval, 1);
		interval->start = start;
		interval->end = end;
		interval->comp = comp;

		list = g_list_insert (list, interval, -1);

		e_intervaltree_insert (tree, start, end, comp);
	}

	/* insert open ended intervals */
	for (i = 0; i < NUM_INTERVALS_OPEN; i++)
	{
		ECalComponent *comp;
		start = g_rand_int_range (myrand, 0, 1000);
		comp = create_test_component (start, end);
		if (!comp)
		{
			g_message (G_STRLOC ": error");
			exit (-1);
		}

		interval = g_new (EInterval, 1);
		interval->start = start;
		interval->end = _TIME_MAX;
		interval->comp = comp;
		list = g_list_insert (list, interval, -1);

		e_intervaltree_insert (tree, start, interval->end, comp);
		/* g_print ("%d - %d\n", start, interval->end); */
	}

	g_print ("Number of intervals inserted: %d\n", NUM_INTERVALS_CLOSED + NUM_INTERVALS_OPEN);

	for (i = 0; i < NUM_SEARCHES; i++)
	{
		start = g_rand_int_range (myrand, 0, 1000);
		end = g_rand_int_range (myrand, 2000, _TIME_MAX);

		/*
		   g_print ("Search for : %d - %d\n", start, end);
		   */

		l1 = e_intervaltree_search (tree, start, end);

		l2 = search_in_list (list, start, end);

		if (!compare_interval_lists (l2, l1))
		{
			e_intervaltree_dump (tree);
			g_message (G_STRLOC "Error");
			exit (-1);
		}

		/* g_print ("OK\n"); */
		g_list_foreach (l1, (GFunc)g_object_unref, NULL);
		g_list_foreach (l2, (GFunc)unref_comp, NULL);
		g_list_free (l1);
		g_list_free (l2);
	}

	/* open-ended intervals */
	for (i = 0; i < 20; i++)
	{
		start = g_rand_int_range (myrand, 0, 1000);
		end = _TIME_MAX;

		/*
		   g_print ("Search for : %d - %d\n", start, end);
		   */

		l1 = e_intervaltree_search (tree, start, end);

		l2 = search_in_list (list, start, end);

		if (!compare_interval_lists (l2, l1))
		{
			e_intervaltree_dump (tree);
			g_message (G_STRLOC "Error");
			exit (-1);
		}

		/* g_print ("OK\n"); */
		g_list_foreach (l1, (GFunc)g_object_unref, NULL);
		g_list_foreach (l2, (GFunc)unref_comp, NULL);
		g_list_free (l1);
		g_list_free (l2);
	}

	l1 = list;

	while (l1)
	{
		/* perhaps we will delete l1 */
		next = l1->next;

		if (g_rand_double (myrand) < pbality_delete)
		{
			ECalComponent *comp;
			const gchar *uid = NULL;
			gchar *rid;
			interval = (EInterval*) l1->data;
			comp = interval->comp;

			/* delete l1 */
			/*
			   g_print ("Deleting interval %d - %d\n", interval->start,
			   interval->end);
			   */

			rid = e_cal_component_get_recurid_as_string (comp);
			e_cal_component_get_uid (comp, &uid);
			if (!e_intervaltree_remove (tree, uid, rid))
			{
				g_free (rid);
				e_intervaltree_dump (tree);
				g_print ("Deleting interval %d - %d ERROR\n", interval->start,
					 interval->end);
				exit (-1);
			}

			g_free (rid);
			g_object_unref (interval->comp);
			g_free (l1->data);
			list = g_list_delete_link (list, l1);
			num_deleted++;
		}

		l1 = next;
	}

	g_print ("Number of intervals deleted: %d\n", num_deleted);

	for (i = 0; i < NUM_SEARCHES; i++)
	{
		start = g_rand_int_range (myrand, 0, 1000);
		end = g_rand_int_range (myrand, start, 2000);

		/*
		   g_print ("Search for : %d - %d\n", start, end);
		   */

		l1 = e_intervaltree_search (tree, start, end);

		/*
		   g_print ("Results from tree:\n");
		   print_nodes_list (l1);
		 */

		l2 = search_in_list (list, start, end);

		if (!compare_interval_lists (l2, l1))
		{
			g_print ("ERROR!\n\n");
			return;
		}

		g_list_foreach (l1, (GFunc)g_object_unref, NULL);
		g_list_foreach (l2, (GFunc)unref_comp, NULL);
		g_list_free (l1);
		g_list_free (l2);

		/* g_print ("OK\n"); */
	}

	e_intervaltree_destroy (tree);
	g_list_foreach (list, (GFunc)unref_comp, NULL);
	g_list_free (list);
}
예제 #15
0
  // This function runs a brush "simulation" step. Usually it is
  // called once or twice per dab. In theory the precision of the
  // "simulation" gets better when it is called more often. In
  // practice this only matters if there are some highly nonlinear
  // mappings in critical places or extremely few events per second.
  //
  // note: parameters are is dx/ddab, ..., dtime/ddab (dab is the number, 5.0 = 5th dab)
  void update_states_and_setting_values (float step_dx, float step_dy, float step_dpressure, float step_declination, float step_ascension, float step_dtime)
  {
    float pressure;
    float inputs[INPUT_COUNT];

    if (step_dtime < 0.0) {
      printf("Time is running backwards!\n");
      step_dtime = 0.001;
    } else if (step_dtime == 0.0) {
      // FIXME: happens about every 10th start, workaround (against division by zero)
      step_dtime = 0.001;
    }

    states[STATE_X]        += step_dx;
    states[STATE_Y]        += step_dy;
    states[STATE_PRESSURE] += step_dpressure;

    states[STATE_DECLINATION] += step_declination;
    states[STATE_ASCENSION] += step_ascension;

    float base_radius = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value);

    // FIXME: does happen (interpolation problem?)
    states[STATE_PRESSURE] = CLAMP(states[STATE_PRESSURE], 0.0, 1.0);
    pressure = states[STATE_PRESSURE];

    { // start / end stroke (for "stroke" input only)
      if (!states[STATE_STROKE_STARTED]) {
        if (pressure > settings[BRUSH_STROKE_THRESHOLD]->base_value + 0.0001) {
          // start new stroke
          //printf("stroke start %f\n", pressure);
          states[STATE_STROKE_STARTED] = 1;
          states[STATE_STROKE] = 0.0;
        }
      } else {
        if (pressure <= settings[BRUSH_STROKE_THRESHOLD]->base_value * 0.9 + 0.0001) {
          // end stroke
          //printf("stroke end\n");
          states[STATE_STROKE_STARTED] = 0;
        }
      }
    }

    // now follows input handling

    float norm_dx, norm_dy, norm_dist, norm_speed;
    norm_dx = step_dx / step_dtime / base_radius;
    norm_dy = step_dy / step_dtime / base_radius;
    norm_speed = sqrt(SQR(norm_dx) + SQR(norm_dy));
    norm_dist = norm_speed * step_dtime;

    inputs[INPUT_PRESSURE] = pressure;
    inputs[INPUT_SPEED1] = log(speed_mapping_gamma[0] + states[STATE_NORM_SPEED1_SLOW])*speed_mapping_m[0] + speed_mapping_q[0];
    inputs[INPUT_SPEED2] = log(speed_mapping_gamma[1] + states[STATE_NORM_SPEED2_SLOW])*speed_mapping_m[1] + speed_mapping_q[1];
    inputs[INPUT_RANDOM] = g_rand_double (rng);
    inputs[INPUT_STROKE] = MIN(states[STATE_STROKE], 1.0);
    inputs[INPUT_DIRECTION] = fmodf (atan2f (states[STATE_DIRECTION_DY], states[STATE_DIRECTION_DX])/(2*M_PI)*360 + 180.0, 180.0);
    inputs[INPUT_TILT_DECLINATION] = states[STATE_DECLINATION];
    inputs[INPUT_TILT_ASCENSION] = states[STATE_ASCENSION];
    inputs[INPUT_CUSTOM] = states[STATE_CUSTOM_INPUT];
    if (print_inputs) {
      g_print("press=% 4.3f, speed1=% 4.4f\tspeed2=% 4.4f\tstroke=% 4.3f\tcustom=% 4.3f\n", (double)inputs[INPUT_PRESSURE], (double)inputs[INPUT_SPEED1], (double)inputs[INPUT_SPEED2], (double)inputs[INPUT_STROKE], (double)inputs[INPUT_CUSTOM]);
    }
    // FIXME: this one fails!!!
    //assert(inputs[INPUT_SPEED1] >= 0.0 && inputs[INPUT_SPEED1] < 1e8); // checking for inf

    for (int i=0; i<BRUSH_SETTINGS_COUNT; i++) {
      settings_value[i] = settings[i]->calculate (inputs);
    }

    {
      float fac = 1.0 - exp_decay (settings_value[BRUSH_SLOW_TRACKING_PER_DAB], 1.0);
      states[STATE_ACTUAL_X] += (states[STATE_X] - states[STATE_ACTUAL_X]) * fac; // FIXME: should this depend on base radius?
      states[STATE_ACTUAL_Y] += (states[STATE_Y] - states[STATE_ACTUAL_Y]) * fac;
    }

    { // slow speed
      float fac;
      fac = 1.0 - exp_decay (settings_value[BRUSH_SPEED1_SLOWNESS], step_dtime);
      states[STATE_NORM_SPEED1_SLOW] += (norm_speed - states[STATE_NORM_SPEED1_SLOW]) * fac;
      fac = 1.0 - exp_decay (settings_value[BRUSH_SPEED2_SLOWNESS], step_dtime);
      states[STATE_NORM_SPEED2_SLOW] += (norm_speed - states[STATE_NORM_SPEED2_SLOW]) * fac;
    }
  
    { // slow speed, but as vector this time

      // FIXME: offset_by_speed should be removed.
      //   Is it broken, non-smooth, system-dependent math?!
      //   A replacement could be a directed random offset.

      float time_constant = exp(settings_value[BRUSH_OFFSET_BY_SPEED_SLOWNESS]*0.01)-1.0;
      // Workaround for a bug that happens mainly on Windows, causing
      // individual dabs to be placed far far away. Using the speed
      // with zero filtering is just asking for trouble anyway.
      if (time_constant < 0.002) time_constant = 0.002;
      float fac = 1.0 - exp_decay (time_constant, step_dtime);
      states[STATE_NORM_DX_SLOW] += (norm_dx - states[STATE_NORM_DX_SLOW]) * fac;
      states[STATE_NORM_DY_SLOW] += (norm_dy - states[STATE_NORM_DY_SLOW]) * fac;
    }

    { // orientation (similar lowpass filter as above, but use dabtime instead of wallclock time)
      float dx = step_dx / base_radius;
      float dy = step_dy / base_radius;
      float step_in_dabtime = hypotf(dx, dy); // FIXME: are we recalculating something here that we already have?
      float fac = 1.0 - exp_decay (exp(settings_value[BRUSH_DIRECTION_FILTER]*0.5)-1.0, step_in_dabtime);

      float dx_old = states[STATE_DIRECTION_DX];
      float dy_old = states[STATE_DIRECTION_DY];
      // use the opposite speed vector if it is closer (we don't care about 180 degree turns)
      if (SQR(dx_old-dx) + SQR(dy_old-dy) > SQR(dx_old-(-dx)) + SQR(dy_old-(-dy))) {
        dx = -dx;
        dy = -dy;
      }
      states[STATE_DIRECTION_DX] += (dx - states[STATE_DIRECTION_DX]) * fac;
      states[STATE_DIRECTION_DY] += (dy - states[STATE_DIRECTION_DY]) * fac;
    }

    { // custom input
      float fac;
      fac = 1.0 - exp_decay (settings_value[BRUSH_CUSTOM_INPUT_SLOWNESS], 0.1);
      states[STATE_CUSTOM_INPUT] += (settings_value[BRUSH_CUSTOM_INPUT] - states[STATE_CUSTOM_INPUT]) * fac;
    }

    { // stroke length
      float frequency;
      float wrap;
      frequency = expf(-settings_value[BRUSH_STROKE_DURATION_LOGARITHMIC]);
      states[STATE_STROKE] += norm_dist * frequency;
      // can happen, probably caused by rounding
      if (states[STATE_STROKE] < 0) states[STATE_STROKE] = 0;
      wrap = 1.0 + settings_value[BRUSH_STROKE_HOLDTIME];
      if (states[STATE_STROKE] > wrap) {
        if (wrap > 9.9 + 1.0) {
          // "inifinity", just hold stroke somewhere >= 1.0
          states[STATE_STROKE] = 1.0;
        } else {
          states[STATE_STROKE] = fmodf(states[STATE_STROKE], wrap);
          // just in case
          if (states[STATE_STROKE] < 0) states[STATE_STROKE] = 0;
        }
      }
    }

    // calculate final radius
    float radius_log;
    radius_log = settings_value[BRUSH_RADIUS_LOGARITHMIC];
    states[STATE_ACTUAL_RADIUS] = expf(radius_log);
    if (states[STATE_ACTUAL_RADIUS] < ACTUAL_RADIUS_MIN) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MIN;
    if (states[STATE_ACTUAL_RADIUS] > ACTUAL_RADIUS_MAX) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MAX;

    // aspect ratio (needs to be caluclated here because it can affect the dab spacing)
    states[STATE_ACTUAL_ELLIPTICAL_DAB_RATIO] = settings_value[BRUSH_ELLIPTICAL_DAB_RATIO];
    states[STATE_ACTUAL_ELLIPTICAL_DAB_ANGLE] = settings_value[BRUSH_ELLIPTICAL_DAB_ANGLE];
  }
예제 #16
0
파일: oilutil.c 프로젝트: cee1/oil
/**
 * oil_rand_f64:
 * @r: a #GRand, representing a random seed
 *
 * Returns: a double, in range [0, 1)
 */
gdouble oil_rand_f64 (GRand *r)
{
    return g_rand_double (r);
}
예제 #17
0
파일: oilutil.c 프로젝트: cee1/oil
/**
 * oil_rand_f32:
 * @r: a #GRand, representing a random seed
 * 
 * Returns: a float, in range [0, 1)
 */
gfloat oil_rand_f32 (GRand *r)
{
    return (gfloat) g_rand_double (r);
}
예제 #18
0
/**
 * crank_bench_run_rand_double: (skip)
 * @run: A benchmark run.
 *
 * Returns random double.
 *
 * Returns: A random double.
 */
gdouble
crank_bench_run_rand_double (CrankBenchRun *run)
{
  return g_rand_double (run->random);
}
예제 #19
0
/**
 * crank_bench_run_rand_float: (skip)
 * @run: A benchmark run.
 *
 * Returns random float.
 *
 * Returns: A random float.
 */
gfloat
crank_bench_run_rand_float (CrankBenchRun *run)
{
  return (gfloat) g_rand_double (run->random);
}
예제 #20
0
    // This function runs a brush "simulation" step. Usually it is
    // called once or twice per dab. In theory the precision of the
    // "simulation" gets better when it is called more often. In
    // practice this only matters if there are some highly nonlinear
    // mappings in critical places or extremely few events per second.
    //
    // note: parameters are is dx/ddab, ..., dtime/ddab (dab is the number, 5.0 = 5th dab)
    void update_states_and_setting_values (float step_dx, float step_dy, float step_dpressure, float step_dtime)
    {
        float pressure;
        float inputs[INPUT_COUNT];

        if (step_dtime < 0.0) {
            printf("Time is running backwards!\n");
            step_dtime = 0.001;
        } else if (step_dtime == 0.0) {
            // FIXME: happens about every 10th start, workaround (against division by zero)
            step_dtime = 0.001;
        }

        states[STATE_X]        += step_dx;
        states[STATE_Y]        += step_dy;
        states[STATE_PRESSURE] += step_dpressure;

        float base_radius = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value);

        // FIXME: does happen (interpolation problem?)
        states[STATE_PRESSURE] = CLAMP(states[STATE_PRESSURE], 0.0, 1.0);
        pressure = states[STATE_PRESSURE];

        { // start / end stroke (for "stroke" input only)
            if (!states[STATE_STROKE_STARTED]) {
                if (pressure > settings[BRUSH_STROKE_THRESHOLD]->base_value + 0.0001) {
                    // start new stroke
                    //printf("stroke start %f\n", pressure);
                    states[STATE_STROKE_STARTED] = 1;
                    states[STATE_STROKE] = 0.0;
                }
            } else {
                if (pressure <= settings[BRUSH_STROKE_THRESHOLD]->base_value * 0.9 + 0.0001) {
                    // end stroke
                    //printf("stroke end\n");
                    states[STATE_STROKE_STARTED] = 0;
                }
            }
        }

        // now follows input handling

        float norm_dx, norm_dy, norm_dist, norm_speed;
        norm_dx = step_dx / step_dtime / base_radius;
        norm_dy = step_dy / step_dtime / base_radius;
        norm_speed = sqrt(SQR(norm_dx) + SQR(norm_dy));
        norm_dist = norm_speed * step_dtime;

        inputs[INPUT_PRESSURE] = pressure;
        inputs[INPUT_SPEED1] = log(speed_mapping_gamma[0] + states[STATE_NORM_SPEED1_SLOW])*speed_mapping_m[0] + speed_mapping_q[0];
        inputs[INPUT_SPEED2] = log(speed_mapping_gamma[1] + states[STATE_NORM_SPEED2_SLOW])*speed_mapping_m[1] + speed_mapping_q[1];
        inputs[INPUT_RANDOM] = g_rand_double (rng);
        inputs[INPUT_STROKE] = MIN(states[STATE_STROKE], 1.0);
        //if (states[STATE_NORM_DY_SLOW] == 0 && states[STATE_NORM_DX_SLOW] == 0) {
        //inputs[INPUT_ANGLE] = fmodf(atan2f (states[STATE_NORM_DY_SLOW], states[STATE_NORM_DX_SLOW])/(M_PI) + 1.0, 1.0);
        inputs[INPUT_CUSTOM] = states[STATE_CUSTOM_INPUT];
        if (print_inputs) {
            g_print("press=% 4.3f, speed1=% 4.4f\tspeed2=% 4.4f\tstroke=% 4.3f\tcustom=% 4.3f\n", (double)inputs[INPUT_PRESSURE], (double)inputs[INPUT_SPEED1], (double)inputs[INPUT_SPEED2], (double)inputs[INPUT_STROKE], (double)inputs[INPUT_CUSTOM]);
        }
        // FIXME: this one fails!!!
        //assert(inputs[INPUT_SPEED1] >= 0.0 && inputs[INPUT_SPEED1] < 1e8); // checking for inf

        for (int i=0; i<BRUSH_SETTINGS_COUNT; i++) {
            settings_value[i] = settings[i]->calculate (inputs);
        }

        {
            float fac = 1.0 - exp_decay (settings_value[BRUSH_SLOW_TRACKING_PER_DAB], 1.0);
            states[STATE_ACTUAL_X] += (states[STATE_X] - states[STATE_ACTUAL_X]) * fac; // FIXME: should this depend on base radius?
            states[STATE_ACTUAL_Y] += (states[STATE_Y] - states[STATE_ACTUAL_Y]) * fac;
        }

        { // slow speed
            float fac;
            fac = 1.0 - exp_decay (settings_value[BRUSH_SPEED1_SLOWNESS], step_dtime);
            states[STATE_NORM_SPEED1_SLOW] += (norm_speed - states[STATE_NORM_SPEED1_SLOW]) * fac;
            fac = 1.0 - exp_decay (settings_value[BRUSH_SPEED2_SLOWNESS], step_dtime);
            states[STATE_NORM_SPEED2_SLOW] += (norm_speed - states[STATE_NORM_SPEED2_SLOW]) * fac;
        }

        { // slow speed, but as vector this time
            float fac = 1.0 - exp_decay (exp(settings_value[BRUSH_OFFSET_BY_SPEED_SLOWNESS]*0.01)-1.0, step_dtime);
            states[STATE_NORM_DX_SLOW] += (norm_dx - states[STATE_NORM_DX_SLOW]) * fac;
            states[STATE_NORM_DY_SLOW] += (norm_dy - states[STATE_NORM_DY_SLOW]) * fac;
        }

        { // custom input
            float fac;
            fac = 1.0 - exp_decay (settings_value[BRUSH_CUSTOM_INPUT_SLOWNESS], 0.1);
            states[STATE_CUSTOM_INPUT] += (settings_value[BRUSH_CUSTOM_INPUT] - states[STATE_CUSTOM_INPUT]) * fac;
        }

        { // stroke length
            float frequency;
            float wrap;
            frequency = expf(-settings_value[BRUSH_STROKE_DURATION_LOGARITHMIC]);
            states[STATE_STROKE] += norm_dist * frequency;
            // can happen, probably caused by rounding
            if (states[STATE_STROKE] < 0) states[STATE_STROKE] = 0;
            wrap = 1.0 + settings_value[BRUSH_STROKE_HOLDTIME];
            if (states[STATE_STROKE] > wrap) {
                if (wrap > 9.9 + 1.0) {
                    // "inifinity", just hold stroke somewhere >= 1.0
                    states[STATE_STROKE] = 1.0;
                } else {
                    states[STATE_STROKE] = fmodf(states[STATE_STROKE], wrap);
                    // just in case
                    if (states[STATE_STROKE] < 0) states[STATE_STROKE] = 0;
                }
            }
        }

        // calculate final radius
        float radius_log;
        radius_log = settings_value[BRUSH_RADIUS_LOGARITHMIC];
        states[STATE_ACTUAL_RADIUS] = expf(radius_log);
        if (states[STATE_ACTUAL_RADIUS] < ACTUAL_RADIUS_MIN) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MIN;
        if (states[STATE_ACTUAL_RADIUS] > ACTUAL_RADIUS_MAX) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MAX;

        // aspect ratio (needs to be caluclated here because it can affect the dab spacing)

        float ratio = settings_value[BRUSH_ELLIPTICAL_DAB_RATIO];
        //float angle = atan2(states[STATE_NORM_DY_SLOW], -states[STATE_NORM_DX_SLOW]) / M_PI * 180;
        float angle = settings_value[BRUSH_ELLIPTICAL_DAB_ANGLE];
        states[STATE_ACTUAL_ELLIPTICAL_DAB_RATIO] = ratio;
        states[STATE_ACTUAL_ELLIPTICAL_DAB_ANGLE] = angle;
    }