00001 #include "m23d_set_q_constraint.h"
00002
00003
00004
00005
00006
00007 #include <vcl_algorithm.h>
00008 #include <vcl_cassert.h>
00009
00010
00011
00012
00013 void m23d_set_q_constraint1(vnl_matrix<double> & A,
00014 vnl_vector<double> & rhs,
00015 unsigned c,
00016 const vnl_vector<double>& a,
00017 const vnl_vector<double>& b,
00018 double r)
00019 {
00020 rhs[c]=r;
00021 unsigned n = a.size();
00022 unsigned k=0;
00023 for (unsigned i=0;i<n;++i)
00024 for (unsigned j=0;j<=i;++j,++k)
00025 {
00026 if (i==j) A(c,k)=a[i]*b[j];
00027 else A(c,k)=a[i]*b[j]+a[j]*b[i];
00028 }
00029 }
00030
00031
00032
00033
00034 void m23d_set_q_constraint2(vnl_matrix<double> & A,
00035 vnl_vector<double> & rhs,
00036 unsigned c,
00037 const vnl_vector<double>& a,
00038 const vnl_vector<double>& b)
00039 {
00040 rhs[c]=0;
00041 unsigned n = a.size();
00042 unsigned k=0;
00043 for (unsigned i=0;i<n;++i)
00044 for (unsigned j=0;j<=i;++j,++k)
00045 {
00046 if (i==j) A(c,k)=a[i]*a[j]-b[i]*b[j];
00047 else A(c,k)=2*(a[i]*a[j]-b[i]*b[j]);
00048 }
00049 }
00050
00051
00052
00053 void m23d_set_q_constraints(const vnl_matrix<double> & M, unsigned k,
00054 vnl_matrix<double>& A,
00055 vnl_vector<double>& rhs)
00056 {
00057 unsigned m = M.cols()/3 -1;
00058 unsigned ns = M.rows()/2;
00059 unsigned nq = ((M.cols()+1)*M.cols())/2;
00060
00061 unsigned n_con = 4*(m*(ns-m-1)+(m+m*m)/2)+3*m+2*(ns-m)+1;
00062
00063
00064 A.set_size(n_con,nq);
00065 rhs.set_size(n_con);
00066
00067 unsigned c=0;
00068
00069
00070 for (unsigned j=0;j<ns;++j)
00071 {
00072 vnl_vector<double> rxj = M.get_row(2*j);
00073 vnl_vector<double> ryj = M.get_row(2*j+1);
00074 for (unsigned i=0;i<=vcl_min(j,m);++i)
00075 {
00076 vnl_vector<double> rxi = M.get_row(2*i);
00077 vnl_vector<double> ryi = M.get_row(2*i+1);
00078
00079 if (i==j)
00080 {
00081 if (i==k)
00082 {
00083
00084 m23d_set_q_constraint1(A,rhs,c,rxi,rxi,1.0); ++c;
00085 m23d_set_q_constraint1(A,rhs,c,ryi,ryi,1.0); ++c;
00086 m23d_set_q_constraint1(A,rhs,c,rxi,ryi,0.0); ++c;
00087 }
00088 else
00089 {
00090
00091 m23d_set_q_constraint1(A,rhs,c,rxi,rxi,0); ++c;
00092 m23d_set_q_constraint1(A,rhs,c,ryi,ryi,0); ++c;
00093 m23d_set_q_constraint1(A,rhs,c,rxi,ryi,0); ++c;
00094 }
00095 }
00096 else
00097 if (!((i==k) && j>m))
00098 {
00099
00100 m23d_set_q_constraint1(A,rhs,c,rxi,rxj,0); ++c;
00101 m23d_set_q_constraint1(A,rhs,c,ryi,ryj,0); ++c;
00102 m23d_set_q_constraint1(A,rhs,c,rxi,ryj,0); ++c;
00103 m23d_set_q_constraint1(A,rhs,c,ryi,rxj,0); ++c;
00104 }
00105 }
00106 }
00107
00108
00109
00110 for (unsigned i=m+1;i<ns;++i)
00111 {
00112 vnl_vector<double> rxi = M.get_row(2*i);
00113 vnl_vector<double> ryi = M.get_row(2*i+1);
00114 m23d_set_q_constraint2(A,rhs,c,rxi,ryi); ++c;
00115 m23d_set_q_constraint1(A,rhs,c,rxi,ryi,0); ++c;
00116 }
00117
00118 assert(c==n_con);
00119 }