Ejemplo n.º 1
0
int __init p_init(void)
{
#ifdef MODULE
//	SET_MODULE_OWNER(&p_fops_mdaa);
#endif
	memset(pipes, 0, sizeof(pipes));

	(pipes[0].mda) = create_proc_entry("a.mda", 0, NULL);
	(pipes[0].mda)->proc_fops = &p_fops_mdaa;
	(pipes[0].idx) = create_proc_entry("a.idx", 0, NULL);
	(pipes[0].idx)->proc_fops = &p_fops_idxa;
	sema_init(&(SEMAPHO(0)), 1);
	init_waitqueue_head(&(RQ(0)));
	init_waitqueue_head(&(WQ(0)));
#ifdef DOUBLE_DEV
	(pipes[1].mda) = create_proc_entry("b.mda", 0, NULL);
	(pipes[1].mda)->proc_fops = &p_fops_mdab;
	(pipes[1].idx) = create_proc_entry("b.idx", 0, NULL);
	(pipes[1].idx)->proc_fops = &p_fops_idxb;
	sema_init(&(SEMAPHO(1)), 1);
	init_waitqueue_head(&(RQ(1)));
	init_waitqueue_head(&(WQ(1)));
#endif
	// init khttp --carl.
	#ifdef KERNEL_PIPE
	printk("\033[1;33mNew kernel pipe 0717_2007................\033[0m\n");
	kpipe_init();
	#endif

	return 0;
}
Ejemplo n.º 2
0
// insert a written block.
int proc_insertBuff(int index,int pathIndex,struct block *buff,loff_t pos, size_t count,context *ct)
{
	loff_t* f_pos,spos;
	size_t left = count, wrt;
	int ret;

	if(RELEASE(index)) return count;

	if(pathIndex==INDEX_PATH_NUM) {
		spos = ((pipes[index].ct)[CONTEXT]).bpos + pos;
	} else {
		spos=pos;
	}
	
			
	f_pos=(loff_t *)&spos;
	
	
	while(1) {
		Down(index);
		wrt = left;
		ret = dev_insertBuff(&((pipes[index]).device), f_pos,buff, &left, ct);
		if(pathIndex==INDEX_PATH_NUM)
			POS(ct)=*f_pos-((pipes[index].ct)[CONTEXT]).bpos;
		else
			POS(ct)=*f_pos;
			
		if(ret == DEV_FAULT) {Up(index); return -EFAULT;}

		if(wrt && !R_ABLE(ct)) {
			R_ABLE(ct) = 1;
			if(ret == DEV_SEEK) {
				wake_up_interruptible_sync(&(RQ(index)));
			}
			else {
				wake_up_interruptible(&(RQ(index)));
			}
		}
		if(ret == DEV_SEEK) {Up(index); return -P_ESEEK;}

		if(ret == DEV_FULL) {
			W_ABLE(ct) = 0; Up(index);
			PDEBUG("<%d>: device full, sleep, left %d\n", current->pid, (int)left);
			Wait_Event(WQ(index), RELEASE(index)||W_ABLE(ct));
			if(RELEASE(index)) return count;
			continue;
		}
		Up(index);

		if(left <= 0) break;
	}
	return count;

}
Ejemplo n.º 3
0
void GQR
( Matrix<F>& A, Matrix<F>& tA, Matrix<Base<F>>& dA, 
  Matrix<F>& B, Matrix<F>& tB, Matrix<Base<F>>& dB )
{
    DEBUG_ONLY(CallStackEntry cse("GQR"))
    QR( A, tA, dA );
    qr::ApplyQ( LEFT, ADJOINT, A, tA, dA, B );
    RQ( B, tB, dB );
}
Ejemplo n.º 4
0
static ssize_t p_write(int index, struct file* filp, const char* buf, size_t count, loff_t* f_pos)
{
	context *ct = filp->private_data;
	size_t left = count, wrt;
	int ret;

	if(RELEASE(index)) return count;

	while(1) {
		Down(index);
		wrt = left;
		ret = dev_write(&((pipes[index]).device), f_pos, buf+(count-left), &left, ct);

		if(ret == DEV_FAULT) {Up(index); return -EFAULT;}

#ifdef __PIPE_SELECT
        pipes[index].r_poll = 1;
#endif
		if(wrt) {
			R_ABLE(ct) = 1;
			if(ret == DEV_SEEK) {
				wake_up_interruptible_sync(&(RQ(index)));
			}
			else {
				wake_up_interruptible(&(RQ(index)));
			}
		}
		if(ret == DEV_SEEK) {Up(index); return -P_ESEEK;}

		if(ret == DEV_FULL) {
			W_ABLE(ct) = 0; Up(index);
			PDEBUG("<%d>: device full, sleep, left %d\n", current->pid, (int)left);
			Wait_Event(WQ(index), RELEASE(index)||W_ABLE(ct));
			if(RELEASE(index)) return count;
			continue;
		}
		Up(index);

		if(left <= 0) break;
	}
	return count;
}
Ejemplo n.º 5
0
static unsigned int p_poll(int index, struct file *filp, poll_table *wait)
{
    unsigned int mask = 0;
    pipe_file *pp = &(pipes[index]);

#ifdef KERNEL_PIPE
	if(pipeType[index]>=PIPE_TYPE_KERNEL_THREAD)
		return (POLLIN|POLLRDNORM);
#endif

    poll_wait(filp, &(RQ(index)), wait);
    if(pp->r_poll || dev_search(&(pp->device), pp->r_pos, (pp->device).head)){
        if(pp->r_poll) pp->r_poll = 0;
        mask |= POLLIN | POLLRDNORM;  /* readable */
    }
    return mask;
}
Ejemplo n.º 6
0
ValueInt<Base<F>> InverseFreeSignDivide( ElementalMatrix<F>& XPre )
{
    DEBUG_CSE

    DistMatrixReadWriteProxy<F,F,MC,MR> XProx( XPre );
    auto& X = XProx.Get();

    typedef Base<F> Real;
    const Grid& g = X.Grid();
    const Int n = X.Width();
    if( X.Height() != 2*n )
        LogicError("Matrix should be 2n x n");
   
    // Expose A and B, and then copy A
    auto B = X( IR(0,n  ), ALL );
    auto A = X( IR(n,2*n), ALL );
    DistMatrix<F> ACopy( A );

    // Run the inverse-free alternative to Sign
    InverseFreeSign( X );

    // Compute the pivoted QR decomp of inv(A + B) A [See LAWN91]
    // 1) B := A + B 
    // 2) [Q,R,Pi] := QRP(A)
    // 3) B := Q^H B
    // 4) [R,Q] := RQ(B)
    B += A;
    DistMatrix<F,MD,STAR> t(g);
    DistMatrix<Base<F>,MD,STAR> d(g);
    DistMatrix<Int,VR,STAR> p(g);
    QR( A, t, d, p );
    qr::ApplyQ( LEFT, ADJOINT, A, t, d, B );
    RQ( B, t, d );

    // A := Q^H A Q
    A = ACopy;
    rq::ApplyQ( LEFT, ADJOINT, B, t, d, A );
    rq::ApplyQ( RIGHT, NORMAL, B, t, d, A );

    // Return || E21 ||1 / || A ||1
    // Return || E21 ||1 / || A ||1
    ValueInt<Real> part = ComputePartition( A );
    part.value /= OneNorm(ACopy);
    return part;
}
Ejemplo n.º 7
0
Base<F> InverseFreeSignDivide( Matrix<F>& X )
{
    DEBUG_CSE
    typedef Base<F> Real;
    const Int n = X.Width();
    if( X.Height() != 2*n )
        LogicError("Matrix should be 2n x n");
   
    // Expose A and B, and then copy A
    auto B = X( IR(0,n  ), ALL );
    auto A = X( IR(n,2*n), ALL );
    Matrix<F> ACopy( A );

    // Run the inverse-free alternative to Sign
    InverseFreeSign( X );

    // Compute the pivoted QR decomp of inv(A + B) A [See LAWN91]
    // 1) B := A + B 
    // 2) [Q,R,Pi] := QRP(A)
    // 3) B := Q^H B
    // 4) [R,Q] := RQ(B)
    B += A;
    Matrix<F> t;
    Matrix<Base<F>> d;
    Matrix<Int> p;
    QR( A, t, d, p );
    qr::ApplyQ( LEFT, ADJOINT, A, t, d, B );
    RQ( B, t, d );

    // A := Q^H A Q
    A = ACopy;
    rq::ApplyQ( LEFT, ADJOINT, B, t, d, A );
    rq::ApplyQ( RIGHT, NORMAL, B, t, d, A );

    // Return || E21 ||1 / || A ||1
    ValueInt<Real> part = ComputePartition( A );
    part.value /= OneNorm(ACopy);
    return part;
}
Ejemplo n.º 8
0
  SimpleCamera simpleCamera(const Matrix& P) {

    // P = [A|a] = s K cRw [I|-T], with s the unknown scale
    Matrix A = P.topLeftCorner(3, 3);
    Vector a = P.col(3);

    // do RQ decomposition to get s*K and cRw angles
    Matrix sK;
    Vector xyz;
    boost::tie(sK, xyz) = RQ(A);

    // Recover scale factor s and K
    double s = sK(2, 2);
    Matrix K = sK / s;

    // Recover cRw itself, and its inverse
    Rot3 cRw = Rot3::RzRyRx(xyz);
    Rot3 wRc = cRw.inverse();

    // Now, recover T from a = - s K cRw T = - A T
    Vector T = -(A.inverse() * a);
    return SimpleCamera(Pose3(wRc, T),
        Cal3_S2(K(0, 0), K(1, 1), K(0, 1), K(0, 2), K(1, 2)));
  }
