示例#1
0
//---------- Begin of function PieChart::draw_scale -------------//
//!
void PieChart::draw_scale() {
    find_scale();

    short xAxisPos;

    //------ Draw y-axis -------//

    if (x_axis_pos)
	vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2+COMMON_OFFSET*2, axis_color);
    else
	vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2, axis_color);

    short scaleNum = (series_y2-series_y1-font_ptr->max_font_height) / (font_ptr->max_font_height*3/2);
    if ( scaleNum > 0 )
	scaleNum = short(pow(2,floor(log10(double(scaleNum))/log10(2.0))));
    else
	scaleNum = 0;
    short scaleStep = (series_y2-series_y1) / scaleNum;
    double scaleValue;
    for (int i = 0; i <= scaleNum; i++) {
	if ( (x_axis_pos && i == scaleNum / 2) || !(x_axis_pos || i) )
	    vga_back.bar(series_x1, xAxisPos=series_y2-i*scaleStep-1, series_x2+COMMON_OFFSET*8, series_y2-i*scaleStep, axis_color);
	else
	    vga_back.bar(series_x1, series_y2-i*scaleStep, series_x1+COMMON_OFFSET*2, series_y2-i*scaleStep, axis_color);

	if (x_axis_pos)
	    scaleValue = max_scale*2/scaleNum*i - max_scale;
	else
	    scaleValue = max_scale/scaleNum*i;

	switch (data_type_flag) {
	case DATA_FLOAT:
	case DATA_DOUBLE:
	    font_ptr->right_put(series_x1-COMMON_OFFSET, series_y2-i*scaleStep-font_ptr->max_font_height/2, m.format(scaleValue,num_format));
	    break;
	case DATA_INT:
	case DATA_LONG:
	    font_ptr->right_put(series_x1-COMMON_OFFSET, series_y2-i*scaleStep-font_ptr->max_font_height/2, m.format(long(scaleValue),num_format));
	}
    }

    //------ Draw x-axis -------//

    short maxLabelWidth = font_ptr->text_width(m.format(*x_end, 4))+COMMON_OFFSET*2;
    x_axis_step = (series_x2-series_x1) / (data_num-1);
    short displayInc = 1;
    while (displayInc * x_axis_step / maxLabelWidth < 1) displayInc++;
    int xAxisStep = (*x_end - *x_start) / (data_num - 1);
    for (int i = 0; i < data_num-1; i += displayInc) {
	vga_back.bar(series_x2-i*x_axis_step, xAxisPos-COMMON_OFFSET*2, series_x2-i*x_axis_step, xAxisPos, axis_color);
	font_ptr->center_put((series_x2-i*x_axis_step)-maxLabelWidth/2-COMMON_OFFSET, xAxisPos+COMMON_OFFSET,
			     (series_x2-i*x_axis_step)+maxLabelWidth/2+COMMON_OFFSET, xAxisPos+COMMON_OFFSET+font_ptr->max_font_height, m.format(*x_end-xAxisStep*i, 4));
    }
}
void fast_s_large_n(double *X, double *y,
		int *nn, int *pp, int *NN, int *K,
		int *ggroups, int *nn_group,
		int *bbest_r, double *bb, double *rrhoc,
		double *bbeta, double *sscale)
{
/* *X = the design matrix as a vector (as sent by R)
// *y = the response vector
// *nn = the length of y
// *pp = the number of columns in X
// *NN = number of re-sampling candidates to be
//       used in each partition
// *bbest_r = no. of best candidates to be iterated
//            further
// *bb = right-hand side of S-equation (typically 1/2)
// *rrhoc = tuning constant for Tukey's bi-square loss
//          (this should be associated with *bb)
// *bbeta = final estimator
// *sscale = associated scale estimator
// *ggroups = number of groups in which to split the
//            random subsample
// *nn_group = size of each of the (*ggroups) groups
//             to use in the random subsample
*/
void reset_mat(double **a, int n, int m);
double loss_rho(double *r, double scale, int n, int p, double rhoc);
double find_scale(double *r, double b, double rhoc,
			double initial_scale, int n, int p);
// void disp_mat(double **a, int n, int m);
// void disp_vec(double *a, int n);
void fast_s_with_memory(double **x, double *y,
		int *nn, int *pp, int *NN, int *K,
		int *bbest_r, double *bb,
		double *rrhoc,
		double **best_betas, double *best_scales);
void sample_n_outof_N(int n, int N, int *x);
void refine_fast_s(double **x, double *y, double *weights,
			int n, int p, double *res,
			double *tmp, double *tmp2,
			double **tmp_mat, double **tmp_mat2,
			double *beta_cand, int kk,
			int conv, double b, double rhoc, double *is, double *beta_ref,
			double *scale);
int find_max(double *a, int n);
register int i,j,k,k2;
int n = *nn, p = *pp, kk = *K, *indices;
int groups = *ggroups, n_group = *nn_group, best_r = *bbest_r;
double **best_betas, *best_scales;
double **final_best_betas, *final_best_scales;
double **x, **xsamp, *ysamp, *res, sc, *beta_ref;
double *tmp, *tmp2, **tmp_mat, **tmp_mat2, *weights;
double best_sc, worst_sc, b = *bb, rhoc = *rrhoc, aux;
int pos_worst_scale, conv;
res = (double *) malloc( n * sizeof(double) );
weights = (double *) malloc( n * sizeof(double) );
tmp  = (double *) malloc( n * sizeof(double) );
tmp2 = (double *) malloc( n * sizeof(double) );
tmp_mat  = (double **) malloc( p * sizeof(double *) );
tmp_mat2 = (double **) malloc( p * sizeof(double *) );
for(i=0;i<p;i++) {
	tmp_mat[i] = (double *) malloc( p * sizeof(double) );
	tmp_mat2[i] = (double *) malloc( (p+1) * sizeof(double) );
};
beta_ref = (double *) malloc( p * sizeof(double) );
final_best_betas = (double **) malloc( best_r * sizeof( double * ) );
for(i=0; i < best_r; i++)
	final_best_betas[i] = (double *) malloc(
				p * sizeof(double) );
final_best_scales = (double *) malloc( best_r * sizeof(double) );
k = best_r * groups;
best_betas = (double **) malloc( k * sizeof( double * ) );
best_scales = (double *) malloc( k * sizeof( double ) );
for(i=0; i < k; i++)
		best_betas[i] = (double*) malloc( p * sizeof(double) );
x = (double**) malloc( n * sizeof(double *) );
for(i=0; i<n; i++)
	x[i] = (double*) malloc( p * sizeof(double) );
k = n_group * groups;
indices = (int *) malloc( k * sizeof(int) );
xsamp = (double**) malloc( k * sizeof(double *) );
ysamp = (double*) malloc( k * sizeof(double) );
for(i=0;i<k;i++)
	xsamp[i] = (double*) malloc( p * sizeof(double) );
for(i=0;i<n;i++)
	for(j=0;j<p;j++)
		x[i][j]=X[j*n+i];
/* assume that n > 2000
// k = n_group * groups
// set the seed
*/
srand((long)37);
/* get a sample of k indices */
sample_n_outof_N(k, n-1, indices);
/* get the sampled design matrix and response */
for(i=0;i<k;i++) {
	for(j=0;j<p;j++)
		xsamp[i][j] = x[indices[i]][j];
		ysamp[i] = y[indices[i]];
};
/* now we go through the groups and get the
// *bbest_r best betas for each group
*/
for(i=0; i<groups; i++) {
	fast_s_with_memory(xsamp+i*n_group, ysamp+i*n_group,
				&n_group, pp, NN, K,
				bbest_r, bb, rrhoc,
				best_betas+i*best_r,
				best_scales+i*best_r);
};
/* now  iterate (refine) these "best_r * groups"
// best betas in the (xsamp,ysamp) sample
// with kk C-steps
// and keep only the "best_r" best ones
*/
best_sc = INFI;
pos_worst_scale = conv = 0;
for(i=0; i < best_r; i++)
	final_best_scales[i] = INFI;
worst_sc = INFI;
/* set the matrix to zero */
reset_mat(final_best_betas, best_r, p);
k = n_group * groups;
for(i=0; i< (best_r * groups) ; i++) {
	refine_fast_s(xsamp, ysamp, weights, k, p, res,
			tmp, tmp2, tmp_mat, tmp_mat2,
			best_betas[i], kk, conv, b, rhoc,
			best_scales+i, beta_ref,
			&sc);
	if ( loss_rho(res, worst_sc, k, p, rhoc) < b )  {
		/* scale will be better */
		sc = find_scale(res, b, rhoc, sc, k, p);
		k2 = pos_worst_scale;
		final_best_scales[ k2 ] = sc;
		for(j=0;j<p;j++)
			final_best_betas[k2][j] = beta_ref[j];
		pos_worst_scale = find_max(final_best_scales, best_r);
		worst_sc = final_best_scales[pos_worst_scale];
	};
};
/* now iterate the best "best_r"
// betas in the whole sample (until convergence if possible)
*/
best_sc = INFI;
conv = 1;
for(i=0; i<best_r; i++) {
	refine_fast_s(x, y, weights, n, p, res,
			tmp, tmp2, tmp_mat, tmp_mat2,
			final_best_betas[i], kk, conv, b, rhoc,
			final_best_scales+i, beta_ref,
			&aux);
	if(aux < best_sc) {
			*sscale = best_sc = aux;
			for(j=0;j<p;j++)
				bbeta[j] = beta_ref[j];
	};
};
/* Done. Now clean-up. */
for(i=0;i<n;i++) free(x[i]); free(x);
free(best_scales);
k = best_r * groups;
for(i=0;i<k;i++) free( best_betas[i] );
free(best_betas); free(indices); free(ysamp);
k = n_group * groups;
for(i=0;i<k;i++) free(xsamp[i]);
free(xsamp); free(tmp); free(tmp2);
for(i=0;i<p;i++) {
	free(tmp_mat[i]);
	free(tmp_mat2[i]);
};
free(tmp_mat); free(tmp_mat2); free(weights);
for(i=0;i<best_r;i++)
	free(final_best_betas[i]);
free(final_best_betas);
free(final_best_scales);
free(res);
free(beta_ref);

}
示例#3
0
//
// main
// ----
//
int main(void)
{
    libusb_device **devs;
    int r; // holds return codes
    ssize_t cnt;
    libusb_device* dev;
    libusb_device_handle* handle;

    int weigh_count = WEIGH_COUNT -1;

    //
    // We first try to init libusb.
    //
    r = libusb_init(NULL);
    // 
    // If `libusb_init` errored, then we quit immediately.
    //
    if (r < 0)
        return r;

#ifdef DEBUG
        libusb_set_debug(NULL, 3);
#endif

    //
    // Next, we try to get a list of USB devices on this computer.
    cnt = libusb_get_device_list(NULL, &devs);
    if (cnt < 0)
        return (int) cnt;

    //
    // Once we have the list, we use **find_scale** to loop through and match
    // every device against the scales.h list. **find_scale** will return the
    // first device that matches, or 0 if none of them matched.
    //
    dev = find_scale(devs);
    if(dev == 0) {
        fprintf(stderr, "No USB scale found on this computer.\n");
        return -1;
    }
    
    //
    // Once we have a pointer to the USB scale in question, we open it.
    //
    r = libusb_open(dev, &handle);
    //
    // Note that this requires that we have permission to access this device.
    // If you get the "permission denied" error, check your udev rules.
    //
    if(r < 0) {
        if(r == LIBUSB_ERROR_ACCESS) {
            fprintf(stderr, "Permission denied to scale.\n");
        }
        else if(r == LIBUSB_ERROR_NO_DEVICE) {
            fprintf(stderr, "Scale has been disconnected.\n");
        }
        return -1;
    }
    //
    // On Linux, we typically need to detach the kernel driver so that we can
    // handle this USB device. We are a userspace tool, after all.
    //
#ifdef __linux__
    libusb_detach_kernel_driver(handle, 0);
#endif
    //
    // Finally, we can claim the interface to this device and begin I/O.
    //
    libusb_claim_interface(handle, 0);



    /*
     * Try to transfer data about status
     *
     * http://rowsandcolumns.blogspot.com/2011/02/read-from-magtek-card-swipe-reader-in.html
     */
    unsigned char data[WEIGH_REPORT_SIZE];
    int len;
    int scale_result = -1;
    
    //
    // For some reason, we get old data the first time, so let's just get that
    // out of the way now. It can't hurt to grab another packet from the scale.
    //
    r = libusb_interrupt_transfer(
        handle,
        //bmRequestType => direction: in, type: class,
                //    recipient: interface
        LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS |
            LIBUSB_RECIPIENT_INTERFACE,
        data,
        WEIGH_REPORT_SIZE, // length of data
        &len,
        10000 //timeout => 10 sec
        );
    // 
    // We read data from the scale in an infinite loop, stopping when
    // **print_scale_data** tells us that it's successfully gotten the weight
    // from the scale, or if the scale or transmissions indicates an error.
    //
    for(;;) {
        //
        // A `libusb_interrupt_transfer` of 6 bytes from the scale is the
        // typical scale data packet, and the usage is laid out in *HID Point
        // of Sale Usage Tables*, version 1.02.
        //
        r = libusb_interrupt_transfer(
            handle,
            //bmRequestType => direction: in, type: class,
                    //    recipient: interface
            LIBUSB_ENDPOINT_IN | //LIBUSB_REQUEST_TYPE_CLASS |
                LIBUSB_RECIPIENT_INTERFACE,
            data,
            WEIGH_REPORT_SIZE, // length of data
            &len,
            10000 //timeout => 10 sec
            );
        // 
        // If the data transfer succeeded, then we pass along the data we
        // received tot **print_scale_data**.
        //
        if(r == 0) {
#ifdef DEBUG
            int i;
            for(i = 0; i < WEIGH_REPORT_SIZE; i++) {
                printf("%x\n", data[i]);
            }
#endif
            if (weigh_count < 1) {
                scale_result = print_scale_data(data);
                if(scale_result != 1)
                   break;
            }
            weigh_count--;
        }
        else {
            fprintf(stderr, "Error in USB transfer\n");
            scale_result = -1;
            break;
        }
    }
    
    // 
    // At the end, we make sure that we reattach the kernel driver that we
    // detached earlier, close the handle to the device, free the device list
    // that we retrieved, and exit libusb.
    //
#ifdef __linux__
    libusb_attach_kernel_driver(handle, 0);
#endif
    libusb_close(handle);
    libusb_free_device_list(devs, 1);
    libusb_exit(NULL);

    // 
    // The return code will be 0 for success or -1 for errors (see
    // `libusb_init` above if it's neither 0 nor -1).
    // 
    return scale_result;
}
void fast_s(double *X, double *y,
		int *nn, int *pp, int *NN, int *K,
		int *bbest_r, double *bb,
		double *rrhoc, double *bbeta, double *sscale)
{
/*
// X an n x p design matrix (including intercept if appropriate)
// y and n vector
// *nn = n, *pp = p
// *NN = number of re-sampling candidates to be taken
// *K = number of refining steps for each candidate
// *bbest_r = number of (refined) to be retained for
// 					full iteration
// 	*bb = right-hand side of the S-equation
// 	*rrhoc  = tuning constant of the \rho function
// 	*bbeta  = returning fast-S estimator
// 	*sscale = returning associated residual scale
*/
void refine_fast_s(double **x, double *y, double *weights,
			int n, int p, double *res,
			double *tmp, double *tmp2,
			double **tmp_mat, double **tmp_mat2,
			double *beta_cand, int kk,
			int conv, double b, double rhoc,
			double *is,
			double *beta_ref, double *scale);
// void disp_vec(double *a, int n);
// void disp_mat(double **a, int n, int m);
int find_max(double *a, int n);
double find_scale(double *r, double b, double rhoc,
			double initial_scale, int n, int p);
double loss_rho(double *r, double s, int n, int p, double rhoc);
double vecprime_vec(double *a, double *b, int n);
void sample_n_outof_N(int n, int N, int *x);
int lu(double **a,int *P, double *x);
register int i,j,k;
int n = *nn, p = *pp, Nres = *NN, kk = *K, no_resamples;
int *b_i, flag, conv;
double **x, **x_samp, *beta_cand, *beta_ref, *res, aux;
double b = *bb, rhoc = *rrhoc, sc, worst_sc = INFI;
double **best_betas, *best_scales, *weights;
int best_r = *bbest_r, pos_worst_scale;
double *tmp, *tmp2, **tmp_mat2, **tmp_mat, best_sc;
best_betas = (double **) malloc( best_r * sizeof(double*) );
best_scales = (double *) malloc( best_r * sizeof(double) );
for(i=0;i<best_r;i++) {
		best_betas[i] = (double*) malloc( p * sizeof(double) );
		best_scales[i] = INFI; };
pos_worst_scale = 0;
res       = (double *) malloc( n * sizeof(double) );
tmp       = (double *) malloc( n * sizeof(double) );
tmp2      = (double *) malloc( n * sizeof(double) );
weights   = (double *) malloc( n * sizeof(double) );
beta_cand = (double *) malloc( p * sizeof(double) );
beta_ref  = (double *) malloc( p * sizeof(double) );
b_i       = (int *) malloc( n * sizeof(int) );
x         = (double **) malloc( n * sizeof(double*) );
x_samp    = (double **) malloc( n * sizeof(double*) );
tmp_mat   = (double **) malloc( p * sizeof(double*) );
tmp_mat2  = (double **) malloc( p * sizeof(double*) );
for(i=0;i<n;i++) {
	x[i]       = (double *) malloc( p * sizeof(double) );
	x_samp[i]  = (double *) malloc( (p+1) * sizeof(double) );
};
for(i=0;i<p;i++) {
	tmp_mat[i] = (double *) malloc( p * sizeof(double) );
	tmp_mat2[i] = (double *) malloc( (p+1) * sizeof(double) );
};
for(i=0;i<n;i++)
        for(j=0;j<p;j++)
                x[i][j]=X[j*n+i];
/* set the seed  */
srand((long)37);
/* flag for refine(), conv == 0 means do k refining steps
// conv == 1 means refine until convergence
*/
conv = 0;
aux = -1.0;
/* resampling approximation  */

for(i=0;i<Nres;i++) {
	flag = 1;
	/* find a candidate */
	no_resamples=0;
	while( flag == 1) {
		if( (++no_resamples) > MAX_NO_RESAMPLES ) {
			// Rprintf("\nToo many singular resamples\nAborting\n\n");
			return;
		};
		/* take a sample of the indices  */
		sample_n_outof_N(p,n-1,b_i);
		/* build the submatrix */
		for(j=0;j<p;j++) {
			for(k=0;k<p;k++)
				x_samp[j][k]=x[b_i[j]][k];
			x_samp[j][p]=y[b_i[j]];
			};
		/* solve the system, lu = 1 means
		// matrix is singular
		*/
		flag = lu(x_samp,pp,beta_cand);
	};
	// Rprintf("\n");
	// for(j=0;j<p;j++) Rprintf("%d ", b_i[j]);
	// Rprintf("\n");
	/* improve the re-sampling candidate */
	refine_fast_s(x, y, weights, n, p, res,
			tmp, tmp2, tmp_mat, tmp_mat2,
			beta_cand, kk, conv, b, rhoc,
			&aux, beta_ref, &sc);
	if( fabs(sc) < ZERO) {
		*sscale = sc;
		for(j=0;j<p;j++) bbeta[j] = beta_cand[j];
		free(best_scales); free(tmp); free(tmp2);
		free(res); free(weights); free(beta_cand);
		free(beta_ref); free(b_i);
		for(i=0;i<best_r;i++)
			free(best_betas[i]);
		free(best_betas);
		for(i=0; i<n; i++) {
			free(x[i]);
			free(x_samp[i]);
		};
		for(i=0; i<p; i++) {
			free(tmp_mat[i]);
			free(tmp_mat2[i]);
		};
		free(x); free(x_samp); free(tmp_mat); free(tmp_mat2);
		return;
	};
	if ( loss_rho(res, worst_sc, n, p, rhoc) < b )  {
		/* scale will be better */
		sc = find_scale(res, b, rhoc, sc, n, p);
		k = pos_worst_scale;
		best_scales[ k ] = sc;
		for(j=0;j<p;j++)
			best_betas[k][j] = beta_ref[j];
		pos_worst_scale = find_max(best_scales, best_r);
		worst_sc = best_scales[pos_worst_scale];
	};
};
/* now look for the very best */
best_sc = INFI;
conv = 1;
for(i=0; i<best_r; i++) {
	refine_fast_s(x, y, weights, n, p, res,
			tmp, tmp2, tmp_mat, tmp_mat2,
			best_betas[i], kk, conv, b, rhoc,
			best_scales+i, beta_ref,
			&aux);
	if(aux < best_sc) {
			*sscale = best_sc = aux;
			for(j=0;j<p;j++)
				bbeta[j] = beta_ref[j];
	};
};
free(best_scales); free(tmp); free(tmp2);
free(res); free(weights); free(beta_cand);
free(beta_ref); free(b_i);
for(i=0;i<best_r;i++)
	free(best_betas[i]);
free(best_betas);
for(i=0; i<n; i++) {
	free(x[i]);
	free(x_samp[i]);
};
for(i=0; i<p; i++) {
	free(tmp_mat[i]);
	free(tmp_mat2[i]);
};
free(x); free(x_samp); free(tmp_mat); free(tmp_mat2);
}