Exemplo n.º 1
0
void
CreateExecutionerAction::populateCommonExecutionerParams(InputParameters & params)
{
  MooseEnum solve_type("PJFNK JFNK NEWTON FD LINEAR");
  params.addParam<MooseEnum>   ("solve_type",      solve_type,
                                "PJFNK: Preconditioned Jacobian-Free Newton Krylov "
                                "JFNK: Jacobian-Free Newton Krylov "
                                "NEWTON: Full Newton Solve "
                                "FD: Use finite differences to compute Jacobian "
                                "LINEAR: Solving a linear problem");

  // Line Search Options
#ifdef LIBMESH_HAVE_PETSC
#if PETSC_VERSION_LESS_THAN(3,3,0)
  MooseEnum line_search("default cubic quadratic none basic basicnonorms", "default");
#else
  MooseEnum line_search("default shell none basic l2 bt cp", "default");
#endif
  std::string addtl_doc_str(" (Note: none = basic)");
#else
  MooseEnum line_search("default", "default");
  std::string addtl_doc_str("");
#endif
  params.addParam<MooseEnum>   ("line_search",     line_search, "Specifies the line search type" + addtl_doc_str);

#ifdef LIBMESH_HAVE_PETSC
  MultiMooseEnum common_petsc_options("", "", true);

  params.addParam<MultiMooseEnum>("petsc_options", common_petsc_options, "Singleton PETSc options");
  params.addParam<std::vector<std::string> >("petsc_options_iname", "Names of PETSc name/value pairs");
  params.addParam<std::vector<std::string> >("petsc_options_value", "Values of PETSc name/value pairs (must correspond with \"petsc_options_iname\"");
#endif //LIBMESH_HAVE_PETSC
}
Exemplo n.º 2
0
void calculate_chi_bf(rpacket_t * packet, storage_model_t * storage)
{
  double doppler_factor = rpacket_doppler_factor (packet, storage);
  double comov_nu = rpacket_get_nu (packet) * doppler_factor;

  int64_t no_of_continuum_edges = storage->no_of_edges;
  int64_t current_continuum_id;
  line_search(storage->continuum_list_nu, comov_nu, no_of_continuum_edges, &current_continuum_id);
  rpacket_set_current_continuum_id(packet, current_continuum_id);

  int64_t shell_id = rpacket_get_current_shell_id(packet);
  double T = storage->t_electrons[shell_id];
  double boltzmann_factor = exp(-(H * comov_nu) / (KB*T));

  double bf_helper = 0;
  for(int64_t i = current_continuum_id; i < no_of_continuum_edges; i++)
    {
      // get the levelpopulation for the level ijk in the current shell:
      double l_pop = storage->l_pop[shell_id * no_of_continuum_edges + i];
      // get the levelpopulation ratio \frac{n_{0,j+1,k}}{n_{i,j,k}} \frac{n_{i,j,k}}{n_{0,j+1,k}}^{*}:
      double l_pop_r = storage->l_pop_r[shell_id * no_of_continuum_edges + i];
      bf_helper += l_pop * bf_cross_section(storage, i, comov_nu) * (1 - l_pop_r * boltzmann_factor);

      // FIXME MR: Is this thread-safe? It doesn't look like it to me ...
      storage->chi_bf_tmp_partial[i] = bf_helper;
    }

  rpacket_set_chi_boundfree(packet, bf_helper * doppler_factor);
}
Exemplo n.º 3
0
FT Scene::optimize_weights_via_newton(FT timestep, bool update)
{
    std::vector<FT> gradient;
    compute_weight_gradient(gradient, -1.0);
    
    std::vector<FT> direction;
    bool ok = solve_newton_step(gradient, direction);
    if (!ok) return 0.0;   
    
    std::vector<FT> weights;
    collect_visible_weights(weights);
    
    if (timestep <= 0.0)
    {
        LSWeights line_search(this, 20, 2.0);
        timestep = line_search.run_bt(weights, direction);
    } else {
        for (unsigned i = 0; i < weights.size(); ++i)
        {
            FT wi = weights[i];
            FT gi = direction[i];
            weights[i] = wi + timestep*gi;
        }
        update_weights(weights);
        if (update) update_triangulation();
    }
    
    compute_weight_gradient(gradient);
    return compute_norm(gradient);
}
Exemplo n.º 4
0
FT Scene::optimize_weights_via_gradient_descent(FT timestep, bool update)
{
    std::vector<FT> gradient;
    compute_weight_gradient(gradient, -1.0);
    
    std::vector<FT> weights;
    collect_visible_weights(weights);
    
    if (timestep <= 0.0)
    {
        LSWeights line_search(this, 10, 2.0);
        timestep = line_search.run_bt(weights, gradient);
    } else {
        for (unsigned i = 0; i < weights.size(); ++i)
        {
            FT wi = weights[i];
            FT gi = gradient[i];
            weights[i] = wi + timestep*gi;
        }
        update_weights(weights);
        if (update) update_triangulation();
    }

    compute_weight_gradient(gradient);
    return compute_norm(gradient);
}
Exemplo n.º 5
0
FT Scene::optimize_positions_via_gradient_ascent(FT timestep, bool update)
{
    std::vector<Point> points;
    collect_visible_points(points);

    std::vector<Vector> gradient;
    compute_position_gradient(gradient);
    
    if (timestep <= 0.0)
    {
        double mean_capacity = compute_mean(m_capacities);
        double max_alpha = 1.0 / mean_capacity;
        LSPositions line_search(this, 10, max_alpha);        
        timestep = line_search.run_bt(points, gradient);
    } else {    
        for (unsigned i = 0; i < points.size(); ++i)
        {
            Point  pi = points[i];
            Vector gi = gradient[i];
            points[i] = pi + timestep*gi;
        }
        update_positions(points);
        if (update) update_triangulation();
    }
    
    compute_position_gradient(gradient);
    return compute_norm(gradient);
}
Exemplo n.º 6
0
    Field<dim> lbfgs(
      const Functional& F,
      const Gradient& dF,
      const Field<dim>& phi_start,
      const unsigned int m,
      const double eps
    )
    {
      double cost_old = std::numeric_limits<double>::infinity();
      double cost = F(phi_start);

      Field<dim> phi0(phi_start);
      DualField<dim> df0 = dF(phi_start);
      const auto& discretization = phi0.get_discretization();

      // Create vectors for storing the last few differences of the guesses,
      // differences of the gradients, and the inverses of their inner products
      std::vector<Field<dim>> s(m, Field<dim>(discretization));
      std::vector<DualField<dim>> y(m, DualField<dim>(discretization));
      std::vector<double> rho(m);

      // As an initial guess, we will assume that the Hessian inverse is a
      // multiple of the inverse of the mass matrix
      double gamma = 1.0;

      for (unsigned int k = 0; std::abs(cost_old - cost)/cost > eps; ++k) {
        const Field<dim> p = -lbfgs_two_loop(df0, s, y, rho, gamma);
        const Field<dim> phi1 = line_search(F, phi0, df0, p, eps);
        const DualField<dim> df1 = dF(phi1);

        s[0] = phi1 - phi0;
        y[0] = df1 - df0;

        const double cos_angle = inner_product(y[0], s[0]);
        const double norm_y = norm(y[0]);
        rho[0] = 1.0 / cos_angle;
        gamma = cos_angle / (norm_y * norm_y);

        std::rotate(s.begin(), s.begin() + 1, s.end());
        std::rotate(y.begin(), y.begin() + 1, y.end());
        std::rotate(rho.begin(), rho.begin() + 1, rho.end());

        phi0 = phi1;
        df0 = df1;
        cost_old = cost;
        cost = F(phi0);
      }

      return phi0;
    }
