AnglesOptimization.cpp

Go to the documentation of this file.
00001 
00006 #include "AnglesOptimization.h"
00007 #include <iostream>
00008 #include "util.h"
00009 #include "Mesh.h"
00010 #include <fstream>
00011 #include <iomanip>
00012 
00013 using namespace std;
00014 
00015 const double AnglesOptimization::epsRange = 1.0e-3;
00016 
00017 AnglesOptimization::AnglesOptimization(Mesh *_mesh, const MSKenv_t & env) {
00018    mesh = _mesh;
00019 
00020    NUMVAR = mesh->numFaces() * 3;
00021    NUMCON = mesh->numFaces() + mesh->numVertices() + mesh->numEdges() - mesh->numBoundary();
00022    NUMANZ = 3*NUMVAR - mesh->numBoundary();
00023    NUMQNZ = NUMVAR;
00024 
00026    int r = MSK_RES_OK;
00027    r = MSK_maketask(env, NUMCON, NUMVAR, &task);
00028    check_error (r != MSK_RES_OK, "Cannot make MOSEK task for angle optimization.");
00029    r = MSK_linkfiletotaskstream(task, MSK_STREAM_LOG, "_AngleOptMosekOut.txt", 0);
00030    check_error (r != MSK_RES_OK, "Cannot link MOSEK \"_AngleOptMosekOut.txt\" output file.");
00031 }
00032 
00039 void AnglesOptimization::doSolve() {
00040    allocateMosekArrays();
00041    setDataStructres();
00042    optimize();
00043 }
00044 
00045 void AnglesOptimization::setDataStructres() {
00046 
00048    int k = 0;
00049    int kBefore = 0;
00050 
00052    Mesh::FaceIterator fIter = mesh->faceIterator();
00053    for ( ; !fIter.end(); fIter++) {
00054       k = fIter.face()->ID;
00055       bkc[k] = MSK_BK_FX;
00056       blc[k] = M_PI;
00057       buc[k] = M_PI;
00058    }
00059 
00060    kBefore = mesh->numFaces();
00061 
00065    Mesh::VertexIterator vIter = mesh->vertexIterator();
00066    for (; !vIter.end(); vIter++) {
00067       Vertex * v = vIter.vertex();
00068       k = kBefore + v->ID;
00069 
00070       if (!v->constrained) {
00071           if (!v->isBoundary()) {
00072              bkc[k] = MSK_BK_FX;
00073              blc[k] = 2*M_PI;
00074              buc[k] = 2*M_PI;
00075           }
00076           else {
00077              bkc[k] = MSK_BK_RA;
00078              blc[k] = 0;
00079              buc[k] = 2*M_PI;  
00080           }
00081       }
00082       else {
00083           if (v->max_cone_angle == v->min_cone_angle) 
00084              bkc[k] = MSK_BK_FX;
00085           else 
00086              bkc[k] = MSK_BK_RA;
00087           blc[k] = v->min_cone_angle*M_PI;
00088           buc[k] = v->max_cone_angle*M_PI;
00089       }
00090    }
00091 
00092    kBefore += mesh->numVertices();
00093    k = kBefore;
00094 
00096    Mesh::EdgeIterator eIter = mesh->edgeIterator();
00097    for ( ; !eIter.end(); eIter++) {
00098       Edge * e = eIter.edge();
00099       if (!e->isBoundary()) {
00100           e->ID = k;
00101           e->pair->ID = e->ID;
00102 
00103           bkc[k] = MSK_BK_RA;
00104           blc[k] = epsRange; 
00105           buc[k] = M_PI - epsRange; 
00106           k++;
00107       }
00108    }
00109 
00110    /* Because we solve for difference between initial angles and valid angles ,   */
00111    /* we need to subtruct initial angles from sum conditions.                     */
00112    Mesh::HalfEdgeIterator hIter = mesh->halfEdgeIterator();
00113    for (; !hIter.end(); hIter++) {
00114       Edge * e = hIter.half_edge();
00115       if (e->face) {
00116           int vId = e->oppositeVertex()->ID;
00117           int fId = e->face->ID;
00118           int eId = e->ID;
00119 
00120           vId += mesh->numFaces();
00121 
00122           blc[fId] -= e->alphaOposite;
00123           buc[fId] -= e->alphaOposite;
00124           blc[vId] -= e->alphaOposite;
00125           buc[vId] -= e->alphaOposite;
00126 
00127           if (!e->isBoundary()) {
00128              blc[eId] -= e->alphaOposite;
00129              buc[eId] -= e->alphaOposite;
00130           }
00131       }
00132    }
00133 
00134 
00136    int currPtr = 0;
00137    int count = 0;
00138 
00139    for (hIter.reset(); !hIter.end(); hIter++) {
00140       Edge * e = hIter.half_edge();
00141       if (e->face) {
00142           Edge * e = hIter.half_edge();
00143 
00144           /* Linear minim part*/
00145           c[count]    = 0.0;
00146 
00147           /* Constraint matrix (our A). */  // assigning over the columns
00148           ptrb[count] = currPtr;
00149 
00150           if (e->isBoundary())
00151              ptre[count] = currPtr + 2;
00152           else
00153              ptre[count] = currPtr + 3;
00154 
00155           int fId = e->face->ID;
00156           sub[currPtr]  = fId;
00157           val[currPtr]  = 1.0;  
00158           currPtr++;
00159 
00160           int vId = e->oppositeVertex()->ID;
00161           vId += mesh->numFaces();
00162           sub[currPtr]  = vId;
00163           val[currPtr]  = 1.0;  
00164           currPtr++;
00165 
00166           if (!e->isBoundary()) {
00167              int eId = e->ID;
00168              sub[currPtr]  = eId;
00169              val[currPtr]  = 1.0;  
00170              currPtr++;
00171           }
00172 
00173           /* Bounds. */
00174           bkx[count]  = MSK_BK_RA;
00175           blx[count]  = epsRange - e->alphaOposite;
00176           bux[count]  = (M_PI - epsRange) - e->alphaOposite;
00177           count++;
00178       }
00179    }
00180 }
00181 
00182 void AnglesOptimization::optimize() {
00183    int r = MSK_RES_OK;
00184    r = MSK_inputdata(task, NUMCON,NUMVAR, NUMCON,NUMVAR, c, 
00185       0.0, ptrb, ptre, sub, val, bkc, blc, buc, bkx, blx, bux);    
00186 
00187    check_error ( r != MSK_RES_OK, 
00188       "Could not input constraints for angle optimization.\n Check  \"AngleOptMosekOut.txt\" for output." );
00189 
00191    int count = 0;
00192    for (count = 0; count < NUMVAR; count++) {
00193       qsubi[count] = count;   
00194       qsubj[count] = count;  
00195       qval[count] = 1;
00196    }
00197 
00198    r = MSK_putqobj(task, NUMQNZ, qsubi, qsubj, qval);
00199    check_error ( r != MSK_RES_OK, 
00200       "Could not input objective for angle optimization.\n Check  \"AngleOptMosekOut.txt\" for output." );
00201 
00202 
00204    r = MSK_optimize(task);
00205    check_error ( r != MSK_RES_OK, 
00206       "Could not solve angle optimization. Possibly the problem is infisible.\n Check  \"AngleOptMosekOut.txt\" for output." );
00207 
00209    r = MSK_solutionsummary(task, MSK_STREAM_ERR);
00210    check_error ( r != MSK_RES_OK, 
00211       "Could not output solution summary.\n Check  \"AngleOptMosekOut.txt\" for output." );
00212 
00213    //MSK_writedata(task,"problem.mbt");
00215    int ps, ss;
00216    r = MSK_getsolution (task, MSK_SOL_ITR, &ps, &ss, NULL, NULL, NULL, NULL, xx, NULL, NULL, NULL, NULL, NULL, NULL);
00217 
00218    check_error ( r != MSK_RES_OK, "Could not get solution of angle optimization.\n Check  \"AngleOptMosekOut.txt\" for output." );
00219    check_error ( ps != MSK_PRO_STA_PRIM_AND_DUAL_FEAS, 
00220       "Either problem is infisible or could not find optimal solution for some other reason.\n Check  \"AngleOptMosekOut.txt\" for output." );
00221 
00223    Mesh::HalfEdgeIterator hIter = mesh->halfEdgeIterator();
00224    count = 0;
00225    for (hIter.reset(); !hIter.end(); hIter++) {
00226       Edge * e = hIter.half_edge();
00227       if (e->face) 
00228           e->alphaOposite = e->alphaOposite + xx[count++];
00229       else
00230           e->alphaOposite = 0;
00231    }
00232 
00233 
00235    Mesh::EdgeIterator eIter = mesh->edgeIterator();
00236    for (eIter.reset(); !eIter.end(); eIter++){ 
00237       Edge * e = eIter.edge();
00238       e->setTheta (M_PI - e->alphaOposite - e->pair->alphaOposite);
00239       e->pair->setTheta (e->theta());
00240    }
00241 
00242    Mesh::VertexIterator vIter = mesh->vertexIterator();
00243    for (vIter.reset(); !vIter.end(); vIter++) {
00244       vIter.vertex()->cone_angle = 0;
00245    }
00246 
00247    for (eIter.reset(); !eIter.end(); eIter++) {
00248       Edge * e = eIter.edge();
00249       e->vertex->cone_angle += e->theta();
00250       e->pair->vertex->cone_angle += e->theta();
00251    }
00252 
00253    for (vIter.reset(); !vIter.end(); vIter++) {
00254       vIter.vertex()->cone_angle /= M_PI;
00255    }
00256 }
00257 
00258 
00259 void AnglesOptimization::allocateMosekArrays() {
00260    bkc = new int[NUMCON];  bkx = new int[NUMVAR];
00261    ptrb = new int[NUMVAR]; ptre = new int[NUMVAR];
00262    sub = new int[NUMANZ];
00263    qsubi = new int[NUMQNZ]; qsubj = new int[NUMQNZ];
00264 
00265    blc = new double[NUMCON];  buc = new double[NUMCON];
00266    c = new double[NUMVAR];    blx = new double[NUMVAR];
00267    bux = new double[NUMVAR];  val = new double[NUMANZ];
00268    xx = new double[NUMVAR];   qval = new double[NUMQNZ];
00269 }
00270 
00271 void AnglesOptimization::clearMosekArrays() {
00272 
00273    if (task) {
00274       delete [] bkc;  delete [] bkx;  delete [] ptrb; 
00275       delete [] ptre;  delete [] sub;  delete [] qsubi; delete [] qsubj;
00276       delete [] buc; delete [] c;   delete [] blx; delete [] blc;
00277       delete [] bux;  delete [] val; delete [] xx;  delete [] qval;
00278       MSK_deletetask(&task);
00279       task = NULL;
00280    }
00281 }
00282 
00283 

Generated on Sat Jun 3 13:33:41 2006 for CirclePatterns by  doxygen 1.4.5