Skip to content
Snippets Groups Projects
linear.cpp 66.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	setlocale(LC_ALL, "C");
    
    	char cmd[81];
    	while(1)
    	{
    		FSCANF(fp,"%80s",cmd);
    		if(strcmp(cmd,"solver_type")==0)
    		{
    			FSCANF(fp,"%80s",cmd);
    			int i;
    			for(i=0;solver_type_table[i];i++)
    			{
    				if(strcmp(solver_type_table[i],cmd)==0)
    				{
    					param.solver_type=i;
    					break;
    				}
    			}
    			if(solver_type_table[i] == NULL)
    			{
    				fprintf(stderr,"unknown solver type.\n");
    				EXIT_LOAD_MODEL()
    			}
    		}
    		else if(strcmp(cmd,"nr_class")==0)
    		{
    			FSCANF(fp,"%d",&nr_class);
    			model_->nr_class=nr_class;
    		}
    		else if(strcmp(cmd,"nr_feature")==0)
    		{
    			FSCANF(fp,"%d",&nr_feature);
    			model_->nr_feature=nr_feature;
    		}
    		else if(strcmp(cmd,"bias")==0)
    		{
    			FSCANF(fp,"%lf",&bias);
    			model_->bias=bias;
    		}
    		else if(strcmp(cmd,"w")==0)
    		{
    			break;
    		}
    		else if(strcmp(cmd,"label")==0)
    		{
    			int nr_class = model_->nr_class;
    			model_->label = Malloc(int,nr_class);
    			for(int i=0;i<nr_class;i++)
    				FSCANF(fp,"%d",&model_->label[i]);
    		}
    		else
    		{
    			fprintf(stderr,"unknown text in model file: [%s]\n",cmd);
    			EXIT_LOAD_MODEL()
    		}
    	}
    
    	nr_feature=model_->nr_feature;
    	if(model_->bias>=0)
    		n=nr_feature+1;
    	else
    		n=nr_feature;
    	int w_size = n;
    	int nr_w;
    	if(nr_class==2 && param.solver_type != MCSVM_CS)
    		nr_w = 1;
    	else
    		nr_w = nr_class;
    
    	model_->w=Malloc(double, w_size*nr_w);
    	for(i=0; i<w_size; i++)
    	{
    		int j;
    		for(j=0; j<nr_w; j++)
    			FSCANF(fp, "%lf ", &model_->w[i*nr_w+j]);
    	}
    
    	setlocale(LC_ALL, old_locale);
    	free(old_locale);
    
    	if (ferror(fp) != 0 || fclose(fp) != 0) return NULL;
    
    	return model_;
    }
    
    int get_nr_feature(const model *model_)
    {
    	return model_->nr_feature;
    }
    
    int get_nr_class(const model *model_)
    {
    	return model_->nr_class;
    }
    
    void get_labels(const model *model_, int* label)
    {
    	if (model_->label != NULL)
    		for(int i=0;i<model_->nr_class;i++)
    			label[i] = model_->label[i];
    }
    
    // use inline here for better performance (around 20% faster than the non-inline one)
    static inline double get_w_value(const struct model *model_, int idx, int label_idx)
    {
    	int nr_class = model_->nr_class;
    	int solver_type = model_->param.solver_type;
    	const double *w = model_->w;
    
    	if(idx < 0 || idx > model_->nr_feature)
    		return 0;
    	if(check_regression_model(model_))
    		return w[idx];
    	else
    	{
    		if(label_idx < 0 || label_idx >= nr_class)
    			return 0;
    		if(nr_class == 2 && solver_type != MCSVM_CS)
    		{
    			if(label_idx == 0)
    				return w[idx];
    			else
    				return -w[idx];
    		}
    		else
    			return w[idx*nr_class+label_idx];
    	}
    }
    
    // feat_idx: starting from 1 to nr_feature
    // label_idx: starting from 0 to nr_class-1 for classification models;
    //            for regression models, label_idx is ignored.
    double get_decfun_coef(const struct model *model_, int feat_idx, int label_idx)
    {
    	if(feat_idx > model_->nr_feature)
    		return 0;
    	return get_w_value(model_, feat_idx-1, label_idx);
    }
    
    double get_decfun_bias(const struct model *model_, int label_idx)
    {
    	int bias_idx = model_->nr_feature;
    	double bias = model_->bias;
    	if(bias <= 0)
    		return 0;
    	else
    		return bias*get_w_value(model_, bias_idx, label_idx);
    }
    
    void free_model_content(struct model *model_ptr)
    {
    	if(model_ptr->w != NULL)
    		free(model_ptr->w);
    	if(model_ptr->label != NULL)
    		free(model_ptr->label);
    }
    
    void free_and_destroy_model(struct model **model_ptr_ptr)
    {
    	struct model *model_ptr = *model_ptr_ptr;
    	if(model_ptr != NULL)
    	{
    		free_model_content(model_ptr);
    		free(model_ptr);
    	}
    }
    
    void destroy_param(parameter* param)
    {
    	if(param->weight_label != NULL)
    		free(param->weight_label);
    	if(param->weight != NULL)
    		free(param->weight);
    	if(param->init_sol != NULL)
    		free(param->init_sol);
    }
    
    const char *check_parameter(const problem *prob, const parameter *param)
    {
    	if(param->eps <= 0)
    		return "eps <= 0";
    
    	if(param->C <= 0)
    		return "C <= 0";
    
    	if(param->p < 0)
    		return "p < 0";
    
    	if(param->solver_type != L2R_LR
    		&& param->solver_type != L2R_L2LOSS_SVC_DUAL
    		&& param->solver_type != L2R_L2LOSS_SVC
    		&& param->solver_type != L2R_L1LOSS_SVC_DUAL
    		&& param->solver_type != MCSVM_CS
    		&& param->solver_type != L1R_L2LOSS_SVC
    		&& param->solver_type != L1R_LR
    		&& param->solver_type != L2R_LR_DUAL
    		&& param->solver_type != L2R_L2LOSS_SVR
    		&& param->solver_type != L2R_L2LOSS_SVR_DUAL
    		&& param->solver_type != L2R_L1LOSS_SVR_DUAL)
    		return "unknown solver type";
    
    	if(param->init_sol != NULL
    		&& param->solver_type != L2R_LR && param->solver_type != L2R_L2LOSS_SVC)
    		return "Initial-solution specification supported only for solver L2R_LR and L2R_L2LOSS_SVC";
    
    	return NULL;
    }
    
    int check_probability_model(const struct model *model_)
    {
    	return (model_->param.solver_type==L2R_LR ||
    			model_->param.solver_type==L2R_LR_DUAL ||
    			model_->param.solver_type==L1R_LR);
    }
    
    int check_regression_model(const struct model *model_)
    {
    	return (model_->param.solver_type==L2R_L2LOSS_SVR ||
    			model_->param.solver_type==L2R_L1LOSS_SVR_DUAL ||
    			model_->param.solver_type==L2R_L2LOSS_SVR_DUAL);
    }
    
    void set_print_string_function(void (*print_func)(const char*))
    {
    	if (print_func == NULL)
    		liblinear_print_string = &print_string_stdout;
    	else
    		liblinear_print_string = print_func;
    }