Exemplo n.º 7
0
void OPT_ALGO::parallel_owlqn(int use_list_len, float* ro_list, float** s_list, float** y_list){
    //define and initial local parameters
    float *local_g = new float[fea_dim];//single thread gradient
    float *local_sub_g = new float[fea_dim];//single thread subgradient
    float *p = new float[fea_dim];//single thread search direction.after two loop
    loss_function_gradient(w, local_g);//calculate gradient of loss by global w)
    loss_function_subgradient(local_g, local_sub_g); 
    //should add code update multithread and all nodes sub_g to global_sub_g
    two_loop(use_list_len, local_sub_g, s_list, y_list, ro_list, p);

    pthread_mutex_lock(&mutex);
    for(int j = 0; j < fea_dim; j++){
        *(global_g + j) += *(p + j);//update global direction of all threads
    }
    pthread_mutex_unlock(&mutex);

    pid_t local_thread_id;
    local_thread_id = getpid();
    if(local_thread_id == main_thread_id){
        for(int j = 0; j < fea_dim; j++){ 
            *(all_nodes_global_g + j) = 0.0;
        }
        for(int j = 0; j < fea_dim; j++){//must be pay attention
            *(global_g + j) /= n_threads;
        }   
        MPI_Allreduce(global_g, all_nodes_global_g, 1, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);//all_nodes_global_g store shared sum of every nodes search direction
    }
    pthread_barrier_wait(&barrier);
    //should be synchronous all threads
    line_search(all_nodes_global_g);//use global search direction to search
    //update slist
    if(local_thread_id == main_thread_id){
        cblas_daxpy(fea_dim, -1, (double*)w, 1, (double*)next_w, 1);
        cblas_dcopy(fea_dim, (double*)next_w, 1, (double*)s_list[(m - use_list_len) % m], 1);
    //update ylist
        cblas_daxpy(fea_dim, -1, (double*)global_g, 1, (double*)global_next_g, 1); 
        cblas_dcopy(fea_dim, (double*)global_next_g, 1, (double*)y_list[(m - use_list_len) % m], 1);

        use_list_len++;
        if(use_list_len > m){
            for(int j = 0; j < fea_dim; j++){
                *(*(s_list + abs(m - use_list_len) % m) + j) = 0.0;
                *(*(y_list + abs(m - use_list_len) % m) + j) = 0.0;        
            }
        }
        cblas_dcopy(fea_dim, (double*)next_w, 1, (double*)w, 1);
    }
    pthread_barrier_wait(&barrier);
}
Exemplo n.º 8
0
tardis_error_t
rpacket_init (rpacket_t * packet, storage_model_t * storage, int packet_index,
              int virtual_packet_flag, double * chi_bf_tmp_partial)
{
  int64_t current_line_id;
  tardis_error_t ret_val = TARDIS_ERROR_OK;
  double current_nu = storage->packet_nus[packet_index];
  double current_energy = storage->packet_energies[packet_index];
  double current_mu = storage->packet_mus[packet_index];
  double comov_current_nu = current_nu;
  int current_shell_id = 0;
  double current_r = storage->r_inner[0];
  double beta = current_r * storage->inverse_time_explosion * INVERSE_C;

  if (storage->full_relativity)
    {
      current_nu = current_nu * (1 + beta * current_mu) / sqrt(1 - beta * beta);
      current_energy = current_energy * (1 + beta * current_mu) / sqrt(1 - beta * beta);
      current_mu = (current_mu + beta) / (1 + beta * current_mu);
    }
  else
    {
      current_nu = current_nu / (1 - beta * current_mu);
      current_energy = current_energy / (1 - beta * current_mu);
    }
  if ((ret_val =
       line_search (storage->line_list_nu, comov_current_nu,
                    storage->no_of_lines,
                    &current_line_id)) != TARDIS_ERROR_OK)
    {
      return ret_val;
    }
  bool last_line = (current_line_id == storage->no_of_lines);
  rpacket_set_nu (packet, current_nu);
  rpacket_set_mu (packet, current_mu);
  rpacket_set_energy (packet, current_energy);
  rpacket_set_r (packet, current_r);
  rpacket_set_current_shell_id (packet, current_shell_id);
  rpacket_set_next_line_id (packet, current_line_id);
  rpacket_set_last_line (packet, last_line);
  rpacket_set_close_line (packet, false);
  rpacket_set_virtual_packet_flag (packet, virtual_packet_flag);
  packet->chi_bf_tmp_partial = chi_bf_tmp_partial;
  packet->compute_chi_bf = true;
  packet->vpacket_weight = 1.0;
  return ret_val;
}
Exemplo n.º 9
0
tardis_error_t rpacket_init(rpacket_t *packet, storage_model_t *storage, int packet_index, int virtual_packet_flag)
{
  double nu_line;
  double current_r;
  double current_mu;
  double current_nu;
  double comov_current_nu;
  double current_energy;
  int64_t current_line_id;
  int current_shell_id;
  bool last_line;
  bool close_line;
  int recently_crossed_boundary;
  tardis_error_t ret_val = TARDIS_ERROR_OK;
  current_nu = storage->packet_nus[packet_index];
  current_energy = storage->packet_energies[packet_index];
  current_mu = storage->packet_mus[packet_index];
  comov_current_nu = current_nu;
  current_shell_id = 0;
  current_r = storage->r_inner[0];
  current_nu = current_nu / (1 - (current_mu * current_r * storage->inverse_time_explosion * INVERSE_C));
  current_energy = current_energy / (1 - (current_mu * current_r * storage->inverse_time_explosion * INVERSE_C));
  if ((ret_val = line_search(storage->line_list_nu, comov_current_nu, storage->no_of_lines, &current_line_id)) != TARDIS_ERROR_OK)
    {
      return ret_val;
    }
  last_line = (current_line_id == storage->no_of_lines);
  recently_crossed_boundary = true;
  rpacket_set_nu(packet, current_nu);
  rpacket_set_mu(packet, current_mu);
  rpacket_set_energy(packet, current_energy);
  rpacket_set_r(packet, current_r);
  rpacket_set_current_shell_id(packet, current_shell_id);
  rpacket_set_next_line_id(packet, current_line_id);
  rpacket_set_last_line(packet, last_line);
  rpacket_set_close_line(packet, false);
  rpacket_set_recently_crossed_boundary(packet, recently_crossed_boundary);
  rpacket_set_virtual_packet_flag(packet, virtual_packet_flag);
  return ret_val;
}
Exemplo n.º 10
0
int main(int argc, char ** argv)
{
  utils::mpi_world mpi_world(argc, argv);
  
  const int mpi_rank = MPI::COMM_WORLD.Get_rank();
  const int mpi_size = MPI::COMM_WORLD.Get_size();
  
  try {
    options(argc, argv);

    cicada::optimize::LineSearch::value_min = value_lower;
    cicada::optimize::LineSearch::value_max = value_upper;
    
    if (scorer_list) {
      std::cout << cicada::eval::Scorer::lists();
      return 0;
    }
    
    if (int(yield_sentence) + yield_alignment + yield_span > 1)
      throw std::runtime_error("specify either sentence|alignment|span yield");
    if (int(yield_sentence) + yield_alignment + yield_span == 0)
      yield_sentence = true;

    if (weights_file.empty() || ! boost::filesystem::exists(weights_file))
      throw std::runtime_error("no weight file? " + weights_file.string());
    if (direction_name.empty())
      throw std::runtime_error("no direction?");
    
    // read reference set
    scorer_document_type scorers(scorer_name);
    
    read_refset(refset_files, scorers);
    
    if (mpi_rank == 0 && debug)
      std::cerr << "# of references: " << scorers.size() << std::endl;

    // read test set
    
    if (mpi_rank == 0 && debug)
      std::cerr << "reading hypergraphs" << std::endl;

    hypergraph_set_type graphs(scorers.size());
    
    read_tstset(tstset_files, graphs);
    
    weight_set_type weights;
    {
      utils::compress_istream is(weights_file, 1024 * 1024);
      is >> weights;
    }
    
    weight_set_type direction;
    direction[direction_name] = 1.0;
    
    segment_document_type segments(graphs.size());
    
    compute_envelope(scorers, graphs, weights, direction, segments);

    if (mpi_rank == 0) {
      line_search_type line_search(debug);
      
      utils::compress_ostream os(output_file, 1024 * 1024);
      
      line_search(segments, value_lower, value_upper, OutputIterator(os, weights[direction_name]));
    }
  }
  catch (const std::exception& err) {
    std::cerr << "error: " << err.what() << std::endl;
    return 1;
  }
  return 0;
}
Exemplo n.º 11
0
struct map_type *dfp( function func,
                      struct map_type *map_x,
                      __float128 grad_toler,
                      __float128 fx_toler,
                      const unsigned int max_iter )
{
    unsigned int iter;
    __float128 lambda, result_func_value, temp_func_value;
    struct map_type *result, *b, *grad1, *tmp, *s, *grad2,
            *g, *tmp2, *tmp3, *d, *x1, *x2, *x3, *x4, *x5;

    result = NULL;
    result_func_value = func( map_x );

    b = get_identity_matrix( map_x->j_size );
    grad1 = first_derivatives( func, map_x );
    tmp = transposition( grad1 );
    deallocate( grad1 );
    grad1 = tmp;
    for( iter = 0 ; iter < max_iter; iter++ )
	{
        tmp = multiplicate_on_value( -1, b );
        s = multiplicate( tmp, grad1 );
        deallocate( tmp );

        tmp = transposition( s );
        tmp2 = multiplicate_on_value( powf( get_euclidean_distance( s ), -1 ), tmp );
        deallocate( s );
        deallocate( tmp );
        s = tmp2;

        lambda = 1;
        lambda = line_search( func, map_x, lambda, s );
        d = multiplicate_on_value( lambda, s );

        tmp = addition( map_x, d );
        deallocate( d );
        deallocate( map_x );
        map_x = tmp;
        temp_func_value = func( map_x );
        if( result_func_value > temp_func_value )
        {
            iter = 0;
            result_func_value = temp_func_value;
            if( result != NULL )
            {
                deallocate( result );
            }
            result = clone( map_x );
        }

        grad2 = first_derivatives( func, map_x );
        tmp = transposition( grad2 );
        deallocate( grad2 );
        grad2 = tmp;
        g = subtraction( grad2, grad1 );
        deallocate( grad1 );
        grad1 = grad2;
        if( get_euclidean_distance( grad1 ) < grad_toler )
        {
            /// TODO: Нужно очистить память
            break;
        }

        tmp = transposition( s );
        x1 = multiplicate( s, tmp );
        x2 = multiplicate( s, g );
        deallocate( s );
        deallocate( tmp );

        tmp = multiplicate_on_value( lambda, x1 );
        tmp2 = get_inverse( x2 );
        tmp3 = multiplicate( tmp, tmp2 );
        deallocate( tmp );
        tmp = addition( b, tmp3 );
        deallocate( x1 );
        deallocate( x2 );
        deallocate( tmp2 );
        deallocate( tmp3 );
        deallocate( b );
        b = tmp;

        x3 = multiplicate( b, g );
        tmp = transposition( b );
        x4 = multiplicate( tmp, g );
        deallocate( tmp );

        tmp = transposition( g );
        tmp2 = multiplicate( tmp, b );
        x5 = multiplicate( tmp2, g );
        deallocate( g );
        deallocate( tmp );
        deallocate( tmp2 );

        tmp = transposition( x4 );
        tmp2 = multiplicate( x3, tmp );
        deallocate( tmp );
        tmp = get_inverse( x5 );
        tmp3 = multiplicate( tmp, tmp2 );
        deallocate( tmp );

        tmp = subtraction( b, tmp3 );
        deallocate( b );
        b = tmp;

        deallocate( tmp2 );
        deallocate( tmp3 );
        deallocate( x3 );
        deallocate( x4 );
        deallocate( x5 );
    }
    return result;
}
Exemplo n.º 12
0
	value_t GeometricCGVariant::solve(const TTOperator *_Ap, TTTensor &_x, const TTTensor &_b, size_t _numSteps, value_t _convergenceEpsilon, PerformanceData &_perfData) const {
		const TTOperator &_A = *_Ap;
		static const Index i,j;
		size_t stepCount=0;
		TTTensor residual;
		TTTangentVector gradient;
		value_t gradientNorm = 1.0;
		value_t lastResidual=1e100;
		value_t currResidual=1e100;
		value_t normB = frob_norm(_b);
		
		if (_Ap != nullptr) {
			_perfData << "Conjugated Gradients for ||A*x - b||^2, x.dimensions: " << _x.dimensions << '\n'
					<< "A.ranks: " << _A.ranks() << '\n';
			if (assumeSymmetricPositiveDefiniteOperator) {
				_perfData << " with symmetric positive definite Operator A\n";
			}
		} else {
			_perfData << "Conjugated Gradients for ||x - b||^2, x.dimensions: " << _x.dimensions << '\n';
		}
		_perfData << "x.ranks: " << _x.ranks() << '\n'
					<< "b.ranks: " << _b.ranks() << '\n'
					<< "maximum number of steps: " << _numSteps << '\n'
					<< "convergence epsilon: " << _convergenceEpsilon << '\n';
		_perfData.start();
		
		auto calculateResidual = [&]()->value_t {
			if (_Ap != nullptr) {
				residual(i&0) = _b(i&0) - _A(i/2,j/2)*_x(j&0);
			} else {
				residual = _b - _x;
			}
			return frob_norm(residual);//normB;
		};
		auto updateGradient = [&]() {
			if (assumeSymmetricPositiveDefiniteOperator || (_Ap == nullptr)) {
				gradient = TTTangentVector(_x, residual);
			} else {
				TTTensor grad;
				grad(i&0) = (*_Ap)(j/2,i/2) * residual(j&0); // grad = A^T * (b - Ax)
				gradient = TTTangentVector(_x, grad);
			}
			gradientNorm = gradient.frob_norm();
		};
		
		currResidual = calculateResidual();
		_perfData.add(stepCount, currResidual, _x);
		
		updateGradient();
		TTTangentVector direction = gradient;
		value_t alpha = 1;
		while ((_numSteps == 0 || stepCount < _numSteps)
			&& currResidual/normB > _convergenceEpsilon
			&& std::abs(lastResidual-currResidual)/normB > _convergenceEpsilon
			&& std::abs(1-currResidual/lastResidual)/normB > _convergenceEpsilon) 
		{
			stepCount += 1;
			size_t stepFlags = 0;
			
			// check the derivative along the current direction
			value_t derivative = gradient.scalar_product(direction) / direction.frob_norm();
			
			// if movement in the given direction would increase the residual rather than decrease it, perform one steepest descent step instead
			if (derivative <= 0) {
				direction = gradient;
				derivative = gradient.frob_norm();
				alpha = 1;
				stepFlags |= 1;
			}
			
			line_search(_x, alpha, direction, derivative, currResidual, retraction, calculateResidual, 0.8);
			
			_perfData.add(stepCount, currResidual, _x, stepFlags);
			
// 			direction(i&0) = residual(i&0) + beta * direction(i&0);
			TTTangentVector oldDirection(direction);
			vectorTransport(_x, oldDirection);
			value_t oldGradNorm = gradientNorm;
			updateGradient();
			
			double beta = gradientNorm / oldGradNorm ;// Fletcher-Reeves update
			direction = gradient;
			direction += oldDirection * beta;
		}
		
		return currResidual;
	}
