Esempio n. 1
0
void
stp_curve_reverse(stp_curve_t *dest, const stp_curve_t *source)
{
  CHECK_CURVE(dest);
  CHECK_CURVE(source);
  curve_dtor(dest);
  dest->curve_type = source->curve_type;
  dest->wrap_mode = source->wrap_mode;
  dest->gamma = source->gamma;
  if (source->piecewise)
    {
      const double *source_data;
      size_t size;
      double *new_data;
      int i;
      stp_sequence_get_data(source->seq, &size, &source_data);
      new_data = stp_malloc(sizeof(double) * size);
      for (i = 0; i < size; i += 2)
	{
	  int j = size - i - 2;
	  new_data[i] = 1.0 - source_data[j];
	  new_data[i + 1] = source_data[j + 1];
	}
      dest->seq = stp_sequence_create();
      stp_sequence_set_data(dest->seq, size, new_data);
      stp_free(new_data);
    }
  else
      dest->seq = stp_sequence_create_reverse(source->seq);
  dest->piecewise = source->piecewise;
  dest->recompute_interval = 1;
}
Esempio n. 2
0
int
stp_curve_set_subrange(stp_curve_t *curve, const stp_curve_t *range,
		       size_t start)
{
  double blo, bhi;
  double rlo, rhi;
  const double *data;
  size_t count;
  CHECK_CURVE(curve);
  if (start + stp_curve_count_points(range) > stp_curve_count_points(curve))
    return 0;
  if (curve->piecewise)
    return 0;
  stp_sequence_get_bounds(curve->seq, &blo, &bhi);
  stp_sequence_get_range(curve->seq, &rlo, &rhi);
  if (rlo < blo || rhi > bhi)
    return 0;
  stp_sequence_get_data(range->seq, &count, &data);
  curve->recompute_interval = 1;
  curve->gamma = 0.0;
  invalidate_auxiliary_data(curve);
  stp_sequence_set_subrange(curve->seq, start, stp_curve_count_points(range),
			    data);
  return 1;
}
Esempio n. 3
0
static void
compute_linear_deltas(stp_curve_t *curve)
{
  int i;
  size_t delta_count;
  size_t seq_point_count;
  const double *data;

  stp_sequence_get_data(curve->seq, &seq_point_count, &data);
  if (data == NULL)
    return;

  delta_count = get_real_point_count(curve);

  if (delta_count <= 1) /* No intervals can be computed */
    return;
  delta_count--; /* One less than the real point count.  Note size_t
		    is unsigned. */

  curve->interval = stp_malloc(sizeof(double) * delta_count);
  for (i = 0; i < delta_count; i++)
    {
      if (curve->piecewise)
	curve->interval[i] = data[(2 * (i + 1)) + 1] - data[(2 * i) + 1];
      else
	curve->interval[i] = data[i + 1] - data[i];
    }
}
Esempio n. 4
0
static const double *
stpi_curve_get_data_internal(const stp_curve_t *curve, size_t *count)
{
  const double *ret;
  CHECK_CURVE(curve);
  stp_sequence_get_data(curve->seq, count, &ret);
  *count = get_point_count(curve);
  if (curve->piecewise)
    *count *= 2;
  return ret;
}
Esempio n. 5
0
const stp_curve_point_t *
stp_curve_get_data_points(const stp_curve_t *curve, size_t *count)
{
  const double *ret;
  CHECK_CURVE(curve);
  if (!curve->piecewise)
    return NULL;
  stp_sequence_get_data(curve->seq, count, &ret);
  *count = get_point_count(curve);
  return (const stp_curve_point_t *) ret;
}
Esempio n. 6
0
int
stp_curve_rescale(stp_curve_t *curve, double scale,
		  stp_curve_compose_t mode, stp_curve_bounds_t bounds_mode)
{
  int i;
  double nblo;
  double nbhi;
  size_t count;

  CHECK_CURVE(curve);

  stp_sequence_get_bounds(curve->seq, &nblo, &nbhi);
  if (bounds_mode == STP_CURVE_BOUNDS_RESCALE)
    {
      switch (mode)
	{
	case STP_CURVE_COMPOSE_ADD:
	  nblo += scale;
	  nbhi += scale;
	  break;
	case STP_CURVE_COMPOSE_MULTIPLY:
	  if (scale < 0)
	    {
	      double tmp = nblo * scale;
	      nblo = nbhi * scale;
	      nbhi = tmp;
	    }
	  else
	    {
	      nblo *= scale;
	      nbhi *= scale;
	    }
	  break;
	case STP_CURVE_COMPOSE_EXPONENTIATE:
	  if (scale == 0.0)
	    return 0;
	  if (nblo < 0)
	    return 0;
	  nblo = pow(nblo, scale);
	  nbhi = pow(nbhi, scale);
	  break;
	default:
	  return 0;
	}
    }

  if (! isfinite(nbhi) || ! isfinite(nblo))
    return 0;

  count = get_point_count(curve);
  if (count)
    {
      double *tmp;
      size_t scount;
      int stride = 1;
      int offset = 0;
      const double *data;
      if (curve->piecewise)
	{
	  stride = 2;
	  offset = 1;
	}
      stp_sequence_get_data(curve->seq, &scount, &data);
      tmp = stp_malloc(sizeof(double) * scount);
      memcpy(tmp, data, scount * sizeof(double));
      for (i = offset; i < scount; i += stride)
	{
	  switch (mode)
	    {
	    case STP_CURVE_COMPOSE_ADD:
	      tmp[i] = tmp[i] + scale;
	      break;
	    case STP_CURVE_COMPOSE_MULTIPLY:
	      tmp[i] = tmp[i] * scale;
	      break;
	    case STP_CURVE_COMPOSE_EXPONENTIATE:
	      tmp[i] = pow(tmp[i], scale);
	      break;
	    }
	  if (tmp[i] > nbhi || tmp[i] < nblo)
	    {
	      if (bounds_mode == STP_CURVE_BOUNDS_ERROR)
		{
		  stp_free(tmp);
		  return(0);
		}
	      else if (tmp[i] > nbhi)
		tmp[i] = nbhi;
	      else
		tmp[i] = nblo;
	    }
	}
      stp_sequence_set_bounds(curve->seq, nblo, nbhi);
      curve->gamma = 0.0;
      stpi_curve_set_points(curve, count);
      stp_sequence_set_subrange(curve->seq, 0, scount, tmp);
      stp_free(tmp);
      curve->recompute_interval = 1;
      invalidate_auxiliary_data(curve);
    }
  return 1;
}
Esempio n. 7
0
static void
compute_spline_deltas_dense(stp_curve_t *curve)
{
  int i;
  int k;
  double *u;
  double *y2;
  const double *y;
  size_t point_count;
  size_t real_point_count;
  double sig;
  double p;

  point_count = get_point_count(curve);

  stp_sequence_get_data(curve->seq, &real_point_count, &y);
  u = stp_malloc(sizeof(double) * real_point_count);
  y2 = stp_malloc(sizeof(double) * real_point_count);

  if (curve->wrap_mode == STP_CURVE_WRAP_AROUND)
    {
      int reps = 3;
      int count = reps * real_point_count;
      double *y2a = stp_malloc(sizeof(double) * count);
      double *ua = stp_malloc(sizeof(double) * count);
      y2a[0] = 0.0;
      ua[0] = 0.0;
      for (i = 1; i < count - 1; i++)
	{
	  int im1 = (i - 1);
	  int ip1 = (i + 1);
	  int im1a = im1 % point_count;
	  int ia = i % point_count;
	  int ip1a = ip1 % point_count;

	  sig = (i - im1) / (ip1 - im1);
	  p = sig * y2a[im1] + 2.0;
	  y2a[i] = (sig - 1.0) / p;

	  ua[i] = y[ip1a] - 2 * y[ia] + y[im1a];
	  ua[i] = 3.0 * ua[i] - sig * ua[im1] / p;
	}
      y2a[count - 1] = 0.0;
      for (k = count - 2 ; k >= 0; k--)
	y2a[k] = y2a[k] * y2a[k + 1] + ua[k];
      memcpy(u, ua + ((reps / 2) * point_count),
	     sizeof(double) * real_point_count);
      memcpy(y2, y2a + ((reps / 2) * point_count),
	     sizeof(double) * real_point_count);
      stp_free(y2a);
      stp_free(ua);
    }
  else
    {
      int count = real_point_count - 1;

      y2[0] = 0;
      u[0] = 2 * (y[1] - y[0]);
      for (i = 1; i < count; i++)
	{
	  int im1 = (i - 1);
	  int ip1 = (i + 1);

	  sig = (i - im1) / (ip1 - im1);
	  p = sig * y2[im1] + 2.0;
	  y2[i] = (sig - 1.0) / p;

	  u[i] = y[ip1] - 2 * y[i] + y[im1];
	  u[i] = 3.0 * u[i] - sig * u[im1] / p;
	}

      u[count] = 2 * (y[count] - y[count - 1]);
      y2[count] = 0.0;

      u[count] = 0.0;
      for (k = real_point_count - 2; k >= 0; k--)
	y2[k] = y2[k] * y2[k + 1] + u[k];
    }

  curve->interval = y2;
  stp_free(u);
}
Esempio n. 8
0
static void
compute_spline_deltas_piecewise(stp_curve_t *curve)
{
  int i;
  int k;
  double *u;
  double *y2;
  const double *data = NULL;
  const stp_curve_point_t *dp;
  size_t point_count;
  size_t real_point_count;
  double sig;
  double p;

  point_count = get_point_count(curve);

  stp_sequence_get_data(curve->seq, &real_point_count, &data);
  dp = (const stp_curve_point_t *)data;
  real_point_count = real_point_count / 2;

  u = stp_malloc(sizeof(double) * real_point_count);
  y2 = stp_malloc(sizeof(double) * real_point_count);

  if (curve->wrap_mode == STP_CURVE_WRAP_AROUND)
    {
      int reps = 3;
      int count = reps * real_point_count;
      double *y2a = stp_malloc(sizeof(double) * count);
      double *ua = stp_malloc(sizeof(double) * count);
      y2a[0] = 0.0;
      ua[0] = 0.0;
      for (i = 1; i < count - 1; i++)
	{
	  int im1 = (i - 1) % point_count;
	  int ia = i % point_count;
	  int ip1 = (i + 1) % point_count;

	  sig = (dp[ia].x - dp[im1].x) / (dp[ip1].x - dp[im1].x);
	  p = sig * y2a[im1] + 2.0;
	  y2a[i] = (sig - 1.0) / p;

	  ua[i] = ((dp[ip1].y - dp[ia].y) / (dp[ip1].x - dp[ia].x)) -
	    ((dp[ia].y - dp[im1].y) / (dp[ia].x - dp[im1].x));
	  ua[i] =
	    (((6.0 * ua[ia]) / (dp[ip1].x - dp[im1].x)) - (sig * ua[im1])) / p;
	}
      y2a[count - 1] = 0.0;
      for (k = count - 2 ; k >= 0; k--)
	y2a[k] = y2a[k] * y2a[k + 1] + ua[k];
      memcpy(u, ua + ((reps / 2) * point_count),
	     sizeof(double) * real_point_count);
      memcpy(y2, y2a + ((reps / 2) * point_count),
	     sizeof(double) * real_point_count);
      stp_free(y2a);
      stp_free(ua);
    }
  else
    {
      int count = real_point_count - 1;

      y2[0] = 0;
      u[0] = 2 * (dp[1].y - dp[0].y);
      for (i = 1; i < count; i++)
	{
	  int im1 = (i - 1);
	  int ip1 = (i + 1);

	  sig = (dp[i].x - dp[im1].x) / (dp[ip1].x - dp[im1].x);
	  p = sig * y2[im1] + 2.0;
	  y2[i] = (sig - 1.0) / p;

	  u[i] = ((dp[ip1].y - dp[i].y) / (dp[ip1].x - dp[i].x)) -
	    ((dp[i].y - dp[im1].y) / (dp[i].x - dp[im1].x));
	  u[i] =
	    (((6.0 * u[i]) / (dp[ip1].x - dp[im1].x)) - (sig * u[im1])) / p;
	  stp_deprintf(STP_DBG_CURVE,
		       "%d sig %f p %f y2 %f u %f x %f %f %f y %f %f %f\n",
		       i, sig, p, y2[i], u[i],
		       dp[im1].x, dp[i].x, dp[ip1].x,
		       dp[im1].y, dp[i].y, dp[ip1].y);
	}
      y2[count] = 0.0;
      u[count] = 0.0;
      for (k = real_point_count - 2; k >= 0; k--)
	y2[k] = y2[k] * y2[k + 1] + u[k];
    }

  curve->interval = y2;
  stp_free(u);
}
Esempio n. 9
0
stp_curve_t *
stp_curve_create_from_xmltree(stp_mxml_node_t *curve)  /* The curve node */
{
  const char *stmp;                       /* Temporary string */
  stp_mxml_node_t *child;                 /* Child sequence node */
  stp_curve_t *ret = NULL;                /* Curve to return */
  stp_curve_type_t curve_type;            /* Type of curve */
  stp_curve_wrap_mode_t wrap_mode;        /* Curve wrap mode */
  double fgamma;                          /* Gamma value */
  stp_sequence_t *seq = NULL;             /* Sequence data */
  double low, high;                       /* Sequence bounds */
  int piecewise = 0;

  stp_xml_init();
  /* Get curve type */
  stmp = stp_mxmlElementGetAttr(curve, "type");
  if (stmp)
    {
      if (!strcmp(stmp, "linear"))
	  curve_type = STP_CURVE_TYPE_LINEAR;
      else if (!strcmp(stmp, "spline"))
	  curve_type = STP_CURVE_TYPE_SPLINE;
      else
	{
	  stp_deprintf(STP_DBG_CURVE_ERRORS,
		       "stp_curve_create_from_xmltree: %s: \"type\" invalid\n", stmp);
	  goto error;
	}
    }
  else
    {
      stp_deprintf(STP_DBG_CURVE_ERRORS,
		   "stp_curve_create_from_xmltree: \"type\" missing\n");
      goto error;
    }
  /* Get curve wrap mode */
  stmp = stp_mxmlElementGetAttr(curve, "wrap");
  if (stmp)
    {
      if (!strcmp(stmp, "nowrap"))
	wrap_mode = STP_CURVE_WRAP_NONE;
      else if (!strcmp(stmp, "wrap"))
	{
	  wrap_mode = STP_CURVE_WRAP_AROUND;
	}
      else
	{
	  stp_deprintf(STP_DBG_CURVE_ERRORS,
		       "stp_curve_create_from_xmltree: %s: \"wrap\" invalid\n", stmp);
	  goto error;
	}
    }
  else
    {
      stp_deprintf(STP_DBG_CURVE_ERRORS,
		   "stp_curve_create_from_xmltree: \"wrap\" missing\n");
      goto error;
    }
  /* Get curve gamma */
  stmp = stp_mxmlElementGetAttr(curve, "gamma");
  if (stmp)
    {
      fgamma = stp_xmlstrtod(stmp);
    }
  else
    {
      stp_deprintf(STP_DBG_CURVE_ERRORS,
		   "stp_curve_create_from_xmltree: \"gamma\" missing\n");
      goto error;
    }
  /* If gamma is set, wrap_mode must be STP_CURVE_WRAP_NONE */
  if (fgamma && wrap_mode != STP_CURVE_WRAP_NONE)
    {
      stp_deprintf(STP_DBG_CURVE_ERRORS, "stp_curve_create_from_xmltree: "
		   "gamma set and \"wrap\" is not STP_CURVE_WRAP_NONE\n");
      goto error;
    }
  stmp = stp_mxmlElementGetAttr(curve, "piecewise");
  if (stmp && strcmp(stmp, "true") == 0)
    piecewise = 1;

  /* Set up the curve */
  ret = stp_curve_create(wrap_mode);
  stp_curve_set_interpolation_type(ret, curve_type);

  child = stp_mxmlFindElement(curve, curve, "sequence", NULL, NULL, STP_MXML_DESCEND);
  if (child)
    seq = stp_sequence_create_from_xmltree(child);

  if (seq == NULL)
    {
      stp_deprintf(STP_DBG_CURVE_ERRORS,
		   "stp_curve_create_from_xmltree: sequence read failed\n");
      goto error;
    }

  /* Set curve bounds */
  stp_sequence_get_bounds(seq, &low, &high);
  stp_curve_set_bounds(ret, low, high);

  if (fgamma)
    stp_curve_set_gamma(ret, fgamma);
  else /* Not a gamma curve, so set points */
    {
      size_t seq_count;
      const double* data;

      stp_sequence_get_data(seq, &seq_count, &data);
      if (piecewise)
	{
	  if ((seq_count % 2) != 0)
	    {
	      stp_deprintf(STP_DBG_CURVE_ERRORS,
			   "stp_curve_create_from_xmltree: invalid data count %ld\n",
			   (long)seq_count);
	      goto error;
	    }
	  if (stp_curve_set_data_points(ret, seq_count / 2,
					(const stp_curve_point_t *) data) == 0)
	    {
	      stp_deprintf(STP_DBG_CURVE_ERRORS,
			   "stp_curve_create_from_xmltree: failed to set curve data points\n");
	      goto error;
	    }
	}
      else
	{
	  if (stp_curve_set_data(ret, seq_count, data) == 0)
	    {
	      stp_deprintf(STP_DBG_CURVE_ERRORS,
			   "stp_curve_create_from_xmltree: failed to set curve data\n");
	      goto error;
	    }
	}
    }

  if (seq)
    {
      stp_sequence_destroy(seq);
      seq = NULL;
    }

    /* Validate curve */
  if (stpi_curve_check_parameters(ret, stp_curve_count_points(ret)) == 0)
    {
      stp_deprintf(STP_DBG_CURVE_ERRORS,
		   "stp_curve_create_from_xmltree: parameter check failed\n");
      goto error;
    }

  stp_xml_exit();

  return ret;

 error:
  stp_deprintf(STP_DBG_CURVE_ERRORS,
	       "stp_curve_create_from_xmltree: error during curve read\n");
  if (ret)
    stp_curve_destroy(ret);
  stp_xml_exit();
  return NULL;
}
Esempio n. 10
0
void
stp_array_get_data(const stp_array_t *array, size_t *size, const double **data)
{
  check_array(array);
  stp_sequence_get_data(array->data, size, data);
}