Пример #1
0
/********************************************************************
Fit traditional cubic to  2 points (x,y) and derivatives
Cubic is of the form

  y = c3*x^3 + c2*x^2 + c1*x + c0

Return c3, c2, c1, c0
********************************************************************/
void wn_fit_cubic_2p2d
(
  int *pcode,
  double coef[4],
  double x1,double y1,double dy1,
  double x2,double y2,double dy2
)
{
  double c[4];
  double m,b;
  double xform[2];
  double accum[5],next_accum[5];
  int i,j;

  *pcode = WN_SUCCESS;

  if(x1 == x2)
  {
    *pcode = WN_SINGULAR;
    return;
  }

  /* compute mapping from x space to -1 +1 space */
  m = 2.0/(x2-x1);
  b = 1.0 - m*x2;

  dy1 /= m;
  dy2 /= m;

  /* compute coefs assuming x1==-1,x2==1 */
  c[2] = (1.0/4.0)*(dy2-dy1);
  c[0] = (1.0/2.0)*(y2+y1) - c[2];
  c[3] = (1.0/2.0)*(y1+dy1 + c[2] - c[0]);
  c[1] = dy2 - 3.0*c[3] - 2.0*c[2];

  /* use mapping to transform cubic */
  wn_zero_vect(coef,4);
  wn_zero_vect(accum,4);
  accum[0] = 1.0;

  xform[0] = b;
  xform[1] = m;

  for(i=0;i<4;++i)
  {
    for(j=0;j<=i;++j)
    {
      coef[j] += c[i]*accum[j];
    }

    wn_mult_polys(next_accum,accum,i+1,xform,2);
    wn_copy_vect(accum,next_accum,i+2);
  }

  *pcode = WN_SUCCESS;
}
Пример #2
0
void wn_mult_polys(double out[],double in1[],int len1,double in2[],int len2)
{
  int i1,i2;

  wn_zero_vect(out,len1+len2-1);

  for(i1=0;i1<len1;++i1)
  for(i2=0;i2<len2;++i2)
  {
    out[i1+i2] += in1[i1]*in2[i2];
  }
}
Пример #3
0
local void reset_search_direction
(
  wn_cdn_context_type c,
  wn_cdn_srchdir_type search_direction
)
{
  if(search_direction->dir_vect != NULL)
  {
    wn_zero_vect(search_direction->dir_vect,c->num_vars);
  }

  search_direction->x_min = -WN_FHUGE;
  search_direction->x_max = WN_FHUGE;

  search_direction->x0 = 0.0;  
  search_direction->curvature = 0.0; 
  search_direction->x_width = 0.0;  
  search_direction->max_x_width = WN_FHUGE;
}
Пример #4
0
EXTERN void wn_conj_direction_method
(
  int *pcode,
  double *pval_min,
  double vect[],
  double initial_coord_x0s[],
  int passed_num_vars,
  double (*pfunction)(double vect[]),
  int max_func_calls
)
{
  int i,j,iteration;
  double *old_vect,*coord_direction;
  double *new_search_direction;
  double old_val_min;

  wn_memgp conj_dir_memgp;

  wn_gpmake("no_free");

  force_optimize_stop_flag = FALSE;

  num_vars = passed_num_vars;
  max_num_search_directions = num_vars;

  wn_make_vect(&buffer_vect,num_vars);
  search_directions = (double **)wn_zalloc(
		  max_num_search_directions*sizeof(double *));
  wn_make_vect(&old_vect,num_vars);
  wn_make_vect(&coord_direction,num_vars);
  wn_make_vect(&coord_x0s,num_vars);
  wn_make_vect(&search_direction_x0s,max_num_search_directions);
  wn_make_vect(&coord_as,num_vars);
  wn_make_vect(&search_direction_as,max_num_search_directions);
  if(initial_coord_x0s == NULL)
  {
    wn_zero_vect(coord_x0s,num_vars);
  }
  else
  {
    wn_copy_vect(coord_x0s,initial_coord_x0s,num_vars);
  }
  wn_zero_vect(search_direction_x0s,max_num_search_directions);
  wn_zero_vect(coord_as,num_vars);
  wn_zero_vect(search_direction_as,max_num_search_directions);

  /* name and pop the memory group we created */

  conj_dir_memgp = wn_curgp();
  wn_gppop();

  sqrt_tolerance = sqrt(wn_machine_tolerance());

  num_search_directions = 0;

  num_func_calls = 0;

  last_line_function_x_valid = FALSE;
  *pval_min = wn_clip_f((*pfunction)(vect));
  ++num_func_calls;

  for(iteration=0;;++iteration)
  {
    if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_PASSES)
    {
      printf("iteration = %d ********************************\n",iteration);
      printf("ob = %lg\n",*pval_min);
      fflush(stdout);
    }
    /*
    (void)getchar();
    */

    old_val_min = *pval_min;
    wn_copy_vect(old_vect,vect,num_vars);

    /* minimize along acceleration search directions */
    if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_LINESEARCH)
    {
      printf("start acceleration line minimizations ------------------\n");
    }
    for(i=0;i<num_search_directions;++i)
    {
      if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_LINESEARCH)
      {
        printf("acceleration line search %d\n",i);
      }

      line_minimize(vect,search_directions[i],pval_min,
		    &(search_direction_x0s[i]),&(search_direction_as[i]),
		    pfunction);

      if(
	  ((max_func_calls < WN_IHUGE)&&(num_func_calls > max_func_calls))
	    ||
          force_optimize_stop_flag
	)
      {
        *pcode = WN_SUBOPTIMAL;
	goto finish;
      }
    }

    /* minimize along coordinate directions */
    if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_LINESEARCH) 
    {
      printf("start coordinate line minimizations ------------------\n");
    }
    for(i=0;i<num_vars;++i)
    {
      if(wn_conj_direction_debug >= WN_CONJ_DIR_DBG_LINESEARCH)
      {
        printf("coord line search %d\n",i);
      }

      coord_direction[i] = 1.0;

      line_minimize(vect,coord_direction,pval_min,
		    &(coord_x0s[i]),&(coord_as[i]),
		    pfunction);

      coord_direction[i] = 0.0;

      if(
	  ((max_func_calls < WN_IHUGE)&&(num_func_calls > max_func_calls))
	    ||
          force_optimize_stop_flag
	)
      {
        *pcode = WN_SUBOPTIMAL;
	goto finish;
      }
    }

    if(*pval_min >= old_val_min)
    {
      wn_assert(*pval_min == old_val_min);

      *pcode = WN_SUCCESS;
      break;
    }

    /* compute new acceleration search direction */
    if(num_search_directions < max_num_search_directions)
    {
      wn_gppush(conj_dir_memgp);
      wn_make_vect(&new_search_direction,num_vars);
      wn_gppop();
      for(i=num_search_directions;i>0;--i)
      {
        search_directions[i] = search_directions[i-1];
	search_direction_x0s[i] = search_direction_x0s[i-1];
	search_direction_as[i] = search_direction_as[i-1];
      }
      search_directions[0] = new_search_direction;
      search_direction_x0s[0] = 1.0;
      search_direction_as[0] = 0.0;

      ++num_search_directions;
    }
    else
    {
      new_search_direction = search_directions[max_num_search_directions-1];
      for(i=max_num_search_directions-1;i>0;--i)
      {
        search_directions[i] = search_directions[i-1];
	search_direction_x0s[i] = search_direction_x0s[i-1];
	search_direction_as[i] = search_direction_as[i-1];
      }
      search_directions[0] = new_search_direction;
      search_direction_x0s[0] = 1.0;
      search_direction_as[0] = 0.0;
    }

    for(j=0;j<num_vars;++j)
    {
      new_search_direction[j] = vect[j] - old_vect[j];
    }
  }