Exemplo n.º 13
0
/**
 * @brief Low level fitting routine for non-Gaussian trend filtering problems.
 * Can be configured to handle arbirary losses, as it takes the link function
 * and it first two derivaties as inputs. Fits the solution for a single value
 * of lambda. Most users will want to call tf_admm, rather than tf_admm_glm directly.
 *
 * @param y                    a vector of responses
 * @param x                    a vector of response locations; must be in increasing order
 * @param w                    a vector of sample weights
 * @param n                    the length of y, x, and w
 * @param k                    degree of the trendfilter; i.e., k=1 linear
 * @param max_iter             maximum number of ADMM interations; ignored for k=0
 * @param lam                  the value of lambda
 * @param beta                 allocated space for output coefficents; must pre-fill as it is used in warm start
 * @param alpha                allocated space for ADMM alpha covariates; must pre-fill as it is used in warm start
 * @param u                    allocated space for ADMM u covariates; must pre-fill as it is used in warm start
 * @param obj                  allocated space to store the objective; will fill at most max_iter elements
 * @param iter                 allocated space to store the number of iterations; will fill just one element
 * @param status               allocated space of size nlambda to store the status of each run
 * @param rho                  tuning parameter for the ADMM algorithm; set to 1 for default
 * @param obj_tol              stopping criteria tolerance; set to 1e-10 for default
 * @param alpha_ls             for family != 0, line search tuning parameter
 * @param gamma_ls             for family != 0, line search tuning parameter
 * @param max_iter_ls          for family != 0, max number of iterations in line search
 * @param max_iter_newton      for family != 0, max number of iterations in inner ADMM
 * @param DktDk                pointer to the inner product of DktDk
 * @param b                    the link function for a given loss
 * @param b1                   first derivative of the link function for a given loss
 * @param b2                   second derivative of the link function for a given loss
 * @param verbose              0/1 flag for printing progress
 * @return void
 * @see tf_admm
 */