Ejemplo n.º 9
0
static int p_release(int index, struct inode* inode, struct file* filp)
{
#ifdef __PIPE_SELECT__
    pipe_file *pp = &(pipes[index]);
#endif
#ifdef KERNEL_PIPE
#ifdef NO_KERNEL_PIPE_THREAD
	if (pipeType[index] == PIPE_TYPE_KERNEL_DIRECT) {
		sock_pos_t *sp=(sock_pos_t *)filp->private_data;
		if(sp && sp->magic==SOCK_POS_MAGIC) {
			if(sp->sock) {
				sock_release(sp->sock);
				sp->sock = NULL;
			}
			if(sp->request) {
				kfree(sp->request);
				sp->request = NULL;
				sp->leftLen = 0;
				sp->leftPos = NULL;
			}
			kfree(sp);
			filp->private_data=NULL;
		}
	}
#endif
#endif
	wake_up_interruptible(&(RQ(index)));
	wake_up_interruptible(&(WQ(index)));
#ifdef __PIPE_SELECT__
    pp->r_poll = 1;
    pp->r_pos = 0;
#endif
	rcount--;
	
	return 0;
}
Ejemplo n.º 10
0
static ssize_t p_read(int index, struct file* filp, char* buf, size_t count, loff_t* f_pos)
{
	context *ct = NULL;
	size_t left;
	int ret;

	if(RELEASE(index)) return -ENXIO;

	Down(index);

	ct = getct(index, *f_pos);
	if(*f_pos >= EPOS(ct)) {Up(index); return 0;}

	count = (*f_pos+count>EPOS(ct))?(EPOS(ct)-(*f_pos)):(count); left = count;

	#ifdef KERNEL_PIPE
	#ifdef NO_KERNEL_PIPE_THREAD
		if(pipeType[index] == PIPE_TYPE_KERNEL_DIRECT) {
	 		Up(index);
			return p_sock_read(index,filp,buf,count,f_pos);
		}
	#endif
	#endif
	
	while(1) {
		ret = dev_read(&((pipes[index]).device), f_pos, buf+(count-left), &left, ct);

#ifdef __PIPE_SELECT__
        pipes[index].r_pos = *f_pos+(count-left);
#endif
		if(ret == DEV_FAULT) {Up(index); return -EFAULT;}

		if(!W_ABLE(ct)) {
			W_ABLE(ct) = 1;
			wake_up_interruptible(&(WQ(index)));
		}
		if(left>0) {
			if(filp->f_flags & O_NONBLOCK) {
#ifdef __PIPE_SELECT__
                pipes[index].r_poll = 0;
#endif
				Up(index);
				if(count == left) return -EAGAIN;
				break;
			}
			R_ABLE(ct) = 0; Up(index);
			PDEBUG("<%d>: need more data, sleep\n", current->pid);
			Wait_Event(RQ(index), RELEASE(index)||R_ABLE(ct));
#ifdef	CONFIG_PROC_PIPE_64_BITS_SUPPORT
			if (*f_pos >= pipes[index].mda_size )
#else	// CONFIG_PROC_PIPE_64_BITS_SUPPORT
			if (*f_pos >= pipes[index].mda->size)
#endif	// CONFIG_PROC_PIPE_64_BITS_SUPPORT
				return (count - left);
			if(RELEASE(index)) return -ENXIO;
			Down(index);
		}
		else {Up(index); break;}
	}
	return (count - left);
}
Ejemplo n.º 11
0
static int p_ioctl(int index, struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg)
{
	context *ct = filp->private_data;
	pipe_file *pp = &(pipes[index]);
	tell_inf t_inf;
	size_inf s_inf;
#ifdef KRSA
	krsa_arg rsa;
	unsigned char *input = NULL, output[MAX_RSA_MODULUS_LEN];
	unsigned int inputlen = 0, outputlen = 0;
#endif
	int err = 0, ret = 0, i;

	if(!capable(CAP_SYS_ADMIN)) return -EPERM;

	if(_IOC_TYPE(cmd) != P_IOCMAGIC) return -ENOTTY;

	if(_IOC_DIR(cmd) & _IOC_READ) {
		err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
	}
	else if(_IOC_DIR(cmd) & _IOC_WRITE) {
		err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
	}
	if(err) return -EFAULT;

	Down(index);

	switch(cmd) {
	case P_IOCCLEAR:
		dev_flush(&(pp->device));
		for(i=0; i<=CONTEXT; i++) {
			((pp->ct)[i]).hotp = NULL;	
		}
		break;
	case P_IOCRESET:
		memset(pp->ct, 0, sizeof(context)*(CONTEXT+1));
#ifdef __PIPE_SELECT__
        pp->r_poll = 1;
        pp->r_pos = 0;
#endif
		for(i=0; i<=CONTEXT; i++) {
			((pp->ct)[i]).r_able = 1;
			((pp->ct)[i]).w_able = 1;
		}
		RELEASE(index) = 0; WRITERS(index) = 0;
		dev_flush(&(pp->device));
		(pp->device).ctp = pp->ct;
		(pp->device).pred = 2*BUFF_SIZE;
	#ifdef KERNEL_PIPE
		pipeType[index]=PIPE_TYPE_USER_THREAD;
	#endif
	
		break;
	case P_IOCSIZE:
		if(copy_from_user((char*)&s_inf, (char*)arg, sizeof(size_inf))) {
			ret = (-EFAULT); goto my_error;
		}
#ifndef	CONFIG_PROC_PIPE_64_BITS_SUPPORT
#ifndef CONFIG_PROC_PIPE_KERNEL_SUPPORT_64_BITS
		if(s_inf.mdas > 0xFFFFFFFFF || s_inf.idxs > 0xFFFFFFFF) {
			ret = (-EFAULT); goto my_error;
		}
#endif
		(pp->mda)->size = s_inf.mdas;
		(pp->idx)->size = s_inf.idxs;
#else	// !CONFIG_PROC_PIPE_64_BITS_SUPPORT
#if 0
		(pp->mda)->size = s_inf.mdas;
		(pp->idx)->size = s_inf.idxs;
#else
		(pp->mda)->size = 0; 
		(pp->idx)->size = 0;
#endif
		pp->mda_size = s_inf.mdas;
		pp->idx_size = s_inf.idxs;
#endif	// !CONFIG_PROC_PIPE_64_BITS_SUPPORT
		for(i=0; i<CONTEXT; i++) {
			((pp->ct)[i]).epos = s_inf.mdas;
		}
		((pp->ct)[CONTEXT]).bpos = s_inf.dats;
		((pp->ct)[CONTEXT]).epos = s_inf.dats + s_inf.idxs;
		((pp->ct)[CONTEXT]).seek = s_inf.dats;
		break;
	case P_IOCREVS:
		((pp->ct)[CONTEXT]).reverse = *((int*)arg);
		break;
	case P_IOCTELL:
		t_inf.seek = filp->f_pos;
		t_inf.size = (BPOS(ct))?(BUFF_SIZE):(SIZE(ct));
		if(copy_to_user((char*)arg, (char*)&t_inf, sizeof(tell_inf))) {
			ret = (-EFAULT); goto my_error;
		}
		break;
	case P_IOCRELS:
		RELEASE(index) = 1;
		wake_up_interruptible(&(RQ(index)));
		wake_up_interruptible(&(WQ(index)));
		break;
	case P_IOCPRED:
		(pp->device).pred = *((size_t*)arg);
		break;
#ifdef KRSA
	case P_IOCKRSA:
		if(copy_from_user((char*)&rsa, (char*)arg, sizeof(krsa_arg))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_READ, (void *)(rsa.len), sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_from_user((char*)&inputlen, (char*)(rsa.len), sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!(input = kmalloc(inputlen, GFP_KERNEL))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_READ, (void *)(rsa.buf), inputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_from_user((char*)input, (char*)(rsa.buf), inputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(RSAPrivateBlock(output, &outputlen, input, inputlen, &(rsa.key))) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_WRITE, (void *)(rsa.buf), outputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_to_user((char*)(rsa.buf), (char*)output, outputlen)) {
			ret = (-EFAULT); goto my_error;
		}
		if(!access_ok(VERIFY_WRITE, (void *)(rsa.len), sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		if(copy_to_user((char*)(rsa.len), (char*)&outputlen, sizeof(unsigned int))) {
			ret = (-EFAULT); goto my_error;
		}
		break;
#endif


	#ifdef KERNEL_PIPE
	case P_IOCPIPETYPE:
			{
				int val;

				get_user(val,(int *)arg);

				if(val<0) {
					ret= -EFAULT;
					break;
				}
				
				#ifdef NO_KERNEL_PIPE_THREAD
					if(val<=PIPE_TYPE_KERNEL_DIRECT)
				#else
					if(val<=PIPE_TYPE_KERNEL_THREAD)
				#endif
					pipeType[index]=val;
				 else
				 	ret= -EFAULT;
			}
		break;
	case P_IOCPIPESTART:
		{
		//	int len;
			kpipe_setup userPath;
			kpipe_setup *pipeSetup;
			pipe_thread *pipeThread;
			DECLARE_WAIT_QUEUE_HEAD(WQ);

			copy_from_user(&userPath,(kpipe_setup *)arg,sizeof(kpipe_setup));
			
			
			pipeSetup=pipeManage.threads[index].pipeSetup;
			pipeThread=&(pipeManage.threads[index]);

//select a default pipe type.
			if(pipeType[index]==PIPE_TYPE_USER_THREAD)
				pipeType[index]=defaultPipeType;
			if(pipeType[index]!=PIPE_TYPE_KERNEL_THREAD && pipeType[index]!=PIPE_TYPE_KERNEL_DIRECT)
				pipeType[index]=PIPE_TYPE_KERNEL_DIRECT;

	//pipe_type_kernel_direct doesn't support local file.
	#ifdef NO_KERNEL_PIPE_THREAD
			if(pipeType[index]==PIPE_TYPE_KERNEL_DIRECT) {
				if(userPath.type>PIPE_KP) {
					ret = -EFAULT;
					break;
					}
			}
		#endif
			
			if(*(pipeSetup->host)) //if it has used already? a.dma or a.index.
				pipeSetup++;
			if(*(pipeSetup->host)) {
				HDEBUG("no pipeSetup\n");
				ret = -EFAULT;
				break;
			}
				

			
			pipeThread->index = index;	//a or b.
			pipeSetup->index = index;
		//	copy_from_user(&pipeSetup->nums,&userPath.nums,1);
			pipeSetup->nums = userPath.nums;
			
		//	copy_from_user(&pipeSetup->size,&((kpipe_setup *)arg)->size,sizeof(int));
			 pipeSetup->size = userPath.size;
			 
		//	copy_from_user(&httpThread->type,&((kpipe_setup *)arg)->type,1);
			pipeThread->type = userPath.type;	//close or keep alive.
			
			memcpy(pipeSetup->host,userPath.host,16);

			memcpy(pipeSetup->procfile,userPath.procfile,16);
			
			if(!strcmp(pipeSetup->procfile+strlen("/proc/a."),"mda")) {
				
				pipeSetup->pathIndex = MEDIA_PATH_NUM;	//dma or index.
			} else {
				pipeSetup->pathIndex  = INDEX_PATH_NUM;
			}
			
		
		//	pipeSetup->host=HTTP_MALLOC(strlen(userPath->host)+1);
			pipeSetup->path=HTTP_MALLOC(userPath.pathSize);
		//	pipeSetup->sessionid=HTTP_MALLOC(((kpipe_setup *)arg)->sessionidSize);
			
			if(!pipeSetup->path) {
			// no memroy.
			}
			
			copy_from_user(pipeSetup->path,userPath.path,userPath.pathSize);
		
			if(userPath.sessionid){
				pipeSetup->sessionid=HTTP_MALLOC(userPath.sessionidSize);

				copy_from_user(pipeSetup->sessionid,userPath.sessionid,userPath.sessionidSize);
			}
			
		//	copy_from_user(&(pipeSetup->port),&userPath.port),sizeof(short));
			pipeSetup->port = userPath.port;
			
		//	copy_from_user(&(pipeSetup->protection),&(((kpipe_setup *)arg)->protection),sizeof(int));			
			pipeSetup->protection = userPath.protection;

			HDEBUG("ioctl:%s %d:%s\n",pipeSetup->host,pipeSetup->port,pipeSetup->path);
			
			//pipeManage.starts[index][pipeSetup->index].start=1;
		
			if(pipeType[index]==PIPE_TYPE_KERNEL_THREAD) {
				down_interruptible(&(pipeManage.semaphore));
				atomic_set(&(pipeManage.starts[index][pipeSetup->pathIndex]),1); //start kernel_thread.
			//to wakeup manage thread.
		
				while(pipeManage.change) {
					interruptible_sleep_on_timeout(&WQ,5);
				}
				pipeManage.change=1;
				up(&(pipeManage.semaphore));
				wake_up_interruptible(&(pipeManage.wq));
				
			}
		
	
		}
		
	
		break;
	case P_IOCPIPESTOP:
		{
		
			pipe_thread *thread=&(pipeManage.threads[index]);
			int i;
			DECLARE_WAIT_QUEUE_HEAD(WQ);	

			RELEASE(index) = 1;

		if(pipeType[index]==PIPE_TYPE_KERNEL_THREAD) {
			wake_up_interruptible(&(RQ(index)));
			wake_up_interruptible(&(WQ(index)));



			down_interruptible(&(pipeManage.semaphore));
			atomic_set(&(pipeManage.stops[index]),1);
				//to wakeup manage thread.
			while(pipeManage.change) {
					interruptible_sleep_on_timeout(&WQ,5);
			}
			pipeManage.change = 1;
			up(&(pipeManage.semaphore));
			wake_up_interruptible(&(pipeManage.wq));
			
		} 
		else {
			 	for(i=0;i<END_PATH_NUM;i++) {
				if(thread->pipeSetup[i].path) {
					HTTP_FREE(thread->pipeSetup[i].path);
					if(thread->pipeSetup[i].sessionid)
						HTTP_FREE(thread->pipeSetup[i].sessionid);
					memset(&(thread->pipeSetup[i]),0,sizeof(kpipe_setup));
				}
			}
		}	
	
			
		}
		break;
	#endif
	default:
		ret = (-ENOTTY);
	}
	
my_error:
#ifdef KRSA
	if(input) kfree(input);
#endif
	Up(index);
	return ret;
}
Ejemplo n.º 12
0
/* ************************************************************************* */
Vector3 Rot3::xyz() const {
  Matrix3 I;Vector3 q;
  boost::tie(I,q)=RQ(matrix());
  return q;
}