finish: ;

  force_optimize_stop_flag = FALSE;
  last_line_function_x_valid = FALSE;

  wn_gppush(conj_dir_memgp);
  wn_gpfree();
}
Пример #5
0
local void mat_test_big_simplex()
{
  double val,objective,*solution_vect,*objective_vect,*right_side,**mat;
  int vars,eqs;
  int len_i,len_j,code,i,j;

  wn_gpmake("no_free");    /* temp memory group */

  vars = LEN;
  eqs = LEN;

  len_i = eqs;
  len_j = vars+eqs;

  wn_make_mat(&mat,len_i,len_j);

  wn_make_vect(&solution_vect,len_j);
  wn_make_vect(&objective_vect,len_j);
  wn_make_vect(&right_side,len_i);

  for(j=0;j<len_j;++j)
  {
    val = wn_normal_distribution();
    /*
    if(val < 0.0)
    {
      val = -val;
    }
    */

    objective_vect[j] = val; 
    /*
    objective_vect[j] = 1.0;
    */
  }

  for(i=0;i<len_i;++i)
  {
    val = wn_normal_distribution();
    if(val < 0.0)
    {
      val = -val;
    }

    right_side[i] = val; 
  }

  for(i=0;i<len_i;++i)
  {
    wn_zero_vect(mat[i],len_j);

    for(j=0;j<vars;++j)
    {
      val = wn_normal_distribution();
      if(val < 0.0)
      {
	val = -val;
      }

      mat[i][j] = val;
    }

    mat[i][vars+i] = 1;
  }

  wn_simplex_method(&code,&objective,NULL,solution_vect,
		    objective_vect,mat,right_side,
		    len_i,len_j);
  wn_assert(WN_SUCCESS == code);

  wn_gpfree();
} /* mat_test_big_simplex */
Пример #6
0
local void mat_test_gramm_schmidt(void)
{
  double **mat, **mat_orig;
  int ilen, jlen, code;		/* ilen rows, jlen columns */
  int a, b;
  double *sum_vect, mul, mul2;
  int trial;

  for (trial = 0;  trial < 1000;  ++trial) {
    wn_gpmake("no_free");    /* temp memory group */

      jlen = (unsigned) wn_random_int() % 20    +  1;
      ilen = (unsigned) wn_random_int() % jlen  +  1;

      wn_make_mat(&mat_orig, ilen, jlen);
      wn_random_mat(mat_orig, ilen, jlen);

      wn_make_mat(&mat, ilen, jlen);
      for (a = 0;  a < ilen;  ++a) {
	for (b = 0;  b < jlen;  ++b) {
	  mat[a][b] = mat_orig[a][b];
	}
      }

      wn_gramm_schmidt(&code, mat, ilen, jlen);
      wn_assert(WN_SUCCESS == code);

      /* first ilen vects should be orthogonal */
      for (a = 0;  a < ilen;  ++a) {
	for (b = a+1;  b < ilen;  ++b) {
	  wn_assert(LO_ALMOST_EQUAL(0.0, wn_dot_vects(mat[a], mat[b], jlen)));
	}
      }

      /* let's make the gramm_schmidt be unit vectors, to be simple */
      for (a = 0;  a < ilen;  ++a) {
	mul2 = wn_dot_vects(mat[a], mat[a], jlen);
	mul = 1/sqrt(mul2);
	for (b = 0;  b < jlen;  ++b) {
	  mat[a][b] *= mul;
	}
	wn_assert(LO_ALMOST_EQUAL(1.0, wn_dot_vects(mat[a], mat[a], jlen)));
      }

      /* check again orthogonality */
      for (a = 0;  a < ilen;  ++a) {
	for (b = a+1;  b < ilen;  ++b) {
	  wn_assert(LO_ALMOST_EQUAL(0.0, wn_dot_vects(mat[a], mat[b], jlen)));
	}
      }

      /* make a vector in the space spanned by the original vectors */
      wn_make_vect(&sum_vect, jlen);
      wn_zero_vect(sum_vect, jlen);
      for (a = 0;  a < ilen;  ++a) {
	wn_add_scaled_vect(sum_vect, mat_orig[a], wn_flat_distribution(),
	/**/							jlen);
      }

      /* OK, sum_vect is reached from the original matrix of vectors */
      /* can we reach it from mat? */
      for (a = 0;  a < ilen;  ++a) {
	mul = wn_dot_vects(sum_vect, mat[a], jlen);
	wn_add_scaled_vect(sum_vect, mat[a], -mul, jlen);
      }
      wn_assert(LO_ALMOST_EQUAL(0.0, wn_dot_vects(sum_vect, sum_vect, jlen)));

    wn_gpfree();
  } /* for trial */
} /* mat_test_gramm_schmidt */
Пример #7
0
local void gradient(double grad[],double v[])
{
  double diff,conductance_sum;
  int i;
  wn_sll el;
  wn_sparse_matrix_entry entry;

  printf("gradient.  count = %d\n",count);
  ++count;

  wn_zero_vect(grad,len);

  for(i=0;i<len;++i)
  {
    if(stimulus_type_vect[i] != voltage)
    {
      if(stimulus_type_vect[i] == current)
      {
        /* currents at each node must sum to drive current */
        diff = stimulus_vect[i];
      }
      else
      {
        /* currents at each node must sum to zero */
        diff = 0.0;
      }

      conductance_sum = 0.0;
  
      for(el=(conductance_graph->i_lists)[i];el!=NULL;el=el->next)
      {
        entry = (wn_sparse_matrix_entry)(el->contents);
  
        conductance_sum += entry->value;
      }
  
      diff -= v[i]*conductance_sum;
  
      for(el=(conductance_graph->i_lists)[i];el!=NULL;el=el->next)
      {
        entry = (wn_sparse_matrix_entry)(el->contents);
  
        if(stimulus_type_vect[entry->j] == voltage)
        {
          diff += stimulus_vect[entry->j]*entry->value;
        }
	else
	{
          diff += v[entry->j]*entry->value;
	}
      }
  
      grad[i] += 2.0*diff*(-conductance_sum);

      for(el=(conductance_graph->i_lists)[i];el!=NULL;el=el->next)
      {
        entry = (wn_sparse_matrix_entry)(el->contents);
  
        if(stimulus_type_vect[entry->j] != voltage)
        {
          grad[entry->j] += 2.0*diff*entry->value;
	}
      }
    }
  }
}
Пример #8
0
void wn_make_vect(double **pvect,int len)
{
  *pvect = (double *)wn_alloc(len*sizeof(double));

  wn_zero_vect(*pvect,len);
}