void tf_admm_glm (double * y, double * x, double * w, int n, int k,
        int max_iter, double lam,
        double * beta, double * alpha, double * u,
        double * obj, int * iter,
        double rho, double obj_tol, double alpha_ls, double gamma_ls,
        int max_iter_ls, int max_iter_newton,
        cs * DktDk,
        func_RtoR b, func_RtoR b1, func_RtoR b2, int verbose)
{
  double * d; /* line search direction */
  double * yt;/* working response: ytilde */
  double * H; /* weighted Hessian */
  double * z;
  double * obj_admm;

  int i;
  int * iter_ls;
  int it;
  int iter_admm;
  double * Db;
  double * Dd;
  double loss;
  double pen;
  double t; /* stepsize */

  d  = (double*) malloc(n*sizeof(double)); /* line search direction */
  yt = (double*) malloc(n*sizeof(double));/* working response: ytilde */
  H  = (double*) malloc(n*sizeof(double)); /* weighted Hessian */
  z  = (double*) malloc(n*sizeof(double));

  /* Buffers for line search */
  Db      = (double *) malloc(n*sizeof(double));
  Dd      = (double *) malloc(n*sizeof(double));
  iter_ls = (int *)    malloc(sizeof(int));

  obj_admm = (double*)malloc(max_iter*sizeof(double));

  if (verbose) printf("\nlambda=%0.3e\n",lam);
  if (verbose) printf("Iteration\tObjective\tLoss\tPenalty\tADMM iters\n");

  /* One Prox Newton step per iteration */
  for (it=0; it < max_iter_newton; it++)
  {
    /* Define weighted Hessian, and working response */
    for(i=0; i<n; i++)
    {
      H[i] = w[i] * b2(beta[i]);
      if (fabs(H[i])>WEIGHT_SMALL)
      {
        yt[i] = beta[i] + (y[i]-b1(beta[i]))/H[i];
      }
      else
      {
        yt[i] = beta[i] + (y[i]-b1(beta[i]));
      }
    }

    /* Prox Newton step */
    iter_admm = 0;
    tf_admm_gauss (yt, x, H, n, k,
        max_iter, lam,
        d, alpha, u,
        obj_admm, &iter_admm, rho, obj_tol,
        DktDk, 0);

    for(i=0; i<n; i++)
    {
      d[i] = d[i] - beta[i];
    }

    t = line_search(y, x, w, n, k, lam, b, b1, beta, d, alpha_ls, gamma_ls, max_iter_ls, iter_ls, Db, Dd);
    /* if (verbose) printf("Stepsize t=%.3e,\titers=%d\n", t, *iter_ls+1); */

    for(i=0; i<n; i++)
    {
      beta[i] = beta[i] + t * d[i];
    }

    /* Compute objective */
    /* Compute loss */
    loss = 0;
    for (i=0; i<n; i++) loss += w[i] * (-y[i]*beta[i] + b(beta[i]));
    /* Compute penalty */
    tf_dx(x,n,k+1,beta,z); /* IMPORTANT: use k+1 here! */
    pen = 0;
    for (i=0; i<n-k-1; i++) pen += fabs(z[i]);
    obj[it] = loss+lam*pen;

    if (verbose) printf("\t%i\t%0.3e\t%0.3e\t%0.3e\t%i\n",it+1,obj[it],loss,lam*pen,iter_admm);

    if(it > 0)
    {
      if( fabs(obj[it] - obj[it-1]) < fabs(obj[it]) * obj_tol )
      {
        break;
      }
    }
  }

  *iter = it;

  /* free */
  free(d);
  free(yt);
  free(H);
  free(z);
  free(iter_ls);
  free(Db);
  free(Dd);
  free(obj_admm);
}
Exemplo n.º 14
0
/* main loop */
static int run_grd(CRF_ENG_PTR crf_ptr) {
	int r,iterate,old_valid,converged,conv_time,saved = 0;
	double likelihood,old_likelihood = 0.0;
	double crf_max_iterate = 0.0;
	double tmp_epsilon,alpha0,gf_sd,old_gf_sd = 0.0;

	config_crf(crf_ptr);

	initialize_weights();

	if (crf_learn_mode == 1) {
		initialize_LBFGS();
		printf("L-BFGS mode\n");
	}

	if (crf_learning_rate==1) {
		printf("learning rate:annealing\n");
	} else if (crf_learning_rate==2) {
		printf("learning rate:backtrack\n");
	} else if (crf_learning_rate==3) {
		printf("learning rate:golden section\n");
	}

	if (max_iterate == -1) {
		crf_max_iterate = DEFAULT_MAX_ITERATE;
	} else if (max_iterate >= +1) {
		crf_max_iterate = max_iterate;
	}

	for (r = 0; r < num_restart; r++) {
		SHOW_PROGRESS_HEAD("#crf-iters", r);

		initialize_crf_count();
		initialize_lambdas();
		initialize_visited_flags();

		old_valid = 0;
		iterate = 0;
		tmp_epsilon = crf_epsilon;

		LBFGS_index = 0;
		conv_time = 0;

		while (1) {
			if (CTRLC_PRESSED) {
				SHOW_PROGRESS_INTR();
				RET_ERR(err_ctrl_c_pressed);
			}

			RET_ON_ERR(crf_ptr->compute_feature());

			crf_ptr->compute_crf_probs();

			likelihood = crf_ptr->compute_likelihood();

			if (verb_em) {
				prism_printf("Iteration #%d:\tlog_likelihood=%.9f\n", iterate, likelihood);
			}

			if (debug_level) {
				prism_printf("After I-step[%d]:\n", iterate);
				prism_printf("likelihood = %.9f\n", likelihood);
				print_egraph(debug_level, PRINT_EM);
			}

			if (!isfinite(likelihood)) {
				emit_internal_error("invalid log likelihood: %s (at iteration #%d)",
				                    isnan(likelihood) ? "NaN" : "infinity", iterate);
				RET_ERR(ierr_invalid_likelihood);
			}
			/*        if (old_valid && old_likelihood - likelihood > prism_epsilon) {
					  emit_error("log likelihood decreased [old: %.9f, new: %.9f] (at iteration #%d)",
					  old_likelihood, likelihood, iterate);
					  RET_ERR(err_invalid_likelihood);
					  }*/
			if (likelihood > 0.0) {
				emit_error("log likelihood greater than zero [value: %.9f] (at iteration #%d)",
				           likelihood, iterate);
				RET_ERR(err_invalid_likelihood);
			}

			if (crf_learn_mode == 1 && iterate > 0) restore_old_gradient();

			RET_ON_ERR(crf_ptr->compute_gradient());

			if (crf_learn_mode == 1 && iterate > 0) {
				compute_LBFGS_y_rho();
				compute_hessian(iterate);
			} else if (crf_learn_mode == 1 && iterate == 0) {
				initialize_LBFGS_q();
			}

			converged = (old_valid && fabs(likelihood - old_likelihood) <= prism_epsilon);

			if (converged || REACHED_MAX_ITERATE(iterate)) {
				break;
			}

			old_likelihood = likelihood;
			old_valid = 1;

			if (debug_level) {
				prism_printf("After O-step[%d]:\n", iterate);
				print_egraph(debug_level, PRINT_EM);
			}

			SHOW_PROGRESS(iterate);

			if (crf_learning_rate == 1) { // annealing
				tmp_epsilon = (annealing_weight / (annealing_weight + iterate)) * crf_epsilon;
			} else if (crf_learning_rate == 2) { // line-search(backtrack)
				if (crf_learn_mode == 1) {
					gf_sd = compute_gf_sd_LBFGS();
				} else {
					gf_sd = compute_gf_sd();
				}
				if (iterate==0) {
					alpha0 = 1;
				} else {
					alpha0 = tmp_epsilon * old_gf_sd / gf_sd;
				}
				if (crf_learn_mode == 1) {
					tmp_epsilon = line_search_LBFGS(crf_ptr,alpha0,crf_ls_rho,crf_ls_c1,likelihood,gf_sd);
				} else {
					tmp_epsilon = line_search(crf_ptr,alpha0,crf_ls_rho,crf_ls_c1,likelihood,gf_sd);
				}

				if (tmp_epsilon < EPS) {
					emit_error("invalid alpha in line search(=0.0) (at iteration #%d)",iterate);
					RET_ERR(err_line_search);
				}
				old_gf_sd = gf_sd;
			} else if (crf_learning_rate == 3) { // line-search(golden section)
				if (crf_learn_mode == 1) {
					tmp_epsilon = golden_section_LBFGS(crf_ptr,0,crf_golden_b);
				} else {
					tmp_epsilon = golden_section(crf_ptr,0,crf_golden_b);
				}
			}
			crf_ptr->update_lambdas(tmp_epsilon);

			iterate++;
		}

		SHOW_PROGRESS_TAIL(converged, iterate, likelihood);

		if (r == 0 || likelihood > crf_ptr->likelihood) {
			crf_ptr->likelihood = likelihood;
			crf_ptr->iterate    = iterate;

			saved = (r < num_restart - 1);
			if (saved) {
				save_params();
			}
		}
	}

	if (crf_learn_mode == 1) clean_LBFGS();
	INIT_VISITED_FLAGS;
	return BP_TRUE;
}
Exemplo n.º 15
0
void fwi(sf_file Fdat, sf_file Finv, sf_file Ferr, sf_file Fgrad, sf_mpi *mpipar, sf_sou soupar, sf_acqui acpar, sf_vec_s array, sf_fwi_s fwipar, sf_optim optpar, bool verb1, int seislet)
/*< fwi >*/
{
	int iter=0, flag;
	float fcost;
	float *x, *direction, *grad;
	sf_gradient gradient;
	FILE *fp;

	/* initialize */
	gradient_init(Fdat, mpipar, soupar, acpar, array, fwipar, verb1);

	/* gradient type */
	gradient=gradient_standard;
	x=array->vv;

	/* calculate first gradient */
	grad=sf_floatalloc(nzx);
	gradient(x, &fcost, grad);

	/* output first gradient */
	if(mpipar->cpuid==0) sf_floatwrite(grad, nzx, Fgrad);

	/* if onlygrad=y, program terminates */
	if(fwipar->onlygrad) return; 

	if(mpipar->cpuid==0) fp=fopen("iterate.txt","a");

	direction=sf_floatalloc(nzx);
	optpar->sk=sf_floatalloc2(nzx, optpar->npair);
	optpar->yk=sf_floatalloc2(nzx, optpar->npair);

	optpar->igrad=1;
	optpar->ipair=0;
	optpar->ils=0;
	optpar->fk=fcost;
	optpar->f0=fcost;
	optpar->alpha=1.;
	/* initialize data error vector */
	for(iter=0; iter<optpar->nerr; iter++){
		optpar->err[iter]=0.;
	}
	optpar->err[0]=optpar->fk;
	if (optpar->err_type==1) optpar->err[optpar->nerr/2]=swap;

	iter=0;
	if(mpipar->cpuid==0){
		l2norm(nzx, grad, &optpar->gk_norm);
		print_iteration(fp, iter, optpar);
	}

	/* optimization loop */
	for(iter=0; iter<optpar->niter; iter++){
		if(mpipar->cpuid==0) sf_warning("-------------------iter=%d----------------------", iter+1);
		
		optpar->ils=0;
		if(iter%optpar->repeat==0) optpar->alpha=1.;

		/* search direction */
		if(iter==0){
			reverse(nzx, grad, direction);
		}else{
			lbfgs_update(nzx, x, grad, optpar->sk, optpar->yk, optpar);
			lbfgs_direction(nzx, grad, direction, optpar->sk, optpar->yk, optpar);
		}

		/* line search */
		lbfgs_save(nzx, x, grad, optpar->sk, optpar->yk, optpar);
		line_search(nzx, x, grad, direction, gradient, optpar, threshold, &flag, mpipar->cpuid, 1);
		optpar->err[iter+1]=optpar->fk;
		if (optpar->err_type==1) optpar->err[optpar->nerr/2+iter+1]=swap;
		
		if(mpipar->cpuid==0){
			l2norm(nzx, grad, &optpar->gk_norm);
			print_iteration(fp, iter+1, optpar);
			fclose(fp); /* get written to disk right away */
			fp=fopen("iterate.txt","a");
		}

		if(mpipar->cpuid==0 && flag==2){
			fprintf(fp, "Line Search Failed\n");
			break;
		}

		if(mpipar->cpuid==0 && optpar->fk/optpar->f0 < optpar->conv_error){
			fprintf(fp, "Convergence Criterion Reached\n");
			break;
		}
	} // end of iter

	if(mpipar->cpuid==0 && iter==optpar->niter){
		fprintf(fp, "Maximum Iteration Number Reached\n");
	}

	/* output vel & misfit */
	if(mpipar->cpuid==0) sf_floatwrite(x, nzx, Finv);
	if(mpipar->cpuid==0) sf_floatwrite(optpar->err, optpar->nerr, Ferr);
	if(mpipar->cpuid==0) fclose(fp);

	return;
}
Exemplo n.º 16
0
/**
 * @brief Low level fitting routine for non-Gaussian trend filtering problems.
 * Can be configured to handle arbirary losses, as it takes the link function
 * and it first two derivaties as inputs. Fits the solution for a single value
 * of lambda. Most users will want to call tf_admm, rather than tf_admm_glm directly.
 *
 * @param x                    a vector of data locations; must be in increasing order
 * @param y                    a vector of responses
 * @param w                    a vector of sample weights
 * @param n                    the length of x, y, and w
 * @param k                    polynomial degree of the fitted trend; i.e., k=1 for linear
 * @param max_iter             maximum number of ADMM interations; ignored for k=0
 * @param lam                  the value of lambda
 * @param df                   allocated space for df value at the solution
 * @param beta                 allocated space for output coefficents; must pre-fill as it is used in warm start
 * @param alpha                allocated space for ADMM alpha variable; must pre-fill as it is used in warm start
 * @param u                    allocated space for ADMM u variable; must pre-fill as it is used in warm start
 * @param obj                  allocated space to store the objective; will fill at most max_iter elements
 * @param iter                 allocated space to store the number of iterations; will fill just one element
 * @param status               allocated space of size nlambda to store the status of each run
 * @param rho                  tuning parameter for the ADMM algorithm; set to 1 for default
 * @param obj_tol              stopping criteria tolerance; set to 1e-6 for default
 * @param obj_tol_newton       for family != 0, stopping criteria tolerance for prox Newton
 * @param alpha_ls             for family != 0, line search tuning parameter
 * @param gamma_ls             for family != 0, line search tuning parameter
 * @param max_iter_ls          for family != 0, max number of iterations in line search
 * @param max_iter_newton      for family != 0, max number of iterations in inner ADMM
 * @param DktDk                pointer to the inner product of DktDk
 * @param b                    the link function for a given loss
 * @param b1                   first derivative of the link function for a given loss
 * @param b2                   second derivative of the link function for a given loss
 * @param verbose              0/1 flag for printing progress
 * @return void
 * @see tf_admm
 */
