Esempio n. 1
0
//matrix determinent
//the original matrix is saved in stead of destoryed, so the copy of 
//matrix is used	
double Matrix::det(void)
{
	McoStatus status;
	int32	i, j, k;
	double	**max, **temp;
	double 	returnval;

	//if not a square matrix, return singular error
	if( _row != _col){
		_set_status(MCO_SINGULAR);
		return 0;
	}
	
	max = (double**)McoMalloc(sizeof( double*)*_row);
	if(!max){
		_set_status(MCO_MEM_ALLOC_ERROR);
		return 0;
	}
	for( j = 0; j < _row; j++){
		max[j] = (double*)McoMalloc(sizeof(double)*_col);
		if(!max[j]){
			_set_status(MCO_MEM_ALLOC_ERROR);
			for(k = j-1; k >= 0; k--)
				McoFree((void *) max[k]);	
			McoFree((void *) max);
			return 0.0;
		}
	}
		
	//copy the original matrix
	for( i = 0; i < _row; i++)
		for( j = 0; j < _col; j++)
			max[i][j] = _m[i][j];

	temp = _m;
	_m = max;
	status = _ludcmp();
	if(status != MCO_SUCCESS){ //singular matrix, everything assigned to 0
		returnval = 0.0;
	}	
	else {
		returnval = _m[0][0];
		for( i = 1; i < _row; i++)
			returnval *= _m[i][i];
	}				
	
	for( i = 0; i < _row; i++)				
		McoFree((void *) _m[i]);
	McoFree((void *) _m);	
		
	_m = temp;

	return returnval;
}	
Esempio n. 2
0
//transverse of matrix
Matrix& Matrix::T(void)
{
	int32	i,j;
	double ** newm;
	double tempval;

//added on 8/12 to take out smatrix class	
	if( _row == _col){
		for(i = 0; i < _row; i++){
			for(j = i; j < _col; j++){
				tempval = _m[i][j];
				_m[i][j] = _m[j][i];
				_m[j][i] = tempval;
			}
		}
	
		return *this;
	}
//end of modification

	
	newm = (double**)McoMalloc(sizeof(double*)*_col);
	if(!newm){
		_set_status(MCO_MEM_ALLOC_ERROR);
		return *this;
	}
		
	for(i = 0; i < _col; i++){
		newm[i] = (double*)McoMalloc(sizeof(double)*_row);
		if(!newm[i]){
			for(j = i-1; j >= 0; j--)
				McoFree((void *) newm[j]);
			McoFree((void *) newm);
		}
	}
			
	for( i = 0; i < _row; i++){
		for(j = 0; j < _col; j++){
			newm[j][i] = _m[i][j];
		}
	}
	
	for(i = 0; i < _row; i++){
		McoFree((void *) _m[i]);
	}
	McoFree((void *) _m);
	
	_m = newm;
	int32 temprow = _col;
	_col = _row;
	_row = temprow;
	
	return *this;
}
Esempio n. 3
0
McoStatus ScanSimpleCal::calibrate(long size, double *mea, double *ref)
{
    McoStatus status;
    long i, j, k, m;
    double avg, max;
    int32	which;
    long calsize;	//the number of patches used to calibrate
    double *desmea, *desref;
    double *cyanmea, *cyanref;

    //init
    _cleanup();

    _num_data = size;

    //matrix computation
    Matrix matconv(3);
    double mat[9];

    mat[0] = 0.5242/2.55;
    mat[1] = 0.3083/2.55;
    mat[2] = 0.1316/2.55;
    mat[3] = 0.2851/2.55;
    mat[4] = 0.6554/2.55;
    mat[5] = 0.0594/2.55;
    mat[6] = 0.0293/2.55;
    mat[7] = 0.1377/2.55;
    mat[8] = 0.6578/2.55;

    matconv.loadstruct(mat);
    matconv.inv();
    status = matconv.get_status();
    if(status != MCO_SUCCESS)	return	status;

    desmea = (double*)McoMalloc(sizeof(double)*_num_data*3);
    if(!desmea)	return	MCO_MEM_ALLOC_ERROR;

    desref = (double*)McoMalloc(sizeof(double)*_num_data*3);
    if(!desref)	return	MCO_MEM_ALLOC_ERROR;

    for(j = 0; j < _num_data*3; j++) {
        desmea[j] = mea[j];
        desref[j] = ref[j];
    }

//create global calibration
    status = _globalcal(matconv, _num_data, desmea, ref);
    if(status != MCO_SUCCESS)	return status;

    McoFree(desmea);
    McoFree(desref);

    return status;
}
Esempio n. 4
0
//_row and _col must be set before calling this method
void Matrix::_allocate(void)
{
	_m =  (double**)McoMalloc(sizeof(double*)*_row);

	if(!_m)
		_err = MCO_MEM_ALLOC_ERROR;
	else{
		for(int32 i = 0; i < _row; i++){
			_m[i] = (double*)McoMalloc(sizeof(double)*_col);
			if(!_m[i]){	//not enough memory
				for(int32 j = i-1; j >= 0; j--)
					McoFree((void *) _m[j]);

				McoFree((void *) _m);
				_m = 0;
				_err = MCO_MEM_ALLOC_ERROR;
				break;
			}
		}
	}

	//modified on 8/12 to take out smatrix class
	//for square matrix, also need to allocate for the
	//additional memory 	
	_indx = 0;
	if( _row == _col){
		if(_err == MCO_SUCCESS){
			_indx = (double*)McoMalloc(sizeof(double)*_row);
			if(!_indx){
				_deallocate();
				_err = MCO_MEM_ALLOC_ERROR;
				return;
			}
		}
	}
	//end of modification

}
Esempio n. 5
0
McoStatus ScanCal::_linearstrech(int32 num_linear, PWlinear **linear, int32 num_data, double* data)
{
	long i, j;
	double *rgb;
	
	rgb = (double*)McoMalloc(sizeof(double)*num_data);
	if(!rgb)	return MCO_MEM_ALLOC_ERROR;
	
	for(i = 0; i < num_linear; i++){
		for(j = 0; j < num_data; j++)
			rgb[j] = data[j*num_linear + i];
			
		linear[i]->apply(num_data, rgb);
		
		for(j = 0; j < num_data; j++)
			data[j*num_linear + i] = rgb[j];
	}	
		
	McoFree(rgb);
	return MCO_SUCCESS;	
}	
Esempio n. 6
0
void setup_debug(long MAX_NEWS,long MAX_PTR, long MAX_HANDLE)
{
int i;

current_level = -1;

dbg_ptr_ptrs = (void**)McoMalloc(MAX_PTR*sizeof(void*));
for (i=0; i<MAX_PTR; i++) dbg_ptr_ptrs[i] = 0L;
dbg_ptr_sizes = (long*)McoMalloc(MAX_PTR*sizeof(long));
dbg_ptr_counts = (long*)McoMalloc(MAX_PTR*sizeof(long));
dbg_ptr_levels = (long*)McoMalloc(MAX_PTR*sizeof(long));
max_ptrs = MAX_PTR;
num_ptrs = 0;


dbg_new_ptrs = (void**)McoMalloc(MAX_NEWS*sizeof(void*));
for (i=0; i<MAX_NEWS; i++) dbg_new_ptrs[i] = 0L;
dbg_new_sizes = (size_t*)McoMalloc(MAX_NEWS*sizeof(size_t));
dbg_new_counts = (long*)McoMalloc(MAX_NEWS*sizeof(long));
dbg_new_levels = (long*)McoMalloc(MAX_NEWS*sizeof(long));
max_news = MAX_NEWS;
num_new = 0;


dbg_hand_ptrs = (void**)McoMalloc(MAX_HANDLE*sizeof(void*));
for (i=0; i<MAX_HANDLE; i++) dbg_hand_ptrs[i] = 0L;
dbg_hand_sizes = (long*)McoMalloc(MAX_HANDLE*sizeof(long));
dbg_hand_counts = (long*)McoMalloc(MAX_HANDLE*sizeof(long));
dbg_hand_levels = (long*)McoMalloc(MAX_HANDLE*sizeof(long));
max_hand = MAX_HANDLE;
num_hand = 0;

current_level = 0;

}
Esempio n. 7
0
McoStatus ScanCal::_globalcal(Matrix &mat, long num, double *mea, double *ref)
{
	McoStatus status;
	long i, j;
	double white[3];
	Matrix matdata(num, 3);
	double *rgbref;
	
	white[0] = 96.42;
	white[1] = 100.0;
	white[2] = 82.49;

	rgbref = (double*)McoMalloc(sizeof(double)*num*3);
	if(!rgbref)	return MCO_MEM_ALLOC_ERROR;

	for(i = 0; i < num*3; i++)
		rgbref[i] = ref[i];
	//convert lab to XYZ
	labtonxyzinplace(rgbref, num);
	nxyztoxyzinplace(rgbref, white, num);
	
	//convert XYZ to rgb
	matdata.loadstruct(rgbref);
	matdata.T();
	Matrix matrefrgb = mat*matdata;
	matrefrgb.T();
	matrefrgb.savestruct(rgbref);
		
	//build linearization
	double x[LINEAR_NUM], y[LINEAR_NUM];
	long start = num - 23;
	long end = num;

	_linear = new PWlinear*[3];	
	for(j = 0; j < 3; j++){
		for(i = start; i < end; i++){
			y[i-start] = rgbref[i*3 + j];
			x[i-start] = mea[i*3 + j];
		}
		_linear[j] = new PWlinear(LINEAR_NUM, x, y);
	}

	//linearization stretch
	status = _linearstrech(3, _linear, num, mea);
	if(status != MCO_SUCCESS)	return status;
		
	//create matrix	
	for(i = 0; i < num*3; i++)
		rgbref[i] = ref[i];
	//convert lab to xyz
	labtonxyzinplace(rgbref, num);
	nxyztoxyzinplace(rgbref, white, num);

	_gcal = new MultiLcal(3, 3, 3, func3);
	status = _gcal->compute(num, mea, rgbref);
	if(status != MCO_SUCCESS)	{
		delete _gcal;
		return status;
	}
		
	McoFree(rgbref);
	
	return MCO_SUCCESS;
}	
Esempio n. 8
0
McoStatus Matrix::_ludcmp(void)
{
	int32 i, j, k;
	int32 imax; // row number with largest pivot
	double aamax, sum, dum;
	double *vv; //for save the scaling
	
	vv = (double*)McoMalloc(sizeof(double)*_row);
	if(!vv)
		return MCO_MEM_ALLOC_ERROR;
	
	for(i = 0; i < _row; i++)
		_indx[i] = i;
	
	_d = 1;
	
	for(i = 0; i < _row; i++){
		aamax = 0.0;
		for( j = 0; j < _col; j++)
			if(fabs(_m[i][j]) > aamax)
				aamax = fabs(_m[i][j]);
		if( aamax == 0.0){
			McoFree((void *) vv);
			return MCO_SINGULAR;
		}

		vv[i] = 1.0/aamax;
	}
	
	//loop over columns
	
	for( j = 0; j < _col; j++){
	
		for( i = 0; i < j; i++) {	
			sum = _m[i][j];
			for( k = 0; k < i; k++)
				sum -= _m[i][k]*_m[k][j];
			_m[i][j] = sum;	
		}			
		
		//search for largest pivot element
		aamax = 0;
		imax = j;
		
		for( i = j; i < _col; i++){
			sum = _m[i][j];
			for( k = 0; k < j; k++)
				sum -= _m[i][k]*_m[k][j];
			_m[i][j] = sum;
		
			dum = vv[i]*fabs(sum); //for testing pivot
			if( dum > aamax){
				imax = i;
				aamax = dum;
			}
		}
		
		if( j != imax) { //need interchange rows? j = i 
			for( k = 0; k < _col; k++){
			
				//interchange rows and change parity 
				dum = _m[imax][k];
				_m[imax][k] = _m[j][k];
				_m[j][k] = dum;
				_d = -_d;
				
				//interchange scale factor
				dum = vv[imax];
				vv[imax] = vv[j];
			}
			
			//save the interchange information
			_indx[j] = imax;
		}
		
		//divide by the pivot element
		if( j != _col){
			if( _m[j][j] == 0.0){ //pivot value is 0, singular matrix
				McoFree((void *) vv);
				return MCO_SINGULAR;//at least to the precision of the algorithm
			}
					 		
			dum = 1.0/ _m[j][j];
			for(i = j+1; i < _row; i++)
				_m[i][j] *= dum;		
		}
	}
	
	McoFree((void *) vv);

	if( _m[_row-1][_col-1] == 0.0)
		return MCO_SINGULAR;
		
	return MCO_SUCCESS;
}						
Esempio n. 9
0
//matrix inverse ( only matrix with _row == _col can be inversed	
//if the matrix is singular, 0 matrix will be given
//mathod to use in matrix operation is singular value decomposition
Matrix& Matrix::inv(void)
{
	McoStatus status;
	int32	i, j, k;
	double	**max;
	
	//if not a square matrix, return singular error
	if( _row != _col){
		_set_status(MCO_SINGULAR);
		return *this;
	}

	status = _ludcmp();
	if(status != MCO_SUCCESS){ //singular matrix, everything assigned to 0
		for(i = 0; i < _row; i++)
			for(j = 0; j < _col; j++)
				_m[i][j] = 0.0;
		_set_status(MCO_SINGULAR);
	}
				
	else{
		max = (double**)McoMalloc(sizeof(double*)*_row);
		if(!max){
			_set_status(MCO_MEM_ALLOC_ERROR);
			return *this;
		}
		for( j = 0; j < _row; j++){
			max[j] = (double*)McoMalloc(sizeof(double)*_col);
			if(!max[j]){
				_set_status(MCO_MEM_ALLOC_ERROR);
				for(k = j-1; k >= 0; k--)
					McoFree((void *) max[k]);	
				McoFree((void *) max);
				return *this;
			}
		}
		
		//set to a I matrix and solve the inverse
		for( i = 0; i < _row; i++){
			for( j = 0; j < _col; j++)
				max[i][j] = 0.0;
			max[i][i] = 1.0;	
			
			_lubksb(max[i]);
		}
		
		//fix on 8/12
		//note!!, because the max contains the transverse of
		//of the inverse, do transverse and get it back
		double tempval;
		for( i = 0; i < _row; i++){
			for( j = i; j < _col; j++){
				tempval = max[i][j];
				max[i][j] = max[j][i];
				max[j][i] = tempval;
			}
		}
		//end of fix
		
		for( i = 0; i < _row; i++)				
			McoFree((void *) _m[i]);
		
		McoFree((void *) _m);	
		
		_m = max;		
	}				
	
	return *this;
}