void tf_admm_glm (double * x, double * y, double * w, int n, int k,
    int max_iter, double lam, int tridiag, int * df,
    double * beta, double * alpha, double * u,
    double * obj, int * iter,
    double rho, double obj_tol, double obj_tol_newton, 
    double alpha_ls, double gamma_ls, int max_iter_ls, int max_iter_newton,
    cs * DktDk, double * A0, double * A1, 
    func_RtoR b, func_RtoR b1, func_RtoR b2, int verbose)
{
  double * dir; /* line search direction */
  double * yt;  /* working response: ytilde */
  double * H;   /* weighted Hessian */
  double * obj_admm;
  double * betabest;
  double * alphabest;  

  int i;
  int d;
  int it, itbest;
  int iter_admm;
  int * iter_ls;
  double * Db;
  double * Dd;
  double t; /* stepsize */  

  dir = (double*) malloc(n*sizeof(double));
  yt  = (double*) malloc(n*sizeof(double));
  H   = (double*) malloc(n*sizeof(double));

  /* Buffers for line search */
  Db      = (double *) malloc(n*sizeof(double));
  Dd      = (double *) malloc(n*sizeof(double));
  iter_ls = (int *)    malloc(sizeof(int));

  obj_admm = (double*) malloc(max_iter*sizeof(double));

  betabest = (double*) malloc(n*sizeof(double));
  alphabest = (double*) malloc(n*sizeof(double));

  if (verbose) printf("\nlambda=%0.3f\n",lam);
  if (verbose) printf("Iteration\tObjective\tADMM iters\n");

  itbest = 0;
  obj[0] = tf_obj_glm(x, y, w, n, k, lam, b, beta, yt);
  
  /* One prox Newton step per iteration */
  for (it=0; it < max_iter_newton; it++)
  {
    /* Define weighted Hessian, and working response */
    for (i=0; i<n; i++)
    {
      H[i] = w[i] * b2(beta[i]);
      if (fabs(H[i])>WEIGHT_SMALL) yt[i] = beta[i] + (y[i]-b1(beta[i]))/H[i];
      else yt[i] = beta[i] + (y[i]-b1(beta[i]));
    }

    /* Prox Newton step */
    iter_admm = 0;
    // rho = rho/(double) (it+1);
    if (tridiag)
      tf_admm_gauss_tri(x, yt, H, n, k, max_iter, lam, df, dir, alpha, u,
          obj_admm, &iter_admm, rho, obj_tol, A0, A1, 0);
    else
      tf_admm_gauss(x, yt, H, n, k, max_iter, lam, df, dir, alpha, u,
          obj_admm, &iter_admm, rho, obj_tol, DktDk, 0);

    /* Line search */
    for (i=0; i<n; i++) dir[i] = dir[i] - beta[i];
    t = line_search(y, x, w, n, k, lam, b, b1, beta, dir, alpha_ls, gamma_ls,
        max_iter_ls, iter_ls, Db, Dd);

    if (t < 0) { // line search failed
      break;
    }
    for (i=0; i<n; i++) beta[i] = beta[i] + t * dir[i];

    /* Compute objective */
    obj[it+1] = tf_obj_glm(x, y, w, n, k, lam, b, beta, yt);
    if (verbose) printf("\t%i\t%0.3e\t%i\t%i\n",it+1,obj[it],iter_admm,*iter_ls);

    if (obj[it+1] - obj[itbest] <= 0 )
    {
      memcpy(betabest, beta, n * sizeof(double));
      if (k>0) memcpy(alphabest, alpha, n * sizeof(double));
      if (obj[itbest] - obj[it+1] <= fabs(obj[itbest]) * obj_tol_newton) {
        itbest = it+1; break;
      }
      itbest = it+1;
    }
    if (it >= itbest + 4) break;

  }

  memcpy(beta, betabest, n * sizeof(double));
  if (k>0) memcpy(alpha, alphabest, n * sizeof(double));

  *iter = it;

  /* Compute final df value, based on alpha */
  d = k+1;
  if (k>0) for (i=0; i<n-k-1; i++) if (alpha[i] != alpha[i+1]) d += 1;
  else for (i=0; i<n-k-1; i++) if (beta[i] != beta[i+1]) d += 1;
  *df = d;

  /* Free everything */
  free(dir);
  free(yt);
  free(H);
  free(Db);
  free(Dd);
  free(iter_ls);
  free(obj_admm);
  free(betabest);
  free(alphabest);
}
Exemplo n.º 17
0
Float ConjugateGradients::do_optimize(unsigned int max_steps) {
  IMP_OBJECT_LOG;
  IMP_USAGE_CHECK(get_model(),
                  "Must set the model on the optimizer before optimizing");
  clear_range_cache();
  Vector<NT> x, dx;
  int i;
  // ModelData* model_data = get_model()->get_model_data();

  FloatIndexes float_indices = get_optimized_attributes();

  int n = float_indices.size();
  if (n == 0) {
    IMP_THROW("There are no optimizable degrees of freedom.", ModelException);
  }

  x.resize(n);
  dx.resize(n);
  // get initial state in x(n):
  for (i = 0; i < n; i++) {
#ifdef IMP_CG_SCALE
    x[i] = get_scaled_value(float_indices[i]);  // scaled
#else
    x[i] = get_value(float_indices[i]);            // scaled
#endif
    IMP_USAGE_CHECK(
        !IMP::isnan(x[i]) && std::abs(x[i]) < std::numeric_limits<NT>::max(),
        "Bad input to CG");
  }

  // Initialize optimization variables
  int ifun = 0;
  int nrst;
  NT dg1, xsq, dxsq, alpha, step, u1, u2, u3, u4;
  NT f = 0., dg = 1., w1 = 0., w2 = 0., rtst, bestf;
  bool gradient_direction;

  // dx holds the gradient at x
  // search holds the search vector
  // estimate holds the best current estimate to the minimizer
  // destimate holds the gradient at the best current estimate
  // resy holds the restart Y vector
  // ressearch holds the restart search vector
  Vector<NT> search, estimate, destimate, resy, ressearch;
  search.resize(n);
  estimate.resize(n);
  destimate.resize(n);
  resy.resize(n);
  ressearch.resize(n);

/* Calculate the function and gradient at the initial
   point and initialize nrst,which is used to determine
   whether a Beale restart is being done. nrst=n means that this
   iteration is a restart iteration. */
g20:
  f = get_score(float_indices, x, dx);
  if (get_stop_on_good_score() &&
      get_scoring_function()->get_had_good_score()) {
    estimate = x;
    goto end;
  }
  ifun++;
  nrst = n;
  // this is a gradient, not restart, direction:
  gradient_direction = true;

  /* Calculate the initial search direction, the norm of x squared,
     and the norm of dx squared. dg1 is the current directional
     derivative, while xsq and dxsq are the squared norms. */
  dg1 = xsq = 0.;

  for (i = 0; i < n; i++) {
    search[i] = -dx[i];
    xsq += x[i] * x[i];
    dg1 -= dx[i] * dx[i];
  }
  dxsq = -dg1;

  /* Test if the initial point is the minimizer. */
  if (dxsq <= cg_eps * cg_eps * std::max(NT(1.0), xsq)) {
    goto end;
  }

/* Begin the major iteration loop. */
g40:
  update_states();
  /* Begin linear search. alpha is the steplength. */

  if (gradient_direction) {
    /* This results in scaling the initial search vector to unity. */
    alpha = 1.0 / sqrt(dxsq);
  } else if (nrst == 1) {
    /* Set alpha to 1.0 after a restart. */
    alpha = 1.0;
  } else {
    /* Set alpha to the nonrestart conjugate gradient alpha. */
    alpha = alpha * dg / dg1;
  }

  /* Store current best estimate for the score */
  estimate = x;
  destimate = dx;

  /* Try to find a better score by linear search */
  if (!line_search(x, dx, alpha, float_indices, ifun, f, dg, dg1, max_steps,
                   search, estimate)) {
    /* If the line search failed, it was either because the maximum number
       of iterations was exceeded, or the minimum could not be found */
    if (static_cast<unsigned int>(ifun) > max_steps) {
      goto end;
    } else if (gradient_direction) {
      goto end;
    } else {
      goto g20;
    }
  }

  /* THE LINE SEARCH HAS CONVERGED. TEST FOR CONVERGENCE OF THE ALGORITHM. */
  dxsq = xsq = 0.0;
  for (i = 0; i < n; i++) {
    dxsq += dx[i] * dx[i];
    xsq += x[i] * x[i];
  }
  if (dxsq < threshold_) {
    goto end;
  }

  /* Search continues. Set search(i)=alpha*search(i),the full step vector. */
  for (i = 0; i < n; i++) {
    search[i] *= alpha;
  }

  /* COMPUTE THE NEW SEARCH VECTOR;
     TEST IF A POWELL RESTART IS INDICATED. */
  rtst = 0.;
  for (i = 0; i < n; ++i) {
    rtst += dx[i] * destimate[i];
  }

  if (std::abs(rtst / dxsq) > .2) {
    nrst = n;
  }

  /* If a restart is indicated, save the current d and y
     as the Beale restart vectors and save d'y and y'y
     in w1 and w2. */
  if (nrst == n) {
    ressearch = search;
    w1 = w2 = 0.;
    for (i = 0; i < n; i++) {
      resy[i] = dx[i] - destimate[i];
      w1 += resy[i] * resy[i];
      w2 += search[i] * resy[i];
    }
  }

  /* CALCULATE THE RESTART HESSIAN TIMES THE CURRENT GRADIENT. */
  u1 = u2 = 0.0;
  for (i = 0; i < n; i++) {
    u1 -= ressearch[i] * dx[i] / w1;
    u2 += ressearch[i] * dx[i] * 2.0 / w2 - resy[i] * dx[i] / w1;
  }
  u3 = w2 / w1;
  for (i = 0; i < n; i++) {
    estimate[i] = -u3 * dx[i] - u1 * resy[i] - u2 * ressearch[i];
  }

  /* If this is a restart iteration, estimate contains the new search vector. */
  if (nrst != n) {

    /* NOT A RESTART ITERATION. CALCULATE THE RESTART HESSIAN
       TIMES THE CURRENT Y. */
    u1 = u2 = u3 = 0.0;
    for (i = 0; i < n; i++) {
      u1 -= (dx[i] - destimate[i]) * ressearch[i] / w1;
      u2 = u2 - (dx[i] - destimate[i]) * resy[i] / w1 +
           2.0 * ressearch[i] * (dx[i] - destimate[i]) / w2;
      u3 += search[i] * (dx[i] - destimate[i]);
    }
    step = u4 = 0.;
    for (i = 0; i < n; i++) {
      step =
          (w2 / w1) * (dx[i] - destimate[i]) + u1 * resy[i] + u2 * ressearch[i];
      u4 += step * (dx[i] - destimate[i]);
      destimate[i] = step;
    }

    /* CALCULATE THE DOUBLY UPDATED HESSIAN TIMES THE CURRENT
       GRADIENT TO OBTAIN THE SEARCH VECTOR. */
    u1 = u2 = 0.0;
    for (i = 0; i < n; i++) {
      u1 -= search[i] * dx[i] / u3;
      u2 +=
          (1.0 + u4 / u3) * search[i] * dx[i] / u3 - destimate[i] * dx[i] / u3;
    }
    for (i = 0; i < n; i++) {
      estimate[i] = estimate[i] - u1 * destimate[i] - u2 * search[i];
    }
  }

  /* CALCULATE THE DERIVATIVE ALONG THE NEW SEARCH VECTOR. */
  search = estimate;
  dg1 = 0.0;
  for (i = 0; i < n; i++) {
    dg1 += search[i] * dx[i];
  }

  /* IF THE NEW DIRECTION IS NOT A DESCENT DIRECTION,STOP. */
  if (dg1 <= 0.0) {

    /* UPDATE NRST TO ASSURE AT LEAST ONE RESTART EVERY N ITERATIONS. */
    if (nrst == n) {
      nrst = 0;
    }
    nrst++;
    gradient_direction = false;
    goto g40;
  }

/* ROUNDOFF HAS PRODUCED A BAD DIRECTION. */

end:
  // If the 'best current estimate' is better than the current state, return
  // that:
  bestf = get_score(float_indices, estimate, destimate);
  if (bestf < f) {
    f = bestf;
  } else {
    // Otherwise, restore the current state x (note that we already have the
    // state x and its derivatives dx, so it's rather inefficient to
    // recalculate the score here, but it's cleaner)
    f = get_score(float_indices, x, dx);
  }
  update_states();
  return f;
}
Exemplo n.º 18
0
int LatentRelevance::run_gd()
{
	int iter_num = 1;
	float loss = 0.0f;
	loss = calculate_loss();

	// Save the gradients of weights for line search
	float* gradient_weights = NULL;
	if (factorize_mode == 0) {
		gradient_weights = new float[vector_size*vector_size];
	}
	else {
		gradient_weights = new float[2*vector_size*k];
	}

	printf("------------------------------------------------------------------------\n");
	printf("Iteration Process... [%d iterations in total]\n", MAX_STOP_ITER_NUM);
	printf("------------------------------------------------------------------------\n");
	
	// Iteration
	while (loss > MIN_STOP_LOSS * data_num && iter_num <= MAX_STOP_ITER_NUM) {
		// Calculate gradients of w0 and w_cos
		float gradient_w0 = calculate_gradient_w0();
		float gradient_wcos = calculate_gradient_wcos();

		// calculate gradients w or v
		if (factorize_mode == 0) {
			for (int i = 0; i < vector_size; ++i) {
				for (int j = 0; j < vector_size; ++j) {
					int index = i * vector_size + j;
					gradient_weights[index] = calculate_gradient_w(i, j);
				}
			}
		}
		else if (factorize_mode == 1) {
            // Store intermediate gradient variables
            float* temp_gd1 = new float[data_num*k];
            float* temp_gd2 = new float[data_num*k];
            
			for (int j = 0; j < k; ++j) {
                // Pre-calculate temp_gd
                for (int m = 0; m < data_num; ++m) {
                    int index_temp_gd = j * data_num + m;
                    temp_gd1[index_temp_gd] = 0;
                    temp_gd2[index_temp_gd] = 0;
					
                    for (int i = 0; i < vector_size; ++i) {
						temp_gd1[index_temp_gd] += v[i*k+j] * m_data[m].x[i];
					}

					for (int i = vector_size; i < 2 * vector_size; ++i) {
						temp_gd2[index_temp_gd] += v[i*k+j] * m_data[m].x[i];
					}
				}     

                for (int i = 0; i < 2 * vector_size; ++i) {
                    int index = i * k + j;
                    if (i < vector_size) {
                        gradient_weights[index] = calculate_gradient_v(i, j, temp_gd2);
                    }
                    else {
                        gradient_weights[index] = calculate_gradient_v(i, j, temp_gd1);
                    }
                }
			}

			delete temp_gd1;
			temp_gd1 = NULL;
			delete temp_gd2;
			temp_gd2 = NULL;
		}
		
		printf("Iter[%d]\tLoss[%f]\tW0[%f]\tWCos[%f]\n", iter_num, loss, w0, w_cos);

		// Find next point by line search
		line_search(gradient_w0, gradient_wcos, gradient_weights, loss);
		++iter_num;
	}

	delete gradient_weights;
	gradient_weights = NULL;

	return 0;
}
Exemplo n.º 19
0
void check_line_search() {
    CHECK(line_search(t_sevens,  0, 7),  0, "ls-7s-ok-1");
    CHECK(line_search(t_sevens,  5, 7),  5, "ls-7s-ok-2");
    CHECK(line_search(t_sevens, 31, 7), 31, "ls-7s-ok-3");
    CHECK(line_search(t_sevens,  0, 1), -1, "ls-7s-fail-1");
    CHECK(line_search(t_sevens, 31, 1), -1, "ls-7s-fail-2");

    CHECK(line_search(t_mixed, 0, 7),  0, "ls-m-ok-1");
    CHECK(line_search(t_mixed, 0, 1),  1, "ls-m-ok-2");
    CHECK(line_search(t_mixed, 1, 7),  2, "ls-m-ok-3");
    CHECK(line_search(t_mixed, 0, 9), 31, "ls-m-ok-4");
    CHECK(line_search(t_mixed, 0, 8), -1, "ls-m-fail-1");

    CHECK(line_search(t_mixed, 16, 1), 20, "ls-m-ok-